Some checks failed
Deploy to Cloudflare Workers / deploy (push) Has been cancelled
56 lines
1.6 KiB
TypeScript
56 lines
1.6 KiB
TypeScript
import { cn } from "@/lib/utils";
|
||
import type { LucideIcon } from "lucide-react";
|
||
import { Card, CardContent, CardHeader } from "@/components/ui/card";
|
||
import { Badge } from "@/components/ui/badge";
|
||
|
||
export function StatCard({
|
||
title,
|
||
value,
|
||
subtitle,
|
||
icon: Icon,
|
||
trend,
|
||
trendLabel,
|
||
}: {
|
||
title: string;
|
||
value: string | number;
|
||
subtitle?: string;
|
||
icon: LucideIcon;
|
||
trend?: "up" | "down" | "neutral";
|
||
trendLabel?: string;
|
||
}) {
|
||
return (
|
||
<Card>
|
||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||
<p className="text-sm font-medium text-muted-foreground">{title}</p>
|
||
<div className="rounded-md border border-border bg-muted/50 p-2">
|
||
<Icon className="h-4 w-4 text-muted-foreground" />
|
||
</div>
|
||
</CardHeader>
|
||
<CardContent>
|
||
<div className="text-2xl font-bold tracking-tight">{value}</div>
|
||
<div className="mt-2 flex flex-wrap items-center gap-2">
|
||
{trend && trendLabel && (
|
||
<Badge
|
||
variant={
|
||
trend === "up"
|
||
? "success"
|
||
: trend === "down"
|
||
? "destructive"
|
||
: "secondary"
|
||
}
|
||
>
|
||
{trend === "up" ? "+" : trend === "down" ? "−" : ""}
|
||
{trendLabel}
|
||
</Badge>
|
||
)}
|
||
{subtitle && (
|
||
<span className={cn("text-xs text-muted-foreground")}>
|
||
{subtitle}
|
||
</span>
|
||
)}
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
);
|
||
}
|