97 lines
2.4 KiB
TypeScript
97 lines
2.4 KiB
TypeScript
import { Card, Group, Text, ThemeIcon, Stack, Progress, Badge } from '@mantine/core'
|
|
import { IconType } from 'react-icons'
|
|
import { TbTrendingUp, TbTrendingDown } from 'react-icons/tb'
|
|
|
|
interface SummaryCardProps {
|
|
title: string
|
|
value: string | number
|
|
icon: IconType
|
|
color?: string
|
|
trend?: {
|
|
value: string
|
|
positive: boolean
|
|
}
|
|
progress?: {
|
|
value: number
|
|
label: string
|
|
}
|
|
isError?: boolean
|
|
}
|
|
|
|
export function SummaryCard({
|
|
title,
|
|
value,
|
|
icon: Icon,
|
|
color = 'brand-blue',
|
|
trend,
|
|
progress,
|
|
isError
|
|
}: SummaryCardProps) {
|
|
return (
|
|
<Card
|
|
withBorder
|
|
padding="xl"
|
|
radius="2xl"
|
|
className="glass"
|
|
styles={(theme) => ({
|
|
root: {
|
|
backgroundColor: isError && Number(value) > 0 ? 'rgba(239, 68, 68, 0.05)' : 'rgba(30, 41, 59, 0.4)',
|
|
borderColor: isError && Number(value) > 10 ? 'rgba(239, 68, 68, 0.3)' : 'rgba(255, 255, 255, 0.08)',
|
|
transition: 'transform 0.2s ease',
|
|
'&:hover': {
|
|
transform: 'translateY(-4px)',
|
|
}
|
|
}
|
|
})}
|
|
>
|
|
<Group justify="space-between" mb="md">
|
|
<ThemeIcon
|
|
size={48}
|
|
radius="lg"
|
|
variant="light"
|
|
color={isError ? 'red' : color}
|
|
>
|
|
<Icon size={26} />
|
|
</ThemeIcon>
|
|
|
|
{trend && (
|
|
<Badge
|
|
variant="light"
|
|
color={trend.positive ? 'teal' : 'red'}
|
|
leftSection={trend.positive ? <TbTrendingUp size={14} /> : <TbTrendingDown size={14} />}
|
|
>
|
|
{trend.value}
|
|
</Badge>
|
|
)}
|
|
</Group>
|
|
|
|
<Stack gap={2}>
|
|
<Text size="xs" fw={700} c="dimmed" style={{ letterSpacing: '0.05em' }}>
|
|
{title.toUpperCase()}
|
|
</Text>
|
|
<Text size="2.4rem" fw={900} style={{ fontFamily: 'Outfit, sans-serif', letterSpacing: '-1px' }}>
|
|
{value}
|
|
</Text>
|
|
</Stack>
|
|
|
|
{progress && (
|
|
<Box mt="md">
|
|
<Group justify="space-between" mb={4}>
|
|
<Text size="xs" c="dimmed" fw={600}>{progress.label}</Text>
|
|
<Text size="xs" fw={700}>{progress.value}%</Text>
|
|
</Group>
|
|
<Progress
|
|
value={progress.value}
|
|
color={color}
|
|
size="sm"
|
|
radius="xl"
|
|
styles={{ section: { transition: 'width 1s ease' } }}
|
|
/>
|
|
</Box>
|
|
)}
|
|
</Card>
|
|
)
|
|
}
|
|
|
|
import { Box } from '@mantine/core'
|