All Projects
Selected Work2026Full-Stack Application

American YouthDance Theater

FreelanceNext.jsTypeScriptSupabaseTailwindSass
Client Portal
aydance.org
American Youth Dance Theater — enrollment portal homepage
Admin Portal
admin.aydance.org
American Youth Dance Theater — admin operations dashboard
Outcomes

Results after launch

$44,100
5-Year Savings (Projected)
Worst-case analysis: $75k with Active vs. $30,900 with the custom portal over 5 years. Break-even in Year 3.
~80%
of Net Profit Freed
Active's $15k annual fee represented nearly 80% of AYDT's net profit. The new platform costs $780–$1,908/year.
Apr 30
Launch Target
19-week build: Discovery → Backend → Portal → Admin → Email & Analytics → QA → Launch & data migration.
Type
Custom Registration Portal
Stack
Next.jsTypeScriptSupabaseTailwindSass
Third-Party Integrations
Twilio SMSResendElevonSentryUpstash Redis
Overview

A platform fee consuming 80% of net profit

American Youth Dance Theater — a NYC dance studio operating since 1996 across two locations (Upper East Side and Washington Heights) — had been running their entire enrollment operation on Active, a registration platform built for outdoor recreational events like camping and sports leagues. The $15,000 annual license fee represented nearly 80% of the studio's net profit. It had no native concept of dance divisions, recital cycles, or per-class fee conditions — and its volume-based pricing model was designed to scale costs upward as AYDT grew.

The project brief was clear: build a simple, affordable, purpose-built replacement. Not another SaaS subscription. A platform AYDT owns outright — with full control over its UX, its data, and its operating costs. The result is a dual-surface system: a consumer-facing enrollment portal for families and a full admin operations dashboard for studio staff, both powered by a single Supabase backend.

Challenge

Four problems Active created

01
A Cost Structure That Scaled Against Growth
At $15,000/year — nearly 80% of net profit — Active's volume-based pricing meant the more AYDT grew, the more they'd pay. There was no path to profitability without replacing the platform. The studio needed a cost model it could forecast and a system it owned.
02
An Archaic, Non-Mobile Platform
Active was built for desktop and designed for outdoor recreational event management — camps, sports leagues, community programs. It wasn't mobile-friendly, and it had no domain model for dance: no divisions, no recital cycles, no multi-dancer family accounts, no class-level fee conditions. Every AYDT workflow required a workaround.
03
No Analytics or UX Control
AYDT had no visibility into how families moved through the registration flow — no engagement data, no conversion tracking, no marketing performance. The platform owned the experience and the data. Switching systems meant reclaiming both.
Solution

Ownership, forecastability, and a schema built for dance

The build was structured around three goals from the proposal: complete ownership (eliminate recurring license fees with a system the studio controls), forecastability (open-source infrastructure with transparent, stable costs), and reclaiming the UX and data layer (full analytics visibility via Google Analytics 4 and Sentry). The decision to build a custom solution rather than renew Active's license pays for itself immediately. Running on Vercel, Supabase, and Resend, AYDT's infrastructure costs fall from $15,000/year to an estimated $780–$1,908/year — the same capability at a fraction of the price.

The backend is a 65-table Supabase schema modeled around how a dance studio actually operates. The fee engine is the most complex component: enrollment cost is resolved server-side by evaluating a conditional rule chain — division, class count, semester type, multi-dancer family discounts, and coupons — in sequence. Automatic fees (registration, recital, costume) attach or detach based on class properties, not user input. Data migration from Active runs as a three-step pipeline: clean and archive inactive records from Active, populate the Supabase database, then seed Resend with user data and trigger welcome emails — executable at any time without interrupting the existing system.

65-table domain model
Schema purpose-built for dance studio operations — divisions, recital cycles, multi-dancer family accounts, and class-level fee structures all modeled correctly.
Server-side fee engine
Enrollment cost resolved via conditional rule chain: division → class count → semester → family discounts → coupons, all calculated before the cart confirms.
Zero-to-ownership cost model
$15k/year license replaced with $780–$1,908/year in infrastructure — on free-tier services the studio owns outright, with no volume-based scaling.
Color System

Palette & Design Rationale

Client Portal

The client portal leads with a near-black hero — it reads as a stage before the first word registers, placing the studio's 30-year identity front and center. The violet-to-rose gradient on 'Center Stage' is the only decorative moment; it earns that prominence by being the only color that isn't load-bearing. Below the hero, the portal content lives on a cool lavender-tinted off-white — not pure white, but close enough to feel neutral while still belonging to the same color family as the hero.

Stage Black
Hero background — theatrical depth, immediate authority
#18141c
Stage Violet
Gradient start — left side of the 'Center Stage' heading
#b89af0
Stage Rose
Gradient end — right side, warmth paired with performing arts identity
#e882c2
Portal Surface
Content background — lavender-tinted off-white for enrollment flows
#f4f2f9
Admin Portal

The admin surface flips to a light, high-contrast environment — staff spending hours in the dashboard need legibility over atmosphere. Deep crimson anchors the primary actions: warm enough to feel branded without competing with the data-dense tables and registration lists that dominate the screen. Light bone grounds the table backgrounds; dark slate keeps operational data readable across long work sessions.

Deep Crimson
Primary actions — branded authority in a data-dense surface
#8b1a2c
Light Bone
Table backgrounds — calm foundation for dense data views
#f5f4f1
Dark Slate
Data typography — maximum contrast for operational clarity
#1e2530
Clean White
Content surfaces — base for forms, panels, and modals
#ffffff
Backend

Architecture & Fee Engine

01
Server-Side Fee Engine
Enrollment cost is resolved server-side by evaluating a 6-layer conditional rule chain — division, class count, semester type, family discounts, coupons, and automatic fees — in sequence, before the cart ever confirms.
Backend
Resolution order — evaluated server-side before cart confirms
01
Division
Base tier lookup
02
Class Count
Volume adjustments
03
Semester Type
Annual vs. semester rate
04
Family Discounts
Multi-dancer rules
05
Coupons
Promotional overrides
06
Auto Fees
Reg / recital / costume
TOTAL
Cart Confirmed
Pre-checkout
65
Tables
Purpose-built domain model
3
Migration phases
Clean → Seed → Email
6
Fee rule layers
Server-side resolution chain
02
Full Schema — 65 Tables, 10 Domain Clusters
Every table in the schema, organized by domain. 8 cross-domain FK flows shown as bezier curves — each connecting two clusters with an FK count badge. Scroll right on smaller screens.
Schema
65 tables  ·  10 domains  ·  8 cross-domain FK flows
Identity & Accounts
Semester & Program
Class Structure
Requirements & Access
Enrollment & Registration
Auditions & Waitlist
Discounts & Pricing
Payments
Email & Comms
Media
5 FK4 FK6 FK4 FK3 FK4 FK4 FK3 FK
Identity & Accounts4
users
families
dancers
authorized_pickups
Semester & Program9
semesters
semester_fee_config
semester_payment_plans
semester_payment_installments
semester_audit_logs
special_program_tuition
tuition_rate_bands
semester_coupons
semester_discounts
Class Structure13
classes
class_schedules
class_sessions
class_schedule_excluded_dates
class_session_excluded_dates
class_session_options
class_session_price_rows
schedule_price_tiers
session_groups
session_group_sessions
session_group_tags
session_tags
session_occurrence_dates
Requirements & Access7
class_requirements
class_requirement_approved_dancers
requirement_waivers
concurrent_enrollment_groups
concurrent_enrollment_options
class_invites
invite_events
Enrollment & Registration6
registrations
registration_batches
registration_line_items
registration_days
schedule_enrollments
batch_payment_installments
Auditions & Waitlist3
audition_sessions
audition_bookings
waitlist_entries
Discounts & Pricing7
discounts
discount_rules
discount_rule_schedules
discount_rule_sessions
discount_coupons
coupon_redemptions
coupon_session_restrictions
Payments4
payments
stored_payment_methods
shoppers
family_account_credits
Email & Comms10
emails
email_templates
email_deliveries
email_recipients
email_recipient_selections
email_activity_logs
email_subscribers
email_subscriptions
notification_subscription_emails
sms_notifications
Media2
media_images
media_folders
Up Next
Back to First · Web Design
Coaching & Consulting
Private practice website — Next.js · TypeScript · Tailwind · Sass