// ============ ABOUT + NOW + GH ACTIVITY ============ function About() { const { t } = window.useLang(); const ref = window.useReveal(); const [events, setEvents] = React.useState(null); const [err, setErr] = React.useState(false); React.useEffect(() => { let alive = true; fetch('https://api.github.com/users/AngeloVPerrotta/events/public') .then(r => r.ok ? r.json() : Promise.reject()) .then(data => { if (!alive) return; const pushes = (data || []).filter(e => e.type === 'PushEvent').slice(0, 4).map(e => ({ repo: e.repo?.name || '', msg: e.payload?.commits?.[0]?.message?.split('\n')[0] || 'push', when: relTime(e.created_at) })); if (pushes.length === 0) throw new Error('no events'); setEvents(pushes); }) .catch(() => { if (alive) setErr(true); }); return () => { alive = false; }; }, []); const display = events || (err ? window.GH_MOCK : null); return (
{t.about.kicker}

{t.about.h2}

{t.about.paragraphs.map((p, i) =>

{p}

)}

{t.about.nowTitle}

    {t.about.now.map((it, i) => (
  • {it.icon}{it.label}
  • ))}

{t.about.ghTitle}

{display ? display.map((e, i) => (
{e.repo} › {e.msg}
{e.when}
)) : err ? (
› GitHub took a coffee break
) : ( Array.from({length:3}).map((_,i)=>(
···› loading...
···
)) )}
); } function relTime(iso) { if (!iso) return ''; const d = new Date(iso); const diff = (Date.now() - d.getTime()) / 1000; if (diff < 60) return 'hace segundos'; if (diff < 3600) return `hace ${Math.floor(diff/60)} min`; if (diff < 86400) return `hace ${Math.floor(diff/3600)} h`; return `hace ${Math.floor(diff/86400)} d`; } window.About = About;