150 lines
4.7 KiB
TypeScript
150 lines
4.7 KiB
TypeScript
"use client";
|
|
|
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
import {
|
|
Users,
|
|
MessageSquare,
|
|
CreditCard,
|
|
TrendingUp,
|
|
TrendingDown,
|
|
Activity,
|
|
Euro,
|
|
} from "lucide-react";
|
|
import { cn } from "@/lib/utils";
|
|
import { convertCreditsToEuros } from "@/lib/utils/currency";
|
|
|
|
interface MetricCardProps {
|
|
title: string;
|
|
value: string;
|
|
change?: {
|
|
value: number;
|
|
type: "increase" | "decrease";
|
|
};
|
|
icon: React.ComponentType<{ className?: string }>;
|
|
description?: string;
|
|
}
|
|
|
|
function MetricCard({
|
|
title,
|
|
value,
|
|
change,
|
|
icon: Icon,
|
|
description,
|
|
}: MetricCardProps) {
|
|
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>
|
|
{description && (
|
|
<p className="text-xs text-muted-foreground mt-1">{description}</p>
|
|
)}
|
|
{change && (
|
|
<div className="flex items-center space-x-2 text-xs text-muted-foreground mt-1">
|
|
{change.type === "increase" ? (
|
|
<TrendingUp className="h-3 w-3 text-green-500" />
|
|
) : (
|
|
<TrendingDown className="h-3 w-3 text-red-500" />
|
|
)}
|
|
<span
|
|
className={cn(
|
|
change.type === "increase" ? "text-green-500" : "text-red-500"
|
|
)}
|
|
>
|
|
{change.type === "increase" ? "+" : "-"}
|
|
{change.value}%
|
|
</span>
|
|
<span>par rapport au mois dernier</span>
|
|
</div>
|
|
)}
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
}
|
|
|
|
interface MetricCardsProps {
|
|
metrics: {
|
|
totalUsers: number;
|
|
activeUsers: number;
|
|
totalConversations: number;
|
|
totalMessages: number;
|
|
totalTokensConsumed: number;
|
|
totalCreditsUsed: number;
|
|
};
|
|
}
|
|
|
|
export function MetricCards({ metrics }: MetricCardsProps) {
|
|
// Conversion des crédits en euros
|
|
const creditsConversion = convertCreditsToEuros(metrics.totalCreditsUsed);
|
|
|
|
return (
|
|
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
|
|
<MetricCard
|
|
title="Utilisateurs totaux"
|
|
value={metrics.totalUsers.toLocaleString()}
|
|
change={{ value: 12, type: "increase" }}
|
|
icon={Users}
|
|
description={`${metrics.activeUsers} actifs cette semaine`}
|
|
/>
|
|
<MetricCard
|
|
title="Conversations"
|
|
value={metrics.totalConversations.toLocaleString()}
|
|
change={{ value: 8, type: "increase" }}
|
|
icon={MessageSquare}
|
|
description={`${metrics.totalMessages.toLocaleString()} messages au total`}
|
|
/>
|
|
<MetricCard
|
|
title="Tokens consommés"
|
|
value={metrics.totalTokensConsumed.toLocaleString()}
|
|
change={{ value: 15, type: "increase" }}
|
|
icon={Activity}
|
|
description="Tokens utilisés au total"
|
|
/>
|
|
<Card>
|
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
|
<CardTitle className="text-sm font-medium text-muted-foreground">
|
|
Crédits totaux
|
|
</CardTitle>
|
|
<div className="flex items-center gap-1">
|
|
<CreditCard className="h-4 w-4 text-muted-foreground" />
|
|
<Euro className="h-4 w-4 text-green-600" />
|
|
</div>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="text-2xl font-bold">
|
|
{metrics.totalCreditsUsed.toLocaleString()}
|
|
</div>
|
|
<p className="text-xs text-muted-foreground mt-1">
|
|
crédits disponibles
|
|
</p>
|
|
|
|
{/* Conversion en euros */}
|
|
<div className="mt-2 p-2 bg-green-50 rounded-lg border border-green-200">
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-sm font-medium text-green-800">Valeur en EUR:</span>
|
|
<span className="text-lg font-bold text-green-600">
|
|
{creditsConversion.formatted.eur}
|
|
</span>
|
|
</div>
|
|
<div className="flex items-center justify-between text-xs text-green-600">
|
|
<span>USD: {creditsConversion.formatted.usd}</span>
|
|
<span>Taux: 1 USD = 0.92 EUR</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex items-center space-x-2 text-xs text-muted-foreground mt-2">
|
|
<TrendingUp className="h-3 w-3 text-green-500" />
|
|
<span className="text-green-500">+23%</span>
|
|
<span>par rapport au mois dernier</span>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|