mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-07 11:39:00 +00:00
68 lines
1.7 KiB
TypeScript
68 lines
1.7 KiB
TypeScript
import type { ReactNode } from "react";
|
|
import { Box, ButtonBase, Paper } from "@mui/material";
|
|
import { Text } from "@/components/ui/text";
|
|
|
|
type KpiTone = "success" | "primary" | "info" | "warning";
|
|
|
|
const toneColor: Record<KpiTone, string> = {
|
|
success: "success.main",
|
|
primary: "primary.main",
|
|
info: "info.main",
|
|
warning: "warning.main",
|
|
};
|
|
|
|
interface DashboardKpiCardProps {
|
|
title: string;
|
|
value?: number;
|
|
icon: ReactNode;
|
|
tone: KpiTone;
|
|
loading?: boolean;
|
|
active?: boolean;
|
|
onSelect?: () => void;
|
|
}
|
|
|
|
export function DashboardKpiCard({
|
|
title,
|
|
value,
|
|
icon,
|
|
tone,
|
|
loading = false,
|
|
active = false,
|
|
onSelect,
|
|
}: DashboardKpiCardProps) {
|
|
const color = toneColor[tone];
|
|
const content = (
|
|
<Box className="flex w-full items-center gap-4 p-4" sx={{ textAlign: "left" }}>
|
|
<Box
|
|
className="flex h-12 w-12 shrink-0 items-center justify-center rounded-full"
|
|
sx={{ bgcolor: `${color}22`, color }}
|
|
>
|
|
{icon}
|
|
</Box>
|
|
<Box className="flex min-w-0 flex-col gap-0.5">
|
|
<Text variant="label" tone="muted">
|
|
{title}
|
|
</Text>
|
|
<Text variant="label" sx={{ fontSize: 28, fontWeight: 700, lineHeight: 1.2 }}>
|
|
{loading ? "…" : (value ?? 0).toLocaleString()}
|
|
</Text>
|
|
</Box>
|
|
</Box>
|
|
);
|
|
|
|
return (
|
|
<Paper
|
|
variant="outlined"
|
|
className="min-h-[104px]"
|
|
sx={{ borderLeftWidth: 4, borderLeftStyle: "solid", borderLeftColor: color }}
|
|
>
|
|
{active && Boolean(onSelect) ? (
|
|
<ButtonBase sx={{ width: "100%", cursor: "pointer" }} onClick={onSelect}>
|
|
{content}
|
|
</ButtonBase>
|
|
) : (
|
|
content
|
|
)}
|
|
</Paper>
|
|
);
|
|
}
|