mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
109 lines
3.5 KiB
TypeScript
109 lines
3.5 KiB
TypeScript
import type { LucideIcon } from "lucide-react";
|
|
import { Card, Group, Stack, Text, Paper } from "@mantine/core";
|
|
|
|
export interface StatItem {
|
|
label: string;
|
|
value: number | string;
|
|
hint?: string;
|
|
icon: LucideIcon;
|
|
accent?: "default" | "amber" | "emerald" | "rose";
|
|
}
|
|
|
|
const accentColors = {
|
|
default: { bg: "var(--mantine-color-gray-1)", color: "var(--mantine-color-gray-6)" },
|
|
amber: { bg: "var(--mantine-color-yellow-1)", color: "var(--mantine-color-yellow-6)" },
|
|
emerald: { bg: "var(--freight-brand-muted)", color: "var(--freight-brand)" },
|
|
rose: { bg: "var(--mantine-color-red-1)", color: "var(--mantine-color-red-6)" },
|
|
};
|
|
|
|
export function BookingStatGrid({ items }: { items: StatItem[] }) {
|
|
return (
|
|
<Paper
|
|
p="md"
|
|
radius="lg"
|
|
withBorder
|
|
style={{
|
|
background: "white",
|
|
border: "1px solid var(--mantine-color-gray-2)",
|
|
overflowX: "auto",
|
|
overflowY: "hidden",
|
|
WebkitOverflowScrolling: "touch",
|
|
scrollBehavior: "smooth",
|
|
}}
|
|
>
|
|
<Group
|
|
gap="lg"
|
|
style={{
|
|
minWidth: "min-content",
|
|
display: "flex",
|
|
flexWrap: "nowrap",
|
|
}}
|
|
>
|
|
{items.map((item) => {
|
|
const Icon = item.icon;
|
|
const accent = item.accent ?? "default";
|
|
const accentStyle = accentColors[accent];
|
|
|
|
return (
|
|
<Card
|
|
key={item.label}
|
|
p="lg"
|
|
radius="lg"
|
|
withBorder
|
|
style={{
|
|
background: "white",
|
|
border: "1px solid var(--mantine-color-gray-2)",
|
|
transition: "all 0.2s ease",
|
|
cursor: "pointer",
|
|
minWidth: "280px",
|
|
width: "280px",
|
|
flexShrink: 0,
|
|
}}
|
|
onMouseEnter={(e) => {
|
|
e.currentTarget.style.boxShadow = "0 4px 12px rgba(34, 197, 94, 0.12)";
|
|
e.currentTarget.style.borderColor = "var(--freight-brand-border)";
|
|
}}
|
|
onMouseLeave={(e) => {
|
|
e.currentTarget.style.boxShadow = "none";
|
|
e.currentTarget.style.borderColor = "var(--mantine-color-gray-2)";
|
|
}}
|
|
>
|
|
<Group justify="space-between" align="flex-start">
|
|
<Stack gap="xs" style={{ flex: 1 }}>
|
|
<Text size="xs" fw={600} c="dimmed" tt="uppercase">
|
|
{item.label}
|
|
</Text>
|
|
<Text size="32px" fw={700} style={{ lineHeight: 1, letterSpacing: "-0.02em" }}>
|
|
{item.value}
|
|
</Text>
|
|
{item.hint && (
|
|
<Text size="xs" c="dimmed">
|
|
{item.hint}
|
|
</Text>
|
|
)}
|
|
</Stack>
|
|
<div
|
|
style={{
|
|
display: "flex",
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
width: "44px",
|
|
height: "44px",
|
|
borderRadius: "10px",
|
|
background: accentStyle.bg,
|
|
color: accentStyle.color,
|
|
flexShrink: 0,
|
|
transition: "transform 0.2s ease",
|
|
}}
|
|
>
|
|
<Icon size={22} strokeWidth={1.75} />
|
|
</div>
|
|
</Group>
|
|
</Card>
|
|
);
|
|
})}
|
|
</Group>
|
|
</Paper>
|
|
);
|
|
}
|