// Shared layout components: header, footer, ticker, placeholders, lang state const { useState, useEffect, useRef, useMemo, createContext, useContext } = React; // Language context (mock — toggles copy between IT and EN where we bother) const LangCtx = createContext({ lang: 'it', setLang: () => {} }); function useLang() { return useContext(LangCtx); } function t(it, en) { const { lang } = useLang(); return lang === 'en' ? en : it; } function T({ it, en }) { const { lang } = useLang(); return lang === 'en' ? en : it; } function LangProvider({ children }) { const [lang, setLang] = useState(() => { try { return localStorage.getItem('geek_lang') || 'it'; } catch { return 'it'; } }); useEffect(() => { try { localStorage.setItem('geek_lang', lang); } catch {} document.documentElement.lang = lang; }, [lang]); return {children}; } function LangToggle() { const { lang, setLang } = useLang(); return (
); } function SiteHeader({ current }) { const items = [ { id: 'home', href: 'index.html', it: 'Home', en: 'Home' }, { id: 'servizi', href: 'servizi.html', it: 'Servizi', en: 'Services' }, { id: 'progetti', href: 'progetti.html', it: 'Progetti', en: 'Work' }, { id: 'metodo', href: 'metodo.html', it: 'Metodo', en: 'Method' }, { id: 'blog', href: 'blog.html', it: 'Blog', en: 'Journal' }, { id: 'contatti', href: 'contatti.html', it: 'Contatti', en: 'Contact' }, ]; const [menuOpen, setMenuOpen] = useState(false); const close = () => setMenuOpen(false); useEffect(() => { if (!menuOpen) return; const prev = document.body.style.overflow; document.body.style.overflow = 'hidden'; const onKey = (e) => { if (e.key === 'Escape') close(); }; window.addEventListener('keydown', onKey); return () => { document.body.style.overflow = prev; window.removeEventListener('keydown', onKey); }; }, [menuOpen]); return (
Geek { e.target.outerHTML = 'GeeK.srls'; }} />
{menuOpen &&
); } function Ticker({ items }) { const defaultItems = [ 'SOFTWARE GESTIONALE SU MISURA', 'WEBSERVICES REST / SOAP', 'AGENTI AI PER PROCESSI AZIENDALI', 'INTEGRAZIONE SISTEMI LEGACY', 'KPI MISURABILI, NON PROMESSE', 'PMI ITALIANE • 10–80 DIPENDENTI', ]; const it = items || defaultItems; const doubled = [...it, ...it]; return ( ); } function SiteFooter() { return ( ); } const NEWSLETTER_ENDPOINT = 'server/api/newsletter.php'; function NewsletterForm({ source = 'web', compact = false }) { const { lang } = useLang(); const [email, setEmail] = useState(''); const [website, setWebsite] = useState(''); // honeypot const [busy, setBusy] = useState(false); const [state, setState] = useState(null); // 'ok' | 'already' | 'error' const [errorMsg, setErrorMsg] = useState(''); const onSubmit = async (e) => { e.preventDefault(); if (busy) return; setBusy(true); setState(null); setErrorMsg(''); try { const res = await fetch(NEWSLETTER_ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, lang, source, website }), }); const data = await res.json().catch(() => ({})); if (res.ok && data && data.ok) { setState(data.status === 'already' ? 'already' : 'ok'); setEmail(''); } else { setState('error'); setErrorMsg((data && data.error) || (lang === 'en' ? 'Something went wrong.' : 'Qualcosa è andato storto.')); } } catch (err) { setState('error'); setErrorMsg(lang === 'en' ? 'Network error.' : 'Errore di rete.'); } finally { setBusy(false); } }; if (state === 'ok') { return (
); } if (state === 'already') { return (
); } return (
setEmail(e.target.value)} placeholder={lang === 'en' ? 'email@company.com' : 'email@azienda.it'} disabled={busy} style={{ flex: 1, border: 0, padding: compact ? '10px 12px' : '12px 14px', fontFamily: 'var(--mono)', fontSize: compact ? 12 : 13, background: 'transparent', outline: 'none' }} />
setWebsite(e.target.value)} style={{ position: 'absolute', left: '-10000px', width: 1, height: 1, opacity: 0 }} aria-hidden="true" /> {state === 'error' && (
{errorMsg}
)}
); } function Placeholder({ label, aspect = '4/3', style = {}, children }) { return (
{label}
{children}
); } // Expose globally Object.assign(window, { LangCtx, LangProvider, LangToggle, SiteHeader, SiteFooter, Ticker, Placeholder, NewsletterForm, useLang, T, t });