SPA React/TypeScript che fonde un portfolio personale con un hub di sei applicazioni ludico-didattiche a tema architettura, geografia e lingua, su design system Bootstrap Italia e palette neroverde Sassuolo.
🔗 Live: albertopecchini.it · Repo: albertoxpecchini/AP · Autore: @albertoxpecchini
I badge di metrica derivano in tempo reale dall'API GitHub: si ricalcolano a ogni
git push, senza manutenzione.
| Dominio | Valore | Dettaglio |
|---|---|---|
| Codebase | ~28.7k LOC in src/ |
74 .tsx · 27 .ts · 6 .css |
| Componenti UI | 48 primitivi | wrapper shadcn/ui su Radix in src/app/components/ui/ |
| Dipendenze | 58 runtime + 7 dev | pnpm workspace, lockfile riproducibile |
| Applicazioni | 6 giochi + 1 portfolio | code-split via React.lazy per rotta |
| Trivia — quiz | 1005 domande su 40 capitoli | 401 multipla · 401 vero/falso · 201 aperta |
| Parole — lessico | ~27,7k lemmi (5–6 lettere) | dizionario di validazione + pool soluzioni curate |
| Mappa — atlante | 30 città da satellite | riconoscimento da imagery zenitale |
| Cronologia | 176 commit dal 2026-05-24 | 63 feat · 50 fix · 21 style · 6 chore · 4 altri |
Ogni gioco è un sotto-applicativo autonomo (route dedicata, lazy chunk indipendente, gating del nickname, leaderboard Supabase isolata). La home (App.tsx) funge da vetrina e da dispatcher di navigazione.
Pattern condiviso per ogni gioco: NicknameGate (onboarding identità) → loop di gioco → Leaderboard + leaderboardApi (persistenza Supabase) → schermata di esito. Trivia aggiunge Pagella, progressApi, gradesApi e copertura statistica per capitolo.
Pipeline content-driven, zero-config: i capitoli sono file Markdown in content/trivia/, importati a build-time via import.meta.glob(..., { query: '?raw', eager: true }) e parsati una sola volta in parseTrivia.ts. Aggiungere un capitolo = aggiungere un .md; nessun codice da toccare.
- 40 capitoli (
Neoclassicismo → … → CityLife), ordinati dal campoordine:con fallback alfabetico. - 1005 domande tipizzate:
multipla(401),vero/falso (401),aperta/completamento (201). - Versionamento automatico —
__TRIVIA_VERSION__è iniettata davite.config.tscome1.<git rev-list --count -- src/app/trivia/>: ogni deploy che tocca il modulo incrementa la minor da solo. - Arricchimento AI — middleware dev
/api/trivia(vite.config.ts) interroga Claude Opus 4.8 (@anthropic-ai/sdk) per curiosità contestuali; chiave viaANTHROPIC_API_KEYnel.env.
AP/
├── content/trivia/ # 40 capitoli .md → fonte unica delle domande Trivia
├── public/
│ ├── bootstrap-italia/ # Design System AgID (CSS/JS/font/svg)
│ ├── images/ # Asset hobby, passioni, copertine
│ └── site.webmanifest # PWA: manifest + favicon/icone maskable 192/512
├── src/
│ ├── app/
│ │ ├── App.tsx # Home/portfolio + dispatcher di navigazione
│ │ ├── trivia/ parole/ angoli/ mappa/ movimento/ pcto/ # 6 giochi
│ │ ├── components/ui/ # 48 primitivi shadcn/Radix
│ │ └── utils/ # keyboard guard, local mode, helper
│ ├── lib/ # utilità trasversali (players, ecc.)
│ ├── styles/ # theme.css (token palette) · tailwind · fonts · index
│ └── main.tsx # BrowserRouter + 7 Route lazy-loaded
├── scripts/ # build_cv.py · build_favicon.py
└── vite.config.ts # plugin React/Tailwind, asset resolver, versioning, dev-API
Dalla sorgente (testi, dati, immagini, codice) agli artefatti prodotti dagli
script di build (PDF · ZIP · WebP · JSON · bundle · service worker), fino al deploy
su Vercel e ai dati live che il browser richiede a runtime (GitHub, Supabase, /api).
Lo stesso schema è consultabile dal sito: footer → «Come funziona» (finestra interna).
sequenceDiagram
autonumber
actor Dev as Alberto · dev
participant CC as Claude Code
participant GH as GitHub · main
participant VC as Vercel · CI/hosting
participant BR as Browser · PWA
participant EXT as API e servizi esterni
Note over Dev,CC: 1 · Sviluppo locale (codifiche)
Dev->>CC: "fai la modifica X"
activate CC
Note over CC: build-cv.ps1 → 4× PDF · sharp → WebP · import-trivia → JSON
CC->>GH: git commit + push → main
deactivate CC
Note over GH,VC: 2 · Build e deploy (CI)
GH->>VC: webhook · nuovo commit su main
activate VC
Note over VC: prebuild · build-zips → ZIP
Note over VC: vite build · Rollup → bundle JS/CSS
Note over VC: vite-plugin-pwa · Workbox → service worker
VC-->>GH: deploy ok
deactivate VC
Note over BR,EXT: 3 · Un utente apre il sito
BR->>VC: GET / (HTML · JS · CSS · WebP · font)
VC-->>BR: SPA React + service worker (precache offline)
Note over BR,EXT: 4 · Dati live a runtime
BR->>EXT: GitHub API · profilo / eventi
EXT-->>BR: JSON → sparkline dei commit
BR->>EXT: Supabase · REST + Realtime WS
EXT-->>BR: classifiche + aggiornamenti live
BR->>VC: GET /api/trivia · parola
activate VC
VC->>EXT: Anthropic Claude (Haiku)
EXT-->>VC: curiosità (testo)
VC-->>BR: JSON (cache 24 h)
deactivate VC
BR->>VC: POST /api/notify · voto Festa
activate VC
VC->>EXT: Resend · invio email
EXT-->>VC: 202 accepted
VC-->>BR: ok
deactivate VC
| Servizio esterno | Uso | Dove |
|---|---|---|
| GitHub API (pubblica) | attività + sparkline dei commit nel footer | client |
| Supabase (REST + Realtime WS) | classifiche live dei giochi (fallback localStorage) |
client |
| Anthropic Claude | curiosità sulle parole (gioco Parole) | serverless /api/trivia |
| Resend | email dei voti della Festa | serverless /api/notify |
| Layer | Tecnologie |
|---|---|
| Core | React 18.3 · TypeScript · Vite 6.3 |
| Routing | react-router 7 (BrowserRouter, route lazy + Suspense) |
| Styling | Tailwind CSS 4 · CSS custom properties · Bootstrap Italia (AgID) |
| UI kit | 48 primitivi Radix UI in chiave shadcn/ui · class-variance-authority · tailwind-merge |
| Motion | motion (Framer Motion 12), rispettoso di prefers-reduced-motion |
| Dataviz / FX | recharts · canvas-confetti · embla-carousel · skinview3d |
| Form / input | react-hook-form · input-otp · cmdk · sonner (toast) |
| Backend | Supabase (leaderboard, pagelle, progressi per gioco) |
| AI | @anthropic-ai/sdk → Claude Opus 4.8 (curiosità Trivia) |
| Tooling | pnpm · playwright (E2E) · script Python per CV/favicon |
Requisiti: Node ≥ 18 · pnpm ≥ 8 (compatibile npm/yarn).
git clone https://github.com/albertoxpecchini/AP.git && cd AP
pnpm install
pnpm dev # http://localhost:5173 — HMR attivo, strictPort
pnpm build # bundle di produzione in dist/Per l'arricchimento AI di Trivia in locale, creare un .env con ANTHROPIC_API_KEY=....
| Comando | Azione |
|---|---|
pnpm dev |
Dev server Vite + middleware /api/trivia (porta 5173) |
pnpm build |
Build statica in dist/ |
python scripts/build_cv.py |
Rigenera il PDF del CV |
python scripts/build_favicon.py |
Rigenera set favicon + icone PWA |
- Supabase — persistenza realtime di leaderboard, pagelle e progressi, con API isolata per ciascun gioco (
*/leaderboardApi.ts,trivia/gradesApi.ts,trivia/progressApi.ts). - Anthropic / Claude Opus 4.8 — generazione di curiosità testuali on-demand.
- GitHub REST API —
App.tsxleggepushed_ate ultima release dei repo dei progetti (no-auth, rate limit pubblico). - Microlink — screenshot live 1200×630 come anteprima delle card progetto.
- Google Fonts — Titillium Web · Lora · Roboto Mono (
preconnect+display=swap).
A11y: skiplink al contenuto/contatti · landmark semantici (main/nav[aria-label]/header/footer) · aria-labelledby sui modali · focus visibile · contrasto AA sull'intera palette · prefers-reduced-motion onorato · Backspace neutralizzato fuori dai campi testo (disableBackspaceNavigation).
Deploy: SPA statica → deploy su Vercel (autodetect Vite, dist/, branch main = produzione). Equivalente su Netlify, GitHub Pages o qualunque static host.
Override completo del primario Bootstrap Italia (--bs-primary) propagato in App.tsx; token globali light/dark in src/styles/theme.css.
Codice sotto licenza MIT — liberamente riutilizzabile. Testi, foto personali, CV e brand «Alberto Pecchini» sono © Alberto Pecchini, non riproducibili senza autorizzazione. Bootstrap Italia è BSD-3-Clause (Presidenza del Consiglio dei Ministri).