Project 2 · Done Checklist
Every box ticked = ready for Project 3.
When every box is checked, your static school site is real and you're ready for the big one — the actual school SaaS.
Infrastructure
- Next.js project on your machine, running at
localhost:3000 - Code in a GitHub repo (your personal account)
- Vercel project connected to GitHub — push triggers deploy
- Live URL at
your-school.vercel.app(custom domain optional) - Supabase project provisioned in ap-south-1
- Resend account, API key in VaultMate
Design and Setup
tailwind.config.tsextended with your school's colour tokens (indigo,amber,dark-base, etc.)- Two fonts loaded via
next/font/google(one sans, one display) src/lib/constants.tswithSCHOOL,BRANCHES,CONTACT,ADMISSION_STEPS,ELIGIBILITY- Branch photos in
public/branches/ - One hero photo in
public/hero.jpg
Pages
- Home page (
/) — hero, about strip, featured branches, admissions CTA - Branches page (
/branches) — one card per branch fromBRANCHESconstant - Admissions page (
/admissions) — steps, eligibility table, contact form - About page (
/about) — school story + philosophy - Every page has metadata (title + description)
Components
<Nav>— site-wide navigation with sticky top + Apply button<Footer>— branches list, contact, copyright<BranchCard>— used on home + branches<InquiryForm>— working contact form with validation + Resend
Edge Function
supabase/functions/contact-inquiry/index.tsdeployed to SupabaseRESEND_API_KEY,ADMISSIONS_EMAIL,FROM_EMAILset as Supabase secrets- CORS headers configured — POSTs from your Vercel URL succeed
- Server-side validation present (not just client-side)
- Test inquiry sent on production — email actually arrived in admissions inbox
Quality
- Mobile view checked on DevTools emulator AND a real phone if you have one
- All
<Link>navigation works (no broken links) - No
anytypes in any file - No console errors in the browser when you load each page
pnpm tsc --noEmitpasses with zero errorspnpm lintpasses- Contact form shows clear inline errors for bad input
- Contact form shows a friendly success state
Security
.env.localis in.gitignore(verify withgit status— it must not show up)- Anon Supabase key is the ONLY Supabase key in client code
- Service role key is NOT in
.env.local(it's not needed in Project 2) - All Resend, Supabase credentials saved in VaultMate
Reflection
- Show the live site to the same person who saw Project 1. Note what's different from their reaction last time.
- Compare a Lovable-generated file (Project 1) to one you wrote here (Project 2). Notice the differences.
- List 3 things you understand now that you didn't after Project 1.
- List 2 things in your code you'd refactor if you had another day.
Self-Check Questions
- What does
'use client'mean and when do you need it? - Why does the same
BranchCardcomponent work on two different pages? - Why is the form validation defined in two places (client and server)?
- What happens between you typing
git pushand your changes being live on Vercel? - Where does
RESEND_API_KEYactually live, and why is it not in your code?
If any answer is fuzzy, jump back to the relevant page before starting Project 3.
What's Next
You have a real school website built with real engineering. The next project — Project 3 · School SaaS — is where it becomes a real school system. Same school, same look, but now with:
- Student enrolment that actually stores data
- Attendance tracking
- Exams and marks
- Razorpay fee payments
- WhatsApp / email circulars to parents
- Multi-branch isolation (RLS)
- Multi-persona access (admin, teacher, parent, student)
That's the system parents and teachers use every day. It's the deepest, most rewarding project in the program.