import React from "react"; import { useMutation } from "@tanstack/react-query"; import { ChevronDown, Mail } from "lucide-react"; import { apiClient } from "../../lib/api-client"; import { useToast } from "../ui/toast"; import { Button } from "../ui/button"; import { Popover, PopoverTrigger, PopoverContent } from "../ui/popover"; import { __ } from "../../lib/i18n"; interface ResendEmailMenuProps { bookingId: number; /** Booking status (e.g. "cancelled", "completed") used to gate items. */ status?: string; /** Amount already paid — payment emails only show when > 0. */ amountPaid?: number; } type EmailItem = { type: string; label: string; group: "customer" | "admin"; /** Only show when the booking has a recorded payment. */ needsPayment?: boolean; /** Only show for these booking statuses. */ statuses?: string[]; }; const EMAIL_ITEMS: EmailItem[] = [ { type: "confirmation", label: __("Booking confirmation", "yatra"), group: "customer" }, { type: "payment_confirmation", label: __("Payment confirmation", "yatra"), group: "customer", needsPayment: true, }, { type: "reminder", label: __("Trip reminder", "yatra"), group: "customer" }, { type: "cancellation", label: __("Cancellation notice", "yatra"), group: "customer", statuses: ["cancelled"], }, { type: "completed", label: __("Trip completed / thank-you", "yatra"), group: "customer", statuses: ["completed"], }, { type: "admin_new_booking", label: __("New booking", "yatra"), group: "admin" }, { type: "admin_payment_received", label: __("Payment received", "yatra"), group: "admin", needsPayment: true, }, ]; /** * "Resend Email" menu for a booking. Lets an administrator manually re-send any * of the booking/payment transactional emails after manual changes or a failed * automated send. Items are contextual to the booking's state. */ export const ResendEmailMenu: React.FC = ({ bookingId, status = "", amountPaid = 0, }) => { const { showToast } = useToast(); const [open, setOpen] = React.useState(false); const mutation = useMutation({ mutationFn: async (type: string) => { const res: any = await apiClient.post(`/bookings/${bookingId}/send-email`, { type, }); // The endpoint returns { success, message }. Treat success:false as an error. if (res && res.success === false) { throw new Error(res.message || __("Failed to send email.", "yatra")); } return res; }, onSuccess: (res: any) => { showToast(res?.message || __("Email sent.", "yatra"), "success"); setOpen(false); }, onError: (err: any) => { showToast(err?.message || __("Failed to send email.", "yatra"), "error"); }, }); const paid = Number(amountPaid || 0) > 0; const items = EMAIL_ITEMS.filter((item) => { if (item.needsPayment && !paid) return false; if (item.statuses && !item.statuses.includes(status)) return false; return true; }); const customerItems = items.filter((i) => i.group === "customer"); const adminItems = items.filter((i) => i.group === "admin"); const renderItem = (item: EmailItem) => ( ); const groupLabel = (text: string) => (
{text}
); return ( {customerItems.length > 0 && ( <> {groupLabel(__("To customer", "yatra"))} {customerItems.map(renderItem)} )} {adminItems.length > 0 && ( <> {groupLabel(__("To admin", "yatra"))} {adminItems.map(renderItem)} )} {mutation.isPending && (
{__("Sending…", "yatra")}
)}
); }; export default ResendEmailMenu;