- Workshop details verwijzen naar src/config/workshop.js (single source) - Deployment sectie herschreven: git push triggert Coolify auto-deploy - Forgejo URLs toegevoegd (SSH + HTTPS varianten met verwijzing naar memory) - Static Assets sectie aangepast: base is nu / maar BASE_URL prefix blijft praktijk - Legacy 301-redirect notitie toegevoegd voor frankmeeuwsen.com/workshopclaudecode/ Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Sales page for the "Claude Code Workshop" - a hands-on workshop for Dutch entrepreneurs (ZZP/MKB). Built as a static React SPA. All content is in Dutch (nl).
Workshop details: zie src/config/workshop.js (datum, tijd, locatie, prijs, beschikbare plekken). Niet hardcoden in deze CLAUDE.md - die raakt anders out-of-sync.
Commands
npm run dev # Vite dev server on port 5173
npm run build # Production build to dist/
npm run preview # Preview production build (port 4173)
npm run lint # ESLint
./preflight.sh # Pre-push checks (lint + build + asset path validation)
Architecture
React 19 + Vite 7 + Tailwind CSS 3 (dark mode via class strategy)
Routing
src/main.jsx- React Router setup with BrowserRouter/- Main sales page (App.jsx orchestrates all section components)/privacy- Privacy policy page/voorwaarden- Terms & conditions page
Component Structure
src/components/ contains the sales page sections, rendered in conversion-optimized order in App.jsx:
Hero → PainPoints → Testimonials → Benefits → Program → ForWho → Trainer → Pricing → FAQ → FinalCTA → Footer → StickyBar → CookieBanner
All components are barrel-exported from src/components/index.js.
src/pages/ contains standalone route pages (Privacy.jsx, Terms.jsx).
Design System
Custom color tokens defined in tailwind.config.js:
- coral (primary/CTA):
coral-500= #F25C3D - teal (accent):
teal-500= #14B8A6 - warm (neutrals): brown-gray scale for text and backgrounds
Custom fonts loaded via Google Fonts in index.html:
- Bricolage Grotesque (
font-display) - headings - Inter (
font-sans) - body text
Reusable component classes defined in src/index.css using @layer components:
- Headings:
.heading-hero,.heading-1,.heading-2,.heading-3 - Buttons:
.btn-primary,.btn-secondary,.btn-ghost - Cards:
.card,.card-feature - Layout:
.section,.section-alt,.container-page
Content Source
content/workshop-sales-page.md contains the original copywriting reference. Components contain the actual rendered content (some adjusted from source).
Deployment
Auto-deploy via Coolify: elke git push naar main triggert Coolify om de Dockerfile te bouwen en de nieuwe nginx-container live te zetten. Geen handmatig deploy-script meer.
Workflow:
./preflight.shlokaal draaien (lint + build + asset path check)git push(naarorigin/main→ Forgejo)- Coolify pulled, bouwt
Dockerfile(multi-stage node→nginx), deployt - Verifieer op https://workshopclaudecode.nl/
- Live URL: https://workshopclaudecode.nl
- Repo:
git@git.dutchstack.nl:frankmeeuwsen/workshopclaudecode.git(SSH push) /https://forgejo.dutchstack.nl/frankmeeuwsen/workshopclaudecode.git(HTTPS clone, gebruikt door Coolify) - zie memoryforgejo_urls.md - Hosting: Coolify static-app container op Hetzner (37.27.183.46) via SSH alias
coolify-deploy - SSL: Let's Encrypt automatisch via Traefik (Coolify regelt dit)
- Build artefacten in repo:
Dockerfile+nginx.conf(SPA fallback via try_files) +.dockerignore
Legacy redirect
De oude URL https://frankmeeuwsen.com/workshopclaudecode/* 301-redirect naar https://workshopclaudecode.nl/* met pad-behoud. Dit zit in een .htaccess in de WordPress container (wordpress-d0wko4gskokosssogcw8040g, pad /var/www/html/workshopclaudecode/.htaccess). Backup van originele htaccess staat als .htaccess.bak naast.
Actief project: Configuratie centraliseren
Zie PRD.md voor het volledige bouwplan. Korte samenvatting:
Doel: Alle workshopdetails (datum, tijd, locatie, prijs, e-mail) centraliseren in src/config/workshop.js zodat een nieuwe editie een one-stop-change is.
| Fase | Beschrijving | Status |
|---|---|---|
| Fase 1 | Snelle fixes + config completeren (bug Footer, ongebruikte assets, Tally ID in config, ESLint blokkerend) | Afgerond |
| Fase 2 | Workshop details centraliseren in workshop.js - 7 componenten bijwerken | Afgerond |
| Fase 3 | Code deduplicatie - gedeeld TallyForm component | Afgerond |
| Fase 4 | Deployment en kwaliteit - post-deploy check, valuta-inconsistentie | Afgerond |
Openstaande punten (volgende sessie)
- Signup.jsx workshopsamenvatting: Regel ~75 bevat hardcoded datum/tijd/locatie ("Vrijdag 3 april 2026 | 9:00 - 14:00 | Utrecht"). Kan naar WORKSHOP_CONFIG als die pagina hergebruikt wordt.
Conventions
- Components use static data arrays +
.map()for list rendering (benefits, FAQ items, timeline) - Inline SVG icons (Heroicons-style) rather than an icon library
- StickyBar has separate mobile (bottom) and desktop (top) layouts triggered by scroll position (600px threshold)
- Anchor links use
#inschrijvenfor CTA scroll targets
Verificatie Werkwijze
Voor elke wijziging: check bestaande patronen in de code voordat je iets nieuws toevoegt. Hoe doen vergelijkbare items het? Gebruik dezelfde aanpak.
Wanneer ./preflight.sh draaien:
- Nieuwe bestanden toevoegen (afbeeldingen, componenten)
- Nieuwe data-entries met paden of URLs
- Imports of exports wijzigen
- Structurele wijzigingen (nieuw component, nieuwe route)
- Configuratie aanpassen (vite.config, tailwind.config)
Niet nodig bij:
- Tekst aanpassen (quote, titel, beschrijving)
- Getallen wijzigen (bijv. availableSpots)
- CSS tweaks (kleur, spacing, font-size)
Vuistregel: als het kan breken, check het. Als het alleen tekst is, niet.
Static Assets
- Statische bestanden (afbeeldingen, etc.) staan in
public/ - Vite
basestaat op/(productie draait op het root domein workshopclaudecode.nl) - Toch
${import.meta.env.BASE_URL}als prefix blijven gebruiken — toekomstbestendig en./preflight.shcontroleert hierop - Voorbeeld:
src={`${import.meta.env.BASE_URL}foto.jpg`} - Vermijd:
src="/foto.jpg"(werkt nu wel maar breekt zodra base ooit weer een sub-pad wordt)