import { useEffect, useMemo, useState } from "react"; import type { PractitionerRole } from "fhir/r4"; import { usePractitionerServiceContext, type PractitionerWithRoles } from "../services"; // The door's staff list covers only the door's practice. Every other practice's people are read under // that practice's own organization, then merged with the door's list; someone at two practices keeps the // roles from both, because roles are what place a person in a practice. export const usePracticeStaff = ( organizationIds: string[], doorOrganizationId: string | undefined, doorStaff: PractitionerWithRoles[], ): PractitionerWithRoles[] => { const { fetchPractitioners } = usePractitionerServiceContext(); const [byOrganization, setByOrganization] = useState>({}); const key = organizationIds.filter((id) => id && id !== doorOrganizationId).sort().join(","); useEffect(() => { let active = true; setByOrganization({}); for (const id of key ? key.split(",") : []) { fetchPractitioners(id) .then((bundle) => { if (active) setByOrganization((current) => ({ ...current, [id]: (bundle.entry ?? []).flatMap((entry) => (entry.resource ? [entry.resource] : [])) })); }) .catch((err) => console.error(`Error loading the people at practice ${id}:`, err)); } return () => { active = false; }; }, [key, fetchPractitioners]); return useMemo(() => { const merged = new Map(); for (const person of [doorStaff, ...Object.values(byOrganization)].flat()) { const id = person.practitioner.id; if (!id) continue; const known = merged.get(id); if (!known) { merged.set(id, person); continue; } const roleKey = (role: PractitionerRole) => role.id ?? JSON.stringify(role); const seen = new Set(known.roles.map(roleKey)); merged.set(id, { ...known, roles: [...known.roles, ...person.roles.filter((role) => !seen.has(roleKey(role)))] }); } return [...merged.values()]; }, [doorStaff, byOrganization]); };