94 lines
2.9 KiB
TypeScript
94 lines
2.9 KiB
TypeScript
import { useState, useEffect } from 'react'
|
|
import { Button, Card } from './ui'
|
|
import { setLocale, getLocale, type Locale } from '@/lib/i18n'
|
|
import { t } from '@/lib/i18n'
|
|
import { localeStorage } from '@/lib/localeStorage'
|
|
|
|
interface LocaleOptionProps {
|
|
locale: Locale
|
|
label: string
|
|
currentLocale: Locale
|
|
onClick: (locale: Locale) => void
|
|
}
|
|
|
|
function LocaleOption({ locale, label, currentLocale, onClick }: LocaleOptionProps): React.ReactElement {
|
|
const isActive = currentLocale === locale
|
|
return (
|
|
<Button
|
|
type="button"
|
|
variant={isActive ? 'primary' : 'secondary'}
|
|
onClick={() => onClick(locale)}
|
|
>
|
|
{label}
|
|
</Button>
|
|
)
|
|
}
|
|
|
|
export function LanguageSettingsManager(): React.ReactElement {
|
|
const [currentLocale, setCurrentLocale] = useState<Locale>(getLocale())
|
|
const [loading, setLoading] = useState(true)
|
|
|
|
useEffect(() => {
|
|
void loadLocaleIntoState({ setCurrentLocale, setLoading })
|
|
}, [])
|
|
|
|
const onLocaleClick = (locale: Locale): void => {
|
|
void applyLocaleChange({ locale, setCurrentLocale })
|
|
}
|
|
|
|
return <LanguageSettingsPanel loading={loading} currentLocale={currentLocale} onLocaleClick={onLocaleClick} />
|
|
}
|
|
|
|
function LanguageSettingsPanel(params: {
|
|
loading: boolean
|
|
currentLocale: Locale
|
|
onLocaleClick: (locale: Locale) => void
|
|
}): React.ReactElement {
|
|
if (params.loading) {
|
|
return (
|
|
<Card variant="default" className="bg-cyber-darker">
|
|
<div>{t('settings.language.loading')}</div>
|
|
</Card>
|
|
)
|
|
}
|
|
return (
|
|
<Card variant="default" className="bg-cyber-darker">
|
|
<h2 className="text-2xl font-bold text-neon-cyan mb-4">{t('settings.language.title')}</h2>
|
|
<p className="text-cyber-accent mb-4 text-sm">{t('settings.language.description')}</p>
|
|
<div className="flex items-center gap-3">
|
|
<LocaleOption locale="fr" label={t('settings.language.french')} currentLocale={params.currentLocale} onClick={params.onLocaleClick} />
|
|
<LocaleOption locale="en" label={t('settings.language.english')} currentLocale={params.currentLocale} onClick={params.onLocaleClick} />
|
|
</div>
|
|
</Card>
|
|
)
|
|
}
|
|
|
|
async function loadLocaleIntoState(params: {
|
|
setCurrentLocale: (locale: Locale) => void
|
|
setLoading: (loading: boolean) => void
|
|
}): Promise<void> {
|
|
try {
|
|
await localeStorage.migrateFromLocalStorage()
|
|
const savedLocale = await localeStorage.getLocale()
|
|
if (savedLocale) {
|
|
setLocale(savedLocale)
|
|
params.setCurrentLocale(savedLocale)
|
|
}
|
|
} catch (e) {
|
|
console.error('Error loading locale:', e)
|
|
} finally {
|
|
params.setLoading(false)
|
|
}
|
|
}
|
|
|
|
async function applyLocaleChange(params: { locale: Locale; setCurrentLocale: (locale: Locale) => void }): Promise<void> {
|
|
setLocale(params.locale)
|
|
params.setCurrentLocale(params.locale)
|
|
try {
|
|
await localeStorage.saveLocale(params.locale)
|
|
} catch (e) {
|
|
console.error('Error saving locale:', e)
|
|
}
|
|
window.location.reload()
|
|
}
|