From 5a6e1ef3633ef439807edda5c43694abf98fd9a9 Mon Sep 17 00:00:00 2001 From: Hagernesh Date: Wed, 17 Jun 2026 22:01:47 +0000 Subject: [PATCH] automation --- apps/edr-freight-web/backoffice/src/App.tsx | 2 + .../src/pages/warehouses/ArrivalQueuePage.tsx | 200 ++++++++++++++++++ 2 files changed, 202 insertions(+) create mode 100644 apps/edr-freight-web/backoffice/src/pages/warehouses/ArrivalQueuePage.tsx diff --git a/apps/edr-freight-web/backoffice/src/App.tsx b/apps/edr-freight-web/backoffice/src/App.tsx index 5b457bd64..c99d39294 100644 --- a/apps/edr-freight-web/backoffice/src/App.tsx +++ b/apps/edr-freight-web/backoffice/src/App.tsx @@ -55,6 +55,7 @@ import WarehouseDashboardPage from "./pages/warehouses/WarehouseDashboardPage"; import LoadingQueuePage from "./pages/warehouses/LoadingQueuePage"; import LoadedInventoryPage from "./pages/warehouses/LoadedInventoryPage"; import DispatchQueuePage from "./pages/warehouses/DispatchQueuePage"; +import ArrivalQueuePage from "./pages/warehouses/ArrivalQueuePage"; const buildSidebarSections = (demoItems: SidebarItem[]): SidebarSection[] => [ { @@ -309,6 +310,7 @@ const App = () => { } /> } /> } /> + } /> } /> } /> } /> diff --git a/apps/edr-freight-web/backoffice/src/pages/warehouses/ArrivalQueuePage.tsx b/apps/edr-freight-web/backoffice/src/pages/warehouses/ArrivalQueuePage.tsx new file mode 100644 index 000000000..c05f2c626 --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/pages/warehouses/ArrivalQueuePage.tsx @@ -0,0 +1,200 @@ +import { useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { + Badge, + Button, + Card, + Container, + Group, + Loader, + Stack, + Table, + Text, +} from '@mantine/core'; +import { ClipboardList, Eye, PackageOpen, Truck } from 'lucide-react'; + +import Breadcrumbs from '@/components/ui/Breadcrumbs'; +import { + InspectionReportModal, + VisualEmptyState, + WarehouseHero, + formatDate, +} from '@/components/warehouses'; +import { useArrivalQueue, useAutoUnloadArrived, useUnloadBooking } from '@/hooks/useWarehouses'; +import { useToast } from '@/hooks/use-toast'; +import type { ArrivalQueueItem } from '@/types/warehouse'; + +function inspectionBadge(status: string | null) { + if (!status) return Not inspected; + const color = status === 'PASSED' ? 'green' : status === 'FAILED' ? 'red' : 'orange'; + return {status.replace(/_/g, ' ')}; +} + +/** Batch 4.5 — arrived bookings awaiting unload / inspection. */ +export default function ArrivalQueuePage() { + const navigate = useNavigate(); + const { toast } = useToast(); + const { data, isLoading } = useArrivalQueue(); + const autoUnload = useAutoUnloadArrived(); + const unloadOne = useUnloadBooking(); + const [inspectInventoryId, setInspectInventoryId] = useState(null); + + const items = data ?? []; + + const handleAutoUnload = async () => { + try { + const res = await autoUnload.mutateAsync(); + const r = res.data; + toast({ + title: 'Auto-unload complete', + description: `Processed ${r.processedCount}, skipped ${r.skippedCount}, failed ${r.failedCount}.`, + }); + } catch { + toast({ variant: 'destructive', title: 'Auto-unload failed' }); + } + }; + + const handleUnloadOne = async (item: ArrivalQueueItem) => { + try { + await unloadOne.mutateAsync({ bookingId: item.bookingId }); + toast({ title: 'Booking unloaded', description: `${item.bookingReference} stored as RECEIVED.` }); + } catch { + toast({ variant: 'destructive', title: 'Unload failed' }); + } + }; + + return ( + + + + + + + + + {items.length} arrived booking(s) + + + + {isLoading ? ( + + + + ) : items.length === 0 ? ( + + ) : ( + + + + + Booking + Customer + Cargo / Container + Arrival + Facility + Warehouse + Yard + Zone + Status + Inspection + Actions + + + + {items.map((item) => ( + + + {item.bookingReference} + + {item.customer ?? '—'} + {item.container ?? item.cargo ?? '—'} + + {formatDate(item.arrivalDate)} + + {item.facility ?? '—'} + {item.warehouse ?? '—'} + {item.yard ?? '—'} + {item.zone ?? '—'} + + {item.unloaded ? ( + + {item.currentStatus ?? 'RECEIVED'} + + ) : ( + + Not unloaded + + )} + + {inspectionBadge(item.inspectionStatus)} + + + {!item.unloaded && ( + + )} + {item.inventoryId && ( + + )} + {item.inventoryId && ( + + )} + + + + ))} + +
+
+ )} +
+
+ + setInspectInventoryId(null)} + inventoryId={inspectInventoryId} + /> +
+ ); +}