import { useT } from "@agent-native/core/client/i18n"; import { IconCalendar, IconClock, IconCircleX, IconCalendarPlus, IconCircleCheck, } from "@tabler/icons-react"; import { useQuery, useMutation } from "@tanstack/react-query"; import { format, parseISO } from "date-fns"; import { useState } from "react"; import { Link, useParams, useNavigate } from "react-router"; import { toast } from "sonner"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from "@/components/ui/alert-dialog"; import { Button } from "@/components/ui/button"; import { Spinner } from "@/components/ui/spinner"; import { appApiPath } from "@/lib/api-path"; interface BookingInfo { eventTitle: string; name: string; start: string; end: string; slug: string; meetingLink?: string; status: "confirmed" | "cancelled"; } export function ManageBookingPage() { const t = useT(); const { token } = useParams<{ token: string }>(); const navigate = useNavigate(); const [justCancelled, setJustCancelled] = useState(false); const { data: booking, isLoading, error, } = useQuery({ queryKey: ["manage-booking", token], queryFn: async () => { const res = await fetch(appApiPath(`/api/public/bookings/${token}`)); if (!res.ok) { const body = await res.json().catch(() => ({})); throw new Error(body.error || t("manageBooking.notFound")); } return res.json(); }, enabled: !!token, }); const cancelMutation = useMutation({ mutationFn: async () => { const res = await fetch(appApiPath(`/api/public/bookings/${token}`), { method: "DELETE", }); if (!res.ok) { const body = await res.json().catch(() => ({})); throw new Error(body.error || t("manageBooking.cancelFailed")); } return res.json(); }, onSuccess: () => { setJustCancelled(true); }, }); const isCancelled = booking?.status === "cancelled" || justCancelled; const isPast = booking ? new Date(booking.end) < new Date() : false; if (isLoading) { return (
); } if (error || !booking) { return (

{t("manageBooking.notFound")}

{t("manageBooking.notFoundDescription")}

); } if (isCancelled) { return (

{t("manageBooking.cancelled")}

{t("manageBooking.cancelledPrefix")}{" "} {booking.eventTitle} {" "} {t("manageBooking.cancelledDateConnector")}{" "} {format(parseISO(booking.start), "MMMM d, yyyy")} {" "} {t("manageBooking.cancelledSuffix")}

{booking.slug && ( )}
); } return (

{t("manageBooking.title")}

{t("manageBooking.description")}

{/* Booking details */}

{booking.eventTitle}

{format(parseISO(booking.start), "EEEE, MMMM d, yyyy")}
{format(parseISO(booking.start), "h:mm a")} -{" "} {format(parseISO(booking.end), "h:mm a")}
{t("manageBooking.bookedBy", { name: booking.name })}
{isPast ? (

{t("manageBooking.pastMeeting")}

) : (
{booking.slug && ( {t("manageBooking.rescheduleTitle")} {t("manageBooking.rescheduleDescription")} {t("manageBooking.keepCurrentTime")} { e.preventDefault(); cancelMutation.mutate(undefined, { onSuccess: () => navigate(`/book/${booking.slug}`), onError: () => toast.error(t("manageBooking.cancelFailed")), }); }} disabled={cancelMutation.isPending} > {cancelMutation.isPending ? t("manageBooking.cancelling") : t("manageBooking.reschedule")} )} {t("manageBooking.cancelTitle")} {t("manageBooking.cancelDescriptionPrefix")}{" "} {booking.eventTitle} {" "} {t("manageBooking.cancelDescriptionDateConnector")}{" "} {format(parseISO(booking.start), "MMMM d, yyyy")} {t("manageBooking.cancelDescriptionSuffix")} {t("manageBooking.keepBooking")} { e.preventDefault(); cancelMutation.mutate(undefined, { onError: () => toast.error(t("manageBooking.cancelFailed")), }); }} disabled={cancelMutation.isPending} > {cancelMutation.isPending ? t("manageBooking.cancelling") : t("manageBooking.yesCancel")}
)}
); }