42 lines
1.9 KiB
TypeScript
42 lines
1.9 KiB
TypeScript
interface StatCardProps {
|
|
label: string;
|
|
value: string | number;
|
|
sub?: string;
|
|
accent?: "green" | "red" | "blue" | "purple" | "gold";
|
|
delta?: string;
|
|
deltaUp?: boolean;
|
|
}
|
|
|
|
const accentColors = {
|
|
green: { val: "text-acid-green", border: "border-t-acid-green/40" },
|
|
red: { val: "text-red-400", border: "border-t-red-500/40" },
|
|
blue: { val: "text-blue-400", border: "border-t-blue-400/40" },
|
|
purple: { val: "text-purple-400", border: "border-t-purple-400/40" },
|
|
gold: { val: "text-yellow-400", border: "border-t-yellow-400/40" },
|
|
};
|
|
|
|
export default function StatCard({ label, value, sub, accent = "green", delta, deltaUp }: StatCardProps) {
|
|
const colors = accentColors[accent];
|
|
return (
|
|
<div className={`bg-wy-surface border border-wy-border border-t-2 ${colors.border} rounded-lg p-5 relative group hover:-translate-y-0.5 transition-transform duration-200`}>
|
|
<div className="text-xs font-mono tracking-widest text-wy-text-secondary uppercase mb-3">
|
|
{label}
|
|
</div>
|
|
<div className={`text-4xl font-black tracking-tight ${colors.val} leading-none mb-1`}>
|
|
{value === "—" || value === 0 ? <span className="text-wy-text-secondary">—</span> : value}
|
|
</div>
|
|
{sub && (
|
|
<div className="text-xs text-wy-text-secondary font-mono mt-1">{sub}</div>
|
|
)}
|
|
{delta && (
|
|
<div className={`absolute top-4 right-4 text-xs font-mono tracking-wider px-2 py-1 rounded-md border ${
|
|
deltaUp
|
|
? "text-acid-green bg-acid-green/10 border-acid-green/30"
|
|
: "text-red-400 bg-red-500/10 border-red-500/30"
|
|
}`}>
|
|
{deltaUp ? "▲" : "▼"} {delta}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
} |