import { cn } from "@/lib/utils" import type { LucideIcon } from "lucide-react" import { TrendingUp, TrendingDown, Minus } from "lucide-react" import { AnimatedNumber } from "@/components/ui/animated-number" interface StatsCardProps { label: string value: string | number sub?: string icon: LucideIcon trend?: { value: number; label: string } variant?: "default" | "success" | "warning" | "danger" progress?: number className?: string } export function StatsCard({ label, value, sub, icon: Icon, trend, variant = "default", progress, className, }: StatsCardProps) { const themes = { default: { icon: "text-indigo-400 bg-indigo-500/10 border-indigo-500/20", glow: "group-hover:shadow-indigo-500/10", bar: "from-indigo-500 to-violet-500", gradient: "group-hover:from-indigo-500/[0.04]", }, success: { icon: "text-emerald-400 bg-emerald-500/10 border-emerald-500/20", glow: "group-hover:shadow-emerald-500/10", bar: "from-emerald-500 to-teal-500", gradient: "group-hover:from-emerald-500/[0.04]", }, warning: { icon: "text-amber-400 bg-amber-500/10 border-amber-500/20", glow: "group-hover:shadow-amber-500/10", bar: "from-amber-500 to-orange-500", gradient: "group-hover:from-amber-500/[0.04]", }, danger: { icon: "text-red-400 bg-red-500/10 border-red-500/20", glow: "group-hover:shadow-red-500/10", bar: "from-red-500 to-rose-500", gradient: "group-hover:from-red-500/[0.04]", }, } const theme = themes[variant] const trendColor = !trend ? "" : trend.value > 0 ? "text-emerald-400" : trend.value < 0 ? "text-red-400" : "text-white/40" const TrendIcon = !trend ? Minus : trend.value > 0 ? TrendingUp : trend.value < 0 ? TrendingDown : Minus // Detect if value is a plain number (animate) or a formatted string const isNumeric = typeof value === "number" // For currency strings like "$4,200" — extract the number to animate const isCurrencyString = typeof value === "string" && value.startsWith("$") const numericVal = isNumeric ? value : isCurrencyString ? parseFloat(value.replace(/[$,]/g, "")) : null return (
{/* Hover gradient */}
{/* Top accent line */}
{/* Label + icon */}

{label}

{/* Value — animated if numeric */}

{numericVal !== null ? ( ) : ( value )}

{/* Trend */} {trend && (
{trend.value > 0 ? "+" : ""}{trend.value}% {trend.label}
)} {/* Progress bar */} {progress !== undefined && (
)} {/* Sub */} {sub && (

{sub}

)}
) }