Files
triqura-ecd/app/epd/patients/page.tsx
colinislit 86995a4466 feat: implement patient list and new patient form (E2.S1 & E2.S2)
Epic 2 - Cliëntenbeheer: Complete implementation of patient list with
search/filter functionality and comprehensive new patient form with
John Doe crisis admission support.

E2.S1 - Cliëntenlijst:
- Add client-side search bar with form submission
- Implement status filter dropdown (all/screening/active/finished/cancelled)
- Create StatusBadge component with color-coded status indicators
- Update table columns: Status, Name, BSN, Last Updated
- Add status filtering support to FHIR Patient API route
- Update FHIR patient transform to include episode-status extension
- Sort patients by updated_at descending (newest first)

E2.S2 - Nieuwe Cliënt Flow:
- Complete rewrite of patient form with all FO-required fields
- Implement John Doe checkbox with conditional BSN requirement
- Add BSN validation with Dutch Modulo-11 check algorithm
- Add comprehensive form fields:
  * Name fields: prefix, given name, family name
  * BSN with 9-digit pattern validation
  * Birth date with max date validation
  * Gender selection
  * Address: street, postal code, city
  * Contact: phone, email
  * Insurance: company, policy number
- Add warning messages for John Doe crisis admissions
- Set default episode status to 'planned' for all new patients
- Redirect to patient detail page after successful creation
- Update FHIR transform bidirectional insurance extension support:
  * dbPatientToFHIR: serialize insurance to JSON extension
  * fhirPatientToDB: parse insurance from JSON extension
- Pre-populate form fields when editing existing patients

Technical changes:
- app/api/fhir/Patient/route.ts: Add status query param and sorting
- app/epd/patients/actions.ts: Add status filter parameter
- app/epd/patients/page.tsx: Pass status searchParam
- app/epd/patients/components/patient-list.tsx: Complete UI rewrite
- app/epd/patients/components/patient-form.tsx: Complete form rewrite
- lib/fhir/transforms/patient.ts: Add insurance extension handling
- docs/specs/screening-intake/bouwplan-screening-intake-v1.0.md: Update status

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-22 13:58:31 +01:00

55 lines
1.7 KiB
TypeScript

import { Suspense } from 'react';
import { Plus } from 'lucide-react';
import { getPatients } from './actions';
import { PatientList } from './components/patient-list';
import Link from 'next/link';
interface SearchParams {
search?: string;
status?: string;
}
export default async function PatientsPage({
searchParams,
}: {
searchParams: Promise<SearchParams>;
}) {
const params = await searchParams;
return (
<div className="px-4 sm:px-6 lg:px-8 py-8">
{/* Page Header */}
<div className="mb-8">
<div className="flex items-center justify-between">
<div>
<h1 className="text-2xl font-bold text-slate-900">Patiënten</h1>
<p className="text-sm text-slate-600 mt-1">
Overzicht van alle patiënten met screening en intake status
</p>
</div>
<Link
href="/epd/patients/new"
className="inline-flex items-center gap-2 px-4 py-2 bg-gradient-to-r from-teal-600 to-teal-700 hover:from-teal-700 hover:to-teal-800 text-white font-medium rounded-lg shadow-sm hover:shadow-md transition-all"
>
<Plus className="h-4 w-4" />
<span>Nieuwe patiënt</span>
</Link>
</div>
</div>
{/* Patient List */}
<Suspense fallback={<div>Loading patients...</div>}>
<PatientListWrapper searchParams={params} />
</Suspense>
</div>
);
}
async function PatientListWrapper({ searchParams }: { searchParams: SearchParams }) {
const patients = await getPatients({
search: searchParams.search,
status: searchParams.status,
});
return <PatientList initialPatients={patients} />;
}