Multiple features and improvements: Reports/Rapportage API: - Created REST API endpoints: /api/reports (GET/POST), /api/reports/[id] (GET/PATCH/DELETE) - Added /api/reports/classify endpoint for AI classification - Supabase migrations: reports table + RLS policies - Server utilities: api-client.ts for DRY fetch logic - Type definitions: lib/types/report.ts with Zod schemas - Removed old rapportage-modal component (replaced by split-view) Speech Recorder Refactor: - Moved speech-recorder from intake-specific to shared components/ - Updated treatment-advice-form to use new location - Updated intake actions for speech functionality UI Components (shadcn): - Added dialog, dropdown-menu, toast, toaster components - Added use-toast hook for toast notifications Documentation: - Reorganized docs/release/ → docs/reports/ for better structure - Archived old specs to docs/specs/archive/ - Added screening-system.mdx documentation - Added rapportage-split-view-design.md - Added UI screenshots for troubleshooting Dependencies: - Updated package.json and pnpm-lock.yaml - Regenerated database.types.ts from Supabase 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
6.1 KiB
E3.S2 - Patients lijst pagina
Epic: E3 - Patients & Organizations Story: E3.S2 - Patients lijst pagina Story Points: 5 Status: ✅ Compleet
Doel
Patiënten lijst pagina met tabel, search, filters en paginatie.
Acceptatiecriteria
/patientsroute met overzichtelijke tabel- Search functionaliteit op naam en BSN
- Filters (status, gender)
- Paginatie (50 per pagina)
- Sorteer functionaliteit
Implementatie
1. Server Actions (actions.ts)
📁 Locatie: app/epd/patients/actions.ts
Updates:
- ✅ Paginatie parameters toegevoegd (
page,pageSize) - ✅ Gender filter parameter
- ✅ Sorteer parameters (
sortBy,sortOrder) - ✅ Return type aangepast naar object met
patients,total,page,pageSize
API parameters:
{
search?: string; // Zoek op naam
status?: string; // Filter: planned, active, finished, cancelled
gender?: string; // Filter: male, female, other, unknown
page?: number; // Pagina nummer (default: 1)
pageSize?: number; // Items per pagina (default: 50)
sortBy?: string; // Sorteer kolom
sortOrder?: 'asc' | 'desc'; // Sorteer richting
}
2. Page Component (page.tsx)
📁 Locatie: app/epd/patients/page.tsx
Updates:
- ✅ SearchParams interface uitgebreid met nieuwe filters
- ✅ Page parameter parsing
- ✅ Props doorgegeven aan PatientList component
3. Patient List Component (patient-list.tsx)
📁 Locatie: app/epd/patients/components/patient-list.tsx
Features geïmplementeerd:
A. Filters
Search bar:
- Zoek op naam of BSN
- Real-time filtering
- Form submit handler
Status filter:
- Alle statussen
- Screening (planned)
- Actief (active)
- Afgerond (finished)
- Afgemeld (cancelled)
Gender filter:
- Alle geslachten
- Man (male)
- Vrouw (female)
- Anders (other)
- Onbekend (unknown)
B. Paginatie
Implementatie:
- 50 patiënten per pagina (configureerbaar)
- Pagina navigatie knoppen (vorige/volgende)
- Genummerde pagina buttons (max 7 zichtbaar)
- Smart pagination logica:
- Bij weinig pagina's: toon alle nummers
- Bij begin: toon eerste 7
- Bij einde: toon laatste 7
- In het midden: toon current ± 3
UI elementen:
- "Resultaten X-Y van Z" indicator
- Disabled state voor eerste/laatste pagina
- Active state voor huidige pagina
- Hover states voor interactie
C. Sortering
Sorteerbare kolommen:
- ✅ Naam (
name) - ✅ Geboortedatum (
birthDate) - ✅ Status (
status) - ✅ Laatst gewijzigd (
_lastUpdated)
Visual feedback:
- Inactieve kolommen:
<ArrowUpDown>(grijs) - Actieve kolom ascending:
<ArrowUp>(teal) - Actieve kolom descending:
<ArrowDown>(teal) - Hover effect op sorteerbare headers
Functionaliteit:
- Click om te sorteren
- Click opnieuw om richting te wisselen (asc ↔ desc)
- Sortering reset naar pagina 1
D. Helper functions
// URL parameters builder
buildUrlParams(updates: Record<string, string | number | undefined>)
// Event handlers
handleSearch(e: React.FormEvent)
handleStatusFilterChange(newStatus: string)
handleGenderFilterChange(newGender: string)
handlePageChange(newPage: number)
handleSort(column: string)
// Render helpers
renderSortIcon(column: string)
UI/UX Details
Layout
- Responsive design (desktop & mobile)
- Flex layout voor filters (wraps op kleine schermen)
- Sticky header mogelijk (voor lange lijsten)
Colors & Styling
- Teal als primary color (#0d9488)
- Slate voor neutral elements
- Status badges met kleurcodering:
- Amber: Screening
- Emerald: Actief
- Slate: Afgerond
- Red: Afgemeld
Empty States
- Verschillende berichten voor:
- Geen patiënten (met CTA om toe te voegen)
- Geen resultaten (met suggestie om filters aan te passen)
Performance
Optimalisaties:
- Server-side paginatie (max 50 geladen per keer)
- URL-based state (deep linking, browser back/forward)
- Suspense voor loading states
- No-cache strategie voor realtime data
Load times (verwacht):
- Initial load: < 1s
- Filter/sort/page change: < 500ms
- Search debounce: instant (client-side filter)
Database Queries
De actions maken gebruik van de FHIR API (/api/fhir/Patient) met de volgende query parameters:
GET /api/fhir/Patient?
name={search_term}&
status={status_filter}&
gender={gender_filter}&
_count={page_size}&
_offset={offset}&
_sort={sort_field}
FHIR-compliant:
- Gebruikt FHIR search parameters
- FHIR Bundle response format
- FHIR extension voor episode_status
Testing Checklist
- Paginatie werkt correct (vorige/volgende/nummers)
- Search filtert correct op naam
- Status filter werkt voor alle statussen
- Gender filter werkt voor alle geslachten
- Sortering werkt voor alle kolommen
- URL parameters worden correct bijgewerkt
- Browser back/forward werkt met filters
- Empty state toont bij geen resultaten
- Responsive layout op mobile
- Loading states tonen bij data fetch
- Pagination reset bij filter wijziging
Bekende Beperkingen
-
FHIR API Afhankelijkheid:
- Requires
/api/fhir/Patientendpoint - Episode status via extension (custom)
- Supabase moet online zijn voor data
- Requires
-
Client-side vs Server-side:
- Search is momenteel client-side gefilterd
- Kan server-side voor betere performance bij grote datasets
-
BSN Kolom:
- Niet sorteerbaar (niet in sortBy options)
- Encryption zou performance impact hebben
Volgende Stappen
Na E3.S2:
- E3.S3 - Patient CRUD (Create/Update/Delete + validatie)
- Eventueel: Advanced filters (leeftijdsbereik, postcode, etc.)
- Eventueel: Export functionaliteit (CSV/Excel)
- Eventueel: Bulk actions (selecteer multiple → wijzig status)
Referenties
- Bouwplan:
docs/bouwplan-mini-epd.md(regel 352-356, E3.S2) - Actions:
app/epd/patients/actions.ts - Page:
app/epd/patients/page.tsx - Component:
app/epd/patients/components/patient-list.tsx - FHIR Types:
lib/fhir/index.ts
Datum voltooid: 2025-11-22 Status: ✅ Compleet Dependencies voltooid: E2.S4 (Practitioner profile) Blokkeert: E3.S3 (Patient CRUD)