diff --git a/app/(admin)/admin/booking/[id]/page.tsx b/app/(admin)/admin/booking/[id]/page.tsx index 3ec4ccb..c101ee4 100644 --- a/app/(admin)/admin/booking/[id]/page.tsx +++ b/app/(admin)/admin/booking/[id]/page.tsx @@ -20,7 +20,7 @@ import { MapPin, } from "lucide-react"; import { useAppTheme } from "@/components/ThemeProvider"; -import { getAppointmentDetail, scheduleAppointment, rejectAppointment } from "@/lib/actions/appointments"; +import { getAppointmentDetail, scheduleAppointment, rejectAppointment, listAppointments } from "@/lib/actions/appointments"; import { Button } from "@/components/ui/button"; import { Dialog, @@ -58,8 +58,23 @@ export default function AppointmentDetailPage() { setLoading(true); try { - const data = await getAppointmentDetail(appointmentId); - setAppointment(data); + // Fetch both detail and list to get selected_slots from list endpoint + const [detailData, listData] = await Promise.all([ + getAppointmentDetail(appointmentId), + listAppointments().catch(() => []) // Fallback to empty array if list fails + ]); + + // Find matching appointment in list to get selected_slots + const listAppointment = Array.isArray(listData) + ? listData.find((apt: Appointment) => apt.id === appointmentId) + : null; + + // Merge selected_slots from list into detail data + if (listAppointment && listAppointment.selected_slots && Array.isArray(listAppointment.selected_slots) && listAppointment.selected_slots.length > 0) { + detailData.selected_slots = listAppointment.selected_slots; + } + + setAppointment(detailData); } catch (error) { toast.error("Failed to load appointment details"); router.push("/admin/booking"); @@ -367,7 +382,7 @@ export default function AppointmentDetailPage() { )} - {/* Selected Slots (replacing Matching Slots) */} + {/* Selected Slots */} {appointment.selected_slots && Array.isArray(appointment.selected_slots) && appointment.selected_slots.length > 0 && (
@@ -382,46 +397,65 @@ export default function AppointmentDetailPage() {
-
- {appointment.selected_slots.map((slot: any, idx: number) => { - const dayNames: Record = { - 0: "Monday", - 1: "Tuesday", - 2: "Wednesday", - 3: "Thursday", - 4: "Friday", - 5: "Saturday", - 6: "Sunday", - }; - const timeSlotLabels: Record = { - morning: "Morning", - afternoon: "Lunchtime", - evening: "Evening", - }; - const dayName = dayNames[slot.day] || `Day ${slot.day}`; - const timeSlot = String(slot.time_slot).toLowerCase().trim(); - const timeLabel = timeSlotLabels[timeSlot] || slot.time_slot; - - return ( -
-

- {dayName} -

-

- {timeLabel} -

- {slot.date && ( -

- {formatShortDate(slot.date)} -

- )} -
- ); - })} -
+ {(() => { + const dayNames: Record = { + 0: "Monday", + 1: "Tuesday", + 2: "Wednesday", + 3: "Thursday", + 4: "Friday", + 5: "Saturday", + 6: "Sunday", + }; + const timeSlotLabels: Record = { + morning: "Morning", + afternoon: "Lunchtime", + evening: "Evening", + }; + + // Group slots by date + const slotsByDate: Record = {}; + appointment.selected_slots.forEach((slot: any) => { + const date = slot.date || ""; + if (!slotsByDate[date]) { + slotsByDate[date] = []; + } + slotsByDate[date].push(slot); + }); + + return ( +
+ {Object.entries(slotsByDate).map(([date, slots]) => ( +
+
+

+ {formatShortDate(date)} +

+ {slots.length > 0 && slots[0]?.day !== undefined && ( +

+ {dayNames[slots[0].day] || `Day ${slots[0].day}`} +

+ )} +
+
+ {slots.map((slot: any, idx: number) => { + const timeSlot = String(slot.time_slot).toLowerCase().trim(); + const timeLabel = timeSlotLabels[timeSlot] || slot.time_slot; + return ( + + {timeLabel} + + ); + })} +
+
+ ))} +
+ ); + })()}
)} diff --git a/app/(admin)/admin/booking/page.tsx b/app/(admin)/admin/booking/page.tsx index 532ba43..49abfc8 100644 --- a/app/(admin)/admin/booking/page.tsx +++ b/app/(admin)/admin/booking/page.tsx @@ -680,27 +680,52 @@ export default function Booking() { {(() => { - // Handle preferred_dates + const dayNames: Record = { + 0: "Monday", + 1: "Tuesday", + 2: "Wednesday", + 3: "Thursday", + 4: "Friday", + 5: "Saturday", + 6: "Sunday", + }; + const timeSlotLabels: Record = { + morning: "Morning", + afternoon: "Lunchtime", + evening: "Evening", + }; + + // Show selected_slots if available + if (appointment.selected_slots && Array.isArray(appointment.selected_slots) && appointment.selected_slots.length > 0) { + return ( +
+ {appointment.selected_slots.slice(0, 2).map((slot, idx) => ( + + {dayNames[slot.day] || `Day ${slot.day}`} - {timeSlotLabels[slot.time_slot] || slot.time_slot} + + ))} + {appointment.selected_slots.length > 2 && ( + + +{appointment.selected_slots.length - 2} more + + )} +
+ ); + } + + // Fallback to preferred_dates and preferred_time_slots if selected_slots not available const dates = Array.isArray(appointment.preferred_dates) ? appointment.preferred_dates : appointment.preferred_dates ? [appointment.preferred_dates] : []; - // Handle preferred_time_slots const timeSlots = Array.isArray(appointment.preferred_time_slots) ? appointment.preferred_time_slots : appointment.preferred_time_slots ? [appointment.preferred_time_slots] : []; - // Time slot labels - const timeSlotLabels: Record = { - morning: "Morning", - afternoon: "Lunchtime", - evening: "Evening", - }; - if (dates.length === 0 && timeSlots.length === 0) { return -; } diff --git a/app/(user)/user/appointments/[id]/page.tsx b/app/(user)/user/appointments/[id]/page.tsx index 1330fdd..a15cf6c 100644 --- a/app/(user)/user/appointments/[id]/page.tsx +++ b/app/(user)/user/appointments/[id]/page.tsx @@ -18,7 +18,7 @@ import { Copy, } from "lucide-react"; import { useAppTheme } from "@/components/ThemeProvider"; -import { getAppointmentDetail } from "@/lib/actions/appointments"; +import { getAppointmentDetail, listAppointments } from "@/lib/actions/appointments"; import { Button } from "@/components/ui/button"; import { Navbar } from "@/components/Navbar"; import { toast } from "sonner"; @@ -40,8 +40,23 @@ export default function UserAppointmentDetailPage() { setLoading(true); try { - const data = await getAppointmentDetail(appointmentId); - setAppointment(data); + // Fetch both detail and list to get selected_slots from list endpoint + const [detailData, listData] = await Promise.all([ + getAppointmentDetail(appointmentId), + listAppointments().catch(() => []) // Fallback to empty array if list fails + ]); + + // Find matching appointment in list to get selected_slots + const listAppointment = Array.isArray(listData) + ? listData.find((apt: Appointment) => apt.id === appointmentId) + : null; + + // Merge selected_slots from list into detail data + if (listAppointment && listAppointment.selected_slots && Array.isArray(listAppointment.selected_slots) && listAppointment.selected_slots.length > 0) { + detailData.selected_slots = listAppointment.selected_slots; + } + + setAppointment(detailData); } catch (error) { toast.error("Failed to load appointment details"); router.push("/user/dashboard"); @@ -306,7 +321,7 @@ export default function UserAppointmentDetailPage() { )} - {/* Selected Slots (replacing Matching Slots) */} + {/* Selected Slots */} {appointment.selected_slots && Array.isArray(appointment.selected_slots) && appointment.selected_slots.length > 0 && (
@@ -321,46 +336,65 @@ export default function UserAppointmentDetailPage() {
-
- {appointment.selected_slots.map((slot: any, idx: number) => { - const dayNames: Record = { - 0: "Monday", - 1: "Tuesday", - 2: "Wednesday", - 3: "Thursday", - 4: "Friday", - 5: "Saturday", - 6: "Sunday", - }; - const timeSlotLabels: Record = { - morning: "Morning", - afternoon: "Lunchtime", - evening: "Evening", - }; - const dayName = dayNames[slot.day] || `Day ${slot.day}`; - const timeSlot = String(slot.time_slot).toLowerCase().trim(); - const timeLabel = timeSlotLabels[timeSlot] || slot.time_slot; - - return ( -
-

- {dayName} -

-

- {timeLabel} -

- {slot.date && ( -

- {formatShortDate(slot.date)} -

- )} -
- ); - })} -
+ {(() => { + const dayNames: Record = { + 0: "Monday", + 1: "Tuesday", + 2: "Wednesday", + 3: "Thursday", + 4: "Friday", + 5: "Saturday", + 6: "Sunday", + }; + const timeSlotLabels: Record = { + morning: "Morning", + afternoon: "Lunchtime", + evening: "Evening", + }; + + // Group slots by date + const slotsByDate: Record = {}; + appointment.selected_slots.forEach((slot: any) => { + const date = slot.date || ""; + if (!slotsByDate[date]) { + slotsByDate[date] = []; + } + slotsByDate[date].push(slot); + }); + + return ( +
+ {Object.entries(slotsByDate).map(([date, slots]) => ( +
+
+

+ {formatShortDate(date)} +

+ {slots.length > 0 && slots[0]?.day !== undefined && ( +

+ {dayNames[slots[0].day] || `Day ${slots[0].day}`} +

+ )} +
+
+ {slots.map((slot: any, idx: number) => { + const timeSlot = String(slot.time_slot).toLowerCase().trim(); + const timeLabel = timeSlotLabels[timeSlot] || slot.time_slot; + return ( + + {timeLabel} + + ); + })} +
+
+ ))} +
+ ); + })()}
)}