Elkhorn Top Dogs

A production web platform for a Special Olympics Nebraska delegation, combining a public site, a members-only portal, and an admin console for running the club.

Elkhorn Top Dogs flag football group photo

Three apps, one codebase

  • Public site

    The front door for families finding the club: homepage, photo galleries, sports offered, social club, fundraisers, and the legal pages.

  • Member portal

    Gated behind admin-approved accounts. A shared calendar, event listings, registration and waiver forms, and a household profile each family maintains itself.

  • Admin console

    Seven tabs of back office: account approval, family lookup, email distribution lists, jersey inventory, site content, calendar scheduling, and birthdays.

The delegation

Six sports and a monthly social club across Elkhorn and the surrounding communities. Every photo here is served by the platform's own gallery pipeline, cropped and published from the admin console.

  • Elkhorn Top Dogs flag football athletes together in 2025
  • Elkhorn Top Dogs flag football team photo from 2025
  • Elkhorn Top Dogs softball team photo from 2025
  • Elkhorn Top Dogs social club gathering in Fort Calhoun in 2025

Project overview

Elkhorn Top Dogs is a Special Olympics Nebraska delegation founded in 2023 by the Troia and Prodel families to bring more teams to the Elkhorn area. It serves athletes, partners, volunteers, and families across six sports plus a monthly social club, and it was being run out of spreadsheets, Facebook posts, and email chains. I built this platform to replace all of it.

The result is three applications in one codebase: a public marketing site, a members-only portal gated behind admin-approved accounts, and an admin console the club's leadership uses to run day-to-day operations. It is live in production at elkhorntopdogs.com and is the system the delegation actually operates on.

Roughly 20,600 lines across 60 modules, organized with a strict dependency direction: a backend layer that owns every Supabase call, a domain layer of pure business rules with no React or network dependencies, and pure utilities for recurrence expansion and event retention. Even the router is hand-written, about 100 lines on the History API with declarative auth gating, rather than another dependency.

Technical features

  • Admin-approved account lifecycleA pending, approved, or rejected flow layered on Supabase Auth. One SECURITY DEFINER Postgres function is the single source of truth, consulted on signup, sign-in, and every session restore, so an account revoked after login is signed out on the next page load rather than keeping a stale session.
  • Row Level Security across 11 tablesAround 50 policies covering owners, verified members, admins, and the public, plus a trigger that inspects the calling role and blocks any browser client from granting itself admin or verified status. Only the public anon key ever ships to the frontend.
  • Recurring-event calendarAdmins build recurrence rules through a form that serializes to jsonb. FullCalendar renders the month grid, and a hand-written occurrence-expansion utility feeds the homepage upcoming-events widget and a custom mobile agenda view, correctly including events that begin before the window but overlap into it.
  • Client-side image croppingPhotos are zoomed and positioned against an aspect-locked crop box, rendered through a canvas to JPEG, and uploaded to Supabase Storage. The crop rectangle is persisted, so reopening a photo slot restores the previous framing instead of starting over.
  • Live content updatesPostgres change subscriptions on six tables push an admin edit out to every open browser without a refresh, using a subscribe-and-refetch pattern that avoids a loading flash on background updates.
  • Email distribution builderAudience selection across each sport, the social club, and volunteers matches family members, rolls them up to their account owner, then normalizes, validates, and de-duplicates the addresses into a sorted list or an escaped CSV.
  • Jersey inventory managementPer-sport stock tracked by number and size, checked out to a specific athlete and back in again, with natural-order sorting and wildcard-escaped filters. Seeded from two legacy spreadsheets, de-duplicated with the provenance of each row recorded.
  • Business rules in the databaseCHECK constraints enforce what the client cannot be trusted with: all-or-nothing mailing addresses, dates of birth validated by a round-trip that rejects impossible dates, and a checked-in jersey that cannot hold an assignment.