A modern, multilingual online school website built with React + Vite, Supabase (auth + database), and ready to deploy on Vercel.
eduonline/
├── public/
├── src/
│ ├── components/
│ │ ├── auth/
│ │ │ └── ProtectedRoute.jsx # Route guard for authenticated pages
│ │ └── layout/
│ │ ├── Layout.jsx # App shell (Navbar + Outlet + Footer)
│ │ ├── Navbar.jsx / .css # Sticky top nav with language switcher
│ │ └── Footer.jsx / .css # Site footer
│ ├── context/
│ │ └── AuthContext.jsx # Supabase auth state & helpers
│ ├── i18n/
│ │ └── index.js # i18next config (EN / FR / AR)
│ ├── lib/
│ │ └── supabase.js # Supabase client initialisation
│ ├── pages/
│ │ ├── Home.jsx / .css # Hero, stats, intro, subjects preview, CTA
│ │ ├── About.jsx / .css # Mission, values, pillars
│ │ ├── Subjects.jsx / .css # Full subject grid
│ │ ├── Videos.jsx / .css # Featured + video grid with embeds
│ │ ├── Contact.jsx / .css # Contact info + form (saves to Supabase)
│ │ ├── Login.jsx # Supabase sign-in
│ │ ├── Register.jsx # Supabase sign-up with email verification
│ │ ├── Auth.css # Shared auth page styles
│ │ └── Dashboard.jsx / .css # Protected user dashboard
│ ├── App.jsx # Router + all routes
│ ├── main.jsx # React entry point
│ └── index.css # Global design system (CSS vars, utilities)
├── supabase_schema.sql # Full DB schema with RLS policies
├── vercel.json # SPA rewrite rules for Vercel
├── vite.config.js
├── package.json
└── .env.example
npm install- Create a project at supabase.com
- Go to SQL Editor → paste and run
supabase_schema.sql - In Authentication → Settings, enable email confirmations if desired
cp .env.example .envEdit .env:
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-keyFind both values in Supabase → Project Settings → API.
npm run devThe app auto-detects language from the browser locale:
- English → default
- French → auto-selected for
fr-*locales - Arabic → auto-selected for
ar-*locales + RTL layout applied
The manual language switcher in the Navbar persists via localStorage.
To add a new language:
- Add a new translation object in
src/i18n/index.js - Add it to the
LANGSarray insrc/components/layout/Navbar.jsx
| Table | Purpose |
|---|---|
users |
Extended user info synced from Supabase Auth |
profiles |
Role, avatar, bio |
subjects |
Course catalogue |
videos |
Embedded video library |
contact_messages |
Contact form submissions |
announcements |
School announcements |
enrollments |
Student ↔ subject junction |
All tables have Row Level Security (RLS) enabled with appropriate policies.
- Push the project to GitHub
- Import the repo in vercel.com
- Add environment variables:
VITE_SUPABASE_URLVITE_SUPABASE_ANON_KEY
- Deploy —
vercel.jsonhandles SPA routing automatically
| Action | Implementation |
|---|---|
| Sign up | supabase.auth.signUp() + auto profile insert |
| Email verify | Supabase sends verification link |
| Sign in | supabase.auth.signInWithPassword() |
| Protected pages | <ProtectedRoute> redirects to /login |
| Sign out | supabase.auth.signOut() + redirect to / |
CSS custom properties defined in src/index.css:
| Variable | Value | Use |
|---|---|---|
--navy |
#0B1F3A |
Primary colour |
--gold |
#C9993A |
Accent / CTA |
--gold-pale |
#FDF3DC |
Backgrounds |
--font-display |
Playfair Display | Headings |
--font-body |
DM Sans | Body text |
- Payment integration (Stripe / local gateways)
- Student progress charts and analytics
- Parent portal / linked accounts
- Push notifications for class reminders
- PWA support for offline access
Run this in Supabase SQL Editor (replace the email):
UPDATE public.profiles
SET role = 'admin'
WHERE user_id = (
SELECT id FROM auth.users WHERE email = 'admin@yourdomain.com'
);Then visit /admin to access the admin panel.
MIT — free for personal and commercial use.