Files
edr-platform/apps/edr-freight-web/backoffice/src/pages/warehouses/LoadedInventoryPage.tsx
Hagernesh 95c6a71438 feat(warehouse): batch 3 — loading, dispatch & train-departure visibility
- WarehouseLoading entity + Batch3 migration (wagon loading records)
- wagon-aware load() with validation; dispatch moved to PATCH
- read-only SchedulingReadFacade (schedule/wagon/departure) — never writes scheduling
- new endpoints: GET /warehouse-loadings, loadable-wagons, booking schedule
- Loading Queue / Loaded Inventory / Dispatch Queue pages + routes + sidebar
- FreightVisual illustrations (page heroes + empty states)
- booking detail: loaded/dispatched/wagon + read-only train schedule

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 12:44:40 +00:00

87 lines
3.3 KiB
TypeScript

import { Badge, Card, Container, Group, Loader, Stack, Table, Text } from '@mantine/core';
import Breadcrumbs from '@/components/ui/Breadcrumbs';
import { FreightVisual, VisualEmptyState, WarehouseHero, formatDate, formatNumber } from '@/components/warehouses';
import { useWarehouseLoadings } from '@/hooks/useWarehouses';
/** Record of every inventory item loaded onto a wagon. */
export default function LoadedInventoryPage() {
const { data, isLoading } = useWarehouseLoadings();
const loadings = data ?? [];
return (
<Container size="xxl" py="lg">
<Breadcrumbs items={[{ label: 'Loaded inventory' }]} />
<Stack gap="lg" mt="sm">
<WarehouseHero
variant="container"
secondaryVariant="wagon"
title="Loaded Inventory"
subtitle="Items loaded onto wagons, with their loading records."
/>
<Card withBorder radius="md" padding="lg">
{isLoading ? (
<Group justify="center" py="xl">
<Loader />
</Group>
) : loadings.length === 0 ? (
<VisualEmptyState
variant="container"
title="No loaded inventory yet"
description="Once items are loaded onto a wagon, their records show here."
/>
) : (
<Table.ScrollContainer minWidth={760}>
<Table verticalSpacing="sm" highlightOnHover>
<Table.Thead>
<Table.Tr>
<Table.Th>Wagon</Table.Th>
<Table.Th>Warehouse</Table.Th>
<Table.Th>Zone</Table.Th>
<Table.Th>Loaded Weight (kg)</Table.Th>
<Table.Th>Loaded At</Table.Th>
<Table.Th>Status</Table.Th>
</Table.Tr>
</Table.Thead>
<Table.Tbody>
{loadings.map((l) => (
<Table.Tr key={l.id}>
<Table.Td>
<Group gap={6} wrap="nowrap">
<FreightVisual variant="wagon" size={22} />
<Text fw={600} size="sm">
{l.wagonNumber ?? l.wagonId.slice(0, 8)}
</Text>
</Group>
</Table.Td>
<Table.Td>
{l.inventory?.warehouse
? `${l.inventory.warehouse.name} (${l.inventory.warehouse.code})`
: '—'}
</Table.Td>
<Table.Td>{l.inventory?.zone ? l.inventory.zone.name : '—'}</Table.Td>
<Table.Td>{formatNumber(l.loadedWeight)}</Table.Td>
<Table.Td>{formatDate(l.loadedAt)}</Table.Td>
<Table.Td>
<Badge
variant="light"
color={l.inventory?.status === 'DISPATCHED' ? 'green' : 'teal'}
size="sm"
>
{l.inventory?.status ?? 'LOADED'}
</Badge>
</Table.Td>
</Table.Tr>
))}
</Table.Tbody>
</Table>
</Table.ScrollContainer>
)}
</Card>
</Stack>
</Container>
);
}