mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-31 21:17:38 +00:00
116 lines
3.2 KiB
TypeScript
116 lines
3.2 KiB
TypeScript
import { Train, Truck, Wrench } from "lucide-react";
|
|
import { Grid, Stack } from "@mantine/core";
|
|
|
|
import type { IOverviewOperationsTab, IOverviewStatusCount } from "@/types/overview";
|
|
import { OverviewDonutChart } from "../OverviewDonutChart";
|
|
import { OverviewHorizontalBarChart } from "../OverviewHorizontalBarChart";
|
|
import { OverviewKpiStrip } from "../OverviewKpiStrip";
|
|
|
|
function formatStatusLabel(status: string) {
|
|
return status
|
|
.replace(/_/g, " ")
|
|
.toLowerCase()
|
|
.replace(/\b\w/g, (char) => char.toUpperCase());
|
|
}
|
|
|
|
function sumCounts(items: IOverviewStatusCount[]) {
|
|
return items.reduce((sum, item) => sum + item.count, 0);
|
|
}
|
|
|
|
function countByStatus(items: IOverviewStatusCount[], status: string) {
|
|
return items.find((item) => item.status === status)?.count ?? 0;
|
|
}
|
|
|
|
function toDonutData(items: IOverviewStatusCount[]) {
|
|
return items.map((item) => ({
|
|
name: formatStatusLabel(item.status),
|
|
value: item.count,
|
|
}));
|
|
}
|
|
|
|
interface OverviewFleetTabPanelProps {
|
|
data: IOverviewOperationsTab;
|
|
}
|
|
|
|
export function OverviewFleetTabPanel({ data }: OverviewFleetTabPanelProps) {
|
|
return (
|
|
<Stack gap="lg">
|
|
<OverviewKpiStrip
|
|
items={[
|
|
{
|
|
label: "Total trains",
|
|
value: sumCounts(data.trainStatusBreakdown),
|
|
icon: Train,
|
|
accent: "gold",
|
|
hint: "All time",
|
|
},
|
|
{
|
|
label: "Active trains",
|
|
value: data.kpis.trainsActive,
|
|
icon: Train,
|
|
accent: "emerald",
|
|
},
|
|
{
|
|
label: "Total wagons",
|
|
value: sumCounts(data.wagonStatusBreakdown),
|
|
icon: Truck,
|
|
accent: "gold",
|
|
hint: "All time",
|
|
},
|
|
{
|
|
label: "Wagons available",
|
|
value: data.kpis.wagonsAvailable,
|
|
icon: Truck,
|
|
accent: "emerald",
|
|
},
|
|
{
|
|
label: "In maintenance",
|
|
value: countByStatus(data.wagonStatusBreakdown, "MAINTENANCE"),
|
|
icon: Wrench,
|
|
accent: "amber",
|
|
},
|
|
]}
|
|
/>
|
|
|
|
<Grid gap="md">
|
|
<Grid.Col span={{ base: 12, md: 6 }}>
|
|
<OverviewHorizontalBarChart
|
|
title="Wagon fleet by type"
|
|
data={data.wagonsByType.map((item) => ({
|
|
label: item.label,
|
|
value: item.count,
|
|
}))}
|
|
valueLabel="Wagons"
|
|
/>
|
|
</Grid.Col>
|
|
<Grid.Col span={{ base: 12, md: 6 }}>
|
|
<OverviewHorizontalBarChart
|
|
title="Wagons by yard"
|
|
data={data.wagonsByYard.map((item) => ({
|
|
label: item.label,
|
|
value: item.count,
|
|
}))}
|
|
valueLabel="Wagons"
|
|
emptyMessage="No wagons assigned to yards"
|
|
/>
|
|
</Grid.Col>
|
|
</Grid>
|
|
|
|
<Grid gap="md">
|
|
<Grid.Col span={{ base: 12, md: 6 }}>
|
|
<OverviewDonutChart
|
|
title="Train status"
|
|
data={toDonutData(data.trainStatusBreakdown)}
|
|
/>
|
|
</Grid.Col>
|
|
<Grid.Col span={{ base: 12, md: 6 }}>
|
|
<OverviewDonutChart
|
|
title="Wagon status"
|
|
data={toDonutData(data.wagonStatusBreakdown)}
|
|
/>
|
|
</Grid.Col>
|
|
</Grid>
|
|
</Stack>
|
|
);
|
|
}
|