'use client'; import { createContext, useContext, useEffect, useMemo, useState, type ReactNode, } from 'react'; import { DEFAULT_LOCALE, dict, type Dict, type Locale } from './dictionaries'; type Direction = 'rtl' | 'ltr'; type Ctx = { locale: Locale; dir: Direction; t: Dict; setLocale: (l: Locale) => void; toggle: () => void; }; const LocaleContext = createContext(null); const STORAGE_KEY = 'sa.locale'; function dirFor(locale: Locale): Direction { return locale === 'fa' ? 'rtl' : 'ltr'; } export function LocaleProvider({ initialLocale, content, children, }: { initialLocale?: Locale; /** * Server-resolved content (dict defaults merged with admin overrides). * When omitted we fall back to the in-code dictionary, so the provider keeps * working in isolation (tests, storybook, etc.). */ content?: { fa: Dict; en: Dict }; children: ReactNode; }) { const [locale, setLocaleState] = useState(initialLocale ?? DEFAULT_LOCALE); const source = content ?? (dict as unknown as { fa: Dict; en: Dict }); // Hydrate from localStorage on the client. useEffect(() => { try { const saved = window.localStorage.getItem(STORAGE_KEY) as Locale | null; if (saved === 'fa' || saved === 'en') { setLocaleState(saved); } } catch { /* noop */ } }, []); // Reflect locale + direction on the html element without a reload. useEffect(() => { const html = document.documentElement; html.lang = locale; html.dir = dirFor(locale); html.dataset.locale = locale; }, [locale]); const setLocale = (l: Locale) => { setLocaleState(l); try { window.localStorage.setItem(STORAGE_KEY, l); } catch { /* noop */ } }; const value = useMemo( () => ({ locale, dir: dirFor(locale), t: source[locale], setLocale, toggle: () => setLocale(locale === 'fa' ? 'en' : 'fa'), }), [locale, source], ); return {children}; } export function useLocale() { const ctx = useContext(LocaleContext); if (!ctx) throw new Error('useLocale must be used inside '); return ctx; }