// ===================== Core components: Reveal, Nav, Hero, About, Experience ===================== const { useState, useEffect, useRef, useContext } = React; // scroll reveal wrapper function Reveal({ children, delay=0, as='div', className='', ...rest }){ const ref = useRef(null); const [seen, setSeen] = useState(false); useEffect(()=>{ const el = ref.current; const io = new IntersectionObserver((es)=>{ es.forEach(e=>{ if(e.isIntersecting){ setSeen(true); io.disconnect(); } }); }, { threshold:0.12, rootMargin:'0px 0px -8% 0px' }); if(el) io.observe(el); return ()=>io.disconnect(); },[]); const Tag = as; return {children}; } function useC(){ const { lang } = useContext(window.LangCtx); return window.CONTENT[lang]; } const H = (html)=>({ dangerouslySetInnerHTML:{ __html:html } }); // ---------- NAV ---------- function Nav({ lang, setLang }){ const C = window.CONTENT[lang]; const [scrolled, setScrolled] = useState(false); useEffect(()=>{ const on = ()=>setScrolled(window.scrollY > 40); on(); window.addEventListener('scroll', on, { passive:true }); return ()=>window.removeEventListener('scroll', on); },[]); const N = C.nav; return ( Patrick Chaves {N.about} {N.skills} {N.companies} {N.projects} setLang('pt')}>PT setLang('en')}>EN {N.contact} ); } // ---------- HERO ---------- function Hero(){ const C = useC(); const h = C.hero; return ( {h.tag} PatrickChaves {window.SOCIALS.map((s,i)=>( {s.k} {s.v} ↗ ))} {h.corner} {h.b1} ); } // ---------- ABOUT ---------- function About(){ const C = useC(); const a = C.about; const ref = useRef(null); const [vis, setVis] = useState(false); useEffect(()=>{ const io = new IntersectionObserver((es)=>{ es.forEach(e=>{ if(e.isIntersecting) setVis(true); }); }, { threshold:0.3 }); if(ref.current) io.observe(ref.current); return ()=>io.disconnect(); },[]); return ( {a.num} · Patrick Chaves / {a.num} {a.quote} {a.stats.map((s,i)=>({s.n}{s.l}))} {a.body.map((p,i)=>({p}))} {a.langs_title} {a.langs.map((L,i)=>( {L.n}{L.l} ))} ); } // ---------- EXPERIENCE ---------- function Experience(){ const C = useC(); const e = C.exp; return ( {e.num} · {e.kicker} / {e.num} {e.jobs.map((j,i)=>( {j.when} {j.live && {j.live}} {j.co}{j.ceo && CEO} {j.role} {j.tags.map((t,k)=>({t}))} {j.items.map((it,k)=>({it}))} ))} ); } Object.assign(window, { Reveal, useC, H, Nav, Hero, About, Experience });
{p}