/* global React, Icon, MODULES_CATALOG */
const { useState: useNs, useEffect: useNe, useRef: useNr } = React;
// ============================================
// SHARED NAV + FOOTER — used across all pages
// ============================================
function getCurrentPage() {
const p = window.location.pathname.split('/').pop() || 'index.html';
return p.replace('.html', '') || 'index';
}
function Nav({ dark = false }) {
const [scrolled, setScrolled] = useNs(false);
const [openMenu, setOpenMenu] = useNs(null); // null | 'modulos'
const current = getCurrentPage();
const closeTimer = useNr(null);
useNe(() => {
const onScroll = () => setScrolled(window.scrollY > 20);
window.addEventListener('scroll', onScroll);
return () => window.removeEventListener('scroll', onScroll);
}, []);
useNe(() => {
const onKey = (e) => { if (e.key === 'Escape') setOpenMenu(null); };
window.addEventListener('keydown', onKey);
return () => window.removeEventListener('keydown', onKey);
}, []);
const openMenuNow = (key) => {
if (closeTimer.current) { clearTimeout(closeTimer.current); closeTimer.current = null; }
setOpenMenu(key);
};
const closeMenuSoon = () => {
if (closeTimer.current) clearTimeout(closeTimer.current);
closeTimer.current = setTimeout(() => setOpenMenu(null), 120);
};
const links = [
{ href: 'modulos.html', label: 'Módulos', match: 'modulos', hasMenu: 'modulos' },
{ href: 'whatsapp.html', label: 'WhatsApp', match: 'whatsapp' },
{ href: 'automacoes.html', label: 'Automações', match: 'automacoes' },
{ href: 'whitelabel.html', label: 'White-label', match: 'whitelabel' },
{ href: 'precos.html', label: 'Preços', match: 'precos' },
];
const linkStyle = (active) => ({
fontSize: 14,
color: dark
? (active ? 'white' : 'rgba(255,255,255,0.65)')
: (active ? 'var(--text)' : 'var(--text-muted)'),
transition: 'color 0.15s ease',
fontWeight: active ? 500 : 400,
position: 'relative',
});
return (
<>
{openMenu &&
setOpenMenu(null)}/>}
>
);
}
function ModulesFlyout() {
if (typeof MODULES_CATALOG === 'undefined') return null;
return (
{MODULES_CATALOG.map((p, i) => (
))}
);
}
function Footer() {
return (
);
}
// ============================================
// THEME TOGGLE — discreet light/dark switcher in footer
// Reads from localStorage (per-visitor preference, no tweak panel needed).
// ============================================
function ThemeToggle() {
const [theme, setTheme] = useNs(() => {
try { return localStorage.getItem('tsa_theme') || (window.__TWEAK_DEFAULTS?.theme ?? 'light'); }
catch { return window.__TWEAK_DEFAULTS?.theme ?? 'light'; }
});
useNe(() => {
document.documentElement.setAttribute('data-theme', theme);
try { localStorage.setItem('tsa_theme', theme); } catch {}
}, [theme]);
const next = theme === 'light' ? 'dark' : 'light';
return (
);
}
// ============================================
// Scroll reveal (shared)
// ============================================
function useScrollReveal() {
useNe(() => {
const io = new IntersectionObserver((entries) => {
entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('in'); });
}, { threshold: 0.1 });
const scan = () => document.querySelectorAll('.reveal:not(.in)').forEach(el => io.observe(el));
scan();
const t = setInterval(scan, 500);
return () => { clearInterval(t); io.disconnect(); };
}, []);
}
// ============================================
// Page wrapper
// ============================================
function Page({ navDark = true, children }) {
// navDark defaults to true because all internal pages start with the dark PageHero.
useScrollReveal();
return (
<>