mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
94 lines
2.8 KiB
TypeScript
94 lines
2.8 KiB
TypeScript
import { Group, Stack, Text, Timeline, Tooltip } from "@mantine/core";
|
|
import { Check } from "lucide-react";
|
|
|
|
/** One stage of the last-mile delivery workflow. */
|
|
export interface LastMileStepState {
|
|
label: string;
|
|
done: boolean;
|
|
active: boolean;
|
|
/** Optional stamp/value shown next to the step (plate, time, distance…). */
|
|
detail?: string | null;
|
|
}
|
|
|
|
/**
|
|
* Compact 6-dot progress bar for a table row — filled = done, ringed = current,
|
|
* hollow = pending. Hover a dot for its label + stamp.
|
|
*/
|
|
export function LastMileStepBar({ steps }: { steps: LastMileStepState[] }) {
|
|
return (
|
|
<Group gap={4} wrap="nowrap">
|
|
{steps.map((s, i) => {
|
|
const color = s.done
|
|
? "var(--mantine-color-green-6)"
|
|
: s.active
|
|
? "var(--mantine-color-blue-5)"
|
|
: "var(--mantine-color-gray-4)";
|
|
return (
|
|
<Tooltip
|
|
key={i}
|
|
withArrow
|
|
label={`${s.label}${s.detail ? ` · ${s.detail}` : ""}`}
|
|
>
|
|
<span
|
|
style={{
|
|
width: 10,
|
|
height: 10,
|
|
borderRadius: "50%",
|
|
background: s.done ? color : "transparent",
|
|
border: `2px solid ${color}`,
|
|
boxShadow: s.active
|
|
? "0 0 0 2px var(--mantine-color-blue-1)"
|
|
: undefined,
|
|
display: "inline-block",
|
|
flex: "0 0 auto",
|
|
}}
|
|
/>
|
|
</Tooltip>
|
|
);
|
|
})}
|
|
</Group>
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Vertical stepper for the detail view — completed steps bulleted + green, the
|
|
* current step highlighted, each showing its stamp/value when known.
|
|
*/
|
|
export function LastMileStepper({ steps }: { steps: LastMileStepState[] }) {
|
|
const activeIndex = steps.findIndex((s) => s.active);
|
|
// Timeline highlights items with index < `active`; count of done steps drives it.
|
|
const doneCount = steps.filter((s) => s.done).length;
|
|
return (
|
|
<Timeline
|
|
active={activeIndex === -1 ? steps.length : doneCount}
|
|
bulletSize={22}
|
|
lineWidth={2}
|
|
color="green"
|
|
>
|
|
{steps.map((s, i) => (
|
|
<Timeline.Item
|
|
key={i}
|
|
bullet={s.done ? <Check size={12} /> : undefined}
|
|
title={
|
|
<Text size="sm" fw={s.active ? 600 : 500} c={s.active ? "blue" : undefined}>
|
|
{s.label}
|
|
</Text>
|
|
}
|
|
lineVariant={s.done ? "solid" : "dashed"}
|
|
>
|
|
<Stack gap={0}>
|
|
<Text size="xs" c="dimmed">
|
|
{s.done ? "Done" : s.active ? "Current step" : "Pending"}
|
|
</Text>
|
|
{s.detail && (
|
|
<Text size="xs" c="dimmed">
|
|
{s.detail}
|
|
</Text>
|
|
)}
|
|
</Stack>
|
|
</Timeline.Item>
|
|
))}
|
|
</Timeline>
|
|
);
|
|
}
|