6.8 KiB
Les 8 — Docenttekst
Van In-Memory naar Supabase
Lesoverzicht
| Gegeven | Details |
|---|---|
| Les | 8 van 18 |
| Onderwerp | Supabase koppelen aan Next.js |
| Duur | 3 uur (09:00 – 12:00) |
| Voorbereiding | Werkend QuickPoll project, Supabase project met polls/options tabellen |
| Benodigdheden | Laptop, Cursor/VS Code, browser, Supabase account |
| Lesmateriaal | Lesopdracht PDF (studenten werken hier zelfstandig doorheen) |
Leerdoelen
Na deze les kunnen studenten:
- De Supabase JavaScript client installeren en configureren
- Environment variables gebruiken voor API keys
- Data ophalen via Supabase queries (select met relaties, eq, single)
- Het verschil uitleggen tussen Server Components en Client Components
- Een formulier bouwen dat data INSERT in Supabase
Aanpak
Studenten krijgen een Lesopdracht PDF met alle component-code (volledige UI). Ze hoeven alleen de Supabase queries zelf te schrijven (gemarkeerd als TODO-blokken). De docent legt concepten uit met slides, doet een korte demo, en loopt daarna rond.
Lesplanning
09:00–09:15 | Welkom & Uitleg aanpak (15 min)
📌 Slide 1, 2, 3
Wat te zeggen:
- "Vorige week: werkende polling app met in-memory data."
- "Vandaag koppelen we Supabase: onze database-as-a-service."
- "Jullie werken vandaag zelfstandig met een PDF. Alle UI-code staat erin. Jullie schrijven de Supabase queries."
- "Ik leg eerst de concepten uit, dan gaan jullie aan de slag."
Check:
- Iedereen heeft Supabase account met polls en options tabellen
- Iedereen heeft QuickPoll project lokaal draaiend
- Deel de Lesopdracht PDF uit (digitaal)
09:15–09:45 | Uitleg concepten (30 min)
📌 Slide 4, 5, 6
09:15 | Slide 4: Van Array naar Database
Zeg: "Tot nu toe stond jullie data in een array. Dat werkt, maar is weg zodra je de server herstart. Supabase geeft ons een echte PostgreSQL database."
Toon het verschil:
// OUD: in-memory
const polls = [{ question: "...", votes: [0, 0] }]
// NIEUW: Supabase
supabase.from("polls").select("*, options(*)")
09:25 | Slide 5: Supabase queries
Toon de vier belangrijkste operaties:
.from("polls").select("*, options(*)")→ Haal alles op met relaties.eq("id", 5).single()→ Filter op 1 record.insert({ question })→ Nieuw record toevoegen.rpc("vote_option", { option_id })→ Database functie aanroepen
Demo: Open Supabase dashboard, toon Table Editor met polls en options tabel. Laat de relatie zien (foreign key).
09:35 | Slide 6: Server vs Client
Zeg:
"Belangrijk patroon: Server Components zijn async — die halen data op. Client Components hebben 'use client' — die zijn interactief (forms, klikken). In de PDF zien jullie dit terug."
09:45–10:15 | Deel 1: Setup + Queries (30 min, zelfstandig)
📌 Slide 5 (blijft staan als referentie)
Zeg: "Open de Lesopdracht PDF. Werk Deel 1, 2 en 3 door. Dat is de setup, queries schrijven, en componenten kopiëren. Na de pauze doen we Deel 4: de /create pagina."
Studenten doen nu:
- Deel 1 (PDF): npm install, .env, supabase client, types
- Deel 2 (PDF): lib/data.ts — TODO blokken invullen (getPolls, getPollById, votePoll)
- Deel 3 (PDF): Componenten kopiëren (page.tsx, PollItem, VoteForm, poll/[id])
Jij loopt rond. Veelvoorkomende issues:
| Probleem | Oplossing |
|---|---|
| npm install failed | Check internet, node_modules verwijderen en opnieuw |
| Env vars undefined | NEXT_PUBLIC_ prefix? Dev server herstart? |
| getPolls() returns [] | Query syntax checken. Staat er data in Supabase? |
| TypeScript errors | Import vergeten? Types kloppen met database? |
| "RLS policy violation" | RLS uitschakelen of SELECT policy toevoegen |
Check-in (10:00): "Wie heeft de homepage al werkend met Supabase data? Steek je hand op." → Als minder dan de helft: kort voordoen op beamer. → Als meer dan de helft: doorgaan, help de rest individueel.
10:15–10:30 | PAUZE (15 min)
📌 Slide 7
10:30–10:45 | Uitleg INSERT + /create (15 min)
📌 Slide 8
Zeg: "Nu gaan jullie een /create pagina bouwen. Het formulier staat al in de PDF — jullie schrijven alleen de INSERT logica."
Toon op beamer:
// 1. Insert poll
const { data: poll } = await supabase
.from("polls")
.insert({ question: "Mijn vraag" })
.select()
.single();
// 2. Insert options met poll.id
await supabase.from("options").insert([
{ poll_id: poll.id, text: "Optie A", votes: 0 },
{ poll_id: poll.id, text: "Optie B", votes: 0 },
]);
Zeg:
- "Eerst insert je de poll → je krijgt het id terug"
- "Dan insert je de options met dat poll_id"
- "En dan redirect je naar de homepage"
RLS policy: "Voordat het werkt: voeg INSERT policies toe. Staat in Deel 4, Stap 4.1 van de PDF."
10:45–11:30 | Deel 2: /create pagina (45 min, zelfstandig)
Studenten doen nu:
- Deel 4 (PDF): RLS policy toevoegen, handleSubmit implementeren
- Testen: poll aanmaken → verschijnt op homepage
Jij loopt rond. Veelvoorkomende issues:
| Probleem | Oplossing |
|---|---|
| "RLS policy violation" bij INSERT | SQL policy uitgevoerd in dashboard? |
| poll is undefined na insert | .select().single() vergeten? |
| Opties worden niet opgeslagen | poll.id doorgeven aan options insert? |
| Form refresht de pagina | e.preventDefault() in handleSubmit? |
| Redirect werkt niet | useRouter van "next/navigation"? |
Check-in (11:15): "Wie heeft succesvol een poll aangemaakt? Open Supabase dashboard en toon dat ie erin staat." → Toon op beamer als demo.
11:30–11:45 | Vragen & Reflectie (15 min)
Mogelijke vragen:
V: Waarom async/await? A: Supabase is over het netwerk. We moeten wachten op antwoord.
V: Wat is het verschil tussen Server en Client Component? A: Server = async, data fetching, geen interactiviteit. Client = 'use client', useState, onClick.
V: Kan ik realtime updates zien? A: Later! Supabase heeft realtime subscriptions.
11:45–12:00 | Huiswerk & Afsluiting (15 min)
📌 Slide 9, 10
Huiswerk:
- /create pagina afmaken (als niet klaar)
- Validatie: vraag niet leeg, min 2 opties, foutmeldingen
- Extra: delete functionaliteit, styling
Slide 10: Afsluiting "Volgende les: Supabase Auth. Inloggen, registreren, en bepalen wie wat mag. Tot dan!"
Tips voor docenten
- Niet te veel voordoen. De PDF is self-contained. Studenten leren meer door zelf te doen.
- Loop ronde, spot problemen vroeg. De eerste 10 minuten na "ga aan de slag" zijn cruciaal.
- Check-ins doen. Vraag om handopsteken. Als <50% het heeft: kort voordoen.
- Toon Supabase dashboard. "Zie je? De data staat echt in de database!"
- Authenticatie is volgende les. Zeg het af en toe, zodat ze weten dat RLS nog tijdelijk is.