// Eu Faço Parte — Sections part 1: Nav, LanguageSwitcher, TranslationBanner, Hero, Partners, Loja const HeartIcon = ({ size = 14 }) => ( ); // Helper: caminho relativo da página atual (ex.: index.html, projeto-x.html) const currentPage = () => { const path = location.pathname.replace(/^\/(en|it|de)(\/|$)/, '/'); const last = path.split('/').pop() || 'index.html'; return last || 'index.html'; }; // "Início" → /index.html, "Nossa História" → /nossa-historia.html // Mantém o prefixo de idioma atual ao construir links de navegação interna const langPath = (file) => { const prefix = window.LANG === 'pt' ? '/' : '/' + window.LANG + '/'; return prefix + file; }; const Logo = ({ src = "assets/logo.png" }) => Eu Faço Parte ; const PROJETOS_NAV = [ { name: 'Surf Sagi', file: 'projeto-surf-sagi.html' }, { name: 'Artesanato & Brinquedos', file: 'projeto-artesanato.html' }, { name: 'Sagi Vidas', file: 'projeto-sagi-vidas.html' }, { name: 'Sonhos em Campo', file: 'projeto-sonhos-campo.html' }, { name: 'Juntos nós Cuidamos', file: 'projeto-juntos.html' }, { name: 'Abrigo ANCA & Educação Profissional', file: 'projeto-anca.html' }, { name: 'Roupas & Memórias', file: 'projeto-roupas.html' }, { name: 'Dia das Crianças para 300 jovens', file: 'projeto-dia-criancas.html' }, { name: 'O direito de celebrar', file: 'projeto-celebrar.html' }, { name: 'Memórias Afetivas e Saudáveis na Cozinha', file: 'projeto-cozinha.html' }, ]; const ProjectsModal = ({ onClose }) => (
e.stopPropagation()} style={{ maxWidth: '640px' }}>
01.1 · {t('iniciativas.modal_eyebrow')}

{t('iniciativas.modal_title')}

