# Les 8 — Slide-overzicht ## Van In-Memory naar Supabase (10 slides) --- ### Slide 1: Titelslide **Titel:** Les 8 — Van In-Memory naar Supabase **Ondertitel:** Koppelen van Supabase aan Next.js **Visual:** Supabase + Next.js logo's, BLUE achtergrond --- ### Slide 2: Terugblik vorige les **Titel:** Terugblik — Waar waren we? **Bullets:** - Stemmen werkt lokaal (in-memory data) - QuickPoll app heeft 2 pages: / en /poll/[id] - VoteForm component ziet stemmen onmiddellijk - Nu: alles naar een echte database **Code snippet:** ```javascript // OUD const polls = [ { question: "...", options: [...], votes: [...] } ]; ``` --- ### Slide 3: Planning vandaag **Titel:** Planning — Les 8 (3 uur) **Timeline:** - 09:00-09:15 | Welkom & Uitleg aanpak (15 min) - 09:15-09:45 | **Uitleg concepten** (30 min) - 09:45-10:15 | **Zelfstandig: Setup + Queries** (30 min) - 10:15-10:30 | Pauze (15 min) - 10:30-10:45 | **Uitleg INSERT queries** (15 min) - 10:45-11:30 | **Zelfstandig: /create pagina** (45 min) - 11:30-11:45 | Vragen & Reflectie (15 min) - 11:45-12:00 | Huiswerk & Afsluiting (15 min) **Extra tekst:** "Jullie werken met de Lesopdracht PDF. Alle UI staat erin — jullie schrijven de queries!" --- ### Slide 4: Van Array naar Database **Titel:** Van In-Memory Array naar Supabase **Links:** In-memory (OUD) ```javascript const polls = [ { question: "Favoriete taal?", options: ["JS", "Python"], votes: [10, 5] } ]; ``` **Rechts:** Supabase Database (NIEUW) ``` polls tabel ├─ id (1) ├─ question ("Favoriete taal?") └─ options[] (relatie) options tabel ├─ id (1) ├─ poll_id (1) ├─ text ("JS") ├─ votes (10) ``` --- ### Slide 5: Supabase Queries **Titel:** Supabase Queries — Vier operaties **Vier blokken:** 1. **SELECT alles** (met relaties) ```typescript supabase.from("polls") .select("*, options(*)") ``` 2. **SELECT één** (filter + single) ```typescript supabase.from("polls") .select("*, options(*)") .eq("id", 5).single() ``` 3. **INSERT** (nieuw record) ```typescript supabase.from("polls") .insert({ question: "..." }) .select().single() ``` 4. **RPC** (database functie) ```typescript supabase.rpc("vote_option", { option_id: 42 }) ``` --- ### Slide 6: Server vs Client: Wie doet wat? **Titel:** Server vs Client: Wie doet wat? **Twee kolommen:** **SERVER Component:** - `export default async function HomePage() { ... }` - `const polls = await getPolls()` ✓ - Data fetching - Direct naar database - TypeScript compile-time **CLIENT Component:** - `'use client'` - `const [voted, setVoted] = useState(...)` - Interactief: klikken, typen, formulieren - useEffect, event handlers - Browser runtime **Zeg:** "Server haalt data, Client maakt het interactief." --- ### Slide 7: Pauze **Titel:** Pauze **Tekst:** Setup + queries klaar? Na de pauze: /create pagina bouwen! --- ### Slide 8: Zelf Doen — /create pagina **Titel:** Zelf Doen — /create pagina **Ondertitel:** Het formulier staat in de PDF. Jij schrijft de INSERT logica! **INSERT voorbeeld:** ```typescript // 1. Insert poll → krijg id terug const { data: poll } = await supabase .from("polls") .insert({ question }) .select().single(); // 2. Insert options met poll.id await supabase.from("options").insert([ { poll_id: poll.id, text: "...", votes: 0 } ]); ``` **Stappen:** 1. RLS INSERT policy toevoegen (Stap 4.1 in PDF) 2. handleSubmit invullen (TODO blok in PDF) 3. Testen: poll aanmaken → homepage checken --- ### Slide 9: Huiswerk **Titel:** Huiswerk **Verplicht:** - /create pagina afmaken (als niet klaar) - Validatie toevoegen (vraag niet leeg, min 2 opties) **Extra:** - Delete functionaliteit - Styling verbeteren --- ### Slide 10: Afsluiting **Titel:** Tot volgende week! **Tekst:** - "Volgende les: Supabase Auth" - "Inloggen, registreren" - "Bepalen wie wat mag doen"