Handover SIGN notification, resending until signed no exit before sign

This commit is contained in:
Hagernesh
2026-07-08 09:32:24 +00:00
parent 8de7754e35
commit 80904eeeb2
22 changed files with 703 additions and 215 deletions

View File

@@ -7,6 +7,7 @@ import {
Checkbox,
Group,
Loader,
Menu,
Modal,
NumberInput,
ScrollArea,
@@ -20,6 +21,7 @@ import {
Tooltip,
} from '@mantine/core';
import {
ArrowRightLeft,
ChevronDown,
ChevronRight,
ClipboardCheck,
@@ -27,6 +29,8 @@ import {
FileText,
History,
Info,
MapPin,
MoreHorizontal,
PackageCheck,
PackageOpen,
PackageSearch,
@@ -61,7 +65,6 @@ import type {
} from '@/types/warehouse';
import { BookingSelect } from './BookingSelect';
import { DeliverInventoryModal } from './DeliverInventoryModal';
import { TruckDispatchModal } from './TruckDispatchModal';
import { ContainerItemsModal } from './ContainerItemsModal';
import { FeePreviewModal } from './FeePreviewModal';
import { InspectionReportModal } from './InspectionReportModal';
@@ -69,7 +72,9 @@ import { InventoryDetailModal } from './InventoryDetailModal';
import { InventoryHistoryModal } from './InventoryHistoryModal';
import { InventoryWorkbench } from './InventoryWorkbench';
import { InventoryInquiryDetailModal } from './InventoryInquiryDetailModal';
import { MoveInventoryModal } from './MoveInventoryModal';
import { ReleaseOrderModal } from './ReleaseOrderModal';
import { StoreInventoryModal } from './StoreInventoryModal';
import { WarehouseInquiryTable } from './WarehouseInquiryTable';
import { extractErrorMessage, formatDate, formatNumber, inventoryStatusOptions } from './options';
import { openPdfBlob } from './pdf';
@@ -2182,7 +2187,6 @@ function ImportUnloadedQueueTab({ enabled }: { enabled: boolean }) {
const inspectMutation = useMutation(
api.warehouses.bulkMarkInspected.mutationOptions(),
);
const storeMutation = useMutation(api.warehouses.store.mutationOptions());
const readyMutation = useMutation(api.warehouses.markReadyForPickup.mutationOptions());
const [selected, setSelected] = useState<Set<string>>(new Set());
const [inspectId, setInspectId] = useState<string | null>(null);
@@ -2192,8 +2196,9 @@ function ImportUnloadedQueueTab({ enabled }: { enabled: boolean }) {
const [feeItem, setFeeItem] = useState<WarehouseInventoryItem | null>(null);
const [releaseItem, setReleaseItem] = useState<WarehouseInventoryItem | null>(null);
const [deliverItem, setDeliverItem] = useState<WarehouseInventoryItem | null>(null);
const [loadTruckItem, setLoadTruckItem] = useState<WarehouseInventoryItem | null>(null);
const [containerItemsItem, setContainerItemsItem] = useState<WarehouseInventoryItem | null>(null);
const [storeItem, setStoreItem] = useState<WarehouseInventoryItem | null>(null);
const [moveItem, setMoveItem] = useState<WarehouseInventoryItem | null>(null);
const allSelected = rows.length > 0 && selected.size === rows.length;
const someSelected = selected.size > 0 && !allSelected;
@@ -2413,49 +2418,16 @@ function ImportUnloadedQueueTab({ enabled }: { enabled: boolean }) {
<Eye size={16} />
</ActionIcon>
</Tooltip>
{r.currentStatus === 'UNLOADED' && (
{/* Primary stage action stays visible; the rest live under the kebab. */}
{r.currentStatus === 'READY_FOR_PICKUP' && !r.releaseDate && r.hasAssignedTruck && (
<Button
size="compact-xs"
variant="light"
color="blue"
loading={busyId === r.id}
onClick={() => runRowAction(r, 'Inventory stored', () => storeMutation.mutateAsync(r.id))}
color="yellow"
leftSection={<Truck size={14} />}
onClick={() => setReleaseItem(toInventoryItem(r))}
>
Store
</Button>
)}
{['UNLOADED', 'STORED'].includes(r.currentStatus) && r.inspectionStatus === 'PASSED' && (
<Button
size="compact-xs"
variant="light"
color="orange"
loading={busyId === r.id}
onClick={() => runRowAction(r, 'Ready for pickup', () => readyMutation.mutateAsync(r.id))}
>
Ready Pickup
</Button>
)}
{r.currentStatus === 'READY_FOR_PICKUP' && !r.releaseDate && (
<>
<Button
size="compact-xs"
variant="light"
color="yellow"
onClick={() => setReleaseItem(toInventoryItem(r))}
>
{r.releaseOrderReference ? 'Truck Leaving' : 'Truck Arrival'}
</Button>
</>
)}
{r.currentStatus === 'READY_FOR_PICKUP' && (
<Button
size="compact-xs"
variant="light"
color="green"
loading={busyId === r.id}
onClick={() => setLoadTruckItem(toInventoryItem(r))}
>
Truck_dispatch
{r.releaseOrderReference ? 'Truck Leaving' : 'Truck Arrival'}
</Button>
)}
{r.currentStatus === 'READY_FOR_PICKUP' && r.releaseDate && (
@@ -2470,40 +2442,64 @@ function ImportUnloadedQueueTab({ enabled }: { enabled: boolean }) {
Exit Paper
</Button>
)}
{r.currentStatus === 'READY_FOR_PICKUP' && r.releaseDate && (
<Button
size="compact-xs"
variant="light"
color="green"
onClick={() => setDeliverItem(toInventoryItem(r))}
>
Deliver
</Button>
)}
{r.inspectionStatus === 'PASSED' && (
<Button
size="compact-xs"
variant="light"
color="teal"
leftSection={<FileText size={14} />}
onClick={() => openHandoverDocument(r)}
>
{r.handoverDocumentReference ? 'View Handover' : 'Handover'}
</Button>
)}
<Button size="compact-xs" variant="light" color="orange" onClick={() => setInspectId(r.id)}>
Inspect / Report
</Button>
<Tooltip label="Storage / fee preview" withArrow>
<ActionIcon variant="subtle" color="teal" onClick={() => setFeeItem(toInventoryItem(r))}>
<PackageCheck size={16} />
</ActionIcon>
</Tooltip>
<Tooltip label="History" withArrow>
<ActionIcon variant="subtle" color="gray" onClick={() => setHistoryItem(toInventoryItem(r))}>
<History size={16} />
</ActionIcon>
</Tooltip>
<Menu shadow="md" width={240} position="bottom-end" withinPortal>
<Menu.Target>
<ActionIcon variant="subtle" color="gray" aria-label="More actions" loading={busyId === r.id}>
<MoreHorizontal size={16} />
</ActionIcon>
</Menu.Target>
<Menu.Dropdown>
{r.currentStatus === 'UNLOADED' && (
<Menu.Item leftSection={<MapPin size={14} />} onClick={() => setStoreItem(toInventoryItem(r))}>
Store
</Menu.Item>
)}
{r.currentStatus !== 'UNLOADED' && (
<Menu.Item leftSection={<ArrowRightLeft size={14} />} onClick={() => setMoveItem(toInventoryItem(r))}>
Move
</Menu.Item>
)}
{['UNLOADED', 'STORED'].includes(r.currentStatus) && r.inspectionStatus === 'PASSED' && (
<Menu.Item onClick={() => runRowAction(r, 'Ready for pickup', () => readyMutation.mutateAsync(r.id))}>
Ready for pickup
</Menu.Item>
)}
{r.currentStatus === 'READY_FOR_PICKUP' && !r.releaseDate && (
<Menu.Item
leftSection={<Truck size={14} />}
disabled={!r.hasAssignedTruck}
onClick={() => setReleaseItem(toInventoryItem(r))}
>
{r.hasAssignedTruck
? r.releaseOrderReference
? 'Truck leaving'
: 'Truck arrival'
: 'Truck arrival — assign a truck first'}
</Menu.Item>
)}
{r.currentStatus === 'READY_FOR_PICKUP' && r.releaseDate && (
<Menu.Item leftSection={<FileText size={14} />} onClick={() => openReleaseDocument(r)}>
Exit paper
</Menu.Item>
)}
{r.currentStatus === 'READY_FOR_PICKUP' && r.releaseDate && (
<Menu.Item onClick={() => setDeliverItem(toInventoryItem(r))}>Deliver</Menu.Item>
)}
{r.inspectionStatus === 'PASSED' && (
<Menu.Item leftSection={<FileText size={14} />} onClick={() => openHandoverDocument(r)}>
{r.handoverDocumentReference ? 'View handover' : 'Handover'}
</Menu.Item>
)}
<Menu.Item onClick={() => setInspectId(r.id)}>Inspect / report</Menu.Item>
<Menu.Divider />
<Menu.Item leftSection={<PackageCheck size={14} />} onClick={() => setFeeItem(toInventoryItem(r))}>
Storage / fee preview
</Menu.Item>
<Menu.Item leftSection={<History size={14} />} onClick={() => setHistoryItem(toInventoryItem(r))}>
History
</Menu.Item>
</Menu.Dropdown>
</Menu>
</Group>
</Table.Td>
</Table.Tr>
@@ -2526,13 +2522,9 @@ function ImportUnloadedQueueTab({ enabled }: { enabled: boolean }) {
inventoryId={feeItem?.id ?? null}
/>
<ReleaseOrderModal opened={Boolean(releaseItem)} onClose={() => setReleaseItem(null)} item={releaseItem} />
<StoreInventoryModal opened={Boolean(storeItem)} onClose={() => setStoreItem(null)} item={storeItem} />
<MoveInventoryModal opened={Boolean(moveItem)} onClose={() => setMoveItem(null)} item={moveItem} />
<DeliverInventoryModal opened={Boolean(deliverItem)} onClose={() => setDeliverItem(null)} item={deliverItem} />
<TruckDispatchModal
opened={Boolean(loadTruckItem)}
onClose={() => setLoadTruckItem(null)}
bookingId={loadTruckItem?.booking?.id ?? null}
bookingReference={loadTruckItem?.booking?.reference ?? null}
/>
<ContainerItemsModal
opened={Boolean(containerItemsItem)}
onClose={() => setContainerItemsItem(null)}