{PROJETOS_NAV.map((p, i) => ( e.currentTarget.style.background = 'var(--paper-2)'} onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'} > {p.name} ))}
); // ---- Language Switcher (botão flutuante com bandeira UK como ícone default) ---- const LANG_OPTIONS = [ { code: 'en', country: 'gb', labelKey: 'label_en' }, { code: 'it', country: 'it', labelKey: 'label_it' }, { code: 'de', country: 'de', labelKey: 'label_de' }, { code: 'pt', country: 'br', labelKey: 'label_pt' }, ]; const LanguageSwitcher = () => { const [open, setOpen] = React.useState(false); const wrapRef = React.useRef(null); React.useEffect(() => { const close = (e) => { if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false); }; document.addEventListener('mousedown', close); return () => document.removeEventListener('mousedown', close); }, []); const navigate = (code) => { setOpen(false); window.location.href = window.langHref(code); }; const Flag = ({ country, size = 28 }) => ( {country} { e.currentTarget.style.display = 'none'; }} /> ); // Ícone do botão = bandeira UK (mostra que há opção em inglês mesmo no site PT) // Exceção: se o usuário já está em outro idioma, mostra a bandeira do idioma atual const currentFlag = LANG_OPTIONS.find(l => l.code === window.LANG)?.country || 'gb'; const defaultFlag = window.LANG === 'pt' ? 'gb' : currentFlag; return (
{open && (
{LANG_OPTIONS.map(opt => ( ))}
)}
); }; const Nav = () => { const [projectsOpen, setProjectsOpen] = React.useState(false); React.useEffect(() => { window.openProjectsModal = () => setProjectsOpen(true); }, []); const scrollTo = (id) => (e) => { const el = document.getElementById(id); if (el) { e.preventDefault(); el.scrollIntoView({ behavior: 'smooth' }); } }; return ( <> {projectsOpen && setProjectsOpen(false)} />} ); }; // ---- Translation banner (auto-detect + redirect para pasta de idioma) ---- const BANNER_LANGS = { en: { msg: "We noticed your browser is set to English. Would you like to see this site in English?", btn: "Yes, translate", target: 'en' }, de: { msg: "Wir haben bemerkt, dass Ihr Browser auf Deutsch eingestellt ist. Möchten Sie die Seite auf Deutsch sehen?", btn: "Ja, übersetzen", target: 'de' }, fr: { msg: "Votre navigateur est en français. Souhaitez-vous voir ce site en anglais ?", btn: "Oui, traduire", target: 'en' }, it: { msg: "Il tuo browser è impostato in italiano. Vuoi vedere questo sito in italiano?", btn: "Sì, traduci", target: 'it' }, es: { msg: "Tu navegador está en español. ¿Deseas ver este sitio en inglés?", btn: "Sí, traducir", target: 'en' }, ja: { msg: "ブラウザが日本語に設定されています。このサイトを英語で表示しますか?", btn: "翻訳する", target: 'en' }, zh: { msg: "您的浏览器设置为中文。您是否希望以英文查看此网站?", btn: "翻译网站", target: 'en' }, ar: { msg: "لاحظنا أن متصفحك مضبوط على اللغة العربية. هل تريد رؤية هذا الموقع باللغة الإنجليزية؟", btn: "نعم، ترجم", target: 'en' }, }; const TranslationBanner = () => { const [show, setShow] = React.useState(false); const [info, setInfo] = React.useState(null); React.useEffect(() => { if (sessionStorage.getItem('transl-banner-dismissed')) return; const base = (navigator.language || '').toLowerCase().split('-')[0]; if (base === 'pt') return; // browser em PT → não oferece tradução const cfg = BANNER_LANGS[base]; if (!cfg) return; // Se o usuário já está no idioma alvo, não mostra if (window.LANG === cfg.target) return; setInfo(cfg); setShow(true); }, []); if (!show || !info) return null; const dismiss = () => { setShow(false); sessionStorage.setItem('transl-banner-dismissed', '1'); }; const translate = () => { sessionStorage.setItem('transl-banner-dismissed', '1'); window.location.href = window.langHref(info.target); }; return (
{info.msg} 🤍
); }; // ---- Donation social proof toast ---- const TOAST_NAMES = [ 'Maria S.','João P.','Ana C.','Carlos M.','Fernanda L.', 'Rafael T.','Beatriz O.','Lucas N.','Camila R.','Pedro A.', 'Juliana F.','Marcos V.','Larissa B.','Thiago D.','Isabela G.', 'Bruno K.','Vanessa H.','Diego E.','Natália W.','Felipe C.', 'Letícia M.','Rodrigo A.','Priscila S.','Eduardo B.','Aline F.', ]; const DonationToast = () => { const [visible, setVisible] = React.useState(false); const [info, setInfo] = React.useState({ name: '', value: '' }); React.useEffect(() => { let hideTimer, nextTimer; const trigger = () => { const name = TOAST_NAMES[Math.floor(Math.random() * TOAST_NAMES.length)]; const val = Math.floor(Math.random() * 171) + 30; const symbol = window.LANG === 'pt' ? 'R$' : window.LANG === 'en' ? 'CHF ' : window.LANG === 'it' ? 'CHF ' : 'CHF '; const formatted = window.LANG === 'pt' ? `R$${val},00` : `CHF ${val}`; setInfo({ name, value: formatted }); setVisible(true); hideTimer = setTimeout(() => setVisible(false), 5000); nextTimer = setTimeout(trigger, 60000 + Math.random() * 30000); }; nextTimer = setTimeout(trigger, 4000); return () => { clearTimeout(hideTimer); clearTimeout(nextTimer); }; }, []); return (
{info.name} {t('toast.donated')} {info.value}
); }; // ---- HERO ---- const Hero = () =>
{t('hero.eyebrow')}

{t('hero.cta_history')}
{' '} {t('hero.aster')}

; // ---- Partners band ---- const Partners = () =>
{t('partners.eyebrow')}
Google for Nonprofits
NordVPN
Allegra Private Tours
; // ---- Loja — catálogo movido para src/loja-data.jsx (window.LOJA_ALL) ---- // Fisher-Yates shuffle function lojaShuffled(arr) { const a = [...arr]; for (let i = a.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); const tmp = a[i]; a[i] = a[j]; a[j] = tmp; } return a; } const LOJA_COUNT = 10; const LOJA_VISIBLE = 5; const LOJA_DUR = 380; // ---- Loja item modal ---- const LojaModal = ({ produto, onClose, onEncomenda }) => { React.useEffect(() => { const esc = e => { if (e.key === 'Escape') onClose(); }; document.addEventListener('keydown', esc); document.body.style.overflow = 'hidden'; return () => { document.removeEventListener('keydown', esc); document.body.style.overflow = ''; }; }, [onClose]); return (
e.stopPropagation()}>
{L(produto.name)} { e.currentTarget.style.display = 'none'; }} />
{L(produto.cat)}

{L(produto.name)}

{produto.price && (
{produto.price} {produto.oldPrice && ( {produto.oldPrice} )}
)}
{t('loja_modal.origin_l')} {t('loja_modal.origin_v')}
{t('loja_modal.rarity_l')} {t('loja_modal.rarity_v')}
{t('loja_modal.options_l')} {t('loja_modal.options_v')}
{t('loja_modal.price_l')} {t('loja_modal.price_v')}

{t('loja_modal.discount_note')}
{ onEncomenda(produto.name.pt || L(produto.name)); onClose(); }} > {t('loja_modal.cta')}
); }; const Announce = () => { const produtos = React.useMemo(() => lojaShuffled(window.LOJA_ALL || []).slice(0, LOJA_COUNT), []); const total = produtos.length; const track = React.useMemo(() => [...produtos, ...produtos.slice(0, LOJA_VISIBLE)], [produtos]); const [idx, setIdx] = React.useState(0); const [anim, setAnim] = React.useState(true); const [cardW, setCardW] = React.useState(0); const [modalItem, setModalItem] = React.useState(null); const [paused, setPaused] = React.useState(false); const wrapRef = React.useRef(null); React.useLayoutEffect(() => { const update = () => { if (wrapRef.current) setCardW(wrapRef.current.offsetWidth / LOJA_VISIBLE); }; update(); const ro = new ResizeObserver(update); if (wrapRef.current) ro.observe(wrapRef.current); return () => ro.disconnect(); }, []); const goto = React.useCallback((i, withAnim) => { setAnim(withAnim); setIdx(i); }, []); React.useEffect(() => { if (paused) return; const iv = setInterval(() => { setAnim(true); setIdx(prev => { const next = prev + 1; if (next >= total) setTimeout(() => goto(0, false), LOJA_DUR + 16); return next; }); }, 4000); return () => clearInterval(iv); }, [total, goto, paused]); return ( <>
· {t('announce.eyebrow')}

setPaused(true)} onMouseLeave={() => setPaused(false)} >
{track.map((p, i) => (
{ setModalItem(p); setPaused(true); }} >
{L(p.name)} { e.currentTarget.style.display = 'none'; }} /> {p.oldPrice && {t('announce.promo')}}
{L(p.cat)}

{L(p.name)}

{p.price || t('announce.consult')} {p.oldPrice && <> {p.oldPrice}} {p.price && {t('announce.currency')}}
))}
{modalItem && ( { setModalItem(null); setPaused(false); }} onEncomenda={(name) => { window.setLojaEncomenda?.(name); }} /> )} ); }; // ---- Hero Slider ---- const HeroSlider = () => { const slides = [ { src: "images/iniciativa-surf-sagi.jpg", cKey: "slider.c_surf" }, { src: "images/iniciativa-artesanato.jpg", cKey: "slider.c_arte" }, { src: "images/iniciativa-sagi-vidas.jpg", cKey: "slider.c_vidas" }, { src: "images/iniciativa-sonhos-campo.png", cKey: "slider.c_sonhos" }, { src: "images/iniciativa-juntos.png", cKey: "slider.c_juntos" }, { src: "images/iniciativa-anca.jpg", cKey: "slider.c_anca" }, { src: "images/iniciativa-roupas.jpg", cKey: "slider.c_roupas" }, ]; const [idx, setIdx] = React.useState(0); React.useEffect(() => { const id = setInterval(() => setIdx((i) => (i + 1) % slides.length), 5000); return () => clearInterval(id); }, []); return (
{slides.map((s, i) => {t(s.cKey)} {e.currentTarget.style.display = 'none';}} /> )}
{t(slides[idx].cKey)}
{slides.map((_, i) =>
); }; window.Nav = Nav; window.TranslationBanner = TranslationBanner; window.Hero = Hero; window.HeroSlider = HeroSlider; window.Partners = Partners; window.Announce = Announce; window.HeartIcon = HeartIcon; window.langPath = langPath; window.LanguageSwitcher = LanguageSwitcher; window.DonationToast = DonationToast;