Merge pull request #326 from Tria-plc/freight/feature/vehicle_2

Freight/feature/vehicle 2
This commit is contained in:
yaschalew10
2026-06-29 11:53:31 +03:00
committed by GitHub

View File

@@ -22,6 +22,7 @@ import {
Group,
Menu,
Modal,
NumberInput,
Select,
SimpleGrid,
Stack,
@@ -327,6 +328,9 @@ const FirstMilePage = () => {
const [acceptVehicleValue, setAcceptVehicleValue] = useState<string | null>(null);
const [bookingSearch, setBookingSearch] = useState("");
const [distanceOpen, setDistanceOpen] = useState(false);
const [distanceValue, setDistanceValue] = useState("");
const { data: listData, isLoading } = useQuery({
queryKey: QUERY_KEYS.FIRST_MILE.list(),
queryFn: async () => {
@@ -379,6 +383,21 @@ const FirstMilePage = () => {
},
});
const updateDistanceMutation = useMutation({
mutationFn: ({ id, exactKm }: { id: string; exactKm: number }) =>
firstMileService.update(id, { exactKm }),
onSuccess: () => {
void qc.invalidateQueries({ queryKey: QUERY_KEYS.FIRST_MILE.ROOT });
if (activeRecord) {
toast({ title: "Distance updated", description: `${bookingRef(activeRecord)}${distanceValue} km` });
}
closeDistance();
},
onError: () => {
toast({ title: "Update failed", variant: "destructive" });
},
});
const acceptMutation = useMutation({
mutationFn: async ({ reference, vehicleId }: { reference: string; vehicleId: string | null }) => {
const res = await firstMileService.accept(reference);
@@ -454,6 +473,27 @@ const FirstMilePage = () => {
acceptMutation.mutate({ reference: selectedBooking.reference, vehicleId: acceptVehicleValue });
};
const openDistance = (id: string) => {
setActiveId(id);
setDistanceValue("");
setDistanceOpen(true);
};
const closeDistance = () => {
setDistanceOpen(false);
setActiveId(null);
setDistanceValue("");
};
const handleSaveDistance = () => {
const distance = parseFloat(distanceValue);
if (!activeId || isNaN(distance) || distance < 0) {
toast({ title: "Invalid distance", description: "Enter a valid distance value.", variant: "destructive" });
return;
}
updateDistanceMutation.mutate({ id: activeId, exactKm: distance });
};
const matchesFilter = (r: FirstMileRecord) => {
switch (statusFilter) {
case "ALL": return true;
@@ -726,6 +766,11 @@ const FirstMilePage = () => {
>
View detail
</Menu.Item>
<Menu.Item
onClick={() => openDistance(row.original.id)}
>
Add Actual distance
</Menu.Item>
{canPrint && (
<Menu.Item
leftSection={<Printer size={15} />}
@@ -1030,6 +1075,53 @@ const FirstMilePage = () => {
</Stack>
)}
</Modal>
{/* Add Actual Distance modal */}
<Modal
opened={distanceOpen}
onClose={closeDistance}
title={<Text fw={600}>Add Actual Distance</Text>}
size="md"
radius="lg"
centered
>
<Stack gap="md">
{activeRecord && (
<Card withBorder padding="md" radius="md" bg="var(--mantine-color-gray-0)">
<Stack gap="sm">
<Text fw={600} size="sm">{bookingRef(activeRecord)}</Text>
<Group justify="space-between">
<Text size="xs" c="dimmed">Customer</Text>
<Text size="sm">{customerName(activeRecord)}</Text>
</Group>
<Group justify="space-between">
<Text size="xs" c="dimmed">Est. Distance (KM)</Text>
<Text size="sm">{activeRecord.estimatedKm ?? "—"}</Text>
</Group>
</Stack>
</Card>
)}
<NumberInput
label="Actual Distance (KM)"
placeholder="Enter distance"
value={distanceValue}
onChange={(v) => setDistanceValue(String(v ?? ""))}
min={0}
step={0.1}
decimalScale={2}
/>
<Group justify="flex-end" gap="sm">
<Button variant="default" onClick={closeDistance}>Cancel</Button>
<Button
onClick={handleSaveDistance}
loading={updateDistanceMutation.isPending}
disabled={!distanceValue}
>
Save
</Button>
</Group>
</Stack>
</Modal>
</Stack>
);
};