Files
novi-lessons/Les08-Docenttekst.md
2026-03-31 20:59:53 +02:00

208 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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:
1. De Supabase JavaScript client installeren en configureren
2. Environment variables gebruiken voor API keys
3. Data ophalen via Supabase queries (select met relaties, eq, single)
4. Het verschil uitleggen tussen Server Components en Client Components
5. 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:0009: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:1509: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:**
1. `.from("polls").select("*, options(*)")` → Haal alles op met relaties
2. `.eq("id", 5).single()` → Filter op 1 record
3. `.insert({ question })` → Nieuw record toevoegen
4. `.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:4510: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:1510:30 | PAUZE (15 min)
📌 Slide 7
---
### 10:3010: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:**
```typescript
// 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:4511: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:3011: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:4512:00 | Huiswerk & Afsluiting (15 min)
📌 Slide 9, 10
**Huiswerk:**
1. /create pagina afmaken (als niet klaar)
2. Validatie: vraag niet leeg, min 2 opties, foutmeldingen
3. Extra: delete functionaliteit, styling
**Slide 10: Afsluiting**
"Volgende les: Supabase Auth. Inloggen, registreren, en bepalen wie wat mag. Tot dan!"
---
## Tips voor docenten
1. **Niet te veel voordoen.** De PDF is self-contained. Studenten leren meer door zelf te doen.
2. **Loop ronde, spot problemen vroeg.** De eerste 10 minuten na "ga aan de slag" zijn cruciaal.
3. **Check-ins doen.** Vraag om handopsteken. Als <50% het heeft: kort voordoen.
4. **Toon Supabase dashboard.** "Zie je? De data staat echt in de database!"
5. **Authenticatie is volgende les.** Zeg het af en toe, zodat ze weten dat RLS nog tijdelijk is.