Mission 2: Die Oberfläche bauen
Planzeit: 4 Stunden. Achievement: A03 Erste Oberfläche (100 XP) bei 4 von 4 Tests.
Ziel
Aus den Beispieldaten wird eine bedienbare Oberfläche: eine Liste aller Leads und eine
Detailansicht mit Zurück-Weg. Du lernst, wie React aus Daten Bildschirme macht und was
ein data-testid ist.
Was du baust
Zwei Komponenten, die der Starter nur als Platzhalter enthält:
src/components/LeadList.tsx: Tabelle oder Liste aller Leads.src/components/LeadDetail.tsx: Detailansicht eines Leads mit Zurück-Button.
src/App.tsx ist schon so verdrahtet, dass ein Klick in der Liste die Detailansicht
öffnet und der Zurück-Button zur Liste führt. Lies App.tsx mit deinem Agenten, bevor
du anfängst; dort siehst du, wie view den Bildschirm steuert.
Der Vertrag mit den Tests
Die Tests rendern <App repository={...} /> mit vier Test-Leads und suchen Elemente über
data-testid. Diese Werte müssen exakt stimmen.
| Element | data-testid | Pflicht |
|---|---|---|
| Container der Liste | lead-list | Nur sichtbar, wenn es Leads gibt |
| Eine Zeile pro Lead | lead-row-<id>, z.B. lead-row-T-002 | Zeigt Firma, Kontaktname und Status als Text; Klick ruft onSelect(lead.id) |
| Leerzustand | empty-state | Statt der Liste, wenn keine Leads da sind; mindestens ein verständlicher Satz |
| Container der Detailansicht | lead-detail | Zeigt Firma, E-Mail und Follow-up-Datum (oder "kein Termin") |
| Zurück-Button | back-to-list | Ruft onBack() |
| Kriterium | Was geprüft wird |
|---|---|
| C02-M2-01 | Alle vier Test-Leads erscheinen mit Firma, Kontakt und Status in lead-list. |
| C02-M2-02 | Klick auf lead-row-T-002 zeigt lead-detail mit "Rhein Logistik GmbH", der E-Mail und "2026-04-02"; die Liste ist dann nicht mehr sichtbar. |
| C02-M2-03 | back-to-list führt zurück zur Liste. |
| C02-M2-04 | Ohne Leads erscheint empty-state und keine Zeile. |
Schritte
npm run devstarten und die Seite offen lassen. Jede Änderung ist sofort sichtbar.- Bitte deinen Agenten: "Erkläre mir in fünf Sätzen, was
App.tsxmacht und wasprops.leadsinLeadListist." - Baue
LeadList: Ein<table data-testid="lead-list">mit einer<tr>pro Lead. Beginne mit zwei Spalten, dann erweitern. Teste im Browser. - Leerzustand: Wenn
leads.length === 0, gib stattdessen ein<p data-testid="empty-state">mit einem hilfreichen Satz zurück. Keine leere Tabelle. - Baue
LeadDetail: Zurück-Button zuerst, dann die Felder. Wennleadundefined ist: "Lead nicht gefunden" und trotzdem der Zurück-Button. npm run bic -- check 2. Lies jede rote Zeile. EinUnable to find an element by: [data-testid="lead-list"]heisst: Das Element fehlt oder heisst anders.- Tastatur: Kannst du mit Tab und Enter einen Lead öffnen? Wenn nicht, ergänze einen Button in der Zeile. Das prüft kein Test, aber die Prüfung fragt danach.
git commit -am "Mission 2: Liste und Detail", Eintrag im KI-PROTOKOLL,npm run bic -- submit 2.
Typische Stolpersteine
- Der Test findet
lead-row-T-002nicht, weil dudata-testid={lead.id}stattdata-testid={`lead-row-${lead.id}`}geschrieben hast. onSelectwird nicht aufgerufen, weil der Klick auf einem Kind-Element landet und duonClickam falschen Element hast. Setze ihn auf die Zeile oder auf einen Button in der Zeile.- Die Detailansicht zeigt
nullstatt "kein Termin". Verwendelead.nextFollowUp ?? "kein Termin".
Erklären
- Was passiert, wenn
repository.list()ein leeres Array liefert? Zeige den Pfad durchApp.tsxundLeadList. - Warum gibt es in
App.tsxeinenuseStatefürviewund nicht einfach eine Variable?
Hinweise
missions/hints/02-1.md (Liste), missions/hints/02-2.md (Leerzustand), missions/hints/02-3.md (Detail und Zurück).
Weiter mit missions/03-daten-und-regeln.md.