fix: remove duplicate patient name from EPDHeader
Bug fix: Dubbele patient naam verwijderd (EPDHeader + ClientHeader). Design conflict ontstaan tijdens parallel development: - Epic 1: EPDHeader kreeg patient selector (naam, ID, geb.datum) - Epic 2: ClientHeader toegevoegd met volledige patient context - Resultaat: Patient naam werd twee keer getoond Changes: - Removed: Patient selector UI from EPDHeader center section - Removed: Patient fetch logic (useState, useEffect) - Removed: Unused imports (ChevronDown, usePathname, getPatient) - Simplified: EPDHeader from 91 to 34 lines (-57 lines) Component ownership clarified: - EPDHeader = General navigation (logo, search) - ClientHeader = Patient context (name, status, actions) Result: Clean separation of concerns, no duplicate patient info 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,49 +1,12 @@
|
||||
"use client";
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Search, ChevronDown } from 'lucide-react';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { getPatient } from '../patients/actions';
|
||||
import type { FHIRPatient } from '@/lib/fhir';
|
||||
import React from 'react';
|
||||
import { Search } from 'lucide-react';
|
||||
|
||||
interface EPDHeaderProps {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function EPDHeader({ className = "" }: EPDHeaderProps) {
|
||||
const pathname = usePathname();
|
||||
const [selectedPatient, setSelectedPatient] = useState<FHIRPatient | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
// Context detection: Level 2 if URL contains /patients/[id]
|
||||
const isPatientContext = pathname.match(/\/epd\/patients\/[^\/]+/);
|
||||
const patientId = isPatientContext ? pathname.split('/')[3] : null;
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchPatient() {
|
||||
if (!patientId) {
|
||||
setSelectedPatient(null);
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't re-fetch if we already have the correct patient
|
||||
if (selectedPatient?.id === patientId) return;
|
||||
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const patient = await getPatient(patientId);
|
||||
if (patient) {
|
||||
setSelectedPatient(patient);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch patient for header:', error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
fetchPatient();
|
||||
}, [patientId, selectedPatient?.id]);
|
||||
|
||||
return (
|
||||
<header className={`h-[60px] bg-white border-b border-slate-200 flex items-center px-6 ${className}`}>
|
||||
{/* Left: Logo */}
|
||||
@@ -51,28 +14,8 @@ export function EPDHeader({ className = "" }: EPDHeaderProps) {
|
||||
<span className="text-base font-medium text-slate-800">Mini-ECD</span>
|
||||
</div>
|
||||
|
||||
{/* Center: Patient Selector (only in Level 2) */}
|
||||
<div className="flex-1 flex justify-center">
|
||||
{(selectedPatient || isLoading) && patientId && (
|
||||
<button className="flex flex-col items-center px-4 py-1 hover:bg-slate-50 rounded-md transition-colors group">
|
||||
{isLoading ? (
|
||||
<div className="h-8 w-32 bg-slate-100 animate-pulse rounded" />
|
||||
) : selectedPatient ? (
|
||||
<>
|
||||
<div className="flex items-center gap-1.5">
|
||||
<span className="text-sm font-medium text-slate-900">
|
||||
{selectedPatient.name?.[0]?.given?.join(' ') || ''} {selectedPatient.name?.[0]?.family || ''}
|
||||
</span>
|
||||
<ChevronDown className="h-4 w-4 text-slate-400 group-hover:text-slate-600 transition-colors" />
|
||||
</div>
|
||||
<span className="text-xs text-slate-500">
|
||||
ID: {selectedPatient.id?.substring(0, 8) || ''}... | Geb: {selectedPatient.birthDate ? new Date(selectedPatient.birthDate).toLocaleDateString('nl-NL') : ''}
|
||||
</span>
|
||||
</>
|
||||
) : null}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
{/* Center: Empty space (patient info is shown in ClientHeader below) */}
|
||||
<div className="flex-1" />
|
||||
|
||||
{/* Right: Search */}
|
||||
<div className="flex items-center">
|
||||
|
||||
@@ -25,3 +25,11 @@
|
||||
- Vereenvoudigd: patient detail layout gebruikt nu alleen PatientLayoutClient zonder eigen sidebar rendering
|
||||
- Resultaat: Eén sidebar component die automatisch switcht, -117 regels duplicate code, DRY principle hersteld
|
||||
|
||||
## 2025-11-23 — EPDHeader patient selector cleanup (Colin)
|
||||
- **Bug fix**: Dubbele patient naam in UI (EPDHeader top bar + ClientHeader) verwijderd
|
||||
- Design conflict ontstaan tijdens parallel development: EPDHeader (Epic 1) en ClientHeader (Epic 2) toonden beide patient naam
|
||||
- EPDHeader's patient selector (center section met naam, ID, geboortedatum) was redundant na toevoegen ClientHeader
|
||||
- Verwijderd: Patient fetch logic (useState, useEffect), patient selector UI, onnodige imports uit EPDHeader
|
||||
- Component ownership verduidelijkt: EPDHeader = algemene navigatie (logo, search), ClientHeader = patient context (naam, status, acties)
|
||||
- Resultaat: EPDHeader vereenvoudigd van 91 naar 34 regels (-57 regels), duidelijke separation of concerns
|
||||
|
||||
|
||||
Reference in New Issue
Block a user