**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
50 lines
1.4 KiB
TypeScript
50 lines
1.4 KiB
TypeScript
import '@/styles/globals.css'
|
|
import type { AppProps } from 'next/app'
|
|
import { useI18n } from '@/hooks/useI18n'
|
|
import React from 'react'
|
|
|
|
function I18nProvider({ children }: { children: React.ReactNode }) {
|
|
// Get saved locale from localStorage or default to French
|
|
const getInitialLocale = (): 'fr' | 'en' => {
|
|
if (typeof window === 'undefined') {
|
|
return 'fr'
|
|
}
|
|
try {
|
|
const savedLocale = localStorage.getItem('zapwall-locale') as 'fr' | 'en' | null
|
|
if (savedLocale === 'fr' || savedLocale === 'en') {
|
|
return savedLocale
|
|
}
|
|
} catch {
|
|
// Fallback to browser locale detection
|
|
}
|
|
// Try to detect browser locale
|
|
const browserLocale = navigator.language.split('-')[0]
|
|
return browserLocale === 'en' ? 'en' : 'fr'
|
|
}
|
|
|
|
const [initialLocale, setInitialLocale] = React.useState<'fr' | 'en'>('fr')
|
|
const [localeLoaded, setLocaleLoaded] = React.useState(false)
|
|
|
|
React.useEffect(() => {
|
|
const locale = getInitialLocale()
|
|
setInitialLocale(locale)
|
|
setLocaleLoaded(true)
|
|
}, [])
|
|
|
|
const { loaded } = useI18n(initialLocale)
|
|
|
|
if (!localeLoaded || !loaded) {
|
|
return <div className="min-h-screen bg-cyber-darker flex items-center justify-center text-neon-cyan">Loading...</div>
|
|
}
|
|
|
|
return <>{children}</>
|
|
}
|
|
|
|
export default function App({ Component, pageProps }: AppProps) {
|
|
return (
|
|
<I18nProvider>
|
|
<Component {...pageProps} />
|
|
</I18nProvider>
|
|
)
|
|
}
|