297 lines
9.4 KiB
TypeScript
297 lines
9.4 KiB
TypeScript
import { createContext, useContext, useEffect, useState } from 'react';
|
||
import { Facebook, Instagram, Linkedin, Youtube } from 'lucide-react';
|
||
import type { CSSProperties, ReactNode } from 'react';
|
||
|
||
export const tempoSocialLinks = [
|
||
{
|
||
name: 'Facebook',
|
||
href: 'https://www.facebook.com/revistatempo.mz/',
|
||
icon: Facebook,
|
||
color: '#1877f2',
|
||
},
|
||
{
|
||
name: 'Instagram',
|
||
href: 'https://www.instagram.com/revistatempo.mz/',
|
||
icon: Instagram,
|
||
color: '#e1306c',
|
||
},
|
||
{
|
||
name: 'LinkedIn',
|
||
href: 'https://www.linkedin.com/company/revistatempo/',
|
||
icon: Linkedin,
|
||
color: '#38a5df',
|
||
},
|
||
{
|
||
name: 'YouTube',
|
||
href: 'https://www.youtube.com/@RevistaTempoMz/',
|
||
icon: Youtube,
|
||
color: '#ff3333',
|
||
},
|
||
];
|
||
|
||
const menuTranslations = [
|
||
['Sobre nós', 'About us', 'À propos', 'Sobre nosotros'],
|
||
['Revista Tempo', 'Revista Tempo', 'Revista Tempo', 'Revista Tempo'],
|
||
[
|
||
'Abre num novo separador',
|
||
'Opens in a new tab',
|
||
'Ouvre un nouvel onglet',
|
||
'Abre en una nueva pestaña',
|
||
],
|
||
['O meu painel', 'My dashboard', 'Mon espace', 'Mi panel'],
|
||
[
|
||
'Manifestar interesse',
|
||
'Express interest',
|
||
'Manifester un intérêt',
|
||
'Manifestar interés',
|
||
],
|
||
[
|
||
'pedido recebido',
|
||
'request received',
|
||
'demande reçue',
|
||
'solicitud recibida',
|
||
],
|
||
[
|
||
'pedidos recebidos',
|
||
'requests received',
|
||
'demandes reçues',
|
||
'solicitudes recibidas',
|
||
],
|
||
[
|
||
'Porquê investir em Moçambique',
|
||
'Why invest in Mozambique',
|
||
'Pourquoi investir au Mozambique',
|
||
'Por qué invertir en Mozambique',
|
||
],
|
||
[
|
||
'Oportunidades de investimento',
|
||
'Investment opportunities',
|
||
'Opportunités d’investissement',
|
||
'Oportunidades de inversión',
|
||
],
|
||
[
|
||
'Sectores de investimento',
|
||
'Investment sectors',
|
||
'Secteurs d’investissement',
|
||
'Sectores de inversión',
|
||
],
|
||
['Localizações', 'Locations', 'Localisations', 'Ubicaciones'],
|
||
[
|
||
'Iniciar investimento',
|
||
'Start an investment',
|
||
'Démarrer un investissement',
|
||
'Iniciar una inversión',
|
||
],
|
||
[
|
||
'Incentivos e simulador fiscal',
|
||
'Incentives and tax simulator',
|
||
'Incitations et simulateur fiscal',
|
||
'Incentivos y simulador fiscal',
|
||
],
|
||
['Licenciamento', 'Licensing', 'Autorisations', 'Licencias'],
|
||
['Acesso à terra', 'Land access', 'Accès à la terre', 'Acceso a la tierra'],
|
||
[
|
||
'Serviços ao investidor',
|
||
'Investor services',
|
||
'Services aux investisseurs',
|
||
'Servicios al inversor',
|
||
],
|
||
[
|
||
'Acompanhamento do projecto',
|
||
'Project follow-up',
|
||
'Suivi du projet',
|
||
'Seguimiento del proyecto',
|
||
],
|
||
[
|
||
'Apoio ao investidor',
|
||
'Investor support',
|
||
'Assistance aux investisseurs',
|
||
'Apoyo al inversor',
|
||
],
|
||
[
|
||
'Dossiers e percursos',
|
||
'Investment files and journeys',
|
||
'Dossiers et parcours',
|
||
'Expedientes y recorridos',
|
||
],
|
||
[
|
||
'Perfil e empresas',
|
||
'Profile and companies',
|
||
'Profil et entreprises',
|
||
'Perfil y empresas',
|
||
],
|
||
[
|
||
'Pedidos e tarefas de acompanhamento',
|
||
'Requests and follow-up tasks',
|
||
'Demandes et tâches de suivi',
|
||
'Solicitudes y tareas de seguimiento',
|
||
],
|
||
[
|
||
'Manifestações e favoritos',
|
||
'Expressions of interest and favourites',
|
||
'Manifestations d’intérêt et favoris',
|
||
'Manifestaciones de interés y favoritos',
|
||
],
|
||
['Notificações', 'Notifications', 'Notifications', 'Notificaciones'],
|
||
['A minha atividade', 'My activity', 'Mes activités', 'Mi actividad'],
|
||
[
|
||
'As minhas parcerias',
|
||
'My partnerships',
|
||
'Mes partenariats',
|
||
'Mis alianzas',
|
||
],
|
||
['Os meus negócios', 'My businesses', 'Mes entreprises', 'Mis negocios'],
|
||
];
|
||
const translatedMenu = (column: number) =>
|
||
Object.fromEntries(menuTranslations.map((row) => [row[0], row[column]]));
|
||
|
||
const translations: Record<string, Record<string, string>> = {
|
||
en: {
|
||
...translatedMenu(1),
|
||
Descoberta: 'Discover',
|
||
Realização: 'Invest',
|
||
Suporte: 'Support',
|
||
Entrar: 'Sign in',
|
||
'A minha área': 'My account',
|
||
'Terminar sessão': 'Sign out',
|
||
Contactos: 'Contacts',
|
||
Navegação: 'Navigation',
|
||
Início: 'Home',
|
||
Oportunidades: 'Opportunities',
|
||
Sectores: 'Sectors',
|
||
Legislações: 'Legislation',
|
||
'Guia do investidor': 'Investor guide',
|
||
Contacto: 'Contact',
|
||
'Política de Privacidade': 'Privacy Policy',
|
||
'Termos de Uso': 'Terms of Use',
|
||
'Todos os direitos reservados.': 'All rights reserved.',
|
||
'Siga a Revista Tempo para actualizações exclusivas.':
|
||
'Follow Revista Tempo for exclusive updates.',
|
||
'Número de registo': 'Registration number',
|
||
'A minha conta e atividade': 'My account and activity',
|
||
'Área de trabalho': 'Workspace',
|
||
},
|
||
fr: {
|
||
...translatedMenu(2),
|
||
Descoberta: 'Découvrir',
|
||
Realização: 'Investir',
|
||
Suporte: 'Assistance',
|
||
Entrar: 'Connexion',
|
||
'A minha área': 'Mon compte',
|
||
'Terminar sessão': 'Déconnexion',
|
||
Contactos: 'Contacts',
|
||
Navegação: 'Navigation',
|
||
Início: 'Accueil',
|
||
Oportunidades: 'Opportunités',
|
||
Sectores: 'Secteurs',
|
||
Legislações: 'Législation',
|
||
'Guia do investidor': 'Guide de l’investisseur',
|
||
Contacto: 'Contact',
|
||
'Política de Privacidade': 'Politique de confidentialité',
|
||
'Termos de Uso': 'Conditions d’utilisation',
|
||
'Todos os direitos reservados.': 'Tous droits réservés.',
|
||
'Siga a Revista Tempo para actualizações exclusivas.':
|
||
'Suivez Revista Tempo pour des actualités exclusives.',
|
||
'Número de registo': 'Numéro d’enregistrement',
|
||
'A minha conta e atividade': 'Mon compte et mes activités',
|
||
'Área de trabalho': 'Espace de travail',
|
||
},
|
||
es: {
|
||
...translatedMenu(3),
|
||
Descoberta: 'Descubrir',
|
||
Realização: 'Invertir',
|
||
Suporte: 'Soporte',
|
||
Entrar: 'Entrar',
|
||
'A minha área': 'Mi cuenta',
|
||
'Terminar sessão': 'Cerrar sesión',
|
||
Contactos: 'Contactos',
|
||
Navegação: 'Navegación',
|
||
Início: 'Inicio',
|
||
Oportunidades: 'Oportunidades',
|
||
Sectores: 'Sectores',
|
||
Legislações: 'Legislación',
|
||
'Guia do investidor': 'Guía del inversor',
|
||
Contacto: 'Contacto',
|
||
'Política de Privacidade': 'Política de privacidad',
|
||
'Termos de Uso': 'Términos de uso',
|
||
'Todos os direitos reservados.': 'Todos los derechos reservados.',
|
||
'Siga a Revista Tempo para actualizações exclusivas.':
|
||
'Siga Revista Tempo para recibir novedades exclusivas.',
|
||
'Número de registo': 'Número de registro',
|
||
'A minha conta e atividade': 'Mi cuenta y actividad',
|
||
'Área de trabalho': 'Área de trabajo',
|
||
},
|
||
};
|
||
|
||
const TempoUi = createContext({
|
||
language: 'pt',
|
||
setLanguage: (_language: string) => {},
|
||
t: (text: string) => text,
|
||
requestCount: 0,
|
||
registerSubmittedInterest: () => {},
|
||
});
|
||
|
||
export function TempoUiProvider({ children }: { children: ReactNode }) {
|
||
const [language, setCurrentLanguage] = useState('pt');
|
||
const [requestCount, setRequestCount] = useState(0);
|
||
useEffect(() => {
|
||
try {
|
||
const saved = localStorage.getItem('tempo-navigation-language');
|
||
if (saved && ['pt', 'en', 'fr', 'es'].includes(saved))
|
||
setCurrentLanguage(saved);
|
||
} catch {
|
||
/* Navigation remains usable without browser storage. */
|
||
}
|
||
}, []);
|
||
const setLanguage = (next: string) => {
|
||
setCurrentLanguage(next);
|
||
try {
|
||
localStorage.setItem('tempo-navigation-language', next);
|
||
} catch {
|
||
/* Optional persistence. */
|
||
}
|
||
};
|
||
return (
|
||
<TempoUi.Provider
|
||
value={{
|
||
language,
|
||
setLanguage,
|
||
t: (text) => translations[language]?.[text] ?? text,
|
||
requestCount,
|
||
registerSubmittedInterest: () =>
|
||
setRequestCount((count) => count + 1),
|
||
}}
|
||
>
|
||
{children}
|
||
</TempoUi.Provider>
|
||
);
|
||
}
|
||
|
||
export const useTempoUi = () => useContext(TempoUi);
|
||
|
||
export function TempoSocialLinks({ footer = false }: { footer?: boolean }) {
|
||
return (
|
||
<div
|
||
className="flex items-center gap-1"
|
||
aria-label="Redes sociais da Revista Tempo"
|
||
>
|
||
{tempoSocialLinks.map(({ name, href, icon: Icon, color }) => (
|
||
<a
|
||
key={name}
|
||
href={href}
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
aria-label={`Revista Tempo — ${name}`}
|
||
title={name}
|
||
className={
|
||
footer ? 'tempo-footer-social' : 'tempo-header-social'
|
||
}
|
||
style={{ '--social-color': color } as CSSProperties}
|
||
>
|
||
<Icon size={footer ? 19 : 16} aria-hidden="true" />
|
||
</a>
|
||
))}
|
||
</div>
|
||
);
|
||
}
|