321 lines
6.7 KiB
Markdown
321 lines
6.7 KiB
Markdown
# Les 8: Supabase Basics
|
|
|
|
---
|
|
|
|
## Hoofdstuk
|
|
**Hoofdstuk 2: Intermediate** (Les 4-9)
|
|
|
|
## Beschrijving
|
|
Leer werken met Supabase: een complete backend-as-a-service met database en authenticatie. Je bouwt je eerste full-stack app met data die persistent is.
|
|
|
|
---
|
|
|
|
## Te Behandelen
|
|
|
|
### Wat is Supabase?
|
|
|
|
**Supabase = Database + Auth in één**
|
|
- PostgreSQL database (gratis tier: 500MB)
|
|
- Ingebouwde authenticatie
|
|
- Real-time subscriptions
|
|
- File storage
|
|
- Auto-generated API
|
|
|
|
**Waarom Supabase voor beginners:**
|
|
- Geen eigen server nodig
|
|
- Visuele Table Editor (geen SQL kennis nodig)
|
|
- Simpele JavaScript SDK
|
|
- Gratis tier is ruim voldoende
|
|
|
|
---
|
|
|
|
### Supabase Project Aanmaken
|
|
|
|
**Stap 1:** Ga naar [supabase.com](https://supabase.com) en maak account
|
|
|
|
**Stap 2:** Klik "New Project"
|
|
- Naam: `todo-app`
|
|
- Database Password: (bewaar deze!)
|
|
- Region: `West EU (Frankfurt)` (dichtst bij NL)
|
|
|
|
**Stap 3:** Wacht ~2 minuten tot project klaar is
|
|
|
|
**Stap 4:** Ga naar Settings → API en kopieer:
|
|
- `Project URL`
|
|
- `anon public` key
|
|
|
|
---
|
|
|
|
### Tabel Maken via Table Editor
|
|
|
|
**In Supabase Dashboard:**
|
|
|
|
1. Ga naar "Table Editor"
|
|
2. Klik "New Table"
|
|
3. Naam: `todos`
|
|
4. Kolommen:
|
|
|
|
| Name | Type | Default | Primary |
|
|
|------|------|---------|---------|
|
|
| id | int8 | - | ✓ (auto) |
|
|
| title | text | - | |
|
|
| completed | bool | false | |
|
|
| created_at | timestamptz | now() | |
|
|
|
|
5. Klik "Save"
|
|
|
|
**Test:** Voeg een paar rijen toe via de UI om te zien dat het werkt.
|
|
|
|
---
|
|
|
|
### Environment Variables
|
|
|
|
**Wat zijn environment variables?**
|
|
- Configuratie die NIET in je code hoort
|
|
- API keys, database URLs, secrets
|
|
- Verschillend per omgeving (lokaal vs productie)
|
|
|
|
**Maak `.env.local` in je project root:**
|
|
```bash
|
|
# .env.local - NOOIT committen naar Git!
|
|
NEXT_PUBLIC_SUPABASE_URL=https://xxxxx.supabase.co
|
|
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxxx
|
|
```
|
|
|
|
**Maak ook `.env.example` (WEL committen):**
|
|
```bash
|
|
# .env.example - template voor anderen
|
|
NEXT_PUBLIC_SUPABASE_URL=your-supabase-url
|
|
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
|
|
```
|
|
|
|
**Check `.gitignore` bevat:**
|
|
```
|
|
.env*.local
|
|
```
|
|
|
|
---
|
|
|
|
### Supabase SDK Installeren
|
|
|
|
```bash
|
|
npm install @supabase/supabase-js
|
|
```
|
|
|
|
**Maak `src/lib/supabase.ts`:**
|
|
```typescript
|
|
import { createClient } from '@supabase/supabase-js'
|
|
|
|
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!
|
|
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
|
|
|
|
export const supabase = createClient(supabaseUrl, supabaseAnonKey)
|
|
```
|
|
|
|
---
|
|
|
|
### CRUD Operaties
|
|
|
|
**C - Create (toevoegen):**
|
|
```typescript
|
|
const { data, error } = await supabase
|
|
.from('todos')
|
|
.insert({ title: 'Nieuwe taak' })
|
|
```
|
|
|
|
**R - Read (ophalen):**
|
|
```typescript
|
|
const { data, error } = await supabase
|
|
.from('todos')
|
|
.select('*')
|
|
.order('created_at', { ascending: false })
|
|
```
|
|
|
|
**U - Update (wijzigen):**
|
|
```typescript
|
|
const { data, error } = await supabase
|
|
.from('todos')
|
|
.update({ completed: true })
|
|
.eq('id', todoId)
|
|
```
|
|
|
|
**D - Delete (verwijderen):**
|
|
```typescript
|
|
const { error } = await supabase
|
|
.from('todos')
|
|
.delete()
|
|
.eq('id', todoId)
|
|
```
|
|
|
|
---
|
|
|
|
### Authenticatie met Auth UI
|
|
|
|
**Installeer auth packages:**
|
|
```bash
|
|
npm install @supabase/auth-ui-react @supabase/auth-ui-shared
|
|
```
|
|
|
|
**Login component:**
|
|
```tsx
|
|
import { Auth } from '@supabase/auth-ui-react'
|
|
import { ThemeSupa } from '@supabase/auth-ui-shared'
|
|
import { supabase } from '@/lib/supabase'
|
|
|
|
export function LoginForm() {
|
|
return (
|
|
<Auth
|
|
supabaseClient={supabase}
|
|
appearance={{ theme: ThemeSupa }}
|
|
providers={[]}
|
|
magicLink={true}
|
|
/>
|
|
)
|
|
}
|
|
```
|
|
|
|
**Huidige user checken:**
|
|
```typescript
|
|
const { data: { user } } = await supabase.auth.getUser()
|
|
|
|
if (user) {
|
|
// User is ingelogd
|
|
console.log('Logged in as:', user.email)
|
|
} else {
|
|
// Redirect naar login
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Deployment naar Vercel
|
|
|
|
**Stap 1: Push naar GitHub**
|
|
```bash
|
|
git add .
|
|
git commit -m "Add Supabase integration"
|
|
git push
|
|
```
|
|
|
|
**Stap 2: Deploy op Vercel**
|
|
1. Ga naar [vercel.com](https://vercel.com)
|
|
2. "Add New Project"
|
|
3. Import je GitHub repo
|
|
4. **BELANGRIJK:** Voeg Environment Variables toe!
|
|
- `NEXT_PUBLIC_SUPABASE_URL`
|
|
- `NEXT_PUBLIC_SUPABASE_ANON_KEY`
|
|
5. Klik "Deploy"
|
|
|
|
**Stap 3: Supabase Redirect URLs**
|
|
1. Ga naar Supabase → Authentication → URL Configuration
|
|
2. Voeg toe bij "Redirect URLs":
|
|
- `https://jouw-app.vercel.app/**`
|
|
|
|
---
|
|
|
|
### Lokaal vs Productie
|
|
|
|
| Aspect | Lokaal | Productie |
|
|
|--------|--------|-----------|
|
|
| URL | `localhost:3000` | `jouw-app.vercel.app` |
|
|
| Env vars | `.env.local` | Vercel Dashboard |
|
|
| Database | Supabase (zelfde) | Supabase (zelfde) |
|
|
| Command | `npm run dev` | Automatisch via Vercel |
|
|
|
|
**Let op:** Je gebruikt dezelfde Supabase database voor lokaal en productie. Voor echte projecten zou je aparte databases hebben.
|
|
|
|
---
|
|
|
|
## Tools
|
|
- Supabase
|
|
- Next.js
|
|
- OpenCode/WebStorm
|
|
- Vercel
|
|
- Git
|
|
|
|
---
|
|
|
|
## Lesopdracht (2 uur)
|
|
|
|
### Bouw een Todo App met Supabase
|
|
|
|
**Deel 1: Supabase Setup (30 min)**
|
|
|
|
1. Maak Supabase account en project
|
|
2. Maak `todos` tabel via Table Editor
|
|
3. Kopieer credentials
|
|
4. Installeer `@supabase/supabase-js`
|
|
5. Maak `src/lib/supabase.ts`
|
|
6. Configureer `.env.local`
|
|
|
|
Test: `npm run dev` werkt zonder errors
|
|
|
|
**Deel 2: CRUD Interface (1 uur)**
|
|
|
|
Bouw UI voor todos:
|
|
1. Lijst van todos tonen
|
|
2. Form om nieuwe todo toe te voegen
|
|
3. Checkbox om todo af te vinken
|
|
4. Delete button per todo
|
|
|
|
Gebruik AI hulp voor de components!
|
|
|
|
**Deel 3: Authenticatie (30 min)**
|
|
|
|
1. Installeer auth packages
|
|
2. Maak login pagina met Auth UI
|
|
3. Toon alleen app voor ingelogde users
|
|
4. Test: login met magic link
|
|
|
|
### Deliverable
|
|
- Werkende Todo app lokaal
|
|
- GitHub repository met code
|
|
- Screenshot van werkende app
|
|
|
|
---
|
|
|
|
## Huiswerk (2 uur)
|
|
|
|
### Deploy naar Productie + Uitbreiden
|
|
|
|
**Deel 1: Deployment (30 min)**
|
|
|
|
1. Push naar GitHub
|
|
2. Deploy naar Vercel
|
|
3. Configureer env vars in Vercel
|
|
4. Voeg Vercel URL toe aan Supabase Redirect URLs
|
|
5. Test: app werkt op productie URL!
|
|
|
|
**Deel 2: Features Uitbreiden (1 uur)**
|
|
|
|
Voeg toe:
|
|
1. Filter buttons: Alle / Actief / Voltooid
|
|
2. Sorteer op datum (nieuwste eerst)
|
|
3. Loading state tijdens data ophalen
|
|
4. Error state bij problemen
|
|
5. Empty state: "Geen todos gevonden"
|
|
|
|
**Deel 3: Polish (30 min)**
|
|
|
|
1. Styling verbeteren met Tailwind
|
|
2. Responsive design (mobile friendly)
|
|
3. Kleine animaties (fade in/out)
|
|
|
|
### Deliverable
|
|
- Deployed app op Vercel (werkende URL!)
|
|
- Alle features werken in productie
|
|
- Screenshot van productie app
|
|
|
|
---
|
|
|
|
## Leerdoelen
|
|
Na deze les kan de student:
|
|
- Een Supabase project aanmaken en configureren
|
|
- Tabellen maken via de Table Editor (zonder SQL)
|
|
- Environment variables correct beheren
|
|
- De Supabase client installeren en configureren
|
|
- CRUD operaties uitvoeren met de Supabase SDK
|
|
- Authenticatie implementeren met Auth UI
|
|
- Deployen naar Vercel met environment variables
|
|
- Het verschil tussen lokale en productie omgeving begrijpen
|