A festive CrossFit competition hub built with Vue 3 + TypeScript + Vite + Pinia + Tailwind CSS + Firebase.
LiftOff powers a local holiday throwdown with real-time standings, team management, workout details, and schedule orchestration. Viewers enjoy a red-and-white frosted experience, while authenticated admins can manage every detail inside Firebase.
- 🎯 Live leaderboard with CrossFit-specific scoring (snatch, clean & jerk, WOD)
- 👥 Team directory grouped by category (men + men, women + women)
- 🗓️ Heat schedule with per-event call times
- 🛠️ Admin console gated behind Google Auth and Firebase role control
- ✍️ CRUD interfaces for teams, results, schedule, and workout
- ❄️ Snow-kissed UI with TailwindCSS and responsive Composition API pages
- Frontend: Vue 3, Composition API, TypeScript, Vite, Pinia, Vue Router
- Styles: TailwindCSS, custom festive theming
- Backend: Firebase Auth (Google only) + Firestore (teams, results, workout, schedule)
- Hosting: Firebase Hosting ready (see
firebase.json)
npm install
npm run devCreate a .env file (see .env.example) containing your Firebase project credentials and comma-separated admin UID list:
VITE_FIREBASE_API_KEY=...
VITE_ADMIN_UIDS=uid1,uid2| Collection | Fields |
|---|---|
teams |
name, category, athlete1, athlete2 |
results |
teamId, snatchAthlete1/2, cleanAthlete1/2, wodTime, totalPoints |
workout (doc current) |
description, standards, timeCap |
schedule |
teamId, snatchTime, cleanJerkTime, wodTime |
- Leaderboard: mobile-friendly cards with snatch/clean breakdown; desktop table with chips.
- Teams & Schedule: search bar filters by team or athlete name, division sections collapse gracefully.
- Admin editors: search/filter per screen, stacked cards on mobile, 3-column layout on desktop.
Deploy with Firebase:
npm run build
firebase deploy --only hosting| Command | Description |
|---|---|
npm run dev |
Start local dev server |
npm run build |
Type-check + bundle |
npm run preview |
Preview production build |
npm run set-admin -- path/to/serviceAccount.json |
Apply admin claim to every UID in VITE_ADMIN_UIDS |
- Download a Firebase service-account key (
Project Settings → Service accounts → Generate new private key). - Ensure
.envcontains every UID that should be elevated, e.g.VITE_ADMIN_UIDS=L89ZwNVE3IfNpQCjPNvZ76PIUFp2. - Run
npm run set-admin -- path/to/serviceAccount.jsonto set theadminclaim for each UID. - Have the user sign out/in so their token refreshes and Firestore rules recognize the claim.
- Authenticate CLI:
firebase login. - Create/verify a Hosting site (e.g.
liftoff-b53d8) and add"site": "liftoff-b53d8"tofirebase.json. - Build the SPA:
npm run build. - Deploy static assets:
firebase deploy --only hosting.dist/is uploaded, SPA rewrites are handled byfirebase.json.
- If you need to temporarily take the site offline:
firebase hosting:disable. - Re-enable simply by running the deploy command again.
VITE_*variables are baked into the build; they are not secrets but identifiers. Real access control is enforced via Firestore rules and the{ admin: true }custom claim.
Made with ❤️🔥 + ❄️ for the North Pole gym community.