60 lines
1.5 KiB
TypeScript
60 lines
1.5 KiB
TypeScript
import React, { createContext, useCallback, useContext, useMemo, useState } from 'react';
|
|
import {
|
|
messages,
|
|
toAppLocale,
|
|
type AppLocale,
|
|
type MessageKey,
|
|
} from './messages';
|
|
|
|
const STORAGE_KEY = 'customer_locale';
|
|
|
|
type LocaleContextValue = {
|
|
locale: AppLocale;
|
|
setLocale: (locale: AppLocale) => void;
|
|
t: (key: MessageKey) => string;
|
|
};
|
|
|
|
const LocaleContext = createContext<LocaleContextValue | null>(null);
|
|
|
|
function readStoredLocale(): AppLocale {
|
|
try {
|
|
return toAppLocale(sessionStorage.getItem(STORAGE_KEY));
|
|
} catch {
|
|
return 'en';
|
|
}
|
|
}
|
|
|
|
export const LocaleProvider: React.FC<{ children: React.ReactNode; initial?: AppLocale }> = ({
|
|
children,
|
|
initial,
|
|
}) => {
|
|
const [locale, setLocaleState] = useState<AppLocale>(initial || readStoredLocale());
|
|
|
|
const setLocale = useCallback((next: AppLocale) => {
|
|
setLocaleState(next);
|
|
try {
|
|
sessionStorage.setItem(STORAGE_KEY, next);
|
|
document.documentElement.lang = next === 'hi' ? 'hi' : 'en';
|
|
} catch {
|
|
/* ignore */
|
|
}
|
|
}, []);
|
|
|
|
const t = useCallback(
|
|
(key: MessageKey) => messages[locale][key] || messages.en[key] || key,
|
|
[locale],
|
|
);
|
|
|
|
const value = useMemo(() => ({ locale, setLocale, t }), [locale, setLocale, t]);
|
|
|
|
return <LocaleContext.Provider value={value}>{children}</LocaleContext.Provider>;
|
|
};
|
|
|
|
export function useLocale(): LocaleContextValue {
|
|
const ctx = useContext(LocaleContext);
|
|
if (!ctx) {
|
|
throw new Error('useLocale must be used within LocaleProvider');
|
|
}
|
|
return ctx;
|
|
}
|