76 lines
1.9 KiB
TypeScript
76 lines
1.9 KiB
TypeScript
import { useEffect, useState } from 'react'
|
|
import { setLocale, getLocale, loadTranslations, t, type Locale } from '@/lib/i18n'
|
|
|
|
export function useI18n(locale: Locale = 'fr'): {
|
|
loaded: boolean
|
|
locale: Locale
|
|
t: (key: string, params?: Record<string, string | number>) => string
|
|
} {
|
|
const [loaded, setLoaded] = useState(false)
|
|
const [currentLocale, setCurrentLocale] = useState<Locale>(getLocale())
|
|
|
|
useEffect(() => {
|
|
void initializeI18n({
|
|
locale,
|
|
setLoaded,
|
|
setCurrentLocale,
|
|
})
|
|
}, [locale])
|
|
|
|
return { loaded, locale: currentLocale, t }
|
|
}
|
|
|
|
async function initializeI18n(params: {
|
|
locale: Locale
|
|
setLoaded: (value: boolean) => void
|
|
setCurrentLocale: (value: Locale) => void
|
|
}): Promise<void> {
|
|
try {
|
|
const savedLocale = await readSavedLocale()
|
|
const initialLocale = isSupportedLocale(savedLocale) ? savedLocale : params.locale
|
|
await loadAllTranslations()
|
|
setLocale(initialLocale)
|
|
params.setCurrentLocale(initialLocale)
|
|
} catch (e) {
|
|
console.error('Error loading translations:', e)
|
|
} finally {
|
|
params.setLoaded(true)
|
|
}
|
|
}
|
|
|
|
function isSupportedLocale(value: unknown): value is Locale {
|
|
return value === 'fr' || value === 'en'
|
|
}
|
|
|
|
async function readSavedLocale(): Promise<Locale | null> {
|
|
try {
|
|
const { localeStorage } = await import('@/lib/localeStorage')
|
|
await localeStorage.migrateFromLocalStorage()
|
|
return localeStorage.getLocale()
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|
|
|
|
async function loadAllTranslations(): Promise<void> {
|
|
const [frText, enText] = await Promise.all([
|
|
fetchTranslationText('/locales/fr.txt'),
|
|
fetchTranslationText('/locales/en.txt'),
|
|
])
|
|
|
|
if (frText) {
|
|
void loadTranslations('fr', frText)
|
|
}
|
|
if (enText) {
|
|
void loadTranslations('en', enText)
|
|
}
|
|
}
|
|
|
|
async function fetchTranslationText(url: string): Promise<string | undefined> {
|
|
const response = await globalThis.fetch(url)
|
|
if (!response.ok) {
|
|
return undefined
|
|
}
|
|
return response.text()
|
|
}
|