import { useCallback, useEffect, useState } from "react"; import { useReferralWorkbenchService } from "../services/ReferralWorkbenchService"; import { patientReferrals, type PatientReferral } from "../utils/patientReferrals"; /** * The patient's referrals, read from their orders. Off unless `enabled`: staff work referrals from * the coordinator's Task instead. * * A booked mark is applied locally from the write's answer, because the search index lags a write by * minutes and a re-search would show the referral still open. */ export const usePatientReferrals = (patientId: string | undefined, enabled: boolean) => { const { listPatientReferrals, markReferralBooked, declineReferralInvite } = useReferralWorkbenchService(); const [referrals, setReferrals] = useState([]); // Which patient the list answers for, and which one it failed for: an empty list alone cannot say. const [answeredFor, setAnsweredFor] = useState(); const [failedFor, setFailedFor] = useState(); useEffect(() => { if (!enabled || !patientId) { setReferrals([]); return; } let current = true; listPatientReferrals(patientId) .then((bundle) => { if (!current) return; setReferrals(patientReferrals(bundle)); setAnsweredFor(patientId); setFailedFor(undefined); }) .catch(() => { if (current) setFailedFor(patientId); // The task list still stands without them; the failure is not the patient's to act on. }); return () => { current = false; }; }, [enabled, patientId, listPatientReferrals]); const markBooked = useCallback(async (referralId: string) => { const { patientBookedAt } = await markReferralBooked(referralId); setReferrals((all) => all.map((referral) => ( referral.id === referralId ? { ...referral, stage: "booked", bookedByPatientAt: patientBookedAt } : referral ))); }, [markReferralBooked]); const declineInvite = useCallback(async (referralId: string) => { const { inviteDeclinedAt } = await declineReferralInvite(referralId); setReferrals((all) => all.map((referral) => ( referral.id === referralId ? { ...referral, inviteDeclinedAt } : referral ))); }, [declineReferralInvite]); return { referrals, markBooked, declineInvite, answered: Boolean(patientId) && answeredFor === patientId, failed: Boolean(patientId) && failedFor === patientId, }; }; export default usePatientReferrals;