import { useMemo } from "react"; import { Appointment } from "fhir/r4"; import { CalendarCheck2, CalendarDays, Clock4, HousePlus } from "lucide-react"; import { useAuthServiceContext } from "../../../services"; import { useFhirAppointments } from "../../../hooks"; import { categorizePatientAppointments } from "../../../utils/patientAppointmentCategorization"; import { cancellationExplanation } from "../../../utils/appointmentCancellation"; import { Skeleton } from "../../../components/ui/skeleton"; import { formatDateForDisplay, formatTimeForDisplay, getDaysDifference, } from "../../../lib/utils"; import { getAppointmentPractitionerName, getAppointmentSpecialty, } from "./WorkspaceAppointmentDetail.tsx"; const startMs = (appointment: Appointment) => appointment.start ? new Date(appointment.start).getTime() : 0; // Cancelled visits are history at the desk: never upcoming, newest first, with the recorded reason. const cancelledHistory = (appointments: Appointment[]) => appointments .filter((appointment) => appointment.status === "cancelled") .sort((a, b) => startMs(b) - startMs(a)); // Read-only appointments list for the receptionist workspace modal. Reuses the patient's appointments from context // (useFhirAppointments) + categorization, but renders plain clickable rows that drill IN PLACE (onOpenAppointment) // instead of the patient-portal's per-card Sheet/Dialog stack - which broke nested inside the workspace Dialog. export default function WorkspaceAppointments({ onOpenAppointment, }: { onOpenAppointment: (appointment: Appointment) => void; }) { const { wpOrganization } = useAuthServiceContext(); const { loading, error, answered, listIsThisPatients, appointmentsList } = useFhirAppointments(); const { upcoming, past } = useMemo( () => categorizePatientAppointments(appointmentsList), [appointmentsList], ); const cancelled = useMemo( () => cancelledHistory(appointmentsList ?? []), [appointmentsList], ); if (error) { return (
Could not load appointments. Try again later.
); } if (loading || !answered || !listIsThisPatients) { return (
{[...Array(3)].map((_, index) => ( ))}
); } if (upcoming.length === 0 && past.length === 0 && cancelled.length === 0) { return (
No appointments on file for this patient.
); } const renderRow = (appointment: Appointment) => ( ); const renderCancelledRow = (appointment: Appointment) => (
{renderRow(appointment)}

{cancellationExplanation(appointment)}

); return (

Upcoming

{upcoming.length ? (
{upcoming.map(renderRow)}
) : (

No upcoming appointments.

)}

Past

{past.length ? (
{past.map(renderRow)}
) : (

No past appointments.

)}
{cancelled.length > 0 && (

Cancelled

{cancelled.map(renderCancelledRow)}
)}
); }