A mobile-first web application for managing dance group member check-ins, subscriptions, and profiles. Built with Next.js 14, TypeScript, and Supabase.
Get the project running in 5 minutes:
# 1. Clone the repository
git clone https://github.com/DarleneQing/The-Rookie-Dance-Studio.git
cd The-Rookie-Dance-Studio
# 2. Install dependencies
npm install
# 3. Set up environment variables (see Environment Variables section)
cp .env.example .env.local # Create from template if available
# Or create .env.local manually with your Supabase credentials
# 4. Set up database (see Database Setup section)
# Run docs/schema.sql in your Supabase SQL editor
# 5. Start development server
npm run devOpen http://localhost:3000 to see the application.
Before you begin, ensure you have the following installed:
- Node.js 18.x or higher (check with
node --version) - npm, yarn, or pnpm (npm comes with Node.js)
- Git for version control
- Supabase account (sign up here)
git clone https://github.com/DarleneQing/The-Rookie-Dance-Studio.git
cd The-Rookie-Dance-Studionpm install
# or
yarn install
# or
pnpm install- Go to Supabase Dashboard
- Create a new project (or use an existing one)
- Wait for the project to finish provisioning
- Note your project URL and API keys (found in Settings > API)
Create a .env.local file in the root directory:
# .env.local
NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_keyWhere to find these values:
- Go to your Supabase project dashboard
- Navigate to Settings > API
- Copy the Project URL →
NEXT_PUBLIC_SUPABASE_URL - Copy the anon/public key →
NEXT_PUBLIC_SUPABASE_ANON_KEY
- Open your Supabase project dashboard
- Go to SQL Editor
- Open the file
docs/schema.sqlfrom this repository - Copy the entire SQL script
- Paste it into the SQL Editor
- Click Run to execute the schema
This will create:
- User roles and member type enums
profilestable for user datasubscriptionstable for subscription managementcheck_instable for attendance trackingstudent_verificationstable for student status verification- Required functions and triggers
npm run devThe application will be available at http://localhost:3000.
- Open http://localhost:3000 in your browser
- You should see the landing page with "Log in" and "Sign Up" buttons
- Try registering a new account to test the authentication flow
- Check the browser console for any errors
The following environment variables are required:
| Variable | Description | Where to Find |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL |
Your Supabase project URL | Supabase Dashboard > Settings > API > Project URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY |
Your Supabase anonymous/public key | Supabase Dashboard > Settings > API > anon/public key |
Security Note: The NEXT_PUBLIC_ prefix means these variables are exposed to the browser. This is safe for Supabase anonymous keys, which are designed to be public. Row-level security (RLS) policies in Supabase protect your data.
The database schema is defined in docs/schema.sql. This file contains:
- Enums: User roles, member types, subscription types, verification statuses
- Tables:
profiles- User profile informationsubscriptions- Subscription records (Monthly, 5-Times, 10-Times cards)check_ins- Attendance recordsstudent_verifications- Student status verification requests
- Functions: Database triggers and helper functions
- Constraints: Data integrity rules and relationships
To apply the schema:
- Open Supabase Dashboard > SQL Editor
- Copy contents of
docs/schema.sql - Paste and execute in SQL Editor
- Verify tables were created in Database > Tables
src/
├── app/ # Next.js App Router pages and routes
│ ├── admin/ # Admin-only pages
│ │ ├── scanner/ # QR code scanner for check-ins
│ │ └── users/ # User management dashboard
│ ├── auth/ # Authentication routes
│ │ └── callback/ # OAuth callback handler
│ ├── login/ # Login page
│ ├── register/ # Registration page
│ ├── profile/ # User profile page
│ ├── verify-email/ # Email verification page
│ ├── layout.tsx # Root layout component
│ ├── page.tsx # Home/landing page
│ └── globals.css # Global styles
│
├── components/ # React components
│ ├── admin/ # Admin-specific components
│ │ ├── assign-subscription-dialog.tsx
│ │ ├── qr-scanner.tsx
│ │ └── users-table.tsx
│ ├── auth/ # Authentication UI components
│ │ ├── auth-form.tsx
│ │ ├── auth-input.tsx
│ │ ├── floating-elements.tsx
│ │ ├── orbital-ring.tsx
│ │ ├── register-form.tsx
│ │ └── sparkle.tsx
│ ├── profile/ # Profile-related components
│ │ └── qr-code-display.tsx
│ └── ui/ # Reusable UI components (Shadcn)
│ ├── avatar.tsx
│ ├── button.tsx
│ ├── card.tsx
│ ├── dialog.tsx
│ ├── input.tsx
│ ├── label.tsx
│ ├── select.tsx
│ └── table.tsx
│
├── lib/ # Utility libraries
│ ├── supabase/ # Supabase client configurations
│ │ ├── client.ts # Browser client
│ │ ├── server.ts # Server-side client
│ │ └── middleware.ts # Middleware session handler
│ └── utils.ts # General utilities
│
├── middleware.ts # Next.js middleware for auth
├── types/ # TypeScript type definitions
│ └── auth.ts # Authentication-related types
└── public/ # Static assets
docs/ # Documentation
├── spec.md # Detailed feature specifications
├── brandbook.md # Design system and brand guidelines
└── schema.sql # Database schema
# Start development server (with hot reload)
npm run dev
# Build for production
npm run build
# Start production server (after build)
npm run start
# Run ESLint
npm run lintThe development server runs on http://localhost:3000 by default. It features:
- Hot Module Replacement (HMR) - Changes reflect immediately
- Fast Refresh - React components update without losing state
- TypeScript checking - Type errors shown in terminal and browser
Adding a new page:
- Create a new folder in
src/app/with apage.tsxfile - Example:
src/app/about/page.tsxcreates route/about
Adding a new component:
- Create component file in appropriate
src/components/subdirectory - Use TypeScript for type safety
- Follow existing component patterns
Modifying database schema:
- Update
docs/schema.sqlwith your changes - Run the SQL in Supabase SQL Editor
- Update TypeScript types if needed
Working with Supabase:
- Use
src/lib/supabase/client.tsfor client-side operations - Use
src/lib/supabase/server.tsfor server-side operations - Check Supabase dashboard for data inspection
The app uses Supabase Auth for authentication:
- Registration: User signs up → email verification → profile completion
- Login: Email/password or Google OAuth
- Session Management: Handled by Supabase with middleware refresh
- Protected Routes: Middleware checks authentication status
Key Files:
src/middleware.ts- Route protectionsrc/lib/supabase/- Supabase client setupsrc/app/auth/actions.ts- Authentication server actions
Three user roles:
-
Admin (
role: 'admin'): Full system access- User management
- Subscription assignment
- QR code scanning for check-ins
- Student verification approval
-
Member - Adult (
member_type: 'adult'): Default member type- View and edit own profile
- Generate QR code
- View own subscription and check-in history
-
Member - Student (
member_type: 'student'): Verified student- Same permissions as Adult
- Requires admin verification via student card upload
Access Control:
- Admin routes:
src/app/admin/*(protected by middleware) - Member routes:
src/app/profile/*(accessible to all authenticated users)
Three subscription types:
- Monthly Card: 30-day validity from admin-selected start date
- 5-Times Card: 5 check-in sessions (no expiration date)
- 10-Times Card: 10 check-in sessions (no expiration date)
Key Logic:
- Only one active subscription per user
- New subscription assignment archives previous one
- Check-in validation happens in
src/app/admin/scanner/page.tsx
- Member: Generates QR code on profile page (
src/app/profile/page.tsx) - Admin: Scans QR code using scanner (
src/app/admin/scanner/page.tsx) - Validation: System checks:
- User exists
- Active subscription exists
- Subscription is valid (not expired/depleted)
- Recording: Check-in recorded with timestamp and subscription details
Key Components:
src/components/profile/qr-code-display.tsx- QR code generationsrc/components/admin/qr-scanner.tsx- QR code scanning
- Pages: Next.js App Router - folders with
page.tsxfiles - Server Actions:
actions.tsfiles in route folders - Components: Organized by feature domain
- Types: Centralized in
src/types/ - Utilities: Reusable functions in
src/lib/
| Category | Technology | Purpose |
|---|---|---|
| Framework | Next.js 14+ (App Router) | React framework with server-side rendering |
| Language | TypeScript | Type-safe JavaScript |
| UI Library | React 18 | Component library |
| Styling | Tailwind CSS | Utility-first CSS framework |
| UI Components | Shadcn UI (Radix UI) | Accessible component primitives |
| Backend | Supabase | Authentication, database, and API |
| Database | PostgreSQL (via Supabase) | Relational database |
| Forms | React Hook Form + Zod | Form handling and validation |
| QR Codes | react-qr-code | QR code generation |
| QR Scanner | @yudiel/react-qr-scanner | QR code scanning |
| Icons | Lucide React | Icon library |
| Notifications | Sonner | Toast notifications |
Problem: App can't connect to Supabase
Solutions:
- Ensure
.env.localis in the root directory (not insrc/) - Restart the development server after adding/changing variables
- Check that variable names start with
NEXT_PUBLIC_ - Verify values are correct (no extra spaces or quotes)
Problem: "Failed to fetch" or database errors
Solutions:
- Verify Supabase project is active (not paused)
- Check
NEXT_PUBLIC_SUPABASE_URLmatches your project URL - Ensure database schema has been applied (
docs/schema.sql) - Check Supabase dashboard for any service issues
Problem: Type errors in IDE or build
Solutions:
- Run
npm installto ensure all dependencies are installed - Check that
tsconfig.jsonpaths are correct - Restart TypeScript server in your IDE
- Ensure Node.js version is 18+ (check with
node --version)
Problem: npm run dev fails
Solutions:
- Check Node.js version:
node --version(should be 18+) - Delete
node_modulesand.nextfolders, then runnpm install - Check for port conflicts (3000 already in use)
- Review error message for specific issues
Problem: Camera access denied or scanner doesn't work
Solutions:
- Ensure you're using HTTPS or localhost (required for camera access)
- Grant camera permissions in browser settings
- Test on a physical device (some features don't work in emulators)
- Check browser console for specific errors
- Specification Document - Complete feature specifications and user flows
- Brandbook - Design system, colors, typography, and visual guidelines
- Database Schema - Complete database structure and relationships
- Next.js Documentation - Framework reference
- Supabase Documentation - Backend and database guide
- Tailwind CSS Documentation - Styling reference
- Shadcn UI Documentation - Component library
- React Hook Form - Form handling
- Zod - Schema validation
- Check the Troubleshooting section above
- Review the Specification Document for feature details
- Check Supabase dashboard for database issues
- Review browser console for client-side errors
- Check terminal output for server-side errors
Happy coding! 🎉