Files
Epicure/apps/web/lib/i18n/provider.tsx
T
Arnaud 5b40968c9d feat(web): Next.js 15 app shell, auth, i18n, base UI
App Router setup with next-intl (en/fr), Better Auth wiring, shadcn/ui components,
Tailwind, AES-256-GCM encrypt util, Redis rate limiter, tier limit checker,
site_settings helper for runtime .env overrides.
2026-07-01 08:09:31 +02:00

67 lines
1.9 KiB
TypeScript

"use client";
import { createContext, useContext, useEffect, useState } from "react";
import { NextIntlClientProvider } from "next-intl";
export const SUPPORTED_LOCALES = [
{ code: "en", label: "English" },
{ code: "fr", label: "Français" },
] as const;
export type Locale = (typeof SUPPORTED_LOCALES)[number]["code"];
const STORAGE_KEY = "epicure-locale";
const LocaleContext = createContext<{
locale: Locale;
setLocale: (locale: Locale) => void;
}>({ locale: "en", setLocale: () => {} });
export function useLocale() {
return useContext(LocaleContext);
}
export function I18nProvider({
children,
messages,
initialLocale,
}: {
children: React.ReactNode;
messages: Record<string, Record<string, unknown>>;
initialLocale?: Locale;
}) {
const resolved = initialLocale ?? ("en" as Locale);
const [locale, setLocaleState] = useState<Locale>(resolved);
const [currentMessages, setCurrentMessages] = useState(messages[resolved] ?? messages["en"]!);
useEffect(() => {
// If no server-side locale, fall back to localStorage
if (!initialLocale) {
const stored = localStorage.getItem(STORAGE_KEY) as Locale | null;
if (stored && messages[stored]) {
setLocaleState(stored);
setCurrentMessages(messages[stored]!);
}
}
}, [messages, initialLocale]);
function setLocale(next: Locale) {
setLocaleState(next);
setCurrentMessages(messages[next]!);
localStorage.setItem(STORAGE_KEY, next);
fetch("/api/v1/users/me", {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ locale: next }),
}).catch(() => {});
}
return (
<LocaleContext.Provider value={{ locale, setLocale }}>
<NextIntlClientProvider locale={locale} messages={currentMessages} timeZone="UTC">
{children}
</NextIntlClientProvider>
</LocaleContext.Provider>
);
}