A real-time Formula 1 prediction platform where users can create rooms, make race predictions, and compete with friends throughout the F1 season.
- Room-Based Predictions: Create or join rooms for an entire F1 season
- Race Predictions: Predict driver positions, fastest lap, pole position, and DNFs
- Real-Time Updates: Live leaderboards and room updates powered by Convex
- Flexible Lockout System: Configure when predictions lock (before sessions, custom time offsets)
- Custom Scoring: Configurable scoring systems with position points, bonuses, and penalties
- Race Data Sync: Automatic synchronization with the F1 Connect API for race schedules and results
- Dark Mode: Beautiful dark theme optimized for F1 viewing
- Responsive Design: Works seamlessly on desktop and mobile devices
- Frontend: Next.js 16+ (App Router, React Server Components)
- Backend & Database: Convex (real-time database, reactive queries)
- Authentication: Clerk
- UI Components: shadcn/ui (Radix-based, New York style)
- Styling: Tailwind CSS v4 with CSS variables
- Package Manager: pnpm
- Language: TypeScript (strict mode)
- Race Data: F1 Connect API (
convex/actions/f1Connect.ts)
- Node.js 18+ and pnpm installed
- A Convex account (sign up at convex.dev)
- A Clerk account (sign up at clerk.com)
- Clone the repository:
git clone <repository-url>
cd f1-picks- Install dependencies:
pnpm install- Set up Convex:
pnpm convex:devThis will prompt you to create a new Convex project or link to an existing one. Follow the prompts.
- Set up environment variables:
Create a
.env.localfile in the root directory:
NEXT_PUBLIC_CONVEX_URL=<your-convex-deployment-url>
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=<your-clerk-publishable-key>
CLERK_SECRET_KEY=<your-clerk-secret-key>- Configure Convex environment variables: Set up your Clerk keys in Convex dashboard or via CLI:
npx convex env set CLERK_SECRET_KEY <your-clerk-secret-key>- Run the development server:
pnpm dev- In another terminal, run Convex dev:
pnpm convex:devOpen http://localhost:3000 to see the application.
app/ # Next.js App Router pages
├── layout.tsx # Global layout, theme, navbar
├── page.tsx # Dashboard (active rooms, create/join)
├── races/[raceId]/ # Race details and information
└── rooms/[roomId]/ # Room view: predictions, leaderboard, participants
├── participants/ # Room participants list
├── predictions/ # Prediction management
└── results/ # Race results and scoring
convex/ # Convex backend functions
├── schema.ts # Data model definitions
├── queries/ # Read-only reactive queries
├── mutations/ # Write operations
├── actions/ # External API calls (F1 Connect)
│ ├── f1Connect.ts # F1 Connect API integration
│ └── raceSync.ts # Race result synchronization
├── lib/ # Shared utilities
│ ├── scoring.ts # Scoring calculation logic
│ ├── lockout.ts # Lockout validation logic
│ └── userHelpers.ts # User utility functions
└── crons.js # Scheduled functions
components/ # React components
├── ui/ # shadcn/ui components
├── dashboard/ # Dashboard components
├── room/ # Room-related components
└── race/ # Race-related components
lib/ # Utilities and shared code
hooks/ # Custom React hooks
Rooms are season-long prediction groups. Each room:
- Is tied to a specific F1 season
- Has a host who can configure settings
- Uses a join code for easy access
- Has configurable lockout and scoring rules
Users make predictions for each race in a room:
- Driver Positions: Predict the finishing order (top 10)
- Fastest Lap: Predict which driver will set the fastest lap
- Pole Position: Predict qualifying winner
- DNFs: Predict which drivers will not finish
Predictions lock at configurable times:
- Before a specific session starts (FP1, FP2, FP3, Qualifying, Race)
- Before a session ends
- Custom hours before race start
Points are awarded based on:
- Position Points: Configurable points for correct position predictions
- Fastest Lap Bonus: Points for correct fastest lap prediction
- Pole Position Bonus: Points for correct pole position prediction
- DNF Penalty: Negative points for incorrect DNF predictions
pnpm dev- Start Next.js development serverpnpm build- Build for productionpnpm start- Start production serverpnpm lint- Run ESLintpnpm convex:dev- Start Convex development modepnpm convex:deploy- Deploy Convex functions
- TypeScript strict mode enabled
- Prettier for code formatting (runs on save via lint-staged)
- ESLint for linting
- Husky for git hooks
Convex functions are automatically synced when you run pnpm convex:dev. The Convex dashboard provides:
- Real-time function logs
- Database browser
- Function testing interface
Access the dashboard at the URL provided when you run convex:dev.
- Push your code to GitHub
- Import the project in Vercel
- Add environment variables:
NEXT_PUBLIC_CONVEX_URLNEXT_PUBLIC_CLERK_PUBLISHABLE_KEYCLERK_SECRET_KEY
- Deploy
Deploy Convex functions to production:
pnpm convex:deploySet the CONVEX_DEPLOY_KEY environment variable to your production deploy key (found in Convex dashboard). Set production environment variables in Convex dashboard or via CLI.
- Create a feature branch
- Make your changes
- Ensure code passes linting and formatting
- Submit a pull request
MIT License - see LICENSE file for details.