Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 6x 6x 6x 6x 6x 6x 6x 1x 5x 5x 5x 5x 6x 6x 6x 6x 6x 1x 1x | /**
* @file StatCard.tsx
* @description
* Generic KPI/stat card for dashboards with a large value, subtitle, and loading state.
*
* @usage
* <StatCard title={t('common:dashboard.kpi.totalItems')} value={count} loading={isLoading} />
* @enterprise
* - Reusable component for consistent KPI display
* - Built-in loading state with skeleton
* - Handles null/undefined values gracefully
* - Uses MUI Card for consistent styling
*/
import * as React from 'react';
import { Card, CardContent, Typography, Skeleton } from '@mui/material';
// Props for the StatCard component
export interface StatCardProps {
title: string;
value: number | null | undefined;
loading?: boolean;
}
// StatCard component definition
const StatCard: React.FC<StatCardProps> = ({ title, value, loading }) => {
return (
<Card variant="outlined" sx={{ height: '100%' }}>
<CardContent>
<Typography variant="body2" color="text.secondary" gutterBottom>
{title}
</Typography>
{loading ? (
<Skeleton variant="text" width={80} height={40} />
) : (
<Typography variant="h4" data-testid="stat-value">
{value ?? '—'}
</Typography>
)}
</CardContent>
</Card>
);
};
export default StatCard;
|