feat(mui): migrate Dashboard (Přehled) onto MUI kit

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
BOHA
2026-06-07 01:19:49 +02:00
parent 5ca03bd662
commit 5459d8c325
7 changed files with 1205 additions and 968 deletions

View File

@@ -1,4 +1,7 @@
import { motion } from "framer-motion";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import { StatCard, type StatCardColor } from "../../ui";
import { formatCurrency } from "../../utils/formatters";
interface KpiCard {
@@ -108,11 +111,13 @@ function buildInvoiceKpi(invoices: InvoicesData): KpiCard {
};
}
const KPI_CLASS_MAP: Record<number, string> = {
4: "admin-kpi-4",
3: "admin-kpi-3",
2: "admin-kpi-2",
1: "admin-kpi-1",
// Maps the legacy KPI color tokens to the StatCard color palette
// (danger → error; the rest are 1:1).
const KPI_COLOR_MAP: Record<string, StatCardColor> = {
success: "success",
info: "info",
warning: "warning",
danger: "error",
};
export default function DashKpiCards({ dashData }: DashKpiCardsProps) {
@@ -121,36 +126,50 @@ export default function DashKpiCards({ dashData }: DashKpiCardsProps) {
return null;
}
const kpiClass = KPI_CLASS_MAP[Math.min(kpiCards.length, 4)] || "admin-kpi-4";
return (
<motion.div
className={`admin-kpi-grid ${kpiClass}`}
<Box
component={motion.div}
initial={{ opacity: 0, y: 12 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.25, delay: 0.06 }}
sx={{
display: "grid",
gridTemplateColumns: {
xs: "1fr",
sm: "repeat(2, 1fr)",
lg: `repeat(${Math.min(kpiCards.length, 4)}, 1fr)`,
},
gap: 2,
mb: 3,
}}
>
{kpiCards.map((kpi) => (
<div key={kpi.label} className={`admin-stat-card ${kpi.color}`}>
<div className="admin-stat-label">{kpi.label}</div>
<div className="admin-stat-value admin-mono">
{kpi.value}
{kpi.sub && (
<small
className="text-muted"
style={{
fontSize: "0.75em",
fontWeight: 500,
marginLeft: "0.25rem",
}}
>
{kpi.sub}
</small>
)}
</div>
{kpi.footer && <div className="admin-stat-footer">{kpi.footer}</div>}
</div>
<StatCard
key={kpi.label}
color={KPI_COLOR_MAP[kpi.color] ?? "default"}
label={kpi.label}
value={
<>
{kpi.value}
{kpi.sub && (
<Typography
component="span"
color="text.secondary"
sx={{
fontSize: "0.75em",
fontWeight: 500,
ml: 0.5,
fontFamily: "inherit",
}}
>
{kpi.sub}
</Typography>
)}
</>
}
footer={kpi.footer ?? undefined}
/>
))}
</motion.div>
</Box>
);
}