Files
Dashboard/components/dashboard/add-credits.tsx
2025-10-08 10:14:38 +02:00

219 lines
7.0 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import { useState } from "react";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Plus, DollarSign, Users, TrendingUp } from "lucide-react";
interface AddCreditsStats {
totalUsers: number;
totalBalances: number;
totalCredits: number;
averageCredits: number;
usersWithoutBalance: number;
}
interface AddCreditsResult {
totalUsers: number;
updatedBalances: number;
createdBalances: number;
creditsPerUser: number;
totalCreditsAdded: number;
}
export default function AddCredits() {
const [stats, setStats] = useState<AddCreditsStats | null>(null);
const [result, setResult] = useState<AddCreditsResult | null>(null);
const [loading, setLoading] = useState(false);
const [analyzing, setAnalyzing] = useState(false);
const analyzeCurrentCredits = async () => {
setAnalyzing(true);
try {
const response = await fetch("/api/add-credits");
const data = await response.json();
if (data.statistics) {
setStats(data.statistics);
}
} catch (error) {
console.error("Erreur lors de l'analyse:", error);
} finally {
setAnalyzing(false);
}
};
const addCreditsToAllUsers = async () => {
if (
!confirm(
"Êtes-vous sûr de vouloir ajouter 5 millions de crédits à TOUS les utilisateurs ? Cette action est irréversible."
)
) {
return;
}
setLoading(true);
try {
const response = await fetch("/api/add-credits", {
method: "POST",
});
const data = await response.json();
if (data.success) {
setResult(data.statistics);
// Rafraîchir les stats
await analyzeCurrentCredits();
} else {
alert("Erreur: " + (data.error || data.message));
}
} catch (error) {
console.error("Erreur lors de l'ajout des crédits:", error);
alert("Erreur lors de l'ajout des crédits");
} finally {
setLoading(false);
}
};
return (
<Card className="w-full">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Plus className="h-5 w-5" />
Ajouter des Crédits
</CardTitle>
<CardDescription>
Ajouter 5 millions de tokens à tous les utilisateurs existants
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
{/* Bouton d'analyse */}
<div className="flex gap-2">
<Button
onClick={analyzeCurrentCredits}
disabled={analyzing}
variant="outline"
>
{analyzing ? "Analyse..." : "Analyser les crédits actuels"}
</Button>
</div>
{/* Statistiques actuelles */}
{stats && (
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
<div className="bg-blue-50 p-3 rounded-lg">
<div className="flex items-center gap-2">
<Users className="h-4 w-4 text-blue-600" />
<span className="text-sm font-medium">Utilisateurs</span>
</div>
<p className="text-2xl font-bold text-blue-600">
{stats.totalUsers}
</p>
</div>
<div className="bg-green-50 p-3 rounded-lg">
<div className="flex items-center gap-2">
<DollarSign className="h-4 w-4 text-green-600" />
<span className="text-sm font-medium">Total Crédits</span>
</div>
<p className="text-2xl font-bold text-green-600">
{stats.totalCredits.toLocaleString()}
</p>
</div>
<div className="bg-purple-50 p-3 rounded-lg">
<div className="flex items-center gap-2">
<TrendingUp className="h-4 w-4 text-purple-600" />
<span className="text-sm font-medium">Moyenne</span>
</div>
<p className="text-2xl font-bold text-purple-600">
{stats.averageCredits.toLocaleString()}
</p>
</div>
<div className="bg-orange-50 p-3 rounded-lg">
<div className="flex items-center gap-2">
<Users className="h-4 w-4 text-orange-600" />
<span className="text-sm font-medium">Sans Balance</span>
</div>
<p className="text-2xl font-bold text-orange-600">
{stats.usersWithoutBalance}
</p>
</div>
</div>
)}
{/* Bouton d'ajout de crédits */}
{stats && (
<div className="border-t pt-4">
<div className="bg-yellow-50 border border-yellow-200 rounded-lg p-4 mb-4">
<h4 className="font-semibold text-yellow-800 mb-2">
Action Importante
</h4>
<p className="text-yellow-700 text-sm">
Cette action va ajouter <strong>5,000,000 crédits</strong> à
chacun des {stats.totalUsers} utilisateurs.
<br />
Total de crédits qui seront ajoutés:{" "}
<strong>{(stats.totalUsers * 3000000).toLocaleString()}</strong>
</p>
</div>
<Button
onClick={addCreditsToAllUsers}
disabled={loading}
className="w-full bg-green-600 hover:bg-green-700"
>
{loading
? "Ajout en cours..."
: `Ajouter 5M crédits à ${stats.totalUsers} utilisateurs`}
</Button>
</div>
)}
{/* Résultats */}
{result && (
<div className="border-t pt-4">
<h4 className="font-semibold text-green-600 mb-3">
Crédits ajoutés avec succès !
</h4>
<div className="grid grid-cols-2 gap-4 text-sm">
<div>
<span className="text-gray-600">Balances mises à jour:</span>
<Badge variant="secondary" className="ml-2">
{result.updatedBalances}
</Badge>
</div>
<div>
<span className="text-gray-600">Nouvelles balances:</span>
<Badge variant="secondary" className="ml-2">
{result.createdBalances}
</Badge>
</div>
<div>
<span className="text-gray-600">Crédits par utilisateur:</span>
<Badge variant="secondary" className="ml-2">
{result.creditsPerUser.toLocaleString()}
</Badge>
</div>
<div>
<span className="text-gray-600">Total ajouté:</span>
<Badge variant="secondary" className="ml-2">
{result.totalCreditsAdded.toLocaleString()}
</Badge>
</div>
</div>
</div>
)}
</CardContent>
</Card>
);
}