import type { ReactNode } from "react"; import type { PractitionerRole } from "fhir/r4"; import { useNavigate, useParams } from "react-router-dom"; import { useAuthServiceContext } from "../../../../services/AuthService.tsx"; import { getPractitionerRoleWorkspaces, STAFF_WORKSPACES } from "../../../../utils/staffRoleCatalog"; import AppSpinner from "../../../../components/AppSpinner/AppSpinner.tsx"; import FrontDeskPatientQuickView from "../../ReceptionistHomePage/FrontDeskPatientQuickView.tsx"; /** * The server's own test (`isDeskOnlyCaller`): the front desk and no clinical role, at THIS practice. A clinical * role elsewhere opens nothing here; a clinician also working the desk here is still a clinician. */ export const isDeskOnlyAt = ( roles: readonly PractitionerRole[], organizationId: string, groupOf: (role: PractitionerRole) => string | undefined, ): boolean => { const here = roles .filter((role) => role.active !== false && role.organization?.reference === `Organization/${organizationId}`) .flatMap((role) => getPractitionerRoleWorkspaces(role, groupOf(role))); return here.includes(STAFF_WORKSPACES.RECEPTIONIST) && !here.includes(STAFF_WORKSPACES.PRACTITIONER); }; /** * A chart address typed or bookmarked by a desk-only caller shows the desk's patient view, not the clinical chart * (whose reads the server refuses them, and whose Order they may not use). The list already opens that view for * them; this is the same for the address. Waits for the practice, so no clinical read starts before it is known. */ export const DeskChartGate = ({ children }: { children: ReactNode }) => { const { currentUser, currentOrganization, practitionerRoles, getCognitoGroup } = useAuthServiceContext(); const { id } = useParams(); const navigate = useNavigate(); if (currentUser?.fhir?.resourceType !== "Practitioner") return <>{children}; if (!currentOrganization?.id) return ; if (id && isDeskOnlyAt(practitionerRoles ?? [], currentOrganization.id, getCognitoGroup)) { return navigate("/dashboard/patients")} />; } return <>{children}; };