Files
Investidor-V2/resources/js/components/tempo-brand.tsx
T
2026-10-20 11:39:25 +02:00

297 lines
9.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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>
);
}