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";
|
"use client";
|
||||||
import React, { useState, useEffect } from 'react';
|
import React from 'react';
|
||||||
import { Search, ChevronDown } from 'lucide-react';
|
import { Search } from 'lucide-react';
|
||||||
import { usePathname } from 'next/navigation';
|
|
||||||
import { getPatient } from '../patients/actions';
|
|
||||||
import type { FHIRPatient } from '@/lib/fhir';
|
|
||||||
|
|
||||||
interface EPDHeaderProps {
|
interface EPDHeaderProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function EPDHeader({ className = "" }: EPDHeaderProps) {
|
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 (
|
return (
|
||||||
<header className={`h-[60px] bg-white border-b border-slate-200 flex items-center px-6 ${className}`}>
|
<header className={`h-[60px] bg-white border-b border-slate-200 flex items-center px-6 ${className}`}>
|
||||||
{/* Left: Logo */}
|
{/* Left: Logo */}
|
||||||
@@ -51,28 +14,8 @@ export function EPDHeader({ className = "" }: EPDHeaderProps) {
|
|||||||
<span className="text-base font-medium text-slate-800">Mini-ECD</span>
|
<span className="text-base font-medium text-slate-800">Mini-ECD</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Center: Patient Selector (only in Level 2) */}
|
{/* Center: Empty space (patient info is shown in ClientHeader below) */}
|
||||||
<div className="flex-1 flex justify-center">
|
<div className="flex-1" />
|
||||||
{(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>
|
|
||||||
|
|
||||||
{/* Right: Search */}
|
{/* Right: Search */}
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
|
|||||||
@@ -25,3 +25,11 @@
|
|||||||
- Vereenvoudigd: patient detail layout gebruikt nu alleen PatientLayoutClient zonder eigen sidebar rendering
|
- 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
|
- 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