import { useCallback, useEffect, useRef, useState } from "react"; import { useLocation, useNavigate } from "react-router-dom"; import type { Patient } from "fhir/r4"; import { Plus, Search, UserPlus } from "lucide-react"; import { FRONT_DESK_HOME, FRONT_DESK_APPOINTMENTS, type FrontDeskActionGrants } from "./frontDeskHeaderAction"; import ReceptionistPatientSearchDialog from "../../pages/DashboardPage/ReceptionistHomePage/ReceptionistPatientSearchDialog.tsx"; import ReceptionistRegisterPatientDialog from "../../pages/DashboardPage/ReceptionistHomePage/ReceptionistRegisterPatientDialog.tsx"; import FrontDeskPatientQuickView from "../../pages/DashboardPage/ReceptionistHomePage/FrontDeskPatientQuickView.tsx"; type QuickView = { patientId: string; known?: Patient; fromSearch: boolean }; // Search and Register open over the current page; Book opens on the overview, which owns the board, or over Appointments. // Each action shows only when the caller is granted it; Book opens over Appointments outside the front desk. export const FrontDeskHeaderActions = ({ grants, frontDesk }: { grants: FrontDeskActionGrants; frontDesk: boolean }) => { const navigate = useNavigate(); const { pathname } = useLocation(); const [searchOpen, setSearchOpen] = useState(false); // A new key starts the search over; choosing a patient keeps it for Back. const [searchRun, setSearchRun] = useState(0); const [registerOpen, setRegisterOpen] = useState(false); const [quickView, setQuickView] = useState(); const here = useRef(pathname); here.current = pathname; // Where Register was opened, so a registration that answers after the desk has moved on opens nothing. const registerOpenedOn = useRef(); // A patient detail belongs to the page it opened over; going elsewhere shows that page, not the old detail. useEffect(() => { setQuickView(undefined); }, [pathname]); const openSearch = useCallback(() => { setQuickView(undefined); setSearchRun((run) => run + 1); setSearchOpen(true); }, []); // `/` opens search from anywhere, but never while the receptionist is typing. useEffect(() => { if (!grants.search) return undefined; const onKeyDown = (event: KeyboardEvent) => { if (event.key !== "/" || event.ctrlKey || event.metaKey || event.altKey) return; const target = event.target as HTMLElement | null; const tag = target?.tagName; if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT" || target?.isContentEditable) return; event.preventDefault(); openSearch(); }; window.addEventListener("keydown", onKeyDown); return () => window.removeEventListener("keydown", onKeyDown); }, [openSearch, grants.search]); return (
{/* A button shaped like a field: the matching lives in the search dialog. */} {grants.search && ( )} {grants.book && ( )} {grants.register && ( )} { setSearchOpen(false); setQuickView({ patientId, fromSearch: true }); }} /> { setRegisterOpen(false); if (patient.id && registerOpenedOn.current === here.current) { setQuickView({ patientId: patient.id, known: patient, fromSearch: false }); } }} /> {quickView && ( setQuickView(undefined)} onBack={quickView.fromSearch ? () => { setQuickView(undefined); setSearchOpen(true); } : undefined} backLabel={quickView.fromSearch ? "Back to search" : undefined} /> )}
); }; export default FrontDeskHeaderActions;