All Work

Full-Stack Web Application

Berryessa TNT

A membership and tournament registration platform for a bass fishing tournament series on Lake Berryessa, California.

Visit Site
  • Next.js
  • React
  • TypeScript
  • Supabase
  • Stripe API
  • Resend
  • Sentry
  • Cloudflare Turnstile
  • Tailwind CSS
Berryessa TNT home page

The Challenge

The organizers ran a yearly, two-series bass fishing tournament by hand, which made memberships, registrations, and event logistics slow to manage. They needed one platform where anglers could buy a membership and register for tournaments themselves, and where admins could manage users, oversee registrations, and handle logistics like the boat launch order.

What I Built

I designed and built a full-stack web application with a member-facing site and an admin dashboard. Anglers create an account, purchase a membership, and register a team for each tournament, paying online through Stripe. Each member has a profile and a page listing the tournaments they have entered.

  • Event management: admins create and edit tournaments, upload event images, and set entry prices and membership requirements.
  • Member management: a user list with controls for memberships and admin access.
  • Blast off: a randomized boat launch order for each event, generated with a cryptographically fair shuffle.
Membership page explaining what a membership unlocks, with a purchase button
Tournament registration form with team name, partner, and team captain fields

Payments

Memberships and tournament entries are sold through Stripe Checkout. Entry prices are read from the database on the server when a session is created, never taken from the browser, and membership requirements are enforced before checkout begins.

A webhook verifies each event's Stripe signature and then records the membership or registration in Supabase. The writes are upserts, so Stripe's automatic retries are safe to process more than once. If processing fails, the error is captured in Sentry and an alert email goes out.

Stripe Checkout page for a membership purchase

Accounts and Security

Authentication runs on Supabase with cookie-based sessions that are refreshed on the server. The sign-up, login, and password reset forms are protected with Cloudflare Turnstile, and admin API routes confirm the caller's session and admin role on the server before making any change.

Outcome

The client went from managing everything manually to a purpose-built platform that handles the full tournament lifecycle. Administrative overhead dropped, and members have a self-service path from sign-up to tournament day.

Admin dashboard with user, event, registration, and member totals, quick actions, and upcoming tournaments