import { useEffect, useRef, useState } from 'react'; import type { Patient } from 'fhir/r4'; import { usePatientServiceContext } from '../../../services/PatientService'; import { useActiveEncounterContext } from './ActiveEncounterContext'; import { formatFhirHumanName } from '../../../utils/fhirHumanName'; /** * sub-task 5a - the ACTIVE encounter's patient, hoisted out of `FloatingEncounterNotes` so a * later consumer (the meeting-window notes panel) INHERITS the render-time identity gate rather than * re-deriving the cross-patient write bug sub-task 3's review found. * * `enabled` matters: this hook is mounted app-wide by consumers that may never be visible, so without * the gate every encounter switch fires a patient fetch even for practitioners who never open the pane. */ export const useActiveEncounterPatient = (enabled: boolean) => { const { active } = useActiveEncounterContext(); const { fetchPatient } = usePatientServiceContext(); const [patient, setPatient] = useState(); const token = useRef(0); const patientId = active?.item.patientId; useEffect(() => { const mine = ++token.current; // Skip entirely while no consumer is showing - this is mounted app-wide, so without the gate // every encounter switch fetches a patient for practitioners who never open the pane. if (!patientId || !enabled) { setPatient(undefined); return; } void fetchPatient(patientId) .then((p) => { if (mine === token.current) setPatient(p); }) .catch(() => { if (mine === token.current) setPatient(undefined); }); }, [patientId, enabled, fetchPatient]); // RENDER-TIME identity gate, not an effect. `patient` always lags `active` by at least one // commit, and pairing a stale patient with the new encounter is a wrong-name title AND a // wrong-subject clinical write. An effect cannot fix it - the first committed frame is already wrong. const current = patient?.id === patientId ? patient : undefined; const resolved = current ? formatFhirHumanName(current.name) : undefined; const name = resolved || active?.item.patientName || 'this patient'; return { patient: current, name }; };