Доработка мелочей и начало интернац.
This commit is contained in:
parent
486d46c467
commit
48e8551b0e
21 changed files with 408 additions and 76 deletions
84
FRONT/DEV/src/utils/i18n/provider.tsx
Normal file
84
FRONT/DEV/src/utils/i18n/provider.tsx
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
'use client'
|
||||
import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
|
||||
import { defaultLanguage, Language, Namespace, namespaces, supportedLanguages } from './config';
|
||||
|
||||
type Translation = Record<string, string>;
|
||||
type NamespaceTranslations = Record<Namespace, Translation>;
|
||||
type LanguageTranslations = Record<Language, NamespaceTranslations>;
|
||||
|
||||
const I18nContext = createContext<{
|
||||
language: Language;
|
||||
t: (key: string, namespace?: Namespace) => string;
|
||||
}>({
|
||||
language: defaultLanguage,
|
||||
t: (key: string) => key,
|
||||
});
|
||||
|
||||
interface I18nProviderProps {
|
||||
children: React.ReactNode;
|
||||
initialLanguage: Language;
|
||||
}
|
||||
|
||||
export const I18nProvider = ({ children, initialLanguage }: I18nProviderProps) => {
|
||||
const [language, setLanguage] = useState<Language>(initialLanguage);
|
||||
const [translations, setTranslations] = useState<LanguageTranslations>({} as LanguageTranslations);
|
||||
|
||||
|
||||
// Загрузка переводов
|
||||
useEffect(() => {
|
||||
const loadTranslations = async () => {
|
||||
const newTranslations: LanguageTranslations = { ...translations };
|
||||
|
||||
await Promise.all(
|
||||
(Object.keys(supportedLanguages) as Language[]).map(async (lang) => {
|
||||
if (!newTranslations[lang]) {
|
||||
newTranslations[lang] = {} as NamespaceTranslations;
|
||||
|
||||
await Promise.all(
|
||||
namespaces.map(async (ns) => {
|
||||
try {
|
||||
const data = await import(`../../../public/locales/${lang}/${ns}.json`);
|
||||
newTranslations[lang][ns] = data.default || data;
|
||||
} catch (e) {
|
||||
console.error(`Failed to load ${lang}/${ns} translations`, e);
|
||||
newTranslations[lang][ns] = {};
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
setTranslations(newTranslations);
|
||||
};
|
||||
|
||||
loadTranslations();
|
||||
}, []);
|
||||
|
||||
|
||||
const t = useMemo(() => {
|
||||
return (key: string, namespace: Namespace = 'common') => {
|
||||
return translations[language]?.[namespace]?.[key] || key;
|
||||
};
|
||||
}, [language, translations]);
|
||||
|
||||
|
||||
const contextValue = useMemo(() => ({
|
||||
language,
|
||||
t,
|
||||
}), [language, t]);
|
||||
|
||||
return (
|
||||
<I18nContext.Provider value={contextValue}>
|
||||
{children}
|
||||
</I18nContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useI18n = () => {
|
||||
const context = useContext(I18nContext);
|
||||
if (!context) {
|
||||
throw new Error('useI18n must be used within I18nProvider');
|
||||
}
|
||||
return context;
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue