feat: implement client header and navigation (E2.S3)
Epic 2 - Cliëntenbeheer: Complete Level 2 navigation structure with context-aware header and sidebar for patient dossier. E2.S3 - Cliënt Header & Nav: - Create ClientHeader component showing: * Full patient name with prefix support * Color-coded status badge (screening/actief/afgerond/afgemeld) * Last modified timestamp (Dutch format) * John Doe indicator badge * Patient ID (subtle display) - Create ClientSidebar navigation component with: * Back button to patient list * Navigation items for all tabs (always visible) * Active state highlighting * Icon support for each tab - Create patient detail layout wrapper: * Combines header and sidebar * Full-height flex layout * Scrollable main content area - Update patient detail page to dashboard view: * Quick action cards for Basisgegevens, Screening, Intake * Next steps guide for workflow * Remove old edit-only view - Create Basisgegevens tab page: * Patient form for editing * John Doe warning for incomplete registrations * Pre-populated with existing data - Create placeholder pages for future epics: * Screening (Epic 3) * Intake (Epic 4) * Diagnose (Epic 6) * Behandelplan (future) * Rapportage (future) Technical implementation: - app/epd/patients/[id]/components/client-header.tsx: New - app/epd/patients/[id]/components/client-sidebar.tsx: New - app/epd/patients/[id]/layout.tsx: New - app/epd/patients/[id]/page.tsx: Completely rewritten as dashboard - app/epd/patients/[id]/basisgegevens/page.tsx: New - app/epd/patients/[id]/screening/page.tsx: New placeholder - app/epd/patients/[id]/intake/page.tsx: New placeholder - app/epd/patients/[id]/diagnose/page.tsx: New placeholder - app/epd/patients/[id]/behandelplan/page.tsx: New placeholder - app/epd/patients/[id]/rapportage/page.tsx: New placeholder - docs/specs/screening-intake/bouwplan-screening-intake-v1.0.md: Updated Epic 2 is now complete with all 3 stories implemented! 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
62
app/epd/patients/[id]/basisgegevens/page.tsx
Normal file
62
app/epd/patients/[id]/basisgegevens/page.tsx
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/**
|
||||||
|
* Basisgegevens Page
|
||||||
|
* E2.S3: Patient basic information with edit functionality
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { getPatient } from '../../actions';
|
||||||
|
import { PatientForm } from '../../components/patient-form';
|
||||||
|
import { AlertCircle } from 'lucide-react';
|
||||||
|
|
||||||
|
export default async function BasisgegevensPage({
|
||||||
|
params,
|
||||||
|
}: {
|
||||||
|
params: Promise<{ id: string }>;
|
||||||
|
}) {
|
||||||
|
const { id } = await params;
|
||||||
|
const patient = await getPatient(id);
|
||||||
|
|
||||||
|
// Check if John Doe
|
||||||
|
const isJohnDoe = (patient as any).extension?.find(
|
||||||
|
(ext: any) => ext.url === 'http://mini-epd.local/fhir/StructureDefinition/john-doe'
|
||||||
|
)?.valueBoolean;
|
||||||
|
|
||||||
|
// Check if BSN is missing or placeholder
|
||||||
|
const bsn = patient.identifier?.find(
|
||||||
|
(id) => id.system === 'http://fhir.nl/fhir/NamingSystem/bsn'
|
||||||
|
)?.value;
|
||||||
|
const hasMissingBSN = !bsn || bsn === '999999990';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="p-6">
|
||||||
|
{/* Page Header */}
|
||||||
|
<div className="mb-6">
|
||||||
|
<h2 className="text-lg font-semibold text-slate-900">Basisgegevens</h2>
|
||||||
|
<p className="text-sm text-slate-600 mt-1">
|
||||||
|
NAW-gegevens en contactinformatie
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* John Doe Warning */}
|
||||||
|
{isJohnDoe && hasMissingBSN && (
|
||||||
|
<div className="bg-orange-50 border border-orange-200 rounded-lg p-4 mb-6">
|
||||||
|
<div className="flex items-start gap-3">
|
||||||
|
<AlertCircle className="h-5 w-5 text-orange-600 flex-shrink-0 mt-0.5" />
|
||||||
|
<div>
|
||||||
|
<p className="text-sm font-medium text-orange-900">
|
||||||
|
Incomplete gegevens - John Doe registratie
|
||||||
|
</p>
|
||||||
|
<p className="text-xs text-orange-700 mt-1">
|
||||||
|
Vul BSN aan zodra deze beschikbaar is voor volledige registratie.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Patient Form */}
|
||||||
|
<div className="bg-white rounded-lg border border-slate-200 p-6">
|
||||||
|
<PatientForm patient={patient} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
40
app/epd/patients/[id]/behandelplan/page.tsx
Normal file
40
app/epd/patients/[id]/behandelplan/page.tsx
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* Behandelplan Page
|
||||||
|
* E2.S3: Placeholder for behandelplan functionality (future epic)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Calendar } from 'lucide-react';
|
||||||
|
|
||||||
|
export default async function BehandelplanPage({
|
||||||
|
params,
|
||||||
|
}: {
|
||||||
|
params: Promise<{ id: string }>;
|
||||||
|
}) {
|
||||||
|
const { id } = await params;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="p-6">
|
||||||
|
{/* Page Header */}
|
||||||
|
<div className="mb-6">
|
||||||
|
<h2 className="text-lg font-semibold text-slate-900">Behandelplan</h2>
|
||||||
|
<p className="text-sm text-slate-600 mt-1">
|
||||||
|
Behandeldoelen, interventies en planning
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Placeholder */}
|
||||||
|
<div className="bg-white rounded-lg border border-slate-200 p-12 text-center">
|
||||||
|
<div className="inline-flex items-center justify-center w-16 h-16 rounded-full bg-indigo-50 mb-4">
|
||||||
|
<Calendar className="h-8 w-8 text-indigo-500" />
|
||||||
|
</div>
|
||||||
|
<h3 className="text-lg font-semibold text-slate-900 mb-2">
|
||||||
|
Behandelplan Module - Coming Soon
|
||||||
|
</h3>
|
||||||
|
<p className="text-sm text-slate-600 max-w-md mx-auto">
|
||||||
|
De behandelplan functionaliteit wordt in een latere fase geïmplementeerd.
|
||||||
|
Dit omvat doelstellingen, interventies en planning van de behandeling.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
40
app/epd/patients/[id]/diagnose/page.tsx
Normal file
40
app/epd/patients/[id]/diagnose/page.tsx
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* Diagnose Page
|
||||||
|
* E2.S3: Placeholder for diagnose functionality (to be implemented in Epic 6)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Stethoscope } from 'lucide-react';
|
||||||
|
|
||||||
|
export default async function DiagnosePage({
|
||||||
|
params,
|
||||||
|
}: {
|
||||||
|
params: Promise<{ id: string }>;
|
||||||
|
}) {
|
||||||
|
const { id } = await params;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="p-6">
|
||||||
|
{/* Page Header */}
|
||||||
|
<div className="mb-6">
|
||||||
|
<h2 className="text-lg font-semibold text-slate-900">Diagnose</h2>
|
||||||
|
<p className="text-sm text-slate-600 mt-1">
|
||||||
|
DSM-5 diagnoses en behandeladvies
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Placeholder */}
|
||||||
|
<div className="bg-white rounded-lg border border-slate-200 p-12 text-center">
|
||||||
|
<div className="inline-flex items-center justify-center w-16 h-16 rounded-full bg-purple-50 mb-4">
|
||||||
|
<Stethoscope className="h-8 w-8 text-purple-500" />
|
||||||
|
</div>
|
||||||
|
<h3 className="text-lg font-semibold text-slate-900 mb-2">
|
||||||
|
Diagnose Module - Coming Soon
|
||||||
|
</h3>
|
||||||
|
<p className="text-sm text-slate-600 max-w-md mx-auto">
|
||||||
|
De diagnose functionaliteit wordt geïmplementeerd in Epic 6. Dit omvat
|
||||||
|
DSM-5 diagnose registratie en behandeladvies formulering.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
41
app/epd/patients/[id]/intake/page.tsx
Normal file
41
app/epd/patients/[id]/intake/page.tsx
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/**
|
||||||
|
* Intake Page
|
||||||
|
* E2.S3: Placeholder for intake functionality (to be implemented in Epic 4)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { FileText } from 'lucide-react';
|
||||||
|
|
||||||
|
export default async function IntakePage({
|
||||||
|
params,
|
||||||
|
}: {
|
||||||
|
params: Promise<{ id: string }>;
|
||||||
|
}) {
|
||||||
|
const { id } = await params;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="p-6">
|
||||||
|
{/* Page Header */}
|
||||||
|
<div className="mb-6">
|
||||||
|
<h2 className="text-lg font-semibold text-slate-900">Intake</h2>
|
||||||
|
<p className="text-sm text-slate-600 mt-1">
|
||||||
|
Overzicht van intakes en intake details
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Placeholder */}
|
||||||
|
<div className="bg-white rounded-lg border border-slate-200 p-12 text-center">
|
||||||
|
<div className="inline-flex items-center justify-center w-16 h-16 rounded-full bg-teal-50 mb-4">
|
||||||
|
<FileText className="h-8 w-8 text-teal-500" />
|
||||||
|
</div>
|
||||||
|
<h3 className="text-lg font-semibold text-slate-900 mb-2">
|
||||||
|
Intake Module - Coming Soon
|
||||||
|
</h3>
|
||||||
|
<p className="text-sm text-slate-600 max-w-md mx-auto">
|
||||||
|
De intake functionaliteit wordt geïmplementeerd in Epic 4 en 5. Dit omvat
|
||||||
|
intake overzicht, contactmomenten, kindcheck, risicotaxatie, anamnese,
|
||||||
|
onderzoek en ROM-metingen.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
40
app/epd/patients/[id]/rapportage/page.tsx
Normal file
40
app/epd/patients/[id]/rapportage/page.tsx
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* Rapportage Page
|
||||||
|
* E2.S3: Placeholder for rapportage functionality (future epic)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { FileBarChart } from 'lucide-react';
|
||||||
|
|
||||||
|
export default async function RapportagePage({
|
||||||
|
params,
|
||||||
|
}: {
|
||||||
|
params: Promise<{ id: string }>;
|
||||||
|
}) {
|
||||||
|
const { id } = await params;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="p-6">
|
||||||
|
{/* Page Header */}
|
||||||
|
<div className="mb-6">
|
||||||
|
<h2 className="text-lg font-semibold text-slate-900">Rapportage</h2>
|
||||||
|
<p className="text-sm text-slate-600 mt-1">
|
||||||
|
Overzichten, statistieken en export mogelijkheden
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Placeholder */}
|
||||||
|
<div className="bg-white rounded-lg border border-slate-200 p-12 text-center">
|
||||||
|
<div className="inline-flex items-center justify-center w-16 h-16 rounded-full bg-slate-50 mb-4">
|
||||||
|
<FileBarChart className="h-8 w-8 text-slate-500" />
|
||||||
|
</div>
|
||||||
|
<h3 className="text-lg font-semibold text-slate-900 mb-2">
|
||||||
|
Rapportage Module - Coming Soon
|
||||||
|
</h3>
|
||||||
|
<p className="text-sm text-slate-600 max-w-md mx-auto">
|
||||||
|
De rapportage functionaliteit wordt in een latere fase geïmplementeerd.
|
||||||
|
Dit omvat overzichten, statistieken en exportfunctionaliteit.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
40
app/epd/patients/[id]/screening/page.tsx
Normal file
40
app/epd/patients/[id]/screening/page.tsx
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* Screening Page
|
||||||
|
* E2.S3: Placeholder for screening functionality (to be implemented in Epic 3)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ClipboardList } from 'lucide-react';
|
||||||
|
|
||||||
|
export default async function ScreeningPage({
|
||||||
|
params,
|
||||||
|
}: {
|
||||||
|
params: Promise<{ id: string }>;
|
||||||
|
}) {
|
||||||
|
const { id } = await params;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="p-6">
|
||||||
|
{/* Page Header */}
|
||||||
|
<div className="mb-6">
|
||||||
|
<h2 className="text-lg font-semibold text-slate-900">Screening</h2>
|
||||||
|
<p className="text-sm text-slate-600 mt-1">
|
||||||
|
Activiteitenlog, documenten, hulpvraag en screeningsbesluit
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Placeholder */}
|
||||||
|
<div className="bg-white rounded-lg border border-slate-200 p-12 text-center">
|
||||||
|
<div className="inline-flex items-center justify-center w-16 h-16 rounded-full bg-amber-50 mb-4">
|
||||||
|
<ClipboardList className="h-8 w-8 text-amber-500" />
|
||||||
|
</div>
|
||||||
|
<h3 className="text-lg font-semibold text-slate-900 mb-2">
|
||||||
|
Screening Module - Coming Soon
|
||||||
|
</h3>
|
||||||
|
<p className="text-sm text-slate-600 max-w-md mx-auto">
|
||||||
|
De screening functionaliteit wordt geïmplementeerd in Epic 3. Dit omvat
|
||||||
|
activiteitenlog, documentbeheer, hulpvraag registratie en screeningsbesluit.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
| Epic ID | Titel | Doel | Status | Stories |
|
| Epic ID | Titel | Doel | Status | Stories |
|
||||||
|---------|-------|------|--------|---------|
|
|---------|-------|------|--------|---------|
|
||||||
| E1 | Database & Types | Datamodel implementeren in Supabase | ✅ Done | 3 |
|
| E1 | Database & Types | Datamodel implementeren in Supabase | ✅ Done | 3 |
|
||||||
| E2 | Cliëntenbeheer | Lijstweergave en aanmaken cliënten | 🔨 In Progress | 3 |
|
| E2 | Cliëntenbeheer | Lijstweergave en aanmaken cliënten | ✅ Done | 3 |
|
||||||
| E3 | Screening Module | Screening tab en functionaliteit | ⏳ To Do | 4 |
|
| E3 | Screening Module | Screening tab en functionaliteit | ⏳ To Do | 4 |
|
||||||
| E4 | Intake Core | Intake overzicht en navigatie | ✅ Done | 3 |
|
| E4 | Intake Core | Intake overzicht en navigatie | ✅ Done | 3 |
|
||||||
| E5 | Intake Details | Specifieke tabbladen (Contact, Risico, etc.) | ⏳ To Do | 5 |
|
| E5 | Intake Details | Specifieke tabbladen (Contact, Risico, etc.) | ⏳ To Do | 5 |
|
||||||
@@ -62,15 +62,15 @@
|
|||||||
| E1.S2 | ✅ Done | Migration toepassen | Migration succesvol toegepast op Supabase database met:<br>- Foreign keys en constraints<br>- RLS policies voor alle nieuwe tabellen<br>- Indexes voor performance<br>- Triggers voor `updated_at` timestamps |
|
| E1.S2 | ✅ Done | Migration toepassen | Migration succesvol toegepast op Supabase database met:<br>- Foreign keys en constraints<br>- RLS policies voor alle nieuwe tabellen<br>- Indexes voor performance<br>- Triggers voor `updated_at` timestamps |
|
||||||
| E1.S3 | ✅ Done | TypeScript Types genereren | Types gegenereerd met `supabase gen types` en geëxporteerd naar `lib/supabase/database.types.ts`<br>- 2148+ regels TypeScript types<br>- Alle nieuwe tabellen en enums geëxporteerd |
|
| E1.S3 | ✅ Done | TypeScript Types genereren | Types gegenereerd met `supabase gen types` en geëxporteerd naar `lib/supabase/database.types.ts`<br>- 2148+ regels TypeScript types<br>- Alle nieuwe tabellen en enums geëxporteerd |
|
||||||
|
|
||||||
### Epic 2 — Cliëntenbeheer (Level 1) 🔨
|
### Epic 2 — Cliëntenbeheer (Level 1) ✅
|
||||||
**Doel:** Behandelaars kunnen cliënten vinden en nieuwe cliënten aanmaken.
|
**Doel:** Behandelaars kunnen cliënten vinden en nieuwe cliënten aanmaken.
|
||||||
**Status:** In Progress - 2 van 3 stories voltooid op 22-11-2025
|
**Status:** Done - Alle stories voltooid op 22-11-2025
|
||||||
|
|
||||||
| Story ID | Status | Beschrijving | Acceptatiecriteria |
|
| Story ID | Status | Beschrijving | Acceptatiecriteria |
|
||||||
|----------|--------|--------------|---------------------|
|
|----------|--------|--------------|---------------------|
|
||||||
| E2.S1 | ✅ Done | Cliëntenlijst | Tabel met zoekfunctie, filters en status badges:<br>- `patient-list.tsx` geüpdatet met client-side search bar<br>- Status filter dropdown (alle/screening/actief/afgerond/afgemeld)<br>- StatusBadge component met color-coded badges<br>- Tabel kolommen: Status, Naam, BSN, Laatst gewijzigd<br>- API route `/api/fhir/Patient` ondersteunt status filtering<br>- FHIR transform aangepast voor status extension |
|
| E2.S1 | ✅ Done | Cliëntenlijst | Tabel met zoekfunctie, filters en status badges:<br>- `patient-list.tsx` geüpdatet met client-side search bar<br>- Status filter dropdown (alle/screening/actief/afgerond/afgemeld)<br>- StatusBadge component met color-coded badges<br>- Tabel kolommen: Status, Naam, BSN, Laatst gewijzigd<br>- API route `/api/fhir/Patient` ondersteunt status filtering<br>- FHIR transform aangepast voor status extension |
|
||||||
| E2.S2 | ✅ Done | Nieuwe Cliënt Flow | Formulier voor aanmaken cliënt met John Doe logica:<br>- `patient-form.tsx` compleet herschreven met alle FO velden<br>- John Doe checkbox met conditional BSN requirement<br>- BSN validatie met Modulo-11 check<br>- Alle velden: naam, BSN, geboortedatum, geslacht, adres (straat, postcode, plaats), contact (telefoon, email), verzekering (verzekeraar, polisnummer)<br>- Warning messages voor John Doe patiënten<br>- Status altijd 'planned' voor nieuwe patiënten<br>- Redirect naar patient detail page na aanmaken<br>- FHIR transform ondersteunt insurance extension (bidirectioneel) |
|
| E2.S2 | ✅ Done | Nieuwe Cliënt Flow | Formulier voor aanmaken cliënt met John Doe logica:<br>- `patient-form.tsx` compleet herschreven met alle FO velden<br>- John Doe checkbox met conditional BSN requirement<br>- BSN validatie met Modulo-11 check<br>- Alle velden: naam, BSN, geboortedatum, geslacht, adres (straat, postcode, plaats), contact (telefoon, email), verzekering (verzekeraar, polisnummer)<br>- Warning messages voor John Doe patiënten<br>- Status altijd 'planned' voor nieuwe patiënten<br>- Redirect naar patient detail page na aanmaken<br>- FHIR transform ondersteunt insurance extension (bidirectioneel) |
|
||||||
| E2.S3 | ⏳ To Do | Cliënt Header & Nav | Context-aware header en sidebar navigatie (Level 2). |
|
| E2.S3 | ✅ Done | Cliënt Header & Nav | Context-aware header en sidebar navigatie (Level 2):<br>- `ClientHeader` component met naam, status badge, laatst gewijzigd en John Doe indicator<br>- `ClientSidebar` component met navigatie naar alle tabs<br>- Patient detail layout met header en sidebar<br>- Dashboard pagina met quick actions en volgende stappen<br>- Basisgegevens pagina met patient form en John Doe warning<br>- Placeholder paginas voor alle tabs: Screening, Intake, Diagnose, Behandelplan, Rapportage<br>- Alle tabs altijd zichtbaar, ongeacht status |
|
||||||
|
|
||||||
### Epic 3 — Screening Module (Level 2)
|
### Epic 3 — Screening Module (Level 2)
|
||||||
**Doel:** Faciliteren van het screeningsproces.
|
**Doel:** Faciliteren van het screeningsproces.
|
||||||
|
|||||||
Reference in New Issue
Block a user