This commit is contained in:
Marshal
2026-06-12 12:59:01 +00:00
parent db39e77e90
commit 6b79348074
6 changed files with 166 additions and 399 deletions

View File

@@ -1,14 +1,5 @@
import {
ActionIcon,
Box,
Group,
SegmentedControl,
Stack,
Text,
ThemeIcon,
Title,
} from "@mantine/core";
import { Activity, RefreshCw } from "lucide-react";
import { ActionIcon, Group, SegmentedControl, Text } from "@mantine/core";
import { RefreshCw } from "lucide-react";
import type { OverviewRange } from "@/types/overview";
@@ -29,40 +20,6 @@ function formatRelativeTime(iso: string | undefined) {
return new Date(iso).toLocaleString();
}
/** Decorative line-art locomotive + rails — faint brand tint on the right. */
function TrainArtwork() {
return (
<Box
aria-hidden
style={{
position: "absolute",
right: -10,
bottom: -8,
width: 360,
height: 200,
opacity: 0.06,
pointerEvents: "none",
color: "var(--mantine-color-green-7)",
}}
>
<svg viewBox="0 0 360 200" fill="none" width="100%" height="100%">
<path d="M0 168 H360" stroke="currentColor" strokeWidth="2" strokeDasharray="2 10" strokeLinecap="round" />
<path d="M0 180 H360" stroke="currentColor" strokeWidth="2" />
<path d="M70 60 H250 a14 14 0 0 1 14 14 V150 H56 V94 a34 34 0 0 1 14-28 Z" stroke="currentColor" strokeWidth="3" />
<rect x="84" y="80" width="40" height="30" rx="6" stroke="currentColor" strokeWidth="3" />
<rect x="140" y="80" width="44" height="30" rx="6" stroke="currentColor" strokeWidth="3" />
<rect x="200" y="80" width="44" height="30" rx="6" stroke="currentColor" strokeWidth="3" />
<path d="M56 130 H264" stroke="currentColor" strokeWidth="3" />
<circle cx="96" cy="150" r="16" stroke="currentColor" strokeWidth="3" />
<circle cx="150" cy="150" r="16" stroke="currentColor" strokeWidth="3" />
<circle cx="214" cy="150" r="16" stroke="currentColor" strokeWidth="3" />
<path d="M264 120 H300 a8 8 0 0 1 8 8 V150 H300" stroke="currentColor" strokeWidth="3" />
<path d="M56 100 l-28 -10 M56 112 l-30 0 M56 124 l-28 10" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
</svg>
</Box>
);
}
interface OverviewPageHeaderProps {
range: OverviewRange;
onRangeChange: (range: OverviewRange) => void;
@@ -79,59 +36,31 @@ export function OverviewPageHeader({
isRefreshing,
}: OverviewPageHeaderProps) {
return (
<Box
style={{
position: "relative",
overflow: "hidden",
borderRadius: 20,
padding: "26px 28px",
background: "#ffffff",
border: "1px solid var(--mantine-color-gray-2)",
boxShadow: "0 1px 3px rgba(15,23,42,0.04)",
}}
>
<TrainArtwork />
<Group justify="space-between" align="flex-end" wrap="wrap" gap="lg" style={{ position: "relative" }}>
<Stack gap={6} style={{ minWidth: 0 }}>
<Group gap={8} align="center">
<ThemeIcon size={28} radius="md" variant="light" color="green">
<Activity size={16} />
</ThemeIcon>
<Text size="xs" fw={700} c="green.7" tt="uppercase" style={{ letterSpacing: 1.2 }}>
Freight Backoffice · Live
</Text>
</Group>
<Title order={1} style={{ letterSpacing: "-0.03em", fontSize: 34, lineHeight: 1.1, color: "#0f172a" }}>
Operations Overview
</Title>
<Text size="sm" c="dimmed">
Real-time freight performance · updated {formatRelativeTime(generatedAt)}
</Text>
</Stack>
<Group gap="sm" style={{ position: "relative" }}>
<SegmentedControl
value={range}
onChange={(value) => onRangeChange(value as OverviewRange)}
data={RANGE_OPTIONS}
size="sm"
radius="lg"
color="green"
/>
<ActionIcon
variant="light"
color="green"
size="lg"
radius="lg"
aria-label="Refresh dashboard"
onClick={onRefresh}
loading={isRefreshing}
>
<RefreshCw size={18} />
</ActionIcon>
</Group>
<Group justify="space-between" align="center" wrap="wrap" gap="md">
<Text size="sm" c="dimmed">
Updated {formatRelativeTime(generatedAt)}
</Text>
<Group gap="sm">
<SegmentedControl
value={range}
onChange={(value) => onRangeChange(value as OverviewRange)}
data={RANGE_OPTIONS}
size="sm"
radius="lg"
color="green"
/>
<ActionIcon
variant="light"
color="green"
size="lg"
radius="lg"
aria-label="Refresh dashboard"
onClick={onRefresh}
loading={isRefreshing}
>
<RefreshCw size={18} />
</ActionIcon>
</Group>
</Box>
</Group>
);
}