import { useMemo } from 'react'; import { useNavigate } from 'react-router-dom'; import { Check, X } from 'lucide-react'; import { usePractitionerServiceContext } from '../../../../../services'; import { useFhirLocations } from '../../../../../hooks'; import { useServiceCatalogueBasis } from '../../../../../hooks/useServiceCatalogueBasis'; import { useFhirSchedules } from '../../../../../hooks/useFhirSchedules'; import { useStaffBookabilityContext } from '../../../../../hooks/useStaffBookabilityContext'; import { useStaffPermissionServiceContext } from '../../../../../services/StaffPermissionService'; import { formatFhirHumanName } from '../../../../../utils/fhirHumanName'; import { resolveProviderSetupChain } from '../../../../../utils/booking/providerSetupChain'; import BookabilityPanel from '../../../../../components/booking/BookabilityPanel'; // "What can patients actually book with this provider, and if not - why?" // // A reference point at the person's own profile, which is where someone goes when they ask the question. The // setup chain below is the part that has never existed per-provider: the onboarding hub has a version of it, // but only for the FIRST provider an org sets up. // // This is a REPORT, not an editor - every fix links back to the tab that owns that setting. // // MIRROR, NEVER A GATE - read-only throughout. const StaffPatientBookingPage = () => { const { practitionerState } = usePractitionerServiceContext(); const { canManage } = useStaffPermissionServiceContext(); const navigate = useNavigate(); const serviceBasis = useServiceCatalogueBasis(); const healthcareServicesList = serviceBasis.services; const { locationsList } = useFhirLocations(); const { schedulesList } = useFhirSchedules(); const practitionerId = practitionerState?.practitioner?.id; const bookabilityCtx = useStaffBookabilityContext({ practitioners: practitionerState ? [practitionerState] : [], serviceBasis, locationCount: locationsList?.length ?? 0, }); const chain = useMemo( () => (practitionerState ? resolveProviderSetupChain(practitionerState, schedulesList, bookabilityCtx) : []), [practitionerState, schedulesList, bookabilityCtx], ); const scopeInput = useMemo( () => ({ schedules: schedulesList, ctx: bookabilityCtx, practitionerNameById: new Map( practitionerId ? ([[ practitionerId, formatFhirHumanName(practitionerState?.practitioner?.name) || 'This provider', ]] as [string, string][]) : [], ), locationNameById: new Map( (locationsList ?? []) .filter((location) => location.id) .map((location) => [ location.id as string, location.name ?? (location.id as string), ] as [string, string]), ), orgCatalogSize: healthcareServicesList.length, }), [schedulesList, bookabilityCtx, practitionerId, practitionerState, locationsList, healthcareServicesList], ); if (!practitionerId) { return

Select a staff member to see their booking setup.

; } const firstUndone = chain.find((link) => !link.done); return (

Patient Booking

What patients can book with this provider through the portal, and what still needs setting up.

{serviceBasis.state !== 'complete' ? (
{serviceBasis.state === 'checking' ? 'Checking available services' : 'Available services could not be verified.'} {serviceBasis.state === 'unavailable' && }
) : (<> canManage(section)} defaultOpen />

What has to be true

{firstUndone ? `Next step: ${firstUndone.label.toLowerCase()}.` : 'Every step is done — patients can book this provider.'}

    {chain.map((link) => (
  • {link.done ? ( ) : ( )} {link.label} {link.done ? ' — done' : ' — not done yet'} {link.detail} {!link.done && link.id === 'servicesAssigned' && canManage('staff') && ( )} {!link.done && link.id === 'scheduleWithHours' && canManage('schedules') && ( )}
  • ))}
)}
); }; export default StaffPatientBookingPage;