Files
monitoring-app/src/frontend/components/StatsCard.tsx
2026-04-02 11:59:21 +08:00

67 lines
1.6 KiB
TypeScript

import { Card, Group, Text, ThemeIcon, Stack } from '@mantine/core'
import { IconType } from 'react-icons'
interface StatsCardProps {
title: string
value: string | number
description?: string
icon: IconType
color?: string
trend?: {
value: string
positive: boolean
}
}
export function StatsCard({ title, value, description, icon: Icon, color, trend }: StatsCardProps) {
return (
<Card
withBorder
padding="lg"
radius="xl"
className="premium-card"
styles={(theme) => ({
root: {
backgroundColor: 'var(--mantine-color-body)',
borderColor: 'rgba(128,128,128,0.1)',
},
})}
>
<Group justify="space-between" mb="xs">
<ThemeIcon
size={42}
radius="md"
variant="light"
color={color || 'brand-blue'}
styles={{
root: {
background: 'rgba(124, 58, 237, 0.1)',
},
}}
>
<Icon size={22} />
</ThemeIcon>
{trend && (
<Text size="xs" fw={700} c={trend.positive ? 'teal' : 'red'}>
{trend.positive ? '+' : ''}{trend.value}%
</Text>
)}
</Group>
<Stack gap={0}>
<Text size="sm" c="dimmed" fw={600} style={{ letterSpacing: '0.02em', textTransform: 'uppercase' }}>
{title}
</Text>
<Text size="2xl" fw={800} mt={4}>
{value}
</Text>
{description && (
<Text size="xs" c="dimmed" mt={4}>
{description}
</Text>
)}
</Stack>
</Card>
)
}