File size: 2,174 Bytes
e9d4f6a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
"use client";

import { motion } from "framer-motion";
import { LucideIcon } from "lucide-react";

interface StatCardProps {
  title: string;
  value: string | number;
  icon: LucideIcon;
  change?: number;
  suffix?: string;
  color?: "cyan" | "violet" | "emerald" | "amber" | "rose" | "neutral";
  delay?: number;
}

const colorMap = {
  cyan: { border: "border-[#38bdf8]/30", text: "text-[#38bdf8]", glow: "glow-cyan", iconBg: "bg-[#38bdf8]/10" },
  violet: { border: "border-[#818cf8]/30", text: "text-[#818cf8]", glow: "glow-violet", iconBg: "bg-[#818cf8]/10" },
  emerald: { border: "border-[#00d68f]/30", text: "text-[#00d68f]", glow: "glow-emerald", iconBg: "bg-[#00d68f]/10" },
  amber: { border: "border-[#f59e0b]/30", text: "text-[#f59e0b]", glow: "glow-amber", iconBg: "bg-[#f59e0b]/10" },
  rose: { border: "border-[#f43f5e]/30", text: "text-[#f43f5e]", glow: "glow-rose", iconBg: "bg-[#f43f5e]/10" },
  neutral: { border: "border-white/[0.06]", text: "text-[#9a9aae]", glow: "", iconBg: "bg-white/[0.04]" },
};

export default function StatCard({ title, value, icon: Icon, change, suffix = "", color = "cyan", delay = 0 }: StatCardProps) {
  const cfg = colorMap[color];
  return (
    <motion.div
      initial={{ opacity: 0, y: 12 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.4, delay: delay * 0.05, ease: [0.23, 1, 0.32, 1] }}
      className={`glass rounded-xl p-4 border-l-2 ${cfg.border} ${cfg.glow}`}
    >
      <div className="flex items-center justify-between mb-3">
        <div className={`p-2 rounded-lg ${cfg.iconBg}`}>
          <Icon className={`w-4 h-4 ${cfg.text}`} />
        </div>
        {change !== undefined && (
          <span className={`text-[11px] font-medium ${change >= 0 ? "text-[#00d68f]" : "text-[#f43f5e]"}`}>
            {change >= 0 ? "+" : ""}{change.toFixed(2)}%
          </span>
        )}
      </div>
      <div className="text-[10px] font-bold text-[#5a5a6e] uppercase tracking-widest mb-1">{title}</div>
      <div className={`text-xl font-bold tabular-nums ${cfg.text}`}>
        {typeof value === "number" ? value.toLocaleString() : value}{suffix}
      </div>
    </motion.div>
  );
}