Van idee naar SaaS: een contracten-tracker voor freelancers
Als freelancer of ZZP'er verlies je tijd aan het bijhouden van je lopende contracten. Wanneer loopt dit contract af? Heb ik die klant al gefactureerd? Is dit project afgerond of nog actief? Een simpele spreadsheet werkt even, maar daarna wordt het chaos. Vandaag bouwen we met Claude Code een echte webapplicatie die dit oplost, van nul tot werkende MVP.
Geen developer-ervaring nodig. Wel: Claude Code, een Supabase-account (gratis) en een uurtje of drie concentratie.
Het probleem en de doelgroep
Doelgroep: Freelancers, ZZP'ers en kleine bureaus met 5 tot 50 lopende opdrachten tegelijk.
Kern van het probleem: Contracten lopen af zonder herinnering, factuurmomenten worden gemist, en er is geen overzicht van welke klanten actief zijn versus afgerond.
Wat de app doet:
- Contracten toevoegen met klantnaam, startdatum, einddatum en waarde
- Status bijhouden: actief, afgerond, verlengd
- Automatische waarschuwing als een contract binnen 30 dagen afloopt
- Simpel dashboard met totale pipeline-waarde
Stap 1: Project opstarten en richting geven aan Claude Code
Open Claude Code in een lege map. Begin NIET met coderen, maar geef eerst context. Dit is de meest gemaakte fout: mensen duiken direct in features terwijl Claude Code geen idee heeft wat het grotere plaatje is.
Maak eerst een CLAUDE.md aan in je projectmap met deze inhoud:
# Contracten-tracker voor freelancers
## Wat bouwen we
Een webapplicatie waarmee freelancers hun lopende contracten bijhouden.
Simple, snel, geen poespas.
## Tech stack
- Next.js 14 (App Router)
- Supabase (database + auth)
- Tailwind CSS (styling)
- TypeScript
## Doelgebruiker
ZZP'er of freelancer, geen techneut. UI moet glashelder zijn.
## Kernregels
- Geen onnodige complexiteit. Als iets simpeler kan, doe het simpeler.
- Elke pagina moet op mobiel werken.
- Gebruik Nederlandse teksten in de UI.
- Valideer altijd formulierinput voor je iets opslaat.
Geef dit daarna als eerste prompt aan Claude Code:
Lees CLAUDE.md. Maak een nieuw Next.js 14 project aan met TypeScript en Tailwind CSS. Gebruik
npx create-next-app@latestmet de App Router. Installeer daarna ook@supabase/supabase-jsen@supabase/ssr. Geef me de exacte terminal-commando's en voer ze uit.
Claude Code genereert nu de projectstructuur en installeert alles. Dit duurt twee minuten.
Stap 2: Database opzetten in Supabase
Ga naar supabase.com, maak een gratis project aan en ga naar de SQL Editor. Geef Claude Code nu deze prompt:
Schrijf de SQL voor een Supabase-database met één tabel:
contracts. De tabel heeft deze kolommen: id (uuid, primary key), user_id (uuid, foreign key naar auth.users), client_name (text, verplicht), project_description (text), start_date (date, verplicht), end_date (date), contract_value (numeric), currency (text, default 'EUR'), status (text, default 'actief' - mag alleen 'actief', 'afgerond' of 'verlengd' zijn), created_at (timestamp with time zone, default now()). Voeg ook Row Level Security toe zodat gebruikers alleen hun eigen contracten zien. Geef me de volledige SQL die ik in de Supabase SQL Editor kan plakken.
Kopieer de output naar Supabase SQL Editor en klik op Run. Done.
Maak daarna in je project een .env.local aan:
NEXT_PUBLIC_SUPABASE_URL=jouw-supabase-url
NEXT_PUBLIC_SUPABASE_ANON_KEY=jouw-anon-key
Vervolgens:
Maak een
lib/supabase.tsbestand aan met de Supabase client configuratie voor Next.js App Router. Gebruik@supabase/ssrmetcreateBrowserClientvoor client-side encreateServerClientvoor server-side gebruik. Zorg dat environment variables correct geladen worden.
Stap 3: Authenticatie toevoegen
We gebruiken Supabase Auth, zodat elke freelancer alleen zijn eigen contracten ziet.
Maak een login-pagina aan op
/loginmet een simpel formulier: e-mailadres en wachtwoord. Gebruik Supabase Auth metsignInWithPassword. Voeg ook een registratie-optie toe op dezelfde pagina (tabblad of toggle). Na inloggen redirect je naar/dashboard. Stijl alles met Tailwind, in het Nederlands, en zorg dat het er netjes uitziet op mobiel. Voeg ook een middleware.ts toe in de root die niet-ingelogde gebruikers redirect naar /login.
Test dit door de dev server te starten (npm run dev) en naar localhost:3000 te gaan.
Stap 4: Het kern-dashboard bouwen
Dit is de hoofdpagina. Drie dingen moet je hier zien: een overzichtskaart met totale waarde actieve contracten, een waarschuwingsblok voor contracten die binnen 30 dagen aflopen, en de lijst van alle contracten.
Maak de pagina
/dashboard/page.tsxaan. Dit is een server component die alle contracten van de ingelogde gebruiker ophaalt uit Supabase. Toon bovenaan drie stat-kaarten: totaal aantal actieve contracten, totale waarde van actieve contracten in euro, en aantal contracten dat binnen 30 dagen afloopt. Daaronder een tabel met alle contracten: klantnaam, projectomschrijving (ingekort tot 50 tekens), startdatum, einddatum, waarde, status (met een gekleurde badge: groen voor actief, grijs voor afgerond, blauw voor verlengd). Contracten die binnen 30 dagen aflopen krijgen een oranje rand of achtergrond. Voeg een knop toe rechtsboven: 'Nieuw contract toevoegen'. Gebruik Tailwind voor alle styling.
Subcomponent: statusbadge
Maak een apart component
components/StatusBadge.tsxdat een status-string ('actief', 'afgerond', 'verlengd') ontvangt als prop en een gekleurde pill/badge teruggeeft. Groen voor actief, grijs voor afgerond, blauw voor verlengd. Exporteer het als default.
Stap 5: Contract toevoegen en bewerken
Maak een pagina
/dashboard/nieuw/page.tsxmet een formulier om een nieuw contract aan te maken. Velden: klantnaam (verplicht), projectomschrijving (optioneel, textarea), startdatum (verplicht, date input), einddatum (optioneel, date input), contractwaarde (optioneel, number input), valuta (select, alleen EUR en USD, default EUR), status (select: actief/afgerond/verlengd, default actief). Gebruik een Server Action om het formulier te verwerken: valideer de input server-side, sla op in Supabase en redirect naar /dashboard na succes. Toon foutmeldingen inline bij de velden als validatie faalt. Voeg een 'Annuleren' link toe die teruggaat naar /dashboard.
En voor bewerken:
Maak een pagina
/dashboard/[id]/bewerken/page.tsxdie het contract met het gegeven id ophaalt (en controleert dat het van de ingelogde user is), en hetzelfde formulier toont maar dan pre-filled met de bestaande data. Na opslaan redirect naar /dashboard. Voeg ook een 'Contract verwijderen' knop toe met een confirm-dialoog voor je daadwerkelijk verwijdert.
Stap 6: Afloopwaarschuwingen als e-mail
Dit is de feature die de app echt nuttig maakt. We sturen een wekelijkse e-mail met contracten die binnen 30 dagen aflopen.
Maak een API route aan op
/api/stuur-herinneringen/route.ts. Deze route checkt alle actieve contracten in Supabase waarvan de einddatum tussen vandaag en 30 dagen in de toekomst ligt. Voor elk zo'n contract log je naar de console: 'Herinnering voor: [klantnaam] - afloopt op [datum]'. Beveilig de route met een simpele API key check via de Authorization header (vergelijk met een env variable REMINDER_API_KEY). Retourneer JSON met hoeveel herinneringen er verstuurd zijn. Voeg REMINDER_API_KEY toe aan .env.local.
Leg me in commentaar uit hoe ik deze API route wekelijks automatisch kan aanroepen via een gratis cron-service zoals cron-job.org. Welke URL gebruik ik, en welke Authorization header stuur ik mee?
Later kun je de console.log vervangen door echte e-mails via Resend of Postmark, maar voor de MVP is dit genoeg om te tonen hoe het werkt.
Stap 7: Afronden en deployen
Controleer het hele project op de volgende punten en los problemen op: 1) Werkt de middleware correct en worden niet-ingelogde gebruikers doorgestuurd? 2) Zijn alle formulieren beveiligd met server-side validatie? 3) Zijn er TypeScript-errors? 4) Werkt de app op een smal scherm (mobiel)? Geef me een lijst van wat je aanpast en waarom.
Deploy daarna naar Vercel:
npx vercel
Voeg je environment variables toe in het Vercel-dashboard (Settings - Environment Variables) en je bent live.
Wat te checken na afloop
Loop deze checklist door voor je de app aan iemand laat zien:
- Kan ik inloggen en uitloggen zonder errors?
- Zie ik na inloggen alleen mijn eigen contracten (niet die van andere testaccounts)?
- Worden contracten die binnen 30 dagen aflopen oranje gemarkeerd?
- Werkt het formulier voor nieuw contract met lege verplichte velden (foutmelding zichtbaar)?
- Werkt de bewerkpagina met pre-filled data?
- Is de
/api/stuur-herinneringenroute beveiligd (geeft 401 zonder goede key)? - Laadt het dashboard op mobiel zonder horizontale scroll?
Wat zou je daarna nog willen toevoegen?
Een paar logische vervolgstappen als de MVP staat en je eerste gebruikers hebt:
- PDF-export van contractoverzicht - handig voor accountants
- Koppeling met Mollie of Stripe zodat je facturen kunt versturen vanuit de app
- Meerdere teamleden per account (voor kleine bureaus)
- Herhalings-contracten die automatisch verlengd worden met een nieuwe einddatum
- Klantenpagina met alle historische opdrachten per klant
Deze MVP kun je vandaag bouwen. Met drie uur werk en de prompts hierboven sta je op Vercel met een applicatie die je morgen al aan je eerste vijf freelancer-vrienden kunt laten testen.
Bij Eighty leer ik je Claude Code in het Nederlands gebruiken, van installatie tot een werkend SaaS-product. Wekelijks een nieuwe module, persoonlijke begeleiding.
