import { useEffect, useRef, useState } from "react"; import { Inbox } from "lucide-react"; import { useHttpService } from "../../../services/HttpService.tsx"; import { environment } from "../../../environments/environment.ts"; import { relayServerFailure } from "../../../utils/fetchFailureMessage"; import { Alert, AlertDescription } from "../../../components/ui/alert.tsx"; type Pending = { sender?: string; sentAt: string; expiresAt: string }; /** A failed read is tried again this often, this many times, while its error is shown. */ export const PENDING_RETRY_MS = 10_000; export const PENDING_RETRIES = 3; // Referrals another practice sent to this one before it joined. Who sent them and when is all the // server gives: the patient and reason arrive with the claim code, which the sender hands over. // Read again whenever `refreshKey` moves, since a claim takes a referral off this list. Only the newest // read for this practice (`scope`) may change what is shown, and nothing is read or retried once it is gone. const PendingBeforeJoining = ({ refreshKey = 0, scope }: { refreshKey?: number; scope?: string }) => { const { get } = useHttpService(); const [pending, setPending] = useState([]); const [error, setError] = useState(); const latest = useRef(0); const shownFor = useRef(scope); useEffect(() => { if (shownFor.current !== scope) { shownFor.current = scope; setPending([]); setError(undefined); } const ticket = ++latest.current; let retry: ReturnType | undefined; const read = (failures: number) => { get<{ pending?: Pending[] }>(`${environment.fhirBaseApi}/referral-pending-for-us`) .then((response) => { if (ticket !== latest.current) return; setPending(response?.pending ?? []); setError(undefined); }) .catch((err) => { if (ticket !== latest.current) return; setError(relayServerFailure(err, "Could not check for referrals sent before you joined.")); if (failures < PENDING_RETRIES) { retry = setTimeout(() => { if (ticket === latest.current) read(failures + 1); }, PENDING_RETRY_MS); } }); }; read(0); return () => { latest.current += 1; clearTimeout(retry); }; }, [get, refreshKey, scope]); if (error) { return ( {error} ); } if (pending.length === 0) return null; return ( ); }; export default PendingBeforeJoining;