Wumbotron is a TV/projector scoreboard app for shoveltoss. It has two main surfaces:
- Control: phone/laptop-friendly operator pages for creating matches, recording tosses, and running tournaments.
- Display: read-only TV pages that update from Supabase Realtime.
The app is built with Next.js, React, Tailwind CSS, Vitest, and Supabase.
Install dependencies:
pnpm installStart Docker Desktop, then start the local Supabase stack from the repo root:
supabase start
supabase db resetCopy the local Supabase values into .env.local:
NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54321
NEXT_PUBLIC_SUPABASE_ANON_KEY=<publishable key from supabase status>You can print the local values with:
supabase statusThen start the app:
pnpm devOpen http://localhost:3000.
pnpm dev # run the Next.js dev server
pnpm build # build for production
pnpm start # serve the production build
pnpm lint # run ESLint
pnpm test # run Vitest testsSeed a match into the configured Supabase project:
pnpm seed:matchMigrations live in supabase/migrations/ and run in filename order.
To recreate the local database and apply every migration:
supabase db resetThis project uses direct Postgres port 54332 in supabase/config.toml to
avoid conflicts with other local Supabase projects. The app talks to Supabase
through the API URL on 54321.
More details are in supabase/README.md.
Supabase Auth needs a secure context, which the browser
only grants to localhost or HTTPS origins — not LAN IPs like
http://10.0.0.x:3000. To use Control from a phone in dev, tunnel both
the Next dev server and the local Supabase API over HTTPS with
cloudflared:
brew install cloudflared
# Tunnel Supabase first — its URL is baked into the client bundle.
cloudflared tunnel --url http://localhost:54321
# → https://<random>.trycloudflare.comUpdate .env.local so NEXT_PUBLIC_SUPABASE_URL points at that HTTPS
URL, then restart pnpm dev so the new value is inlined into the
client bundle. Now tunnel the app:
cloudflared tunnel --url http://localhost:3000Open the second URL on your phone.
next.config.ts allows *.trycloudflare.com via allowedDevOrigins so
Next's HMR doesn't reject the cross-origin dev request.
Caveats:
- Both URLs are publicly reachable for the life of the tunnel. RLS still gates writes, but treat them as public.
- Trycloudflare URLs change every run, so the Supabase URL swap +
pnpm devrestart is a per-session step.
- Go to
/. - Create a new match or tournament.
- Open the display link from the control room on a TV/projector.
- Record tosses from the control room.
- Return to
/to resume recent matches or tournaments.