47 lines
1.2 KiB
TypeScript
47 lines
1.2 KiB
TypeScript
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
import { Badge } from "@/components/ui/badge";
|
|
import { LucideIcon } from "lucide-react";
|
|
import { formatNumber } from "@/lib/utils";
|
|
|
|
interface MetricCardProps {
|
|
title: string;
|
|
value: number | string;
|
|
icon: LucideIcon;
|
|
trend?: {
|
|
value: number;
|
|
isPositive: boolean;
|
|
};
|
|
className?: string;
|
|
}
|
|
|
|
export function MetricCard({
|
|
title,
|
|
value,
|
|
icon: Icon,
|
|
trend,
|
|
className
|
|
}: MetricCardProps) {
|
|
return (
|
|
<Card className={className}>
|
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
|
<CardTitle className="text-sm font-medium text-muted-foreground">
|
|
{title}
|
|
</CardTitle>
|
|
<Icon className="h-4 w-4 text-muted-foreground" />
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="text-2xl font-bold">
|
|
{typeof value === 'number' ? formatNumber(value) : value}
|
|
</div>
|
|
{trend && (
|
|
<Badge
|
|
variant={trend.isPositive ? "default" : "destructive"}
|
|
className="mt-2"
|
|
>
|
|
{trend.isPositive ? '+' : ''}{trend.value}%
|
|
</Badge>
|
|
)}
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
} |