mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-07 03:32:06 +00:00
86 lines
2.3 KiB
TypeScript
86 lines
2.3 KiB
TypeScript
import { Box, ButtonBase } from "@mui/material";
|
|
import { Text } from "@/components/ui/text";
|
|
|
|
export interface DashboardBarListRow {
|
|
id: string;
|
|
label: string;
|
|
count: number;
|
|
}
|
|
|
|
interface DashboardBarListProps {
|
|
rows: DashboardBarListRow[];
|
|
onSelectRow?: (row: DashboardBarListRow) => void;
|
|
isSelectable?: (row: DashboardBarListRow) => boolean;
|
|
ariaLabel: string;
|
|
}
|
|
|
|
function percentOf(count: number, max: number): number {
|
|
if (max <= 0 || count <= 0) {
|
|
return 0;
|
|
}
|
|
|
|
return Math.round((count / max) * 100);
|
|
}
|
|
|
|
function BarListRow({ row, width }: { row: DashboardBarListRow; width: number }) {
|
|
return (
|
|
<Box className="flex w-full flex-col gap-1 py-1.5">
|
|
<Box className="flex items-baseline justify-between gap-2">
|
|
<Text variant="description" className="truncate">
|
|
{row.label}
|
|
</Text>
|
|
<Text variant="description" tone="muted">
|
|
{row.count.toLocaleString()}
|
|
</Text>
|
|
</Box>
|
|
<Box className="h-2 w-full overflow-hidden rounded-full" sx={{ bgcolor: "action.hover" }}>
|
|
{width > 0 && (
|
|
<Box
|
|
data-testid="dashboard-bar-mark"
|
|
className="h-full rounded-full"
|
|
sx={{ width: `${width}%`, bgcolor: "primary.main" }}
|
|
/>
|
|
)}
|
|
</Box>
|
|
</Box>
|
|
);
|
|
}
|
|
|
|
export function DashboardBarList({
|
|
rows,
|
|
onSelectRow,
|
|
isSelectable,
|
|
ariaLabel,
|
|
}: DashboardBarListProps) {
|
|
const max = Math.max(...rows.map((row) => row.count), 0);
|
|
|
|
return (
|
|
<Box aria-label={ariaLabel} className="flex flex-col">
|
|
{rows.map((row) => {
|
|
const width = percentOf(row.count, max);
|
|
const selectable = Boolean(onSelectRow) && row.count > 0 && (isSelectable?.(row) ?? true);
|
|
|
|
return selectable ? (
|
|
<ButtonBase
|
|
key={row.id}
|
|
onClick={() => onSelectRow?.(row)}
|
|
sx={{
|
|
width: "100%",
|
|
textAlign: "left",
|
|
borderRadius: 1,
|
|
px: 1,
|
|
mx: -1,
|
|
cursor: "pointer",
|
|
}}
|
|
>
|
|
<BarListRow row={row} width={width} />
|
|
</ButtonBase>
|
|
) : (
|
|
<Box key={row.id} sx={{ px: 1, mx: -1 }}>
|
|
<BarListRow row={row} width={width} />
|
|
</Box>
|
|
);
|
|
})}
|
|
</Box>
|
|
);
|
|
}
|