feat: CMS com limites de caracteres, traduções auto e painel de notificações
This commit is contained in:
85
frontend/src/contexts/LocaleContext.tsx
Normal file
85
frontend/src/contexts/LocaleContext.tsx
Normal file
@@ -0,0 +1,85 @@
|
||||
'use client';
|
||||
|
||||
import React, { createContext, useContext, useEffect, useState } from 'react';
|
||||
import { useRouter, usePathname } from 'next/navigation';
|
||||
import { type Locale, locales, defaultLocale, getNestedValue } from '@/lib/i18n';
|
||||
|
||||
// Importar traduções estaticamente
|
||||
import ptTranslations from '@/locales/pt.json';
|
||||
import enTranslations from '@/locales/en.json';
|
||||
import esTranslations from '@/locales/es.json';
|
||||
|
||||
const translations: Record<Locale, typeof ptTranslations> = {
|
||||
pt: ptTranslations,
|
||||
en: enTranslations,
|
||||
es: esTranslations,
|
||||
};
|
||||
|
||||
interface LocaleContextType {
|
||||
locale: Locale;
|
||||
setLocale: (locale: Locale) => void;
|
||||
t: (key: string) => string;
|
||||
translations: typeof ptTranslations;
|
||||
}
|
||||
|
||||
const LocaleContext = createContext<LocaleContextType | undefined>(undefined);
|
||||
|
||||
interface LocaleProviderProps {
|
||||
children: React.ReactNode;
|
||||
locale: Locale;
|
||||
}
|
||||
|
||||
export function LocaleProvider({ children, locale: initialLocale }: LocaleProviderProps) {
|
||||
const [locale, setLocaleState] = useState<Locale>(initialLocale);
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
|
||||
// Função para trocar idioma (navega para nova URL)
|
||||
const setLocale = (newLocale: Locale) => {
|
||||
// Salvar preferência no cookie
|
||||
document.cookie = `locale=${newLocale};path=/;max-age=31536000`; // 1 ano
|
||||
|
||||
// Remover locale atual do pathname
|
||||
let newPathname = pathname;
|
||||
|
||||
// Verificar se pathname começa com locale
|
||||
for (const loc of locales) {
|
||||
if (pathname.startsWith(`/${loc}/`) || pathname === `/${loc}`) {
|
||||
newPathname = pathname.replace(`/${loc}`, '') || '/';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Construir nova URL
|
||||
if (newLocale === defaultLocale) {
|
||||
// Português não tem prefixo
|
||||
router.push(newPathname);
|
||||
} else {
|
||||
router.push(`/${newLocale}${newPathname === '/' ? '' : newPathname}`);
|
||||
}
|
||||
|
||||
setLocaleState(newLocale);
|
||||
};
|
||||
|
||||
// Função t() para obter tradução
|
||||
const t = (key: string): string => {
|
||||
return getNestedValue(translations[locale] as Record<string, unknown>, key);
|
||||
};
|
||||
|
||||
return (
|
||||
<LocaleContext.Provider value={{ locale, setLocale, t, translations: translations[locale] }}>
|
||||
{children}
|
||||
</LocaleContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useLocale() {
|
||||
const context = useContext(LocaleContext);
|
||||
if (context === undefined) {
|
||||
throw new Error('useLocale must be used within a LocaleProvider');
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
// Alias para compatibilidade
|
||||
export const useLanguage = useLocale;
|
||||
Reference in New Issue
Block a user