Vrda's picture
Feature: EN/HR language toggle on login + full app i18n
81046e2
/**
* Simple i18n system for Learn Pathophysiology
* Supports: English (en) and Croatian (hr)
*/
export type Lang = 'en' | 'hr'
export const LANG_STORAGE_KEY = 'lp_lang'
export function getStoredLang(): Lang {
const stored = localStorage.getItem(LANG_STORAGE_KEY)
if (stored === 'en' || stored === 'hr') return stored
return 'hr' // default to Croatian
}
export function storeLang(lang: Lang) {
localStorage.setItem(LANG_STORAGE_KEY, lang)
}
const translations = {
// ---- Login Page ----
'login.title': {
en: 'Learn Pathophysiology',
hr: 'Learn Pathophysiology',
},
'login.subtitle': {
en: 'AI assistant for learning pathophysiology',
hr: 'AI asistent za učenje patofiziologije',
},
'login.prompt': {
en: 'Sign in to continue',
hr: 'Prijavi se za pristup',
},
'login.loading': {
en: 'Signing in...',
hr: 'Prijava u tijeku...',
},
'login.error.gsi': {
en: 'Failed to load Google Sign-In. Check your internet connection.',
hr: 'Greška pri učitavanju Google prijave. Provjeri internet vezu.',
},
'login.error.failed': {
en: 'Google sign-in failed. Please try again.',
hr: 'Google prijava nije uspjela. Pokušaj ponovo.',
},
'login.iframe.hint': {
en: 'If login doesn\'t work, open the app directly:',
hr: 'Ako prijava ne radi, otvori aplikaciju direktno:',
},
'login.footer.powered': {
en: 'Powered by Gemini AI',
hr: 'Powered by Gemini AI',
},
'login.footer.edition': {
en: 'WC3 Edition',
hr: 'WC3 Edition',
},
// ---- App Header ----
'app.title': {
en: 'Learn Pathophysiology',
hr: 'Learn Pathophysiology',
},
'app.subtitle': {
en: 'AI assistant for learning pathophysiology',
hr: 'AI asistent za ucenje patofiziologije',
},
'app.loading': {
en: 'Loading...',
hr: 'Učitavanje...',
},
// ---- Tabs ----
'tab.chat': {
en: 'Chat',
hr: 'Chat',
},
'tab.image': {
en: 'Image Analysis',
hr: 'Analiza slike',
},
// ---- Sidebar ----
'sidebar.selectModel': {
en: 'Select model',
hr: 'Odaberi model',
},
'sidebar.theme': {
en: 'Theme',
hr: 'Tema',
},
'sidebar.options': {
en: 'Options',
hr: 'Opcije',
},
'sidebar.showSources': {
en: 'Show sources',
hr: 'Prikazi izvore',
},
'sidebar.newChat': {
en: 'New conversation',
hr: 'Novi razgovor',
},
'sidebar.knowledgeBase': {
en: 'Knowledge Base',
hr: 'Baza znanja',
},
'sidebar.documents': {
en: 'documents',
hr: 'dokumenata',
},
'sidebar.logout': {
en: 'Sign out',
hr: 'Odjavi se',
},
'sidebar.language': {
en: 'Language',
hr: 'Jezik',
},
// ---- Chat ----
'chat.welcome': {
en: 'Welcome!',
hr: 'Dobrodosli!',
},
'chat.welcomeHint': {
en: 'Ask a question about pathophysiology.',
hr: 'Postavi pitanje o patofiziologiji.',
},
'chat.placeholder': {
en: 'Ask a question about pathophysiology...',
hr: 'Postavi pitanje o patofiziologiji...',
},
'chat.send': {
en: 'Send',
hr: 'Posalji',
},
'chat.generating': {
en: 'Generating response',
hr: 'Generiranje odgovora',
},
'chat.error': {
en: 'Error sending message',
hr: 'Greska pri slanju poruke',
},
// ---- Image ----
'image.dropHint': {
en: 'Click or drag an image here',
hr: 'Klikni ili povuci sliku ovdje',
},
'image.uploadHint': {
en: 'Upload a page for analysis',
hr: 'Uploadaj stranicu za analizu',
},
'image.questionPlaceholder': {
en: 'Ask a question about the image (optional)...',
hr: 'Postavi pitanje o slici (opcionalno)...',
},
'image.analyze': {
en: 'Analyze image',
hr: 'Analiziraj sliku',
},
'image.analyzing': {
en: 'Analyzing...',
hr: 'Analiziram...',
},
'image.analyzingStatus': {
en: 'Analyzing',
hr: 'Analiziranje',
},
'image.error': {
en: 'Error analyzing image',
hr: 'Greska pri analizi slike',
},
// ---- Citations ----
'citations.sources': {
en: 'Sources',
hr: 'Izvori',
},
'citations.page': {
en: 'p.',
hr: 'str.',
},
} as const
export type TranslationKey = keyof typeof translations
export function t(key: TranslationKey, lang: Lang): string {
const entry = translations[key]
if (!entry) return key
return entry[lang] || entry['en'] || key
}