import { useMemo, useState } from "react"; import { Button, Group, Modal, Stack, Text, TextInput, Textarea } from "@mantine/core"; import toast from "react-hot-toast"; import { trainSchedulingService } from "@/services/trainScheduling.service"; /** `min` for a `datetime-local` input: now, in the browser's local zone. */ function nowLocalDateTime(): string { const now = new Date(); const pad = (n: number) => String(n).padStart(2, "0"); return ( `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}` + `T${pad(now.getHours())}:${pad(now.getMinutes())}` ); } export function RescheduleTrainDialog({ scheduleId, currentBookingIds, opened, onClose, onComplete, }: { scheduleId: string; currentBookingIds: string[]; opened: boolean; onClose: () => void; onComplete?: () => void; }) { const [newDepartureDate, setNewDepartureDate] = useState(""); const [reason, setReason] = useState(""); const [loading, setLoading] = useState(false); // Earliest selectable departure, refreshed each time the dialog opens. const minDepartureDate = useMemo( () => (opened ? nowLocalDateTime() : ""), [opened], ); const handleSubmit = async () => { if (!newDepartureDate) { toast.error("Select a new departure date"); return; } if (new Date(newDepartureDate).getTime() < Date.now()) { toast.error("New departure must be in the future"); return; } setLoading(true); try { await trainSchedulingService.maintenanceReschedule(scheduleId, { incomingBookingIds: currentBookingIds, newDepartureDate: new Date(newDepartureDate).toISOString(), reason, }); toast.success("Train rescheduled for maintenance"); onComplete?.(); onClose(); } catch { toast.error("Reschedule failed"); } finally { setLoading(false); } }; return ( Updates departure and rebalances bookings on this train. Displaced bookings return to the operations queue when capacity is insufficient. setNewDepartureDate(e.target.value)} />