mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-07 07:15:45 +00:00
add goverment booking
This commit is contained in:
@@ -56,6 +56,7 @@ import { RescheduleTrainDialog } from "@/components/trainScheduling/RescheduleTr
|
||||
import BookingWindowSettingsModal from "@/components/trainScheduling/BookingWindowSettingsModal";
|
||||
// import { ScheduleBatchPanel } from "@/components/trainScheduling/ScheduleBatchPanel";
|
||||
import { ScheduleBookingsStep } from "@/components/trainScheduling/ScheduleBookingsStep";
|
||||
import { SwitchGovernmentBookingModal } from "@/components/trainScheduling/SwitchGovernmentBookingModal";
|
||||
import { ScheduleWorkspacePanel } from "@/components/trainScheduling/ScheduleWorkspacePanel";
|
||||
import { FreightTypeBadge } from "@/components/trainScheduling/ScheduleStatusBadge";
|
||||
import {
|
||||
@@ -79,6 +80,7 @@ import { trainSchedulingService } from "@/services/trainScheduling.service";
|
||||
import { useToast } from "@/hooks/use-toast";
|
||||
import type {
|
||||
ContainerPlacement,
|
||||
EligibleContainerBooking,
|
||||
FreightType,
|
||||
TrainSchedulePreviewResponse,
|
||||
} from "@/types/trainScheduling";
|
||||
@@ -110,6 +112,7 @@ export default function TrainScheduleV2DetailPage() {
|
||||
const [gatepassFileUrl, setGatepassFileUrl] = useState("");
|
||||
const [gatepassNotes, setGatepassNotes] = useState("");
|
||||
const [dispatchConfirmOpen, setDispatchConfirmOpen] = useState(false);
|
||||
const [switchTarget, setSwitchTarget] = useState<EligibleContainerBooking | null>(null);
|
||||
const autoPreviewedRef = useRef(false);
|
||||
|
||||
const detailQuery = useQuery(
|
||||
@@ -192,6 +195,7 @@ export default function TrainScheduleV2DetailPage() {
|
||||
const preview = useMutation(api.trainScheduling.preview.mutationOptions());
|
||||
const assign = useMutation(api.trainScheduling.assignBookings.mutationOptions());
|
||||
const unassign = useMutation(api.trainScheduling.unassignBooking.mutationOptions());
|
||||
const switchGov = useMutation(api.trainScheduling.switchGovernmentBooking.mutationOptions());
|
||||
const finalize = useMutation(api.trainScheduling.finalizeSchedule.mutationOptions());
|
||||
const dispatch = useMutation(api.trainScheduling.dispatchSchedule.mutationOptions());
|
||||
const downloadMarshalling = useMutation({
|
||||
@@ -511,6 +515,17 @@ export default function TrainScheduleV2DetailPage() {
|
||||
};
|
||||
|
||||
const handleUnassign = async (bookingId: string) => {
|
||||
// Gov bookings never leave a train by removal — only by switching. The API
|
||||
// enforces this too; the guard here just gives the warning without a call.
|
||||
if (schedule?.bookings?.some((b) => b.id === bookingId && b.isGovernment)) {
|
||||
toast({
|
||||
title: "Government booking cannot be removed",
|
||||
description:
|
||||
"Government bookings cannot be removed from the train. They can only be switched onto another allocation.",
|
||||
variant: "destructive",
|
||||
});
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await unassign.mutateAsync({ id: scheduleId, bookingId });
|
||||
toast({ title: "Booking unassigned" });
|
||||
@@ -631,6 +646,7 @@ export default function TrainScheduleV2DetailPage() {
|
||||
id: b.id,
|
||||
reference: b.reference ?? b.id.slice(0, 8),
|
||||
weightTons: b.weightTons,
|
||||
isGovernment: b.isGovernment,
|
||||
}))}
|
||||
eligibleItems={eligibleQuery.data?.items ?? []}
|
||||
eligibleLoading={eligibleQuery.isLoading}
|
||||
@@ -643,6 +659,7 @@ export default function TrainScheduleV2DetailPage() {
|
||||
freightType={freightType}
|
||||
canRemove={canModifyBookings}
|
||||
onRemove={handleUnassign}
|
||||
onSwitch={canModifyBookings ? setSwitchTarget : undefined}
|
||||
/>
|
||||
|
||||
{canEditBookings ? (
|
||||
@@ -1274,6 +1291,36 @@ export default function TrainScheduleV2DetailPage() {
|
||||
onSaved={() => void detailQuery.refetch()}
|
||||
/>
|
||||
|
||||
<SwitchGovernmentBookingModal
|
||||
key={switchTarget?.id ?? "none"}
|
||||
opened={Boolean(switchTarget)}
|
||||
onClose={() => setSwitchTarget(null)}
|
||||
govBooking={switchTarget}
|
||||
assignedBookings={schedule.bookings ?? []}
|
||||
loading={switchGov.isPending}
|
||||
onConfirm={async (removeBookingIds) => {
|
||||
if (!scheduleId || !switchTarget) return;
|
||||
try {
|
||||
await switchGov.mutateAsync({
|
||||
id: scheduleId,
|
||||
governmentBookingId: switchTarget.id,
|
||||
removeBookingIds,
|
||||
});
|
||||
toast({ title: `Government booking ${switchTarget.reference} switched onto the train` });
|
||||
setSwitchTarget(null);
|
||||
setSelectedBookingIds([]);
|
||||
setPreviewResult(null);
|
||||
autoPreviewedRef.current = false;
|
||||
} catch (err) {
|
||||
toast({
|
||||
title: "Switch failed",
|
||||
description: parseError(err, "Could not switch the government booking"),
|
||||
variant: "destructive",
|
||||
});
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
<Modal
|
||||
opened={dispatchConfirmOpen}
|
||||
onClose={() => setDispatchConfirmOpen(false)}
|
||||
|
||||
Reference in New Issue
Block a user