Files
admin/apps/admin/src/app/providers/I18nProvider.tsx
T

78 lines
2.4 KiB
TypeScript
Executable File

import { DirectionProvider } from '@radix-ui/react-direction';
import { useEffect, useState, type PropsWithChildren } from 'react';
import { IntlProvider } from 'react-intl';
import { LocalStorageService } from '@crux-kit/local-storage';
import { I18N_DEFAULT_LANGUAGE, I18N_LANGUAGES } from '#app/i18n/config';
import TranslationsContext from '#app/i18n/context';
import { type Language, type LanguageCode } from '#app/i18n/types';
import { IntlDate } from '#infrastructure/IntlDate';
import { IntlName } from '#infrastructure/IntlName';
import '@formatjs/intl-relativetimeformat/polyfill';
import '@formatjs/intl-relativetimeformat/locale-data/en';
const storage = new LocalStorageService({ prefix: 'i18n' });
const resolveLanguage = (code?: LanguageCode): Language => {
return I18N_LANGUAGES.find((lang) => lang.code === code) ?? I18N_DEFAULT_LANGUAGE;
};
const getInitialLanguage = () => {
const urlParams = new URLSearchParams(window.location.search);
const langParam = urlParams.get('lang');
if (langParam) {
const matchedLanguage = I18N_LANGUAGES.find((lang) => lang.code === langParam);
if (matchedLanguage) {
storage.set('config', matchedLanguage.code);
return matchedLanguage;
}
}
return resolveLanguage(storage.get<LanguageCode>('config'));
};
const initialLanguage = getInitialLanguage();
IntlDate.setLocaleGlobally(initialLanguage.code);
IntlName.setLanguage(initialLanguage.code);
const I18nProvider = ({ children }: PropsWithChildren) => {
const [currenLanguage, setCurrenLanguage] = useState(initialLanguage);
const changeLanguage = (language: Language) => {
storage.set('config', language.code);
IntlDate.setLocaleGlobally(language.code);
IntlName.setLanguage(language.code);
setCurrenLanguage(language);
};
const isRTL = () => {
return currenLanguage.direction === 'rtl';
};
useEffect(() => {
document.documentElement.setAttribute('dir', currenLanguage.direction);
}, [currenLanguage]);
return (
<TranslationsContext.Provider
value={{
languages: I18N_LANGUAGES,
isRTL,
currenLanguage,
changeLanguage
}}
>
<IntlProvider
messages={currenLanguage.messages}
locale={currenLanguage.code}
defaultLocale={I18N_DEFAULT_LANGUAGE.code}
>
<DirectionProvider dir={currenLanguage.direction}>{children}</DirectionProvider>
</IntlProvider>
</TranslationsContext.Provider>
);
};
export default I18nProvider;