Files
edr-platform/apps/edr-freight-web/backoffice/src/components/overview/tabs/OverviewFleetTabPanel.tsx

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>
);
}