# Les 7 — Lesopdracht ## Supabase Setup + eerste queries **Duur:** ~120 minuten klassikaal --- ## Doel Aan het einde: Supabase project gekoppeld aan QuickPoll. Polls tabel aangemaakt, en homepage leest uit echte database in plaats van in-memory. --- ## Stap 1 — Supabase project klaar Account + project moeten klaar zijn (uit Les 6 huiswerk). Anders nu doen. Check je gegevens (Settings → API): - Project URL: `https://abc123.supabase.co` - Anon key: `eyJ...` --- ## Stap 2 — Tabellen via SQL Editor Supabase Dashboard → SQL Editor → New query: ```sql -- Polls tabel create table polls ( id bigserial primary key, title text not null, created_at timestamp default now() ); -- Options tabel (relatie naar polls) create table options ( id bigserial primary key, poll_id bigint not null references polls(id) on delete cascade, text text not null, votes integer default 0, created_at timestamp default now() ); -- RLS open voor demo alter table polls enable row level security; alter table options enable row level security; create policy "polls demo open" on polls for all to anon using (true) with check (true); create policy "options demo open" on options for all to anon using (true) with check (true); ``` Run → check Table Editor: beide tabellen verschijnen. --- ## Stap 3 — Test data inserten In SQL Editor: ```sql insert into polls (title) values ('Beste programmeertaal?'), ('Beste IDE?'); insert into options (poll_id, text) values (1, 'TypeScript'), (1, 'Python'), (1, 'Go'), (2, 'Cursor'), (2, 'VS Code'), (2, 'Vim'); ``` Check Table Editor → 2 polls, 6 opties. --- ## Stap 4 — Supabase in Next.js ```bash cd quickpoll pnpm add @supabase/supabase-js ``` `.env.local`: ``` NEXT_PUBLIC_SUPABASE_URL=https://abc123.supabase.co NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ... ``` `lib/supabase.ts`: ```typescript import { createClient } from "@supabase/supabase-js"; export const supabase = createClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, ); ``` --- ## Stap 5 — Homepage van Supabase Refactor `app/page.tsx`: ```tsx import { supabase } from "@/lib/supabase"; import Link from "next/link"; export default async function Home() { const { data: polls, error } = await supabase .from("polls") .select("*") .order("created_at", { ascending: false }); if (error) return

Error: {error.message}

; return (

QuickPoll

); } ``` Restart `pnpm dev` (env-changes vereisen restart). Open localhost:3000 → polls zichtbaar uit Supabase. --- ## Stap 6 — Detail-pagina ```tsx // app/poll/[id]/page.tsx import { supabase } from "@/lib/supabase"; import { notFound } from "next/navigation"; export default async function PollPage({ params, }: { params: Promise<{ id: string }> }) { const { id } = await params; const { data: poll } = await supabase .from("polls") .select("*, options(*)") .eq("id", Number(id)) .single(); if (!poll) notFound(); return (

{poll.title}

); } ``` Voting bouwen we in Les 8. --- ## Eisen - [ ] Supabase project actief met `polls` + `options` tabellen - [ ] RLS aan met open policies - [ ] Minstens 2 polls in DB - [ ] Homepage leest van Supabase - [ ] Detail-pagina toont opties van Supabase - [ ] Geen errors in console --- ## Bonus - Voeg een 3e tabel `votes` toe (voor user-tracking later) - Type-generation: `pnpm dlx supabase gen types typescript --linked > types/database.ts` - Loading-skeleton voor detail-pagina --- ## Veelvoorkomende problemen | Probleem | Oplossing | |----------|-----------| | "Invalid API key" | Anon key klopt niet — check .env.local, restart dev | | Polls niet zichtbaar | RLS policy ontbreekt — check beide tabellen | | `.env.local` niet geladen | Restart `pnpm dev` na env-changes | | Foreign key violation | Insert opties na polls (poll_id moet bestaan) | --- ## Klaar? Volgende les: schrijven naar DB (INSERT, UPDATE) — create-pagina + voting werkend.