import dayjs from 'dayjs'; import useSWR, { mutate } from 'swr'; import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework'; import { type AppointmentsFetchResponse } from '../types'; import isToday from 'dayjs/plugin/isToday'; dayjs.extend(isToday); const appointmentsSearchUrl = `${restBaseUrl}/appointments/search`; export function usePatientAppointments(patientUuid: string) { const url = `${restBaseUrl}/mohappointment/appointment?patient=${patientUuid}`; const { data, error, isLoading, mutate: mutatePatientAppointments, } = useSWR(url, (url) => openmrsFetch(url).then((res) => res.data), { revalidateOnFocus: true, revalidateOnReconnect: true, dedupingInterval: 5000, }); // Map the backend response to the Appointment type expected by your table const appointments = data?.results?.map((item) => ({ uuid: String(item.appointmentId), startDateTime: item.appointmentDate, comments: item.reason || item.note || '', reason: item.reason || '', note: item.note || '', service: item.service, location: { ...item.location, display: item.location?.display || item.location?.name || '', }, provider: item.provider, patient: item.patient, appointmentKind: item.appointmentState?.description || '', status: item.appointmentState?.description || '', })) ?? []; const pastAppointments = appointments ?.sort((a, b) => (b.startDateTime > a.startDateTime ? 1 : -1)) ?.filter(({ status }) => status !== 'Cancelled') ?.filter(({ startDateTime }) => dayjs(new Date(startDateTime).toISOString()).isBefore(new Date().setHours(0, 0, 0, 0)), ); const upcomingAppointments = appointments ?.sort((a, b) => (a.startDateTime > b.startDateTime ? 1 : -1)) ?.filter(({ status }) => status !== 'Cancelled') ?.filter(({ startDateTime }) => dayjs(new Date(startDateTime).toISOString()).isAfter(new Date())); const todaysAppointments = appointments ?.sort((a, b) => (a.startDateTime > b.startDateTime ? 1 : -1)) ?.filter(({ status }) => status !== 'Cancelled') ?.filter(({ startDateTime }) => dayjs(new Date(startDateTime).toISOString()).isToday()); return { appointments, isLoading, error, pastAppointments, upcomingAppointments, todaysAppointments, mutate: mutatePatientAppointments, }; } // Add new function to fetch appointment states export const useAppointmentStates = () => { const url = `${restBaseUrl}/mohappointment/appointmentstate`; const { data, error, isLoading } = useSWR(url, (url) => openmrsFetch(url).then((res) => res.data)); return { appointmentStates: data?.results || [], isLoading, error, }; }; // Update the changeAppointmentStatus function export const changeAppointmentStatus = async (toStatus: string, appointmentUuid: string) => { // For cancellation, we need to use the RETIRED state (ID: 7) if (toStatus === 'Cancelled') { const url = `${restBaseUrl}/mohappointment/appointment/${appointmentUuid}`; const response = await openmrsFetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: { appointmentId: parseInt(appointmentUuid), appointmentState: { appointmentStateId: 7, // RETIRED state }, }, }); // Invalidate all appointment-related queries mutate((key) => { return ( (typeof key === 'string' && key.includes('/mohappointment/')) || (Array.isArray(key) && key[0].includes('/mohappointment/')) ); }); return response; } // For other status changes, use the existing endpoint const omrsDateFormat = 'YYYY-MM-DDTHH:mm:ss.SSSZZ'; const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone; const statusChangeTime = dayjs(new Date()).format(omrsDateFormat); const url = `${restBaseUrl}/mohappointment/${appointmentUuid}/status-change`; const response = await openmrsFetch(url, { body: { toStatus, onDate: statusChangeTime, timeZone: timeZone }, method: 'POST', headers: { 'Content-Type': 'application/json' }, }); // Invalidate all appointment-related queries mutate((key) => { return ( (typeof key === 'string' && key.includes('/mohappointment/')) || (Array.isArray(key) && key[0].includes('/mohappointment/')) ); }); return response; };