File size: 1,772 Bytes
7200823 de40b1a 7200823 de40b1a 7200823 de40b1a 7200823 | 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 | 'use client'
import { cn } from '@/lib/utils'
import { LucideIcon } from 'lucide-react'
interface Props { title: string; value: string; change?: number; changeLabel?: string; icon: LucideIcon; variant?: 'default'|'yellow'|'green'|'red'; className?: string }
const vs: Record<string, string> = { default:'border-hairline-dark', yellow:'border-brand-yellow/20 bg-brand-yellow/5', green:'border-trading-up/20 bg-trading-up/5', red:'border-trading-down/20 bg-trading-down/5' }
const is: Record<string, string> = { default:'bg-surface-elevated text-muted', yellow:'bg-brand-yellow/10 text-brand-yellow', green:'bg-trading-up/10 text-trading-up', red:'bg-trading-down/10 text-trading-down' }
export function StatCard({ title, value, change, changeLabel, icon: Icon, variant='default', className }: Props) {
return (
<div className={cn('p-5 rounded-xl bg-surface-card border transition-all duration-300 hover:border-brand-yellow/30 group', vs[variant], className)}>
<div className="flex items-start justify-between mb-3">
<span className="text-caption text-muted uppercase tracking-wider">{title}</span>
<div className={cn('p-2 rounded-lg', is[variant])}><Icon className="w-4 h-4" /></div>
</div>
<div className="font-mono text-num-display text-[#eaecef] tabular-nums leading-none">{value}</div>
{(change !== undefined || changeLabel) && (
<div className="mt-2 flex items-center gap-1.5">
{change !== undefined && <span className={cn('text-num-sm font-mono tabular-nums', change >= 0 ? 'text-trading-up' : 'text-trading-down')}>{change >= 0 ? '+' : ''}{change.toFixed(1)}%</span>}
{changeLabel && <span className="text-caption text-muted">{changeLabel}</span>}
</div>
)}
</div>
)
}
|