import { useEffect, useMemo, useState } from "react"; import { useQuery } from "@tanstack/react-query"; import { I18nProvider } from "@lingui/react"; import { playerQueries } from "@/features/players/queries"; import { createI18n, ensureMessages, hasCachedMessages, resolveLocale, } from "@/lib/i18n"; /** * Must mount ABOVE AuthProvider: the localized server-query hooks (useMe * included) call useLingui, so this provider cannot depend on auth context. * It reads the same auth query via raw useQuery instead — passively (useMe * is the active fetcher; SSR data is ensured in __root beforeLoad). */ export const LinguiProvider = ({ children }: { children: React.ReactNode }) => { const { queryKey, queryFn } = playerQueries.auth(); const { data } = useQuery({ queryKey, queryFn: async () => { const result = await queryFn(); if (!result.success) throw new Error(result.error.userMessage); return result.data; }, staleTime: 30 * 1000, refetchOnMount: false, refetchOnWindowFocus: false, }); const locale = resolveLocale(data?.metadata?.locale); const [catalogVersion, setCatalogVersion] = useState(0); // Fresh instance per locale (and per SSR request tree). __root beforeLoad // preloads the catalog on authed routes; on public routes (login) it may // not be cached yet — createI18n falls back to en until the effect below // loads it and bumps catalogVersion. const i18n = useMemo( () => createI18n(locale), // eslint-disable-next-line react-hooks/exhaustive-deps [locale, catalogVersion] ); useEffect(() => { if (hasCachedMessages(locale)) return; let cancelled = false; ensureMessages(locale).then(() => { if (!cancelled) setCatalogVersion((v) => v + 1); }); return () => { cancelled = true; }; }, [locale]); useEffect(() => { document.documentElement.lang = locale; }, [locale]); return {children}; };