From 39b84996d1458b917148ad1496f2e6e5e13a3afc Mon Sep 17 00:00:00 2001 From: Tiago Yamamoto Date: Mon, 15 Dec 2025 08:58:21 -0300 Subject: [PATCH] =?UTF-8?q?feat(i18n):=20=F0=9F=8E=A3=20hook=20para=20pesc?= =?UTF-8?q?ar=20tradu=C3=A7=C3=B5es=20automaticamente?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/lib/i18n.tsx | 76 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 frontend/src/lib/i18n.tsx diff --git a/frontend/src/lib/i18n.tsx b/frontend/src/lib/i18n.tsx new file mode 100644 index 0000000..c9a3d5e --- /dev/null +++ b/frontend/src/lib/i18n.tsx @@ -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; +} + +const dictionaries: Record = { + en, + es, + 'pt-BR': ptBR, +}; + +const I18nContext = createContext(null); + +export function I18nProvider({ children }: { children: ReactNode }) { + const [locale, setLocale] = useState('en'); + + const t = useCallback((key: string, params?: Record): 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 ( + + {children} + + ); +} + +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: '🇧🇷' }, +];