diff --git a/app/(admin)/admin/booking/[id]/page.tsx b/app/(admin)/admin/booking/[id]/page.tsx index 883faaf..e8bb34e 100644 --- a/app/(admin)/admin/booking/[id]/page.tsx +++ b/app/(admin)/admin/booking/[id]/page.tsx @@ -21,7 +21,7 @@ import { Pencil, } from "lucide-react"; import { useAppTheme } from "@/components/ThemeProvider"; -import { getAppointmentDetail, scheduleAppointment, rejectAppointment, listAppointments, startMeeting, endMeeting, rescheduleAppointment } from "@/lib/actions/appointments"; +import { getAppointmentDetail, scheduleAppointment, rejectAppointment, listAppointments, startMeeting, endMeeting, rescheduleAppointment, cancelAppointment } from "@/lib/actions/appointments"; import { Button } from "@/components/ui/button"; import { Dialog, @@ -57,6 +57,8 @@ export default function AppointmentDetailPage() { const [isRescheduling, setIsRescheduling] = useState(false); const [isStartingMeeting, setIsStartingMeeting] = useState(false); const [isEndingMeeting, setIsEndingMeeting] = useState(false); + const [cancelDialogOpen, setCancelDialogOpen] = useState(false); + const [isCancelling, setIsCancelling] = useState(false); const { theme } = useAppTheme(); const isDark = theme === "dark"; @@ -210,6 +212,56 @@ export default function AppointmentDetailPage() { } }; + const handleReschedule = async () => { + if (!appointment || !rescheduleDate) return; + + setIsRescheduling(true); + try { + const dateTime = new Date(rescheduleDate); + const [hours, minutes] = rescheduleTime.split(":").map(Number); + dateTime.setHours(hours, minutes, 0, 0); + + const userTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone; + + await rescheduleAppointment(appointment.id, { + new_scheduled_datetime: dateTime.toISOString(), + new_scheduled_duration: rescheduleDuration, + timezone: userTimezone, + }); + + toast.success("Appointment rescheduled successfully"); + setRescheduleDialogOpen(false); + + // Refresh appointment data + const updated = await getAppointmentDetail(appointment.id); + setAppointment(updated); + } catch (error: any) { + toast.error(error.message || "Failed to reschedule appointment"); + } finally { + setIsRescheduling(false); + } + }; + + const handleCancelAppointment = async () => { + if (!appointment) return; + + setIsCancelling(true); + try { + await cancelAppointment(appointment.id); + toast.success("Appointment cancelled successfully"); + setCancelDialogOpen(false); + // Refetch appointment to get updated status + const updatedAppointment = await getAppointmentDetail(appointment.id); + setAppointment(updatedAppointment); + router.push("/admin/booking"); + } catch (error) { + const errorMessage = error instanceof Error ? error.message : "Failed to cancel appointment"; + toast.error(errorMessage); + } finally { + setIsCancelling(false); + } + }; + const copyToClipboard = (text: string, label: string) => { navigator.clipboard.writeText(text); toast.success(`${label} copied to clipboard`); @@ -384,10 +436,34 @@ export default function AppointmentDetailPage() { {appointment.scheduled_datetime && (