The challenge
Betting sites have cluttered interfaces: hundreds of markets, banners everywhere and a bet slip that's hard to follow. I set out to design and build a prototype that keeps every feature of a real sportsbook, but organised so that placing a bet is clear and fast.
The solution
Always-visible bet slip
that instantly calculates potential winnings, with quick stakes (+10, +50, x2).
Accumulators
with multiple selections on the same slip.
Live matches
with the current minute, score and updated 1X2 odds.
Favourite leagues
per user and a league sidebar with match counts.
Promotions
(welcome bonus, cashback, free bet, accumulator boost, VIP) in a carousel.
Cash Out
settle a bet before the match ends.
Responsible gambling
with configurable limits, reachable from the menu.
Sign-in
with email and password or with Google.
Mobile first
on small screens the bet slip becomes a floating button.
Outcome
A complete, navigable product that shows how to solve the user experience of a complex application, with many states and data that changes in real time.
For developers
Next.js (App Router) + React 19, server-rendered with Server Components and mutations via Server Actions.
Strict TypeScript, no
any. Tailwind CSS v4 with brand colours as tokens.Zustand for client state (bet slip, favourites, filters and live odds); slip and favourites persisted to
localStorage.Supabase (Postgres): business rules live in SQL functions (placing bets, accumulators, match settlement, promotions, responsible-gambling limits and Cash Out). Anything that moves money runs server-side, and data is protected with RLS.
Supabase Auth with
@supabase/ssr: email and password plus Google OAuth; the session is refreshed on every request.Live match simulation with custom scripts: moving odds, settling matches and seeding demo data.
AI-generated images (OpenAI) in a separate script; AI plays no part while the site is running.
Vercel with automatic deploys on every push to
main· ESLint ·sharp.Private repository: available to walk through in an interview.

