Fanta F1 – Full-Stack F1 Fantasy League Platform
🌍 Live Demo → fanta-f1.web.com
A full-stack web application to manage a Formula 1 fantasy league among friends — real-time standings, automatic points calculation via REST API, sprint race support, advanced admin tools, PWA installability, and push notifications.

Home page — quick access to submissions, F1 hub, race history, and standings
🎮 How It Works
Before each Grand Prix, every player submits a formation before qualifying starts. Points are calculated automatically once official results are fetched from the Ergast F1 API.
- 3 Drivers (P1, P2, P3) — predict the top 3 finishers in order
- Joker — bonus driver: +5 pts if they finish on the podium
- Joker 2 — unlockable via the 29→30 rule
- Sprint Formation — separate picks for sprint weekends (SP1/SP2/SP3 + Sprint Joker)
- Championship Formation — mid-season prediction of top 3 drivers and constructors
🏆 Scoring System
Main Race
- 1st correct → 12 pts · 2nd → 10 · 3rd → 8
- Joker on podium → +5 pts
Sprint Race
- 1st correct → 8 pts · 2nd → 6 · 3rd → 4
- Sprint Joker on podium → +2 pts
- 29→30 Rule: guessing the full podium in order (30 pts) earns 1 extra Joker for a future race — applies to race, sprint, and championship
- Last Race – Double Points: all points doubled in the final race of the season
- Late Submission: −3 pts penalty if submitted after qualifying starts (within grace window)
- Cancelled Races: no points awarded, formations not required

Submit page — formation submission with driver selection

F1 Calendar — admin race calendar management

Personal profile — participant detail and formation history

Personal statistics — performance metrics and points breakdown
📱 App Features
- 📊 Real-Time Leaderboard — standings with gap from leader, jokers, championship points, and season points-progression chart
- 👤 Participant Detail — per-race breakdown (main + sprint), best/worst race, average score, joker usage, and full formation history
- 🏁 Race History — official podium results, all player formations, individual points earned, sprint results
- 🎯 Formation Submission — searchable dropdowns with team logos, real-time duplicate validation, formation preview, and deadline countdown
- 📈 Statistics Dashboard — top performers, hardest race to predict, most popular picks, and trend charts

Race statistics — per-race results and scoring
🔌 REST API Integration – Ergast F1 API
- Automatic podium fetching after each race with one-click admin trigger
- Dynamic driver and constructor roster synced from the API (cached 72 h in localStorage)
- Fallback to manual
f1-data.json if the API is unavailable
⚙️ Admin Panel
Secured via Firebase Custom Claims — no shared passwords, no client-side bypass. Privileges are granted via a server-side Node.js script.
📝 Formation Management
- Submit or edit any user's formation, bypassing the deadline
- Apply or override late submission penalty
- Manage sprint formations separately
📅 Calendar Management
- Edit race, qualifying, and sprint deadlines
- Add/remove sprint weekends
- Cancel races/sprints (skips points calc)
🧮 Points Calculation
- Auto-fetch results from Ergast API or manual entry
- One-click calculation with 29→30 and double-points auto-detection
- Ranking snapshot saved after every calculation
💾 Backup & Restore
- Auto-backup before every critical operation
- Browse, preview, and one-click restore from any snapshot
- Export as JSON; destructive ops require typing "RESTORE"
🔐 Authentication & 📲 PWA
- Email/Password and Google Sign-In
- Account linking: same email → merged profile
- Unique nickname enforcement at registration
- Password reset via Firebase secure email
- Route guards:
ProtectedRoute + AdminRoute
- Installable on Android, iOS, and desktop
- Offline-capable via Workbox service worker
- Auto-update on next launch
- FCM push notifications: qualifying reminders 1 h and 5 min before (night sessions → 21:00 the day before)
- Delivered by Firebase Cloud Functions on cron schedule

F1 Hub — real-time standings and season leaderboard
🎨 Customization
- Points system — all values, joker bonuses, late penalty, and grace window configurable in
racing.js - F1 data — auto-synced from Ergast API; override with custom
f1-data.json for any season - Theme — CSS variables for primary color, dark palette, and accent; full dark mode with localStorage persistence
- i18n — Italian and English via
LanguageContext, easily extensible
🛠️ Tech Stack
Frontend
React 19 · React Router v7 · React Bootstrap · React-Select · Recharts · Vite 6 · vite-plugin-pwa
Backend & Database
Firebase Firestore · Firebase Auth · FCM · Cloud Functions (Node.js 20) · Firebase Hosting · Ergast F1 REST API
Deployment
GitHub Actions CI/CD · Firebase Hosting auto-deploy · Firestore Security Rules · GitHub Secrets