diff --git a/src/Routers/SessionRouter.tsx b/src/Routers/SessionRouter.tsx index 971054f3216..50af90ad597 100644 --- a/src/Routers/SessionRouter.tsx +++ b/src/Routers/SessionRouter.tsx @@ -60,14 +60,8 @@ const routes = { staffUsername={staffUsername} /> ), - "/facility/:facilityId/appointments/:appointmentId/success": ({ - facilityId, - appointmentId, - }: { - facilityId: string; - appointmentId: string; - }) => ( - + "/facility/:facilityId/appointments/:appointmentId/success": () => ( + ), "/login": () => , "/forgot-password": () => , diff --git a/src/Utils/request/api.tsx b/src/Utils/request/api.tsx index 23676938942..bf5033be5ef 100644 --- a/src/Utils/request/api.tsx +++ b/src/Utils/request/api.tsx @@ -68,6 +68,7 @@ import { CreateFileResponse, FileUploadModel, } from "@/components/Patient/models"; +import { SlotAvailability } from "@/components/Schedule/types"; import { SkillModel, SkillObjectModel, @@ -1497,6 +1498,12 @@ const routes = { type: "header", }, }, + getAvailableSlotsForADay: { + path: "/api/v1/otp/slots/get_slots_for_day/", + method: "POST", + TRes: Type<{ results: SlotAvailability[] }>(), + TBody: Type<{ resource: string; day: string }>(), + }, }, } as const; diff --git a/src/pages/Appoinments/AppointmentSuccess.tsx b/src/pages/Appoinments/AppointmentSuccess.tsx index 834a21bd414..4df0101cbfb 100644 --- a/src/pages/Appoinments/AppointmentSuccess.tsx +++ b/src/pages/Appoinments/AppointmentSuccess.tsx @@ -1,3 +1,4 @@ +import careConfig from "@careConfig"; import { useQuery } from "@tanstack/react-query"; import { format } from "date-fns"; import { navigate } from "raviger"; @@ -6,35 +7,44 @@ import CareIcon from "@/CAREUI/icons/CareIcon"; import { Button } from "@/components/ui/button"; -import { ScheduleAPIs } from "@/components/Schedule/api"; import { Appointment } from "@/components/Schedule/types"; +import { UserModel } from "@/components/Users/models"; import * as Notification from "@/Utils/Notifications"; -import query from "@/Utils/request/query"; import { formatName } from "@/Utils/utils"; -interface AppointmentSuccessProps { - facilityId: string; - appointmentId: string; -} - -export function AppointmentSuccess(props: AppointmentSuccessProps) { - const { appointmentId, facilityId } = props; +export function AppointmentSuccess() { + // const { appointmentId } = props; + const OTPaccessToken = localStorage.getItem("OTPaccessToken"); + const doctorData: UserModel = JSON.parse( + localStorage.getItem("doctor") ?? "{}", + ); - const { data, error } = useQuery({ - queryKey: ["appointment", appointmentId], - queryFn: query(ScheduleAPIs.appointments.retrieve, { - pathParams: { id: appointmentId, facility_id: facilityId }, - silent: true, - }), + const { data } = useQuery<{ results: Appointment[] }>({ + queryKey: ["appointment"], + queryFn: async () => { + const response = await fetch( + `${careConfig.apiUrl}/api/v1/otp/slots/get_appointments/`, + { + method: "GET", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${OTPaccessToken}`, + }, + }, + ); + + if (!response.ok) { + Notification.Error({ msg: "Appointment not found" }); + //To do: disabled for mock appointment, remove this + //navigate(`/facility/${facilityId}/`); + } + const data = await response.json(); + return data; + }, + enabled: !!OTPaccessToken, }); - if (error) { - Notification.Error({ msg: "Appointment not found" }); - //To do: disabled for mock appointment, remove this - //navigate(`/facility/${facilityId}/`); - } - const mockAppointment: Appointment = { id: "123", resource: { @@ -79,7 +89,7 @@ export function AppointmentSuccess(props: AppointmentSuccessProps) { status: "booked", } as const; - const appointmentData = data ?? mockAppointment; + const appointmentData = data?.results[0] ?? mockAppointment; return (
@@ -110,9 +120,7 @@ export function AppointmentSuccess(props: AppointmentSuccessProps) {

Doctor/Nurse:

-

- {formatName(appointmentData?.resource)} -

+

{formatName(doctorData)}

@@ -143,8 +151,7 @@ export function AppointmentSuccess(props: AppointmentSuccessProps) {

- {formatName(appointmentData?.resource)} will visit the patient at the - scheduled time. + {formatName(doctorData)} will visit the patient at the scheduled time.

Thank you for choosing our care service

diff --git a/src/pages/Appoinments/OTP.tsx b/src/pages/Appoinments/OTP.tsx index cb8ee4a94aa..60a975b7848 100644 --- a/src/pages/Appoinments/OTP.tsx +++ b/src/pages/Appoinments/OTP.tsx @@ -77,14 +77,14 @@ export default function OTP({ }, }); if (response.res?.status === 200) { - navigate( - `/facility/${facilityId}/appointments/${staffUsername}/book-appointment`, - ); const OTPaccessToken = response.data?.access; localStorage.setItem("phoneNumber", phoneNumber); if (OTPaccessToken) { localStorage.setItem("OTPaccessToken", OTPaccessToken); } + navigate( + `/facility/${facilityId}/appointments/${staffUsername}/book-appointment`, + ); } // To Do: Mock, remove this navigate( diff --git a/src/pages/Appointments/AppointmentSuccess.tsx b/src/pages/Appointments/AppointmentSuccess.tsx new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/pages/Facility/AppointmentsPage.tsx b/src/pages/Facility/AppointmentsPage.tsx index ea6e271bd66..a7a738150d6 100644 --- a/src/pages/Facility/AppointmentsPage.tsx +++ b/src/pages/Facility/AppointmentsPage.tsx @@ -1,3 +1,4 @@ +import careConfig from "@careConfig"; import { useQuery } from "@tanstack/react-query"; import { format, parseISO } from "date-fns"; import { Link, navigate } from "raviger"; @@ -15,9 +16,8 @@ import { Textarea } from "@/components/ui/textarea"; import { Avatar } from "@/components/Common/Avatar"; import { FacilityModel } from "@/components/Facility/models"; -import { ScheduleAPIs } from "@/components/Schedule/api"; import { SlotAvailability } from "@/components/Schedule/types"; -import { SkillModel, UserAssignedModel } from "@/components/Users/models"; +import { SkillModel, UserModel } from "@/components/Users/models"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; @@ -39,9 +39,10 @@ export function AppointmentsPage(props: AppointmentsProps) { const [selectedDate, setSelectedDate] = useState(new Date()); const [selectedSlot, setSelectedSlot] = useState(); const [reason, setReason] = useState(""); - const doctorData: UserAssignedModel = JSON.parse( + const doctorData: UserModel = JSON.parse( localStorage.getItem("doctor") ?? "{}", ); + const OTPaccessToken = localStorage.getItem("OTPaccessToken"); if (!staffUsername) { Notification.Error({ msg: "Staff username not found" }); @@ -99,20 +100,40 @@ export function AppointmentsPage(props: AppointmentsProps) { Notification.Error({ msg: "Error while fetching skills data" }); } - const slotsQuery = useQuery>({ + const slotsQuery = useQuery<{ results: SlotAvailability[] }>({ queryKey: ["slots", facilityId, staffUsername, selectedDate], - queryFn: () => - request(ScheduleAPIs.slots.getAvailableSlotsForADay, { - pathParams: { - facility_id: facilityId, - }, - body: { - resource: doctorData?.id?.toString() ?? "", - day: dateQueryString(selectedDate), + queryFn: async () => { + const response = await fetch( + `${careConfig.apiUrl}/api/v1/otp/slots/get_slots_for_day/`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${OTPaccessToken}`, + }, + body: JSON.stringify({ + facility: facilityId, + resource: doctorData?.external_id?.toString() ?? "", + day: dateQueryString(selectedDate), + }), }, - silent: true, - }), - enabled: !!staffUsername && !!doctorData && !!selectedDate, + ); + if (!response.ok) { + const errorData = await response.json(); + if (errorData.errors?.[0][0] === "Resource is not schedulable") { + Notification.Error({ + msg: "This user is not available for appointments", + }); + } else { + Notification.Error({ msg: "Error while fetching slots data" }); + } + return null; + } + + return response.json(); + }, + enabled: + !!staffUsername && !!doctorData && !!selectedDate && !!OTPaccessToken, }); if (slotsQuery.error) { @@ -141,12 +162,15 @@ export function AppointmentsPage(props: AppointmentsProps) { // To Do: Mock, remove/adjust this function extendDoctor( - doctor: UserAssignedModel | undefined, + doctor: UserModel | undefined, ): DoctorModel | undefined { if (!doctor) return undefined; const randomDoc = mockDoctors[0]; return { ...doctor, + date_of_birth: doctor.date_of_birth + ? new Date(doctor.date_of_birth) + : undefined, role: randomDoc.role, gender: randomDoc.gender, education: doctor.qualification @@ -160,6 +184,12 @@ export function AppointmentsPage(props: AppointmentsProps) { skills: skills?.data?.results.map((s) => s.skill_object) ?? randomDoc.skills.map((s) => s), + doctor_experience_commenced_on: doctor.doctor_experience_commenced_on + ? new Date(doctor.doctor_experience_commenced_on) + : undefined, + weekly_working_hours: doctor.weekly_working_hours + ? doctor.weekly_working_hours.toString() + : undefined, }; } @@ -173,7 +203,7 @@ export function AppointmentsPage(props: AppointmentsProps) { } // To Do: Mock, remove/adjust this - const mockTokenSlots: SlotAvailability[] = [ + /* const mockTokenSlots: SlotAvailability[] = [ // Dec 20 - Morning slots { id: "1", @@ -280,21 +310,21 @@ export function AppointmentsPage(props: AppointmentsProps) { }, allocated: 3, }, - ]; + ]; */ - // To Do: Mock, remove/adjust this - const slotsData = slotsQuery.data?.data?.results ?? mockTokenSlots; - const morningSlots = slotsData.filter((slot) => { + const slotsData = slotsQuery.data?.results; + const morningSlots = slotsData?.filter((slot) => { const slotTime = parseISO(slot.start_datetime); return slotTime.getHours() <= 12; }); - const eveningSlots = slotsData.filter((slot) => { + const eveningSlots = slotsData?.filter((slot) => { const slotTime = parseISO(slot.start_datetime); return slotTime.getHours() >= 12; }); - const getSlotButtons = (slots: SlotAvailability[]) => { + const getSlotButtons = (slots: SlotAvailability[] | undefined) => { + if (!slots) return []; return slots.map((slot) => (