feat(i18n): 🎣 hook para pescar traduções automaticamente
This commit is contained in:
parent
87fcdcd0fb
commit
39b84996d1
1 changed files with 76 additions and 0 deletions
76
frontend/src/lib/i18n.tsx
Normal file
76
frontend/src/lib/i18n.tsx
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
'use client';
|
||||
|
||||
import React, { createContext, useContext, useState, useCallback, ReactNode } from 'react';
|
||||
import en from '@/i18n/en.json';
|
||||
import es from '@/i18n/es.json';
|
||||
import ptBR from '@/i18n/pt-BR.json';
|
||||
|
||||
type Locale = 'en' | 'es' | 'pt-BR';
|
||||
|
||||
interface I18nContextType {
|
||||
locale: Locale;
|
||||
setLocale: (locale: Locale) => void;
|
||||
t: (key: string, params?: Record<string, string | number>) => string;
|
||||
}
|
||||
|
||||
const dictionaries: Record<Locale, typeof en> = {
|
||||
en,
|
||||
es,
|
||||
'pt-BR': ptBR,
|
||||
};
|
||||
|
||||
const I18nContext = createContext<I18nContextType | null>(null);
|
||||
|
||||
export function I18nProvider({ children }: { children: ReactNode }) {
|
||||
const [locale, setLocale] = useState<Locale>('en');
|
||||
|
||||
const t = useCallback((key: string, params?: Record<string, string | number>): string => {
|
||||
const keys = key.split('.');
|
||||
let value: any = dictionaries[locale];
|
||||
|
||||
for (const k of keys) {
|
||||
if (value && typeof value === 'object' && k in value) {
|
||||
value = value[k];
|
||||
} else {
|
||||
return key; // Return key if not found
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof value !== 'string') return key;
|
||||
|
||||
// Replace parameters like {count}, {time}, {year}
|
||||
if (params) {
|
||||
return Object.entries(params).reduce(
|
||||
(str, [paramKey, paramValue]) => str.replace(`{${paramKey}}`, String(paramValue)),
|
||||
value
|
||||
);
|
||||
}
|
||||
|
||||
return value;
|
||||
}, [locale]);
|
||||
|
||||
return (
|
||||
<I18nContext.Provider value={{ locale, setLocale, t }}>
|
||||
{children}
|
||||
</I18nContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useI18n() {
|
||||
const context = useContext(I18nContext);
|
||||
if (!context) {
|
||||
throw new Error('useI18n must be used within an I18nProvider');
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
export function useTranslation() {
|
||||
const { t, locale, setLocale } = useI18n();
|
||||
return { t, locale, setLocale };
|
||||
}
|
||||
|
||||
export const locales: { code: Locale; name: string; flag: string }[] = [
|
||||
{ code: 'en', name: 'English', flag: '🇺🇸' },
|
||||
{ code: 'es', name: 'Español', flag: '🇪🇸' },
|
||||
{ code: 'pt-BR', name: 'Português', flag: '🇧🇷' },
|
||||
];
|
||||
Loading…
Reference in a new issue