feat: testimonial Monique Dubbelman, plekken 8→7, preflight checks
- Testimonial Monique Dubbelman toegevoegd met lokale avatar - Hero: 8 doorgestreept, 7 plekken beschikbaar - preflight.sh: pre-deploy checks (lint, build, asset paden, public/ bestanden) - deploy.sh: draait preflight automatisch voor elke deploy - CLAUDE.md: verificatie werkwijze en static assets conventie gedocumenteerd Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
42c367f8ef
commit
fe08b3c519
6 changed files with 129 additions and 5 deletions
31
CLAUDE.md
31
CLAUDE.md
|
|
@ -15,6 +15,7 @@ npm run dev # Vite dev server on port 5173
|
|||
npm run build # Production build to dist/
|
||||
npm run preview # Preview production build
|
||||
npm run lint # ESLint
|
||||
./preflight.sh # Pre-deploy checks (lint + build + asset path validation)
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
|
@ -58,10 +59,10 @@ Reusable component classes defined in `src/index.css` using `@layer components`:
|
|||
## Deployment
|
||||
|
||||
```bash
|
||||
./deploy.sh # Build + deploy naar productie (geen passphrase nodig)
|
||||
./deploy.sh # Preflight + build + deploy naar productie (geen passphrase nodig)
|
||||
```
|
||||
|
||||
Deployment flow: `npm run build` → rsync naar server → `docker cp` naar WordPress container → chown fix
|
||||
Deployment flow: `./preflight.sh` → `npm run build` → rsync naar server → `docker cp` naar WordPress container → chown fix
|
||||
|
||||
- **Server:** Hetzner (37.27.183.46) via SSH alias `coolify-deploy`
|
||||
- **Container:** `wordpress-d0wko4gskokosssogcw8040g`
|
||||
|
|
@ -75,3 +76,29 @@ Deployment flow: `npm run build` → rsync naar server → `docker cp` naar Word
|
|||
- 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 `#inschrijven` for 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 (BELANGRIJK)
|
||||
- Statische bestanden (afbeeldingen, etc.) staan in `public/`
|
||||
- **Altijd** `${import.meta.env.BASE_URL}` als prefix gebruiken bij verwijzingen vanuit code
|
||||
- Reden: productie draait op `/workshopclaudecode/`, niet op `/`
|
||||
- Voorbeeld: `` src={`${import.meta.env.BASE_URL}foto.jpg`} ``
|
||||
- NOOIT: `src="/foto.jpg"` (werkt lokaal maar breekt op productie)
|
||||
- `./preflight.sh` detecteert hardcoded paden automatisch
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@ CONTAINER="wordpress-d0wko4gskokosssogcw8040g"
|
|||
REMOTE_PATH="/var/www/html/workshopclaudecode"
|
||||
TMP_PATH="/tmp/workshopclaudecode"
|
||||
|
||||
echo "0/4 - Preflight checks..."
|
||||
./preflight.sh
|
||||
echo ""
|
||||
echo "1/4 - Building..."
|
||||
npm run build --silent
|
||||
|
||||
|
|
|
|||
85
preflight.sh
Executable file
85
preflight.sh
Executable file
|
|
@ -0,0 +1,85 @@
|
|||
#!/bin/bash
|
||||
# Preflight checks - draait voor elke deploy om veelvoorkomende fouten te vangen
|
||||
#
|
||||
# Checks:
|
||||
# 1. ESLint
|
||||
# 2. Vite build (syntax errors, missing imports)
|
||||
# 3. Hardcoded asset paden die BASE_URL missen
|
||||
# 4. Gerefereerde public/ bestanden bestaan daadwerkelijk
|
||||
|
||||
set -e
|
||||
|
||||
ERRORS=0
|
||||
|
||||
echo "=== Preflight Checks ==="
|
||||
echo ""
|
||||
|
||||
# 1. Lint check
|
||||
echo "[1/4] ESLint..."
|
||||
if npm run lint --silent 2>&1; then
|
||||
echo " OK"
|
||||
else
|
||||
echo " WAARSCHUWING: lint errors gevonden (niet-blokkerend)"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 2. Build check
|
||||
echo "[2/4] Vite build..."
|
||||
npm run build --silent
|
||||
echo " OK"
|
||||
echo ""
|
||||
|
||||
# 3. Check voor hardcoded asset paden zonder BASE_URL
|
||||
# Zoekt naar src= of avatar: paden die beginnen met "/" gevolgd door een bestandsnaam
|
||||
# maar NIET import.meta.env.BASE_URL gebruiken
|
||||
echo "[3/4] Asset paden check (BASE_URL)..."
|
||||
BAD_PATHS=$(grep -rn 'src=\s*"\/[a-zA-Z0-9]' src/ --include="*.jsx" --include="*.js" 2>/dev/null || true)
|
||||
BAD_AVATAR=$(grep -rn "avatar:\s*[\"']/[a-zA-Z0-9]" src/ --include="*.jsx" --include="*.js" 2>/dev/null || true)
|
||||
|
||||
if [ -n "$BAD_PATHS" ] || [ -n "$BAD_AVATAR" ]; then
|
||||
echo " FOUT: Hardcoded asset paden gevonden zonder BASE_URL prefix!"
|
||||
echo " Deze werken lokaal maar breken op productie (/workshopclaudecode/)."
|
||||
echo ""
|
||||
[ -n "$BAD_PATHS" ] && echo "$BAD_PATHS" | sed 's/^/ /'
|
||||
[ -n "$BAD_AVATAR" ] && echo "$BAD_AVATAR" | sed 's/^/ /'
|
||||
echo ""
|
||||
echo " Fix: gebruik \${import.meta.env.BASE_URL}bestandsnaam.jpg"
|
||||
ERRORS=$((ERRORS + 1))
|
||||
else
|
||||
echo " OK"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 4. Check dat gerefereerde bestanden in public/ bestaan
|
||||
echo "[4/4] Public assets bestaan..."
|
||||
MISSING=0
|
||||
for file in public/*; do
|
||||
[ -f "$file" ] || continue
|
||||
done
|
||||
|
||||
# Zoek alle BASE_URL referenties en check of het bestand bestaat in public/
|
||||
# Matcht alleen bestandsnamen (letters, cijfers, punt, streepje, underscore)
|
||||
REFS=$(grep -roh 'BASE_URL}[a-zA-Z0-9._-]*' src/ --include="*.jsx" --include="*.js" 2>/dev/null | sed 's/BASE_URL}//' | grep -v '^$' || true)
|
||||
for ref in $REFS; do
|
||||
if [ ! -f "public/$ref" ]; then
|
||||
echo " FOUT: public/$ref bestaat niet (gerefereerd in code)"
|
||||
MISSING=$((MISSING + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$MISSING" -eq 0 ]; then
|
||||
echo " OK"
|
||||
else
|
||||
ERRORS=$((ERRORS + MISSING))
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Resultaat
|
||||
echo "=== Resultaat ==="
|
||||
if [ "$ERRORS" -gt 0 ]; then
|
||||
echo "GEFAALD: $ERRORS fout(en) gevonden. Fix deze voor deploy."
|
||||
exit 1
|
||||
else
|
||||
echo "ALLES OK - klaar voor deploy."
|
||||
exit 0
|
||||
fi
|
||||
BIN
public/20260211174-MoniqueDubbelman.jpg
Normal file
BIN
public/20260211174-MoniqueDubbelman.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
|
|
@ -6,8 +6,9 @@
|
|||
*/
|
||||
|
||||
function Hero() {
|
||||
// Aantal beschikbare plaatsen - later dynamisch te maken
|
||||
const availableSpots = 8;
|
||||
// Aantal beschikbare plaatsen
|
||||
const totalSpots = 8;
|
||||
const availableSpots = 7;
|
||||
|
||||
return (
|
||||
<section className="section relative overflow-hidden">
|
||||
|
|
@ -33,7 +34,7 @@ function Hero() {
|
|||
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-coral-500 opacity-75"></span>
|
||||
<span className="relative inline-flex rounded-full h-2 w-2 bg-coral-500"></span>
|
||||
</span>
|
||||
{availableSpots} plekken - kleine groep, persoonlijke aandacht
|
||||
<span className="line-through opacity-60">{totalSpots}</span>{' '}{availableSpots} plekken - kleine groep, persoonlijke aandacht
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,14 @@ function Testimonials() {
|
|||
url: "https://drawn.today/",
|
||||
initials: "JB"
|
||||
},
|
||||
{
|
||||
quote: "Frank leert je op een laagdrempelige en humoristische manier hoe je zelf in een paar uur je eigen app bouwt, zonder technische kennis. Je leert dingen waarvan je niet wist dat je ze wilde leren",
|
||||
name: "Monique Dubbelman",
|
||||
role: "Community Manager",
|
||||
avatar: `${import.meta.env.BASE_URL}20260211174-MoniqueDubbelman.jpg`,
|
||||
url: "https://modub.nl/",
|
||||
initials: "MD"
|
||||
},
|
||||
{
|
||||
quote: "Kan een niet-developer apps, websites, games maken? Het lijkt te mooi om waar te zijn, totdat Frank je met een glimlach en geduld gerust stelt. Voor mij was deze sessie zeer inspirerend en zorgde ervoor dat ik vier apps heb gemaakt in korte tijd.",
|
||||
name: "Ewout Wolff",
|
||||
|
|
|
|||
Loading…
Reference in a new issue