Add minDate handling for vessel and departure dates across components

This commit is contained in:
Marshal
2026-07-09 04:06:40 +00:00
parent b98bc529da
commit df7d796741
5 changed files with 74 additions and 3 deletions

View File

@@ -67,9 +67,13 @@ export default function EditScheduleDateModal({
);
const [value, setValue] = useState("");
// Earliest selectable departure, refreshed each time the modal opens.
const [minValue, setMinValue] = useState("");
useEffect(() => {
if (opened) setValue(toLocalInputValue(currentDate));
if (!opened) return;
setValue(toLocalInputValue(currentDate));
setMinValue(toLocalInputValue(new Date().toISOString()));
}, [opened, currentDate]);
const handleSave = async () => {
@@ -77,6 +81,13 @@ export default function EditScheduleDateModal({
toast({ title: "Pick a departure date", variant: "destructive" });
return;
}
if (new Date(value).getTime() < Date.now()) {
toast({
title: "Departure date must be in the future",
variant: "destructive",
});
return;
}
try {
await save.mutateAsync({
id: scheduleId,
@@ -124,6 +135,7 @@ export default function EditScheduleDateModal({
<TextInput
label="Departure date"
type="datetime-local"
min={minValue}
value={value}
onChange={(e) => setValue(e.currentTarget.value)}
/>

View File

@@ -1,9 +1,19 @@
import { useState } from "react";
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,
@@ -20,12 +30,21 @@ export function RescheduleTrainDialog({
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, {
@@ -53,6 +72,7 @@ export function RescheduleTrainDialog({
<TextInput
label="New departure"
type="datetime-local"
min={minDepartureDate}
value={newDepartureDate}
onChange={(e) => setNewDepartureDate(e.target.value)}
/>