From f65c24ffcd5b657b462bbe7febd8170a6a218ecc Mon Sep 17 00:00:00 2001 From: Tim Rijkse Date: Tue, 31 Mar 2026 20:59:53 +0200 Subject: [PATCH] fix: latest lesson --- Les08-Docenttekst.md | 207 +++++++++++++++++++++++ Les08-Lesopdracht.pdf | 346 +++++++++++++++++++++++++++++++++++++++ Les08-Slide-Overzicht.md | 186 +++++++++++++++++++++ Les08-Slides.pptx | Bin 0 -> 146188 bytes 4 files changed, 739 insertions(+) create mode 100644 Les08-Docenttekst.md create mode 100644 Les08-Lesopdracht.pdf create mode 100644 Les08-Slide-Overzicht.md create mode 100644 Les08-Slides.pptx diff --git a/Les08-Docenttekst.md b/Les08-Docenttekst.md new file mode 100644 index 0000000..ead0f6f --- /dev/null +++ b/Les08-Docenttekst.md @@ -0,0 +1,207 @@ +# 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: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:** +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: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:** +```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: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:** +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. diff --git a/Les08-Lesopdracht.pdf b/Les08-Lesopdracht.pdf new file mode 100644 index 0000000..04d3e89 --- /dev/null +++ b/Les08-Lesopdracht.pdf @@ -0,0 +1,346 @@ +%PDF-1.4 +%“Œ‹ž ReportLab Generated PDF document (opensource) +1 0 obj +<< +/F1 2 0 R /F2 3 0 R /F3 5 0 R /F4 6 0 R /F5 8 0 R /F6 19 0 R +>> +endobj +2 0 obj +<< +/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font +>> +endobj +3 0 obj +<< +/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font +>> +endobj +4 0 obj +<< +/Contents 25 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 24 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +5 0 obj +<< +/BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font +>> +endobj +6 0 obj +<< +/BaseFont /Helvetica-Oblique /Encoding /WinAnsiEncoding /Name /F4 /Subtype /Type1 /Type /Font +>> +endobj +7 0 obj +<< +/Contents 26 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 24 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +8 0 obj +<< +/BaseFont /Courier-Bold /Encoding /WinAnsiEncoding /Name /F5 /Subtype /Type1 /Type /Font +>> +endobj +9 0 obj +<< +/Contents 27 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 24 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +10 0 obj +<< +/Contents 28 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 24 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +11 0 obj +<< +/Contents 29 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 24 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +12 0 obj +<< +/Contents 30 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 24 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +13 0 obj +<< +/Contents 31 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 24 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +14 0 obj +<< +/Contents 32 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 24 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +15 0 obj +<< +/Contents 33 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 24 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +16 0 obj +<< +/Contents 34 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 24 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +17 0 obj +<< +/Contents 35 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 24 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +18 0 obj +<< +/Contents 36 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 24 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +19 0 obj +<< +/BaseFont /ZapfDingbats /Name /F6 /Subtype /Type1 /Type /Font +>> +endobj +20 0 obj +<< +/Contents 37 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 24 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +21 0 obj +<< +/Contents 38 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 24 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +22 0 obj +<< +/PageMode /UseNone /Pages 24 0 R /Type /Catalog +>> +endobj +23 0 obj +<< +/Author (\(anonymous\)) /CreationDate (D:20260331170259+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260331170259+02'00') /Producer (ReportLab PDF Library - \(opensource\)) + /Subject (\(unspecified\)) /Title (\(anonymous\)) /Trapped /False +>> +endobj +24 0 obj +<< +/Count 14 /Kids [ 4 0 R 7 0 R 9 0 R 10 0 R 11 0 R 12 0 R 13 0 R 14 0 R 15 0 R 16 0 R + 17 0 R 18 0 R 20 0 R 21 0 R ] /Type /Pages +>> +endobj +25 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 952 +>> +stream +Gatm:9iKe#&A@sBCi?#<#YVI>WA?]aThlS0Rc;a'(LrB]`3C?'T``'D/(lXP#/c#QbAqd6]C5.9-59^4;Yq=b!5=2,GX?s:#k*:i`.RO\^4jk\Trk6=Lp*2_L%5KaJ\Z]Zj@';A&m;kcN6lBiR6hF!E%W7?@_#n=;Z:K6"[AU7YG`WCp@7/(!$R[/rMKaUA2Ij&8Z^.Jq-bYo0DUeVI1o%D?0U8%u7lBK;U(#J_C$7+=!D9^kB6Q3[l=bb1>$%\0OcCO%a*dD859?t\P27fU$M0/\p7/=3n$*:K#>+H;6?ONVJ.+=%1TcoE-.,G:C:Cr)c.K&pCt#*liE7)N5Ecu9=W6(q-<)A#CAh8D!#M=l#]qkI,E#6n7Ea+4FtU8NT\'6/Ak5*@*>R;l+#'=3W8.9SiK1g!t'4T^J>joi1H3C2W_gX\FPIjY%R/X\?^j>oaQ/T0mL!B^q5SWH$oeO)8fuuA2,P&2cpLg1LN?/*-Oe4[h>Qe1W24()Q)9uX!pp`IC;7$ZYq62SYA_qfXL-r045$/P%pBCkud++ISi:hbG]2rZOIF>Dj+1g*UcR'_ZFsukPUOhm[f^=U":[0$TS.eIO$@u~>endstream +endobj +26 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1267 +>> +stream +Gau0CD0+Dj&H9tYf^ojA*6.Og2OW?+d\FKLF%KP+HT/tS,E*7/Cs/(I8__@:^Qj`a&1G7tJf2aAYG>fTT1:CD0_$@`*[Um-4_VPU5V2,)!HAMQHDf-Se\9PSgsWM;0_gbTD9L*fjd36cfDS2Q:ScHe[i*_FuL?!#.k8B"i_E]l=6n+*=8n!\+q_4#HRgU:XO9n*ZT`h`lEPsksA@hn4cX+WT#:d9ghL9iR1L.Gl)1cG/HjA5,oHApCYPsRN)Er,2XP"V@"S![(S;/X2<9HZlW[)P$R<@Jll)<=K8R+SG>dL;_:_H&t]:-+:9:Jl9JAlM0?(paQHF+%s5csrpgr-[GgG0!M[K@1^c;eiDf^2C/sB#Hg-nbc$?;B7/[(!fAY"Qp-"QGB$S(!,dRh@#J#0pftp&es=@'J=X97-#Enk,e/eDfB]AI!Y?qd(R(O3^2hP#+$E-&'%R[H+Vb"nEFe"m^Q-"h?^ZPJI99V+cajncN`i"Ii[hR2!&H3L4*ot,:4m.ceai\;A>scV)5VR$L47XFJP(T:8ns8;5h^)CFQ80*tL@H,@)I'P[?Q-CXG%I!*20re6ZH;GbA&MeL5WIeOSL53=QQSREE(nn]oYWIEEf6V>W3sF_m?aD6$_fhP_,Pkt0_G!(d\l;4h\@SoV9hbT,Z'VW@$'hN$X"C5!b#IX?=-*GsR4fffU>Bf=,Jb%H0P>Bii\p=aL(*_"nG>-'7C_-Mdq$P<_)@K1;jPU_j/SSAJ]mUb_a5cH!L5`@H)='TgMj;;rr-QPnp[>b*ulcAr%FBlN6.`ESRcrVI@5)snsr/H0KAeA.-Rg1d.HiVL*n\dcXA5"_[7(]*cG?+6HNbPlhXq+endstream +endobj +27 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1525 +>> +stream +Gb!;d?$#!`'Re<2\BP]/CkO*adn\XhdrrL'RjLg98nZ2s(JnRW,0SZF8cF(?CdW^^$"UBd1h8:B=45VZ8&n\MYis',pNR*cgkGH?*4UOe!4]odke;gZ]6dV+]SZ7`o0O%0n6M[VcjQfp2)F1thf45#JRsT<=D40g:r>F7P:oVY*Rb](6oB[DIh/Xp`"YTE:*L]E)F[$W$/rdI3JmT0JT+V`P#r\hpB%p]-Dr59^iE@p%E.X1<$,SRUPmBbDX&<8=OP/"ua17X*Uf90&(qc+M:j3oCffE?0:2tUDemt>N1QF,`k=t_6,hThN[>kcYN^A":F)Zd6u(pqTqa/a3a^3Q(XcHTe(L%k^JJ3+fanF.R>hJsTW_S)2b"7%Q4R7]U@]&W4McopmY?u:cqj8V9?^e6;qqO2-F<"n9elN_K8&"hZ\7_J-cY`>!CTTmR[jS^f;kI-sWY\4([L!C./7:\<@/>#SdY2-1Blk$QrUZf+3#ISAT7o9U*Ym;#l!;U/XN9Ja"iCX7=\?__m(&hE'*u36UL-_6H>36\R@aK[)U-f\u/\:UBI5/urs&4FH&T40E`:4WmU*P-<$ToBl-9W-SJV"OJe.B28FQcmk-cCWSE,2R`r>!/[Etgt/H]Cl4+NLm'$t`@/DHNUZDHGT%"6[).!n&,ro%#7X(+tMQ7'b26,,R)*(8iJ3p]*cp7M,jJ!dZGPBr!'K%bP7c;V0MUdm[p6enh60Q)bD*<*&'/ZK`seiY:ZUA^F8`fV9kT(lQZj_AFHOhTd;ekLd1c+o4q-GI&A,G![d;:GBGU+IVT2U+&[+%1,Np0T`92HAus/a`<_7B#><53T#Tj&c4#78",aAYUEF"On:\)C@#M,nIl]12#AKLaV/k7js+."`Q[L+f4_VA^%7b0*#hMp1X=&C2b;""rl=/B%mdl:hE:$erL=pp;7;2QE&W#%mg7Qsin7[K4_HcMN5NjiS$URN)ORaL+"Fl[69tYje)Bq%`JU,&A0qNOO#>YP.Q<@cHo0,5irJMU038?Tg+`2U?"d5U+DJP/8ajMK\DYTmTtgendstream +endobj +28 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1260 +>> +stream +Gatm:D0+E#&H9tYf\oIk@L5d8+d(4;,Yab'4cW`&rDNLNO;:YDl'0Z=i*lEL\N=,o5V3oW_s-9+pN^q#?O1c7Qg"Gl!Ve@#p2:(i%AP?`a)YR0%A-+LD[j#.l.VHhgHL1;YAY$1oqe1+D:u)JGC!Y>]h[1g_=G5'"+8[]3m!MP;'J`e?u$G@ru-i'&S(#7i$1lMQ=;[&oY$DY';`*`(^$4&']+WYhqTXn0T&:]=#OsQQ5:F!D!i%'Dd9VI7Fg_C]tclD#9-/o7EL'h+?&0)ji1nA&EErcZg6VK*,P@Y=MhdJHG)C!L]go*Y/ZtdtQCp"JSP8dcYgMa%:gYN*a\=0k(C#95c6.[;7[d?9*/8Jm?L6foI0K/?\59N/nBA@eO^$GnNcSPbl6eYW.;H;R'_Z/tt%gToM]N;V%G'b7WtP1$:M:2VS7&=f\#Fd8l*6L#XF2cu_>iQnt/UK0n*cH1Xq^Kh9L?qb*G`?J`LmKZ.E\YmW\C4['?5"tL&43dWfpCM:I$a)PnM>$hn9)2;dTW@rI#QAfsG0&r&FDYWq&iLd'sWqY+q6s_X$3%%5"O)^s6ocB%Zcl)C>?HWNQ'?]nb^"@D7(U)_S*Tq5l-N4C!nXDj?Q@Yq3VVIi9f6(0a-.C-0d)s=;L3^2U7WMbq;cuT`IJT89/3i#mendstream +endobj +29 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 791 +>> +stream +Gb!#[gMWKG&:N^l7TM%mQ53Rr*(]BpMU_@=Wg!k`aUcCq(n-.)bMnGAs1O%<Ap9]1+DXZprHJc,8$GB*4;n)5T34u=SY%.0135k8m2>mU=RdTmo9?2cSPZ'.9imbU->j)Y-"5C]a$uWZ1/^B<[!eFKKM<>'o2W-R-p:M/)6!PZ%Rc$Z5*Xp[^'-E(Z_ms5HCSb8$`Z1X2FZ%XA0%["gH.9N$4":lZH*(RCICZl?8m]E&6a(V(VAZ6WK"!K4T#\'S&<+14W+c/2A'#$W.INb@($!9k3YJV!nNTmZi,-s",@Qq]C(_^F)jVpEqQ`WLOG\-peCi:$[m7Pqk`'f*u\g3Q!,SK0-L]<82)Mn3u%.;MZWW#1_A)e'!!FaYK)7?8\%Za$*0/B+%6E9+)B:9JQ@/P4i>Lk6+F`.17:j/s=\`M8bFq.tP)T;+oo9bnZ`1(Q_I\9Z^91=;9"]/fi8_e@0A4(gke#R1U6V&gq,/ZI><='Pl+F#qm1\T9#lT3D-$/F&:<2MPRCn`94dUSluN0jD7Xm0Mb"M?bmT&@A$Zia09m=P5Hse:7dc`[L"b[>dRnNPs&kIMtC9*Cu#>o/542#k#hW.XgIFUO4q#Wp-$sD^2#UkS:#aEH@\k"g0:KONj%jW?\raOBqShQS2fella_I.IGA.R)i])qTDH%,JbBJt6)]/~>endstream +endobj +30 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1301 +>> +stream +Gau0CgN):C&:N^l3dt5:#m,sQ?pcF*Fe!L&-Z2IKC('%s)#1hIAX!N])Cu!Lb+,EM(n[H,0LVMDbOlFd0m=nF;]NW3pHn!J"8_*H#tE3>hu`]bQ[NF'p0qe0X@BN$L[3j4=7eC%.seDJkZTPt>UeeTC6n_)XL<#oCX?sf+:rET-AM8hcu*qsSI1%<#,2Ei\oBnH+6!RB8b1h-6;0+,*99tAKS24E"=9@%fYCSlF1;h'*-q-i.pe%orniV4>5,^-h.;`iQ2`Y)?GLc\jXS2^7l1tD'#g4u#^IIUMBIjc?"cnf+^]ghD:Ho(5<\JfhX'RJf*$th@i"qs9)sR.>I(XoAEmROhZmOj:IB*b"URtR^g)prIY%jeQh:;6%(7dr[5%7t[&]fOkY[@_'.jQBHU5\D4]B@++-d12^nMQfW#MQ)*o&sKGWnG[Zj,bf^RXGq^D-$N9oA]cTjt=$fPrU&'W*1OekhTNNifZTDbQ*FIHTU2JPG.cn)UeMIU?BA\LU^f9"eKD3!HZ$sd/&)4WV?CNi=KB-Bi)+TXS0]&^X&h7KH4_+lkRQ0H$ba-*SK(b_`\D=6UIf=`a/H9cP%%Ng4c.e!]>'"Vg]BI[2ZTupa;03b:s4;A\idO-=i5o!$rN;kJ;'3C?l4jAg2j(H[hLX@_Q;68k-FJmB#5@t>Wr;:kBQUi;4or%=Od:]04f!M5roCW9ooMmE*<8\SC:2oKW0JRL#O_4HTRB6p=^@OTOu]$*(dL8P+$nif)$KTma6e-%^PoF5.>V%%qD3<(F)o2WhCrAVLYW8/2:UEa*o(f-EUJggm#_t;dBT,Fnm;!RXVjlV=6FDY9phru_ZBXB#YkWBm3o&$5>po[>?DIPW;Hm`ERh/~>endstream +endobj +31 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 675 +>> +stream +GatU0?#Q2d'Rf.GSG%e=_I,n_ABQH6>,FpB['"(<]K!_6XFM`Z9<*mL4p+NFUhSF0!cbES?g%:>LVcq"D83Cc(^D`B'\#T+#OR^=JfB(DZj2RSHb)+TIG:Y:3'O%Ml`3!V-D'[/NfQR'j/YWR=D>]tX\5jY6Wl%K*/<(XI;_A5'aB$CU?!.uBX]ItJjd'rD25-56.R6m;-4i`c&Xjj[1jPU6C&!%\:BS\JmVaPKS#I?X&'>3d2OZoL8\XNj9sJ9>Mh>"m,@3tC-U^fc?n`+a+lEA1o$\b;6f=;=_%Ll"(YkM=7f__m1*AJp_K_ei(kUkTe+r>8DQFXlES,C($I]I5*jg*,#hM+7<,"d;oQEmOe`\K_=?Q&I3g;o5TNKoVpaOUQ"8qFiucb"^'mn8/;=A3pS8\ULF]hU9u\MU0-l:mFaT[i+L^04rJ"L!\3gi4FW0Br-VC-c^U5&U#AQ@g//WEI9#OUC6dn`JN2endstream +endobj +32 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1259 +>> +stream +Gau0BD/\E'&H9tYR.:PYabDYWCoUN.Enh[P)LC>AC.hPYG[_GIc)oTkXY*Eq6n!hO7&=?tCY.pC/t9,)0M"iF8rdBS;?NA0bOuVd#+Ki%;cl@pj\[cVm[85*U\Ggbf7\a-=\h`_BUU>85CJ];biL[j`k)6a@;$KTV>R'=^4K7O>.<&8I1198!_CfhS-J&P47hY_g7OJQ3V&&0b;95JbJ>U(^X^5h+&=9l8lk&srla+iV)2(4&ta8F[eLH2`#2!of[\9a>R5,?VA;`_gnQ*]-Ja4tp-cL^XJreeGHa0EbjOR4jYp%+f'=WED^9@cl7Olib3PrkFqVNY!3>t^P?MjWt_JVYH+R(`7%QCNL"SVYJD!t%cJ0^^C]nXUX;.?NHT3Ga4E[q;F:h3g;$p\3"+Ui&]b*^>l#;[jXM&q\PeML?\f$4E.a&G$cpnXB%H%&Q`4;]i%oQR5IV4T7p*.g;i40[7\XgP1&[V#:I)l\YX)efoP-58PU38AfMGY^HU.sO@q?8,t(Rb`toL=(uh&$^D%le+@Hl`A1,Rdq6#Phk#K!OCA#RqY_&f):eO]'/q..K5asX,GAmHqD8nIBendstream +endobj +33 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1341 +>> +stream +Gau0BD0+Gi%0#[%Ja,n!?:L?g,YRR_&kQ7-OISX+kW\,VuspT:m\[Gr!4[ff!cE#hXhiJLJCC6k>O]75=@MZ9kXbR-u?(rhEjoI>hsEBAgT0@lN03.E7W-@]%)WO\,+WC\G\cm9Eu)fg0uZWLd1P/P[$>p@=sdB%'jQ2<\C@h)+M%?SI(4dEg?2>fZ:7?fT7G%(/LM"M=h1_g>[#]5=Ou$O:iXLP;*$X4+3T'QC;s`)T>ohVAAY"0khWRn&nMmbRuhAO[j&(MOA2W!"Xn.q0IYiX[SL7YfeA5`&OP'uDR$ZPJ!!OSa,12JoL;qqmeW"\ad=;k$PjPk%oN]B^cmF/F8Ib1Q]3H/>rmfXr"18'P$29?O<;$n5i[HTGl2nX/1r\r`+Sm&;??C]OKDSo^&&Xteh!?+%Bem,LB-GA2!KVQhf654H0L3_n#oW,Brrq_Pql4XY>keU?1lG'7Jt48/*f9YI[eRD!`U%Va75HU,0Ff0KtrEI/]Z1nFH(X0rJTZZg&1pn0"-"F8QSe&A>JIe`g"jF#U=2;<"p&'Uh@;/%L?2W,Q:/Z(U3H6Y"lNA6OVg3?5Dr.LQ:d`2j`&5&mj]LM5H9+:/-FtR*YSK!0C#F)b_R]qn?'9T_/EHb,<5~>endstream +endobj +34 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 466 +>> +stream +GasbU?V;n(&B3Q$;]L1"7FNO,?[WU#^=3C1*u?2;>$'G&hVHZg(Vfj[!s-DQbIufj8nT]cqTHlD6nX-lSVem8ctM];5]-H'P(=tkqV27,38jttjO0IL(5NNuqjV)_[4Xt81rm"+^E,E,L6m#fBmf:bVH6AP4&&g)1EL4HnE]%I!Su(pU2iDE-&'I.;j7@[DI6ZU,%#Y'`0Y$`~>endstream +endobj +35 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1122 +>> +stream +Gb"/(>u0HF'Rf.GgmF'ef9T/\V3o4,pFFoS\h7OR!tQ/.5]te[dj\[\s*\P6.MS"6D1RHO`o@'d4nn9t$R3s9"3&$%*l)J/.c1d[*SPp,L2'!N%)0/CG9rKfe'qC(Tf3P4c'jM.Aj]fN?<318%LcA&WN)Rj`Hu.0PO=QX"L8hX-XJ)kqU^*)F)=:Pd)fc]p+/_Hch`G-Z)Tib4;0(FA,_Uang>aQSmJRUX8bKDjl<^NPLc+;[-J.)V'SC75R-O^BN'3V8E&(R6WBO)kU7"1s>Rq`GNJCZC"eSJiVo(R+Z(lOqp`Kt-2105mUgM"SU%NZ38LXAMi+SV9;P[Kct)ZP&&"fSm@i&96Y&6)k??`J//=P6a+FG7b=q9DohKB,+8CZY7g=0\@gaZ'7((;A*+<0u$Dq'dQarZN93'*/Af6.`D&POW>i2F=EEs9hJt.E+*Y9K,6SYu'C[SU?:kotu,M=oRWYTE?iOd/GP7B(Qjo)G?QRM*JJc5m*#dh;`J\DE.7NWB[c9`7l8cu%2U$C;sVq`^Ka!5OlgJ6n\/=0(N^#F]LI,CI6":CHt(PSqdn,rs('XGsudF*8UG]^*?FK?f(ZI-m,@2B.9.Yn/Hk4g,kVK#k]8%ZVi$QIq:?I=--P$>l-6uA^BbUSueFJd[[e:A-e<.74Gf3?I+!Gg'Yn2/&hp'5sN-_TZ"'usN%(%H1[3V?;c:C^S[U+?R--#W0PMWkUcl!fd#FHfeVXbp-pQ@8^3e$NDSQ\D+=,WgJ7=k>J9-JR3q;Haf11lPAJXG\Oq^3HOmY#q5`UdhM,Z~>endstream +endobj +36 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 545 +>> +stream +GauHJd;GF-'Rf-pNd,;"iF3]RUs15tg@eE]lbm:>9Q6q3YVRuT\n_7/#KG>j;Pe,?1?'-eT6m_hY%.ms1toWE'sL5Kp7?j?8CsM51.?MKGH(2YTtb50!Jus^Ta5@'BG)V'SJ`bo')UhuNq(9tLP4;?,`2GWG`$"4$V/'lpWkZ+8Sj\9LjdbmMc8fY0H3UUO3/RR%:*.[$EoH?F2[qtCCobM2=q4+"d#>8";@Slf#jN7V2u[fOJ_K$t&8+P)2miQ=*%CE[u*cp&n4g9CaAsL`oXe1N+AL5[c&#EaGOG.h\5B?MD>IS1#XS>R,mnCC+'q/Xm"fTu.htac:qa)3!]GN`LiV[;&_cB+]H_EZ)bmk6")n6:T6PP1b(GiRnPrVg`AB!uHF=e?N>.G,2CK4FhU3WWAO(L!lQ[aeegeH+"%W4smo*\3Kj(&~>endstream +endobj +37 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1622 +>> +stream +GauHKD/\/e&H88.EQtDg6PR4;;?s:-;tjkpg*HBB!DQGmi`,+DWVbq(.W2V?`;qE'7l=,70-cXDQ^`9\qsehDHJr*IgXcaOSODp%hR%Aqlr+E3W<81f)]q%0(0")!TMs$22u?f>IX`.]2N2%$E,E9gPBl.@TTf$eLaSECIB2hZkd:]S*^i3suJ!cCkOj9p4O172PUCP5F!R!P4&%HkipQ[-!IPp^dHQUR%;HLu3R8u?>fIJbPR-=u(77\4Fj3!QPHa/36<)$N]f_t34l:R-8nSN_9]@Z5lPd[d6F!L5'QuF?j0QGQ2fXOd\W>KG0@qKi?_0JT14>CoXDi@g>;8%gB8m@t_S`\KO*5ghD'-5-:u!,5U1K>CeeJflGmjZ#&i>g9L#5V);Z5fup_,X+r\S6613\T&a(S&V(nu.QL6V"K,M?[$:fsI?krlVB>TXp()GcMkZ[uhp4bl9AdYG4502o3Qj0QI4`_g89n/]\/u?_ODUibCJi^Cg$[&J\i:`T;Z"Z.PffD/P\PBFTjI1_FV<_N$X:3aU!+]+e//X?XqfiTs.4YQq!7&&h>(^)"mLK4JI].cTV.T1AB"8LPnc/Pab0f.&I]p9\+0DC%'j5?d^b@/of'37(pgG;0=:u"36$;+U,'p!iD+\KcEEZ4"q"8E$;D\Y+HW4$5-kB,TIDbO;9I@jJ!nZ[SsR["UD^r1rpbdD>2:R\(YaR1S]pQAhdlX;lgtlb:3G-u$9lBGa3%+aeln:7D^SN*E.8Q?.?S9%-ZnC=lAF1q[:IQ`>9_;6$n%cuBaJ90n3Pa%o&;>U``1:G_L=nf:6*jPou3UoO85:WDQRGQt@T55\QsgATf)<--(JoXd:BJl%F>nF6&7c&pu$D)54gpK*qi-8?cC^WNi6F;ThPjFkj$/,GL$.@/K9i*JYAAkOl&I`hh,l/(n;TL9>0qtLaX7f@`S:B5B-6*'q86>~>endstream +endobj +38 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1632 +>> +stream +Gatm;gN)%,&:O:SD#G""j3T&r&Xg,jini*Y'5O*Sc#d>*Q6Ck\%74*Z:B/!8hF,ML.4I,EU1!>Z4bqYnQ6*P\H0+cO"*cnYb:=)c!g>_8![iN?8,+buGs(V3bD8,T64sgKiRm[`-p^(fG">$@5mWJm]7*)^8UUC?H@CI5?73rB_[lrA)8^iPK[J+=?EBNC3.o_<-00,kAW5Hp@,s=E7U._f?-Y:%L-\St>Z.5=)1>nu[V@Kd5Xb\]#*LbE%t[[g.pA0[k"NMBJ1Y%Wa6g@fE2+kQ6\_3gZs[\[htTO@6bi!f4-r();ue?J?45fp.S![]^(:sS,i#Aqad>W0SAQpcJ,Yo_S'dd1iIQ-`&X6OpSst0[#\P_rUH+O/*0R=%fD,dJlFOmQD3l;snNPB8.pnM..;\cZ3nqa;E@Jp-G^kI.4ZZiW>^=?L^J,1b?1glX`h0Bu+-"a(t9Hi9G0?Jgp8@Tn)8cA4ghEc7n'$P`$9Cko/43!rV:-4>*%>;X,.0@>08sCGmu9/M122NZV/:Phon=E#Wc0E4duV68EEf*k,ZOZXdU--+d"UWtc_3@)Za&Nn4,X>akO^+dYO?dH(EdS+FL1VX8n*\7IZ8G[KDnYbK-Z8[f(5n8NUA:LY_+_5MldN3GA[O8TllpAN4Z;G3t0YS=HJ*M]W(qh)c2B0)\s>h>ChB7$kdXZn>%_u$oc=,O+&Q,g,t`BJ]JLAb,;pn>YI;hiuFl1YKH1]&pqTci;!0=C-Y,QnZF^'G:Le$`*^P5W1gAYcADup$J,JhEt@7PY8@5AYm=N"tf;3+)OV@`A:"@5Oo?Y_gP]H:5_mCP^^N(Dl-95CH[5r8P?]\qj8$7q!W~>endstream +endobj +xref +0 39 +0000000000 65535 f +0000000061 00000 n +0000000143 00000 n +0000000250 00000 n +0000000362 00000 n +0000000567 00000 n +0000000672 00000 n +0000000787 00000 n +0000000992 00000 n +0000001102 00000 n +0000001307 00000 n +0000001513 00000 n +0000001719 00000 n +0000001925 00000 n +0000002131 00000 n +0000002337 00000 n +0000002543 00000 n +0000002749 00000 n +0000002955 00000 n +0000003161 00000 n +0000003245 00000 n +0000003451 00000 n +0000003657 00000 n +0000003727 00000 n +0000004008 00000 n +0000004161 00000 n +0000005204 00000 n +0000006563 00000 n +0000008180 00000 n +0000009532 00000 n +0000010414 00000 n +0000011807 00000 n +0000012573 00000 n +0000013924 00000 n +0000015357 00000 n +0000015914 00000 n +0000017128 00000 n +0000017764 00000 n +0000019478 00000 n +trailer +<< +/ID +[] +% ReportLab generated PDF document -- digest (opensource) + +/Info 23 0 R +/Root 22 0 R +/Size 39 +>> +startxref +21202 +%%EOF diff --git a/Les08-Slide-Overzicht.md b/Les08-Slide-Overzicht.md new file mode 100644 index 0000000..8e8ed08 --- /dev/null +++ b/Les08-Slide-Overzicht.md @@ -0,0 +1,186 @@ +# 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" diff --git a/Les08-Slides.pptx b/Les08-Slides.pptx new file mode 100644 index 0000000000000000000000000000000000000000..057d5a7df4cc92d5d6ddaa33744eaa6eda64a669 GIT binary patch literal 146188 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