66 lines
1.7 KiB
TypeScript
66 lines
1.7 KiB
TypeScript
"use client"
|
|
|
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
|
import { TrendingUp, TrendingDown, Minus } from "lucide-react";
|
|
import { LucideIcon } from "lucide-react";
|
|
|
|
interface MetricsCardProps {
|
|
title: string;
|
|
value: string;
|
|
description: string;
|
|
icon: LucideIcon;
|
|
trend: "up" | "down" | "neutral";
|
|
trendValue: string;
|
|
}
|
|
|
|
export default function MetricsCard({
|
|
title,
|
|
value,
|
|
description,
|
|
icon: Icon,
|
|
trend,
|
|
trendValue
|
|
}: MetricsCardProps) {
|
|
const getTrendIcon = () => {
|
|
switch (trend) {
|
|
case "up":
|
|
return <TrendingUp className="h-4 w-4 text-green-500" />;
|
|
case "down":
|
|
return <TrendingDown className="h-4 w-4 text-red-500" />;
|
|
default:
|
|
return <Minus className="h-4 w-4 text-gray-500" />;
|
|
}
|
|
};
|
|
|
|
const getTrendColor = () => {
|
|
switch (trend) {
|
|
case "up":
|
|
return "text-green-600";
|
|
case "down":
|
|
return "text-red-600";
|
|
default:
|
|
return "text-gray-600";
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Card>
|
|
<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">{value}</div>
|
|
<p className="text-xs text-muted-foreground mt-1">{description}</p>
|
|
<div className="flex items-center gap-1 mt-2">
|
|
{getTrendIcon()}
|
|
<span className={`text-xs ${getTrendColor()}`}>
|
|
{trendValue}
|
|
</span>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
}
|