Nicolas Cantu cc49c9d7c1 Add language preference selector in settings
**Motivations:**
- Allow users to set their preferred language (fr/en) in the settings page
- Load language preference from localStorage at startup to configure the application locale

**Root causes:**
- Language preference was only available in the header via LanguageSelector component
- Language preference was stored in IndexedDB instead of localStorage
- No centralized language settings management in the settings page

**Correctifs:**
- Created LanguageSettingsManager component for settings page
- Migrated language storage from IndexedDB to localStorage for consistency
- Updated _app.tsx to load locale from localStorage synchronously at startup
- Updated useI18n hook to use localStorage instead of IndexedDB
- Updated LanguageSelector component to use localStorage instead of IndexedDB

**Evolutions:**
- Added language preference section in settings page (displayed first)
- Language preference is now loaded at application startup from localStorage
- Added translations for language settings (settings.language.*)

**Pages affectées:**
- components/LanguageSettingsManager.tsx (new)
- pages/settings.tsx
- pages/_app.tsx
- hooks/useI18n.ts
- components/LanguageSelector.tsx
- locales/fr.txt
- locales/en.txt
2026-01-06 14:57:38 +01:00

53 lines
1.7 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(() => {
const load = async (): Promise<void> => {
try {
// Get saved locale from localStorage or use provided locale
let savedLocale: Locale | null = null
try {
if (typeof window !== 'undefined') {
savedLocale = localStorage.getItem('zapwall-locale') as Locale | null
}
} catch {
// Fallback to provided locale
}
const initialLocale = savedLocale && (savedLocale === 'fr' || savedLocale === 'en') ? savedLocale : locale
// Load translations from files in public directory
const frResponse = await fetch('/locales/fr.txt')
const enResponse = await fetch('/locales/en.txt')
if (frResponse.ok) {
const frText = await frResponse.text()
await loadTranslations('fr', frText)
}
if (enResponse.ok) {
const enText = await enResponse.text()
await loadTranslations('en', enText)
}
setLocale(initialLocale)
setCurrentLocale(initialLocale)
setLoaded(true)
} catch (e) {
console.error('Error loading translations:', e)
setLoaded(true) // Continue even if translations fail to load
}
}
void load()
}, [locale])
return { loaded, locale: currentLocale, t }
}