78 lines
2.7 KiB
JavaScript
78 lines
2.7 KiB
JavaScript
import PropTypes from 'prop-types';
|
|
import { Avatar, Box, Card, CardContent, Skeleton, Stack, Typography } from '@mui/material';
|
|
|
|
// ==============================|| STAT / KPI CARD (Doormile-style) ||============================== //
|
|
// Clean metric card: muted label, large value, a single soft-tinted rounded
|
|
// avatar holding the icon. No coloured top-stripe, no rainbow — colour appears
|
|
// only in the small avatar so a row of cards reads calm and corporate.
|
|
//
|
|
// `icon` is a rendered node, e.g. icon={<MdLocalShipping size={20} />}.
|
|
// `color` is a hex accent (defaults to brand purple); `caption` is the small
|
|
// muted line under the value (e.g. "96% of total").
|
|
|
|
export default function StatCard({ title, value, icon, color = '#C01227', caption, loading = false }) {
|
|
return (
|
|
<Card sx={{ height: '100%' }}>
|
|
<CardContent sx={{ p: { xs: 1.75, md: 2 }, '&:last-child': { pb: { xs: 1.75, md: 2 } } }}>
|
|
<Stack direction="row" justifyContent="space-between" alignItems="center" spacing={1}>
|
|
<Box sx={{ minWidth: 0, flex: 1 }}>
|
|
<Typography
|
|
variant="body2"
|
|
sx={{
|
|
fontWeight: 500,
|
|
color: 'text.secondary',
|
|
whiteSpace: 'nowrap',
|
|
overflow: 'hidden',
|
|
textOverflow: 'ellipsis'
|
|
}}
|
|
>
|
|
{title}
|
|
</Typography>
|
|
{loading ? (
|
|
<Skeleton variant="rounded" sx={{ width: 72, height: 30, mt: 0.5 }} animation="wave" />
|
|
) : (
|
|
<Typography
|
|
sx={{
|
|
mt: 0.25,
|
|
fontWeight: 700,
|
|
letterSpacing: '-0.015em',
|
|
color: 'grey.800',
|
|
lineHeight: 1.15,
|
|
fontSize: { xs: '1.375rem', md: '1.5rem' },
|
|
whiteSpace: 'nowrap',
|
|
overflow: 'hidden',
|
|
textOverflow: 'ellipsis'
|
|
}}
|
|
>
|
|
{value}
|
|
</Typography>
|
|
)}
|
|
{caption && (
|
|
<Typography variant="caption" sx={{ display: 'block', mt: 0.5, color: 'text.secondary' }}>
|
|
{caption}
|
|
</Typography>
|
|
)}
|
|
</Box>
|
|
{icon && (
|
|
<Avatar
|
|
variant="rounded"
|
|
sx={{ width: 42, height: 42, borderRadius: 2, bgcolor: `${color}14`, color, flexShrink: 0 }}
|
|
>
|
|
{icon}
|
|
</Avatar>
|
|
)}
|
|
</Stack>
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
}
|
|
|
|
StatCard.propTypes = {
|
|
title: PropTypes.node,
|
|
value: PropTypes.node,
|
|
icon: PropTypes.node,
|
|
color: PropTypes.string,
|
|
caption: PropTypes.node,
|
|
loading: PropTypes.bool
|
|
};
|