'use client'; /** * Patient List Component * E2.S1: Cliëntenlijst met zoekfunctie, filters en status badges */ import { useState } from 'react'; import Link from 'next/link'; import { useRouter, useSearchParams } from 'next/navigation'; import { User, Search, Filter } from 'lucide-react'; import type { FHIRPatient } from '@/lib/fhir'; interface PatientListProps { initialPatients: FHIRPatient[]; } // Status badge component function StatusBadge({ status }: { status?: string }) { const badges = { planned: { label: 'Screening', className: 'bg-amber-100 text-amber-800 border-amber-200' }, active: { label: 'Actief', className: 'bg-emerald-100 text-emerald-800 border-emerald-200' }, finished: { label: 'Afgerond', className: 'bg-slate-100 text-slate-800 border-slate-200' }, cancelled: { label: 'Afgemeld', className: 'bg-red-100 text-red-800 border-red-200' }, }; const badge = status && status in badges ? badges[status as keyof typeof badges] : null; if (!badge) { return -; } return ( {badge.label} ); } export function PatientList({ initialPatients }: PatientListProps) { const router = useRouter(); const searchParams = useSearchParams(); const [searchTerm, setSearchTerm] = useState(searchParams.get('search') || ''); const [statusFilter, setStatusFilter] = useState(searchParams.get('status') || 'all'); const [patients] = useState(initialPatients); // Handle search const handleSearch = (e: React.FormEvent) => { e.preventDefault(); const params = new URLSearchParams(); if (searchTerm) params.set('search', searchTerm); if (statusFilter !== 'all') params.set('status', statusFilter); router.push(`/epd/patients?${params.toString()}`); }; // Handle status filter change const handleStatusFilterChange = (newStatus: string) => { setStatusFilter(newStatus); const params = new URLSearchParams(); if (searchTerm) params.set('search', searchTerm); if (newStatus !== 'all') params.set('status', newStatus); router.push(`/epd/patients?${params.toString()}`); }; if (patients.length === 0) { return (
{/* Search and Filter Bar */}
{/* Search Bar */}
setSearchTerm(e.target.value)} className="w-full pl-10 pr-4 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-teal-500 focus:border-transparent" />
{/* Status Filter */}
{/* Empty State */}

Geen patiënten gevonden

{searchTerm || statusFilter !== 'all' ? 'Probeer een andere zoekopdracht of filter.' : 'Begin met het toevoegen van een nieuwe patiënt.'}

); } return (
{/* Search and Filter Bar */}
{/* Search Bar */}
setSearchTerm(e.target.value)} className="w-full pl-10 pr-4 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-teal-500 focus:border-transparent" />
{/* Status Filter */}
{/* Patient Table */}
{patients.map((patient) => { const name = patient.name?.[0]; const fullName = [ ...(name?.prefix || []), ...(name?.given || []), name?.family, ] .filter(Boolean) .join(' '); const bsn = patient.identifier?.find( (id) => id.system === 'http://fhir.nl/fhir/NamingSystem/bsn' )?.value; // Get status from extension (we'll add this to the FHIR mapping) const statusExtension = patient.extension?.find( (ext) => ext.url === 'http://mini-epd.local/fhir/StructureDefinition/episode-status' ); const status = statusExtension?.valueCode; // Format updated_at date const updatedAt = patient.meta?.lastUpdated ? new Date(patient.meta.lastUpdated).toLocaleDateString('nl-NL', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit', }) : '-'; return ( router.push(`/epd/patients/${patient.id}`)} > ); })}
Naam BSN Geboortedatum Status Laatst gewijzigd
{name?.given?.[0]?.[0]} {name?.family?.[0]}
{fullName}
{bsn || '-'}
{patient.birthDate ? new Date(patient.birthDate).toLocaleDateString('nl-NL') : '-'}
{updatedAt}
); }