A Next.js web application for collecting and managing membership sign-ups for the Rock'em Robotics Booster Club. The application features a multi-step form that accommodates different member types (district employees, parents, and supporting members) and automatically sends confirmation emails to both administrators and members.
- Dynamic Form Logic: Adapts form fields based on member type selection
- Multi-Entity Support: Collect information for multiple students and parent/guardian contacts
- Real-time Validation: Client-side form validation with helpful error messages
- Email Notifications: Automated emails via SendGrid to both admins and new members
- Database Integration: Supabase backend for secure data storage
- Responsive Design: Mobile-friendly UI built with Tailwind CSS and shadcn/ui components
- Theme Support: Dark/light mode via next-themes
- Framework: Next.js 14 (App Router)
- Language: TypeScript
- Styling: Tailwind CSS
- UI Components: shadcn/ui (Radix UI primitives)
- Database: Supabase
- Email Service: SendGrid
- Form Handling: React Hook Form with Zod
- Package Manager: pnpm
- Node.js 18+ and pnpm
- A Supabase project
- A SendGrid account with API key
git clone https://github.com/rockem-robotics/membership-form.git
cd membership-formpnpm install- Create a new Supabase project at supabase.com
- Run the SQL script in
scripts/001_create_tables.sqlin your Supabase SQL editor - Note your project URL and anon key
- Create a SendGrid account at sendgrid.com
- Generate an API key with mail send permissions
- Verify a sender email address
Create a .env.local file in the root directory:
# Supabase
NEXT_PUBLIC_SUPABASE_URL=your-supabase-url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-supabase-anon-key
# SendGrid
SENDGRID_API_KEY=your-sendgrid-api-key
SENDGRID_FROM_EMAIL=verified-sender@example.com
SENDGRID_TO_EMAILS=admin1@example.com,admin2@example.comPlace your team logo at public/team-logo.png (recommended size: 200x200px)
pnpm devOpen http://localhost:3000 to view the application.
membership-form/
├── app/
│ ├── actions.tsx # Server actions for form submission
│ ├── layout.tsx # Root layout with theme provider
│ ├── page.tsx # Home page with form
│ ├── globals.css # Global styles
│ └── thank-you/
│ └── page.tsx # Thank you page after submission
├── components/
│ ├── contact-form.tsx # Main membership form component
│ ├── theme-provider.tsx # Theme context provider
│ └── ui/ # shadcn/ui components
├── lib/
│ ├── utils.ts # Utility functions
│ └── supabase/
│ └── server.ts # Supabase server client
├── scripts/
│ └── 001_create_tables.sql # Database schema
├── public/
│ └── team-logo.png # Team logo image
└── package.json
The form supports four member types:
- School District Employee: District employees who may or may not have children in the program
- Parent/Guardian of Kids in the District: Parents with children in the school district
- Parent/Guardian of Kids in the Program: Parents with children actively participating in robotics
- Supporting Member: Extended family, friends, or community supporters
id(uuid, primary key)member_type(text)first_name(text)last_name(text)email(text)phone(text)involvement(text, optional)created_at(timestamp)
id(uuid, primary key)member_id(uuid, foreign key → members)first_name(text)last_name(text)grade_level(text)team_number(text, optional)team_name(text, optional)dietary_restrictions(text, optional)created_at(timestamp)
The application sends two types of emails:
- Admin Notification: Detailed submission information sent to configured admin emails
- Member Confirmation: Welcome email with registration summary sent to the new member
Both emails feature branded HTML templates with the team logo and colors.
pnpm dev- Start development serverpnpm build- Build for productionpnpm start- Start production serverpnpm lint- Run ESLint
- Push your code to GitHub
- Import the repository in Vercel
- Configure environment variables in Vercel dashboard
- Deploy
Make sure to set all environment variables in your deployment platform:
NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEYSENDGRID_API_KEYSENDGRID_FROM_EMAILSENDGRID_TO_EMAILS
- Team Name: Edit
app/page.tsxandcomponents/contact-form.tsx - Contact Email: Update in
app/page.tsxfooter section - Team Logo: Replace
public/team-logo.png - Colors: Modify theme colors in
app/globals.css
Update the team number dropdown in components/contact-form.tsx around line 430:
<SelectContent>
<SelectItem value="44632A">44632A</SelectItem>
{/* Add or remove team options here */}
</SelectContent>- Row Level Security (RLS) enabled on Supabase tables
- Public insert policies allow form submissions
- Environment variables protect sensitive API keys
- Email validation prevents malformed submissions
- Phone number formatting for consistent data
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is created for the Rock'em Robotics Booster Club.
For questions or issues:
- Email: contact@rockemrobotics.com
- Open an issue on GitHub