mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-09 02:28:18 +00:00
style: WIP BatchBoard and train schedule
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
import { useMemo, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import {
|
||||
ActionIcon,
|
||||
Alert,
|
||||
Box,
|
||||
Button,
|
||||
Card,
|
||||
Container,
|
||||
Group,
|
||||
Menu,
|
||||
Paper,
|
||||
RingProgress,
|
||||
Select,
|
||||
@@ -21,7 +22,9 @@ import {
|
||||
ArrowRight,
|
||||
CalendarClock,
|
||||
CalendarDays,
|
||||
Eye,
|
||||
Inbox,
|
||||
MoreHorizontal,
|
||||
Package,
|
||||
Ruler,
|
||||
Train,
|
||||
@@ -31,7 +34,7 @@ import {
|
||||
import type { ColumnDef } from "@edr/ui-common";
|
||||
import { DataTable, DataTableFooter, usePagination } from "@edr/ui-common";
|
||||
|
||||
import Breadcrumbs from "@/components/ui/Breadcrumbs";
|
||||
import { KpiStrip, PageContainer, PageHeader } from "@/components/page";
|
||||
import FleetToolbar from "@/components/fleet/FleetToolbar";
|
||||
import { useFleetViewMode } from "@/components/fleet/useFleetViewMode";
|
||||
import {
|
||||
@@ -40,7 +43,7 @@ import {
|
||||
totalBookingCount,
|
||||
WindowStatusPill,
|
||||
} from "@/components/trainScheduling/batchVisuals";
|
||||
import { RouteCorridor, StatTile } from "@/components/trainScheduling/scheduleVisuals";
|
||||
import { RouteCorridor } from "@/components/trainScheduling/scheduleVisuals";
|
||||
import { ruleEngineTable } from "@/components/ruleEngine/ruleEngineStyles";
|
||||
import { FREIGHT_BRAND, FREIGHT_BRAND_DARK } from "@/theme/freight-brand";
|
||||
import { useBatchBoard } from "@/hooks/trainScheduling/useTrainScheduling";
|
||||
@@ -365,7 +368,7 @@ function CardSkeleton() {
|
||||
|
||||
export default function BatchBoardPage() {
|
||||
const navigate = useNavigate();
|
||||
const { data, isLoading, isFetching, refetch } = useBatchBoard();
|
||||
const { data, isLoading, isError, isFetching, refetch } = useBatchBoard();
|
||||
const { viewMode, setViewMode } = useFleetViewMode("batch-board");
|
||||
const { pagination, setPagination } = usePagination({ pageSize: 10 });
|
||||
const [search, setSearch] = useState("");
|
||||
@@ -549,72 +552,69 @@ export default function BatchBoardPage() {
|
||||
header: "",
|
||||
meta: { headerClassName, cellClassName: `${cellClassName} whitespace-nowrap` },
|
||||
cell: ({ row }) => (
|
||||
<Group justify="flex-end" wrap="nowrap">
|
||||
<Button
|
||||
variant="light"
|
||||
color="green"
|
||||
size="compact-sm"
|
||||
rightSection={<ArrowRight size={14} />}
|
||||
onClick={() =>
|
||||
navigate(`/dashboard/operations/batch-board/${row.original.scheduleId}`)
|
||||
}
|
||||
>
|
||||
View windows
|
||||
</Button>
|
||||
<Group justify="flex-end" wrap="nowrap" onClick={(e) => e.stopPropagation()}>
|
||||
<Menu position="bottom-end" withinPortal shadow="md" width={180}>
|
||||
<Menu.Target>
|
||||
<ActionIcon variant="subtle" color="gray" aria-label="Row actions">
|
||||
<MoreHorizontal size={16} />
|
||||
</ActionIcon>
|
||||
</Menu.Target>
|
||||
<Menu.Dropdown>
|
||||
<Menu.Item
|
||||
leftSection={<Eye size={15} />}
|
||||
onClick={() =>
|
||||
navigate(`/dashboard/operations/batch-board/${row.original.scheduleId}`)
|
||||
}
|
||||
>
|
||||
View windows
|
||||
</Menu.Item>
|
||||
</Menu.Dropdown>
|
||||
</Menu>
|
||||
</Group>
|
||||
),
|
||||
},
|
||||
];
|
||||
}, [navigate]);
|
||||
|
||||
const tableStatus = isLoading ? "loading" : "success";
|
||||
const tableStatus = isLoading ? "loading" : isError ? "error" : "success";
|
||||
|
||||
return (
|
||||
<Container fluid py="lg" px="xl">
|
||||
<Breadcrumbs items={[{ label: "Operations" }, { label: "Batch board" }]} />
|
||||
<PageContainer>
|
||||
<PageHeader
|
||||
title="Batch Board"
|
||||
subtitle="Active schedules and their booking windows."
|
||||
action={
|
||||
<Button variant="default" loading={isFetching} onClick={() => void refetch()}>
|
||||
Refresh
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
|
||||
<SimpleGrid cols={{ base: 1, xs: 3 }} spacing="md" mt="md">
|
||||
<StatTile
|
||||
icon={Train}
|
||||
label="Active schedules"
|
||||
value={isLoading ? "…" : schedules.length}
|
||||
hint="on the board right now"
|
||||
accent="#F2A516"
|
||||
graph="area"
|
||||
graphAccent="gold"
|
||||
/>
|
||||
<StatTile
|
||||
icon={CalendarDays}
|
||||
label="Open windows"
|
||||
value={isLoading ? "…" : summary.openWindows}
|
||||
hint="accepting bookings"
|
||||
accent="#FB8C2E"
|
||||
graph="line"
|
||||
graphAccent="orange"
|
||||
/>
|
||||
<StatTile
|
||||
icon={Package}
|
||||
label="Bookings in play"
|
||||
value={isLoading ? "…" : summary.totalBookings}
|
||||
hint={`${summary.totalWagons} wagons allocated`}
|
||||
accent="#F2A516"
|
||||
graph="ring"
|
||||
graphAccent="gold"
|
||||
graphPct={
|
||||
schedules.length
|
||||
? Math.min(100, Math.round((summary.openWindows / schedules.length) * 100))
|
||||
: 0
|
||||
}
|
||||
/>
|
||||
</SimpleGrid>
|
||||
<KpiStrip
|
||||
loading={isLoading}
|
||||
items={[
|
||||
{
|
||||
label: "Active schedules",
|
||||
value: schedules.length,
|
||||
hint: "on the board right now",
|
||||
icon: Train,
|
||||
},
|
||||
{
|
||||
label: "Open windows",
|
||||
value: summary.openWindows,
|
||||
hint: "accepting bookings",
|
||||
icon: CalendarDays,
|
||||
},
|
||||
{
|
||||
label: "Bookings in play",
|
||||
value: summary.totalBookings,
|
||||
hint: `${summary.totalWagons} wagons allocated`,
|
||||
icon: Package,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<Card
|
||||
radius="lg"
|
||||
padding={0}
|
||||
withBorder
|
||||
mt="lg"
|
||||
style={{ borderColor: "var(--mantine-color-gray-2)" }}
|
||||
>
|
||||
<Card p={0}>
|
||||
<Stack gap={0}>
|
||||
<Box px="md" pt="md" pb="sm" w="100%">
|
||||
<FleetToolbar
|
||||
@@ -647,6 +647,17 @@ export default function BatchBoardPage() {
|
||||
columns={columns}
|
||||
data={paged}
|
||||
status={tableStatus}
|
||||
onRowClick={(schedule) =>
|
||||
navigate(`/dashboard/operations/batch-board/${schedule.scheduleId}`)
|
||||
}
|
||||
error={
|
||||
isError
|
||||
? {
|
||||
message: "Failed to load the batch board.",
|
||||
onRetry: () => void refetch(),
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
emptyMessage="No active schedules"
|
||||
pagination={{
|
||||
pageIndex: pagination.pageIndex,
|
||||
@@ -688,7 +699,6 @@ export default function BatchBoardPage() {
|
||||
borderRadius: 20,
|
||||
background: "white",
|
||||
border: "1px solid var(--mantine-color-gray-2)",
|
||||
boxShadow: "0 4px 12px rgba(15,23,42,0.06)",
|
||||
}}
|
||||
>
|
||||
<Inbox size={28} color="var(--mantine-color-gray-5)" />
|
||||
@@ -711,18 +721,6 @@ export default function BatchBoardPage() {
|
||||
)}
|
||||
</Stack>
|
||||
</Card>
|
||||
|
||||
<Group justify="flex-end" mt="md">
|
||||
<Button
|
||||
variant="subtle"
|
||||
color="gray"
|
||||
size="xs"
|
||||
loading={isFetching}
|
||||
onClick={() => void refetch()}
|
||||
>
|
||||
Refresh
|
||||
</Button>
|
||||
</Group>
|
||||
</Container>
|
||||
</PageContainer>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user