9.8 KiB
Debug Challenge HARD - Antwoordenblad (ALLEEN VOOR TIM)
⚠️ NIET DELEN MET STUDENTEN
Overzicht
Dit project is aanzienlijk complexer dan de easy versie. Het bevat:
- Blog met dynamische routes
- Dashboard met statistieken
- API route voor quotes
- Utility functions
- TypeScript types
12 fouten verspreid over 4 categorieën:
- Blokkerende fouten (compile/runtime)
- Logische fouten (code draait maar werkt verkeerd)
- Pattern fouten (React anti-patterns)
- Styling fouten (inline styles + custom CSS → Tailwind)
Geschatte tijd: 2-3 uur met AI
CATEGORIE 1: BLOKKERENDE FOUTEN
Fout 1: Missing dependency — clsx
Bestand: lib/utils.ts (regel 2)
Symptoom:
Module not found: Can't resolve 'clsx'
Oorzaak: clsx wordt geïmporteerd maar staat niet in package.json.
formatDate() wordt overal gebruikt, dus dit blokkeert ALLES.
Fix:
npm install clsx
Moeilijkheid: ⭐ (makkelijk, zelfde als easy versie)
Fout 2: Verkeerde import path — NextResponse
Bestand: app/api/quotes/route.ts (regel 2)
Symptoom:
Module not found: Can't resolve 'next/servers'
Oorzaak: "next/servers" moet "next/server" zijn (zonder s).
Fix:
// FOUT:
import { NextResponse } from "next/servers";
// CORRECT:
import { NextResponse } from "next/server";
Moeilijkheid: ⭐⭐ (subtiel — 1 letter verschil)
CATEGORIE 2: LOGISCHE FOUTEN
Fout 3: Array.slice() met verkeerde parameters
Bestand: components/BlogPreview.tsx (regel 7)
Symptoom: BlogPreview sectie op homepage toont GEEN posts (lege grid)
Oorzaak: blogPosts.slice(-2, 0) retourneert een lege array.
slice(-2, 0) betekent: start bij index -2 (2e van achteren), stop bij index 0 — dat is leeg!
Fix:
// FOUT:
const recentPosts = blogPosts.slice(-2, 0);
// CORRECT:
const recentPosts = blogPosts.slice(0, 2);
Moeilijkheid: ⭐⭐⭐ (geen error, gewoon lege output — student moet debuggen WAAROM)
Fout 4: Icon mapping mist "star" entry
Bestand: app/dashboard/page.tsx (regel 25-30)
Symptoom: De "Rating" stat card toont geen icon (undefined rendered als leeg)
Oorzaak: getIcon() functie heeft entries voor "users", "eye", "clock" maar NIET voor "star". De stats array bevat wel icon: "star".
Fix:
function getIcon(iconName: string) {
const icons: Record<string, React.ReactNode> = {
users: <Users size={24} />,
eye: <Eye size={24} />,
clock: <Clock size={24} />,
star: <Star size={24} />, // ← TOEVOEGEN
};
return icons[iconName];
}
Moeilijkheid: ⭐⭐⭐ (geen crash, subtiel visueel verschil)
Fout 5: Mobile menu altijd verborgen
Bestand: components/Header.tsx (regel 62 + 73)
Symptoom: Hamburger menu knop is onzichtbaar, en zelfs als je display: none verwijdert van de button, is het dropdown menu ALSOOK display: none.
Oorzaak: Twee problemen:
- De hamburger button heeft
display: 'none'→ onzichtbaar - Het mobile menu div heeft
display: 'none'→ zelfs alsmenuOpentrue is
Fix: Dit moet volledig naar responsive Tailwind met md:hidden/md:flex:
// Button: verberg op desktop, toon op mobiel
<button className="md:hidden" ...>
// Desktop nav: verberg op mobiel
<nav className="hidden md:flex gap-6" ...>
// Mobile menu: toon als flex wanneer open
{menuOpen && (
<div className="flex flex-col md:hidden p-3 border-t bg-white">
Moeilijkheid: ⭐⭐⭐⭐ (vereist begrijpen van responsive design patterns)
CATEGORIE 3: REACT PATTERN FOUTEN
Fout 6: async functie in useEffect
Bestand: app/dashboard/page.tsx (regel 35-39)
Symptoom: React warning in console:
Warning: useEffect must not return anything besides a function
En mogelijke infinite loop.
Oorzaak: useEffect(async () => {...}) is een React anti-pattern. async functie retourneert een Promise, maar useEffect verwacht void of een cleanup functie.
Fix:
// FOUT:
useEffect(async () => {
const res = await fetch("/api/quotes");
...
}, [quote]);
// CORRECT:
useEffect(() => {
async function fetchQuote() {
const res = await fetch("/api/quotes");
const data = await res.json();
setQuote(data.text);
setLoading(false);
}
fetchQuote();
}, []); // ← ook dependency array gefixed (zie Fout 7)
Moeilijkheid: ⭐⭐⭐⭐ (vereist kennis van React hooks patterns)
Fout 7: Verkeerde dependency array → infinite loop
Bestand: app/dashboard/page.tsx (regel 39)
Symptoom: Dashboard pagina loopt vast, continue fetch requests in Network tab
Oorzaak: [quote] als dependency betekent: "run opnieuw als quote verandert". Maar de effect ZET quote, wat de effect OPNIEUW triggert → infinite loop.
Fix:
// FOUT:
}, [quote]);
// CORRECT:
}, []); // Lege array = run 1x bij mount
Moeilijkheid: ⭐⭐⭐⭐ (vereist begrip van useEffect dependency arrays)
Fout 8: Null check mist op quote state
Bestand: components/QuoteOfTheDay.tsx (regel 22)
Symptoom: TypeError: Cannot read properties of null (reading 'text')
Oorzaak: quote begint als null, maar zodra loading false is, probeert de component quote.text te lezen. Als de API fails of traag is, kan dit crashen.
Fix: Voeg TypeScript type toe en null check:
// Verbeterde state typing:
const [quote, setQuote] = useState<{ text: string; author: string } | null>(null);
// In de render:
{!loading && quote && (
<>
<blockquote>"{quote.text}"</blockquote>
<cite>— {quote.author}</cite>
</>
)}
Moeilijkheid: ⭐⭐⭐ (runtime error, maar duidelijke error message)
CATEGORIE 4: STYLING FOUTEN (Inline Styles → Tailwind)
Fout 9: Custom CSS classes in globals.css
Bestand: app/globals.css
Probleem: .card, .page-container, .section-title zijn custom CSS classes. Deze horen Tailwind utility classes te zijn.
Fix: Verwijder custom CSS uit globals.css. Vervang in alle componenten:
.card→className="p-6 bg-white rounded-xl border border-gray-200 hover:shadow-lg hover:-translate-y-0.5 transition-all".page-container→className="max-w-[1200px] mx-auto px-5".section-title→className="text-3xl font-bold text-center mb-10 text-gray-900"
Moeilijkheid: ⭐⭐⭐ (moet begrijpen waarom Tailwind beter is dan custom CSS)
Fout 10-12: Inline styles in alle componenten
Bestanden met inline styles:
| # | Bestand | Complexiteit |
|---|---|---|
| 10 | components/Hero.tsx |
Hoog (gradient, positioning) |
| 11 | components/Header.tsx |
Hoog (responsive, sticky) |
| 12 | components/Footer.tsx |
Medium (grid, links) |
| - | components/StatsSection.tsx |
Medium (grid) |
| - | components/BlogPreview.tsx |
Medium (grid, cards) |
| - | components/QuoteOfTheDay.tsx |
Laag |
| - | app/blog/page.tsx |
Medium (grid, tags) |
| - | app/blog/[slug]/page.tsx |
Medium (article layout) |
| - | app/dashboard/page.tsx |
Hoog (stats grid, cards) |
Studenten moeten minimaal 3-4 bestanden omzetten.
Aanpak:
- Selecteer inline style code
Ctrl+K→ "Converteer inline styles naar Tailwind CSS. Gebruik de brand- kleuren uit tailwind.config.ts waar mogelijk."- Review + Accept
Moeilijkheid: ⭐⭐ per bestand (maar het zijn er VEEL)
Samenvatting Alle Fouten
| # | Type | Bestand | Ernst | Moeilijkheid |
|---|---|---|---|---|
| 1 | Missing dependency (clsx) | lib/utils.ts | 🔴 Blokkerend | ⭐ |
| 2 | Verkeerde import (next/servers) | api/quotes/route.ts | 🔴 Blokkerend | ⭐⭐ |
| 3 | Verkeerde slice() params | BlogPreview.tsx | 🟡 Logisch | ⭐⭐⭐ |
| 4 | Missende icon mapping | dashboard/page.tsx | 🟡 Logisch | ⭐⭐⭐ |
| 5 | Mobile menu altijd hidden | Header.tsx | 🟡 Logisch | ⭐⭐⭐⭐ |
| 6 | async in useEffect | dashboard/page.tsx | 🟠 Anti-pattern | ⭐⭐⭐⭐ |
| 7 | Infinite loop dep array | dashboard/page.tsx | 🔴 Runtime crash | ⭐⭐⭐⭐ |
| 8 | Null check quote state | QuoteOfTheDay.tsx | 🔴 Runtime crash | ⭐⭐⭐ |
| 9 | Custom CSS → Tailwind | globals.css | 🟡 Styling | ⭐⭐⭐ |
| 10-12 | Inline styles (9+ bestanden) | Overal | 🟡 Styling | ⭐⭐ elk |
Verwachte Oplos-Volgorde
npm install→ werktnpm run dev→Can't resolve 'clsx'→npm install clsxnpm run dev→Can't resolve 'next/servers'→ fix import- Site laadt! Maar:
- BlogPreview is leeg → fix slice()
- Dashboard crasht/loopt vast → fix useEffect + dep array
- Quote component crasht → fix null check
- Rating icon mist → fix icon mapping
- Mobile menu werkt niet → fix responsive
- Inline styles → Tailwind conversie
- Custom CSS → Tailwind refactor
Verwacht Request Gebruik
| Actie | Requests |
|---|---|
| Debug blokkerende errors (Chat) | 2-3 |
| Fix logische fouten (Chat + Edit) | 3-4 |
| Fix React patterns (Chat) | 2-3 |
| Inline styles → Tailwind (Inline Edit × 4-5) | 4-5 |
| Totaal | 11-15 requests |
⚠️ Dit is meer dan de easy versie. Studenten op Hobby plan moeten efficiënt werken. Student plan (500/maand) is ruim voldoende.
Tips voor Tim
- Dit is echt moeilijk. Fout 5, 6, 7 zijn lastig voor beginners. Verwacht dat studenten hier hulp bij nodig hebben.
- De useEffect fouten zijn een goed leermoment — dit is een HEEL veelvoorkomende bug in React.
- De slice() bug is een subtiele logische fout. Studenten moeten leren: "het werkt zonder errors, maar het resultaat klopt niet" → debuggen.
- Mobile menu is bewust moeilijk. Dit vereist dat ze responsive design begrijpen. Goede Cursor prompt: "Maak deze header responsive met een hamburger menu dat werkt op mobiel met Tailwind."
- Geef de easy zip als standaard. Hard is voor studenten die de easy versie snel af hebben of die extra uitdaging willen.