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