the-tip-top-frontend/components/admin/Statistics.tsx
2025-11-17 23:38:02 +01:00

147 lines
4.0 KiB
TypeScript

'use client';
import { useState, useEffect } from 'react';
import { adminService } from '@/services/admin.service';
import { AdminStatistics } from '@/types';
export default function Statistics() {
const [stats, setStats] = useState<AdminStatistics | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
loadStatistics();
}, []);
const loadStatistics = async () => {
try {
setLoading(true);
setError(null);
const data = await adminService.getStatistics();
setStats(data);
} catch (err: any) {
setError(err.message || 'Erreur lors du chargement des statistiques');
setStats(null);
} finally {
setLoading(false);
}
};
if (loading) {
return <div className="text-center py-8">Chargement des statistiques...</div>;
}
if (error || !stats) {
return (
<div className="p-6">
<div className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4">
{error || 'Erreur lors du chargement des statistiques'}
</div>
<button
onClick={loadStatistics}
className="bg-blue-600 text-white px-6 py-2 rounded-lg hover:bg-blue-700"
>
Réessayer
</button>
</div>
);
}
return (
<div className="p-6">
<h1 className="text-2xl font-bold mb-6">Statistiques</h1>
{/* Utilisateurs */}
<div className="mb-8">
<h2 className="text-xl font-semibold mb-4">Utilisateurs</h2>
<div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-5 gap-4">
<StatCard
title="Total"
value={stats.users.total}
color="bg-blue-100 text-blue-800"
/>
<StatCard
title="Clients"
value={stats.users.clients}
color="bg-green-100 text-green-800"
/>
<StatCard
title="Employés"
value={stats.users.employees}
color="bg-purple-100 text-purple-800"
/>
<StatCard
title="Admins"
value={stats.users.admins}
color="bg-red-100 text-red-800"
/>
<StatCard
title="Emails vérifiés"
value={stats.users.verifiedEmails}
color="bg-yellow-100 text-yellow-800"
/>
</div>
</div>
{/* Tickets */}
<div className="mb-8">
<h2 className="text-xl font-semibold mb-4">Tickets</h2>
<div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-5 gap-4">
<StatCard
title="Total"
value={stats.tickets.total}
color="bg-blue-100 text-blue-800"
/>
<StatCard
title="En attente"
value={stats.tickets.pending}
color="bg-yellow-100 text-yellow-800"
/>
<StatCard
title="Réclamés"
value={stats.tickets.claimed}
color="bg-green-100 text-green-800"
/>
<StatCard
title="Rejetés"
value={stats.tickets.rejected}
color="bg-red-100 text-red-800"
/>
<StatCard
title="Récupérés"
value={stats.tickets.claimed}
color="bg-purple-100 text-purple-800"
/>
</div>
</div>
{/* Bouton rafraîchir */}
<div className="mt-8 text-center">
<button
onClick={loadStatistics}
className="bg-blue-600 text-white px-6 py-2 rounded-lg hover:bg-blue-700"
>
Rafraîchir
</button>
</div>
</div>
);
}
interface StatCardProps {
title: string;
value: number;
color: string;
}
function StatCard({ title, value, color }: StatCardProps) {
return (
<div className="bg-white rounded-lg shadow p-6">
<p className="text-sm text-gray-600 mb-2">{title}</p>
<p className={`text-3xl font-bold ${color}`}>
{(value || 0).toLocaleString('fr-FR')}
</p>
</div>
);
}