fix: add 9
This commit is contained in:
179
Les07-Nextjs/Les07-Docenttekst.md
Normal file
179
Les07-Nextjs/Les07-Docenttekst.md
Normal file
@@ -0,0 +1,179 @@
|
||||
# Les 7 — Docenttekst
|
||||
## Van In-Memory naar Supabase
|
||||
|
||||
---
|
||||
|
||||
## Lesoverzicht
|
||||
|
||||
| Gegeven | Details |
|
||||
|---------|---------|
|
||||
| **Les** | 7 van 18 |
|
||||
| **Onderwerp** | Supabase: database koppelen aan Next.js |
|
||||
| **Duur** | 3 uur (09:00 – 12:00) |
|
||||
| **Voorbereiding** | Werkend QuickPoll project uit Les 6, Supabase account |
|
||||
| **Benodigdheden** | Laptop, Cursor/VS Code, browser, GitHub account |
|
||||
|
||||
---
|
||||
|
||||
## Leerdoelen
|
||||
|
||||
Na deze les kunnen studenten:
|
||||
1. Uitleggen wat Supabase is en waarvoor je het gebruikt
|
||||
2. Via de Supabase GUI tabellen aanmaken met relaties (foreign keys)
|
||||
3. RLS policies instellen voor publieke toegang
|
||||
4. De Supabase JavaScript client gebruiken in een Next.js project
|
||||
5. Data ophalen en muteren via de Supabase client (select, update, insert)
|
||||
6. Environment variables gebruiken voor API keys
|
||||
|
||||
---
|
||||
|
||||
## Tijdsplanning
|
||||
|
||||
### 09:00 – 09:10 | Welkom & Terugblik (10 min)
|
||||
|
||||
- Vraag: "Wie heeft het huiswerk gemaakt? Waar liep je tegenaan?"
|
||||
- Kort terugblikken: wat hebben we gebouwd in Les 6?
|
||||
- Aankondigen: "Vandaag maken we de app echt werkend én koppelen we een database"
|
||||
|
||||
### 09:10 – 09:30 | DEEL 1: Poll afmaken (20 min)
|
||||
|
||||
**Stap 1.1** — `votePoll()` in data.ts (5 min)
|
||||
- Leg uit: we missen een functie om stemmen te verwerken
|
||||
- Typ de functie, leg de logica uit
|
||||
|
||||
**Stap 1.2** — POST route fixen (5 min)
|
||||
- Laat zien dat de huidige route alleen logt
|
||||
- Vervang met werkende versie: body uitlezen, votePoll aanroepen, response sturen
|
||||
|
||||
**Stap 1.3** — Server Component + VoteForm split (10 min)
|
||||
- DIT IS HET KERNMOMENT: leg het patroon uit
|
||||
- Maak `components/VoteForm.tsx` — Client Component met useState + fetch
|
||||
- Herschrijf `app/poll/[id]/page.tsx` als Server Component (geen 'use client'!)
|
||||
- Server Component haalt data → geeft als prop door → Client Component doet interactie
|
||||
- Dit patroon verandert NIET meer als we Supabase koppelen
|
||||
|
||||
**Stap 1.4** — GET route + visuele feedback (5 min)
|
||||
- Voeg GET route toe (nodig voor VoteForm na het stemmen)
|
||||
- Update PollItem met percentage bars
|
||||
|
||||
**✅ Check:** Demo op localhost — stem, zie de bar groeien
|
||||
|
||||
> **Tip:** Als studenten vastlopen, laat ze de browser console openen. Fouten in fetch calls verschijnen daar.
|
||||
|
||||
### 09:30 – 10:15 | DEEL 2: Supabase Introductie — No Code (45 min)
|
||||
|
||||
Dit is voor veel studenten hun EERSTE database-ervaring. Neem de tijd!
|
||||
|
||||
**Stap 2.1** — Wat is Supabase? (5 min)
|
||||
- Open-source Firebase alternatief
|
||||
- PostgreSQL = echte database, 30+ jaar oud
|
||||
- Gratis tier voor leren
|
||||
|
||||
**Stap 2.2** — Project aanmaken (5 min)
|
||||
- Iedereen logt in op supabase.com (GitHub)
|
||||
- Maak samen een project aan
|
||||
- Wacht tot het klaar is (~30 sec)
|
||||
|
||||
> **Tip:** Zorg dat iedereen een GitHub account heeft! Dit is een veelvoorkomend blokpunt.
|
||||
|
||||
**Stap 2.3** — polls tabel (10 min)
|
||||
- Table Editor → New Table
|
||||
- Leg uit: id (uuid), created_at (timestamp), question (text)
|
||||
- Leg uit: NOT NULL — het veld mag niet leeg zijn
|
||||
|
||||
**Stap 2.4** — options tabel + foreign key (10 min)
|
||||
- Vier kolommen: poll_id, text, votes
|
||||
- Foreign key: leg uit wat dat is en waarom
|
||||
- CASCADE: als poll weg is, opties ook
|
||||
|
||||
**Stap 2.5** — RLS policies (5 min)
|
||||
- Leg uit: standaard mag niemand iets → we geven toestemming
|
||||
- Maak SELECT policy op polls, SELECT + UPDATE op options
|
||||
|
||||
**Stap 2.6** — Testdata invoeren (5 min)
|
||||
- Voeg 2 polls + 8 opties toe via de GUI
|
||||
|
||||
**Stap 2.7** — SQL Editor (5 min)
|
||||
- Laat SELECT, WHERE en JOIN zien
|
||||
- Dit is een mooi "aha-moment" — de data die ze net hebben ingevoerd komt terug
|
||||
|
||||
> **Tip:** Laat studenten ook zelf een query proberen. Bijv: "Hoeveel opties heeft poll X?"
|
||||
|
||||
### 10:15 – 10:30 | PAUZE (15 min)
|
||||
|
||||
### 10:30 – 11:30 | DEEL 3: Supabase koppelen aan Next.js (60 min)
|
||||
|
||||
**Stap 3.1** — npm install (2 min)
|
||||
- `npm install @supabase/supabase-js`
|
||||
|
||||
**Stap 3.2** — .env.local (5 min)
|
||||
- Kopieer URL + anon key uit Supabase dashboard
|
||||
- Leg uit: NEXT_PUBLIC_ prefix, .gitignore
|
||||
- ⚠️ Check: staat .env.local in .gitignore?
|
||||
|
||||
**Stap 3.3** — supabase.ts client (3 min)
|
||||
- Drie regels code, simpel
|
||||
|
||||
**Stap 3.4** — Types updaten (5 min)
|
||||
- Poll + Option interfaces
|
||||
- Leg uit: waarom twee types? Matcht de twee tabellen
|
||||
|
||||
**Stap 3.5** — data.ts herschrijven (15 min)
|
||||
- Dit is het kernstuk. Neem de tijd.
|
||||
- `getPolls()`: select met options(*)
|
||||
- `getPollById()`: select met eq + single
|
||||
- `votePoll()`: twee stappen (fetch → update)
|
||||
- Leg de Supabase syntax stap voor stap uit
|
||||
|
||||
> **Tip:** Als studenten TypeScript errors krijgen, check of ze de types correct hebben geüpdatet.
|
||||
|
||||
**Stap 3.6** — Homepage async maken (5 min)
|
||||
- `async function Home()` + `await getPolls()`
|
||||
- Leg uit: Server Component mag async zijn
|
||||
|
||||
**Stap 3.7** — PollItem aanpassen (5 min)
|
||||
- option.text, option.votes, option.id
|
||||
|
||||
**Stap 3.8** — VoteForm + detail pagina + API routes (10 min)
|
||||
- VoteForm: optionId (uuid) i.p.v. optionIndex (number)
|
||||
- Page.tsx: alleen `await` toevoegen — structuur verandert niet!
|
||||
- Benadruk: "Dát is de kracht van het Server Component + Client Component patroon"
|
||||
|
||||
**Stap 3.9** — Testen! (10 min)
|
||||
- Samen testen op localhost
|
||||
- Stem, refresh, check Supabase Table Editor
|
||||
- Het "aha-moment": data overleeft een server restart!
|
||||
|
||||
> **Tip:** Open het Supabase dashboard naast de app. Stem in de app, refresh de Table Editor — studenten zien het live veranderen.
|
||||
|
||||
### 11:30 – 11:45 | Vragen & Reflectie (15 min)
|
||||
|
||||
Mogelijke vragen:
|
||||
- "Kan iedereen nu stemmen?" → Ja, via de anon key + RLS policies
|
||||
- "Is dit veilig?" → Voor een leerproject ja. In productie: auth + strakkere RLS
|
||||
- "Hoe voorkom je dubbel stemmen?" → Met authenticatie (volgende les!)
|
||||
- "Wat als de database offline is?" → Error handling in onze functies
|
||||
|
||||
### 11:45 – 12:00 | Huiswerk & Afsluiting (15 min)
|
||||
|
||||
**Opdracht:**
|
||||
1. Maak een /create pagina (formulier → INSERT in Supabase)
|
||||
2. Voeg navbar link toe
|
||||
3. Extra: SQL queries schrijven
|
||||
|
||||
**Vooruitblik:** "Volgende les: Supabase Auth — inloggen, registreren, en bijhouden wie er stemt."
|
||||
|
||||
---
|
||||
|
||||
## Veelvoorkomende problemen
|
||||
|
||||
| Probleem | Oplossing |
|
||||
|----------|-----------|
|
||||
| "supabase.com laadt niet" | Probeer een andere browser of incognito |
|
||||
| "Kan geen project aanmaken" | Check of ze een org hebben, anders aanmaken |
|
||||
| Foreign key lukt niet | Check of de polls tabel al bestaat en data heeft |
|
||||
| RLS blokkeert alles | Check of de policies correct zijn (anon, SELECT, true) |
|
||||
| .env.local werkt niet | Server herstarten na aanmaken .env.local! |
|
||||
| TypeScript errors na type change | Check imports, rebuild, herstart TS server |
|
||||
| "Data verschijnt niet" | Check browser console voor Supabase errors |
|
||||
| Votes updaten niet | Check of UPDATE RLS policy op options staat |
|
||||
Reference in New Issue
Block a user