| '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> |
| ) |
| } |
|
|