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

@@ -55,6 +55,13 @@ import { useToast } from "@/hooks/use-toast";
import type { TrainScheduleListItem } from "@/types/trainScheduling";
import { DataTable, DataTableFooter, usePagination } from "@edr/ui-common";
/** `min` for a `datetime-local` input: now, in the browser's local zone. */
const nowLocalDateTime = () => {
const now = new Date();
now.setMinutes(now.getMinutes() - now.getTimezoneOffset());
return now.toISOString().slice(0, 16);
};
const splitDate = (value?: string | null) => {
if (!value) return { day: "—", time: "" };
const date = new Date(value);
@@ -103,6 +110,12 @@ export default function TrainScheduleV2ListPage() {
const [routeId, setRouteId] = useState("");
const [scheduleDate, setScheduleDate] = useState("");
const [locomotiveIds, setLocomotiveIds] = useState<string[]>([]);
// Recomputed each time the create modal opens so a long-lived tab can't keep
// offering a stale "now" as the earliest selectable departure.
const minScheduleDate = useMemo(
() => (createOpen ? nowLocalDateTime() : ""),
[createOpen],
);
const schedulesQuery = useQuery(
api.trainScheduling.scheduleList.queryOptions({ input: {} }),
@@ -443,6 +456,13 @@ export default function TrainScheduleV2ListPage() {
});
return;
}
if (new Date(scheduleDate).getTime() < Date.now()) {
toast({
title: "Departure date must be in the future",
variant: "destructive",
});
return;
}
try {
const created = await create.mutateAsync({
payload: {
@@ -691,6 +711,7 @@ export default function TrainScheduleV2ListPage() {
<TextInput
label="Departure date"
type="datetime-local"
min={minScheduleDate}
value={scheduleDate}
onChange={(e) => setScheduleDate(e.currentTarget.value)}
/>