Checkpoint: Ajout de badges Actif/Inactif dans la liste des apprenants et création d'une page dédiée aux établissements avec statistiques de participation
This commit is contained in:
123
client/src/pages/AdminEtablissements.tsx
Normal file
123
client/src/pages/AdminEtablissements.tsx
Normal file
@@ -0,0 +1,123 @@
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
||||
import { trpc } from "@/lib/trpc";
|
||||
import { Building2, Users, TrendingUp, Activity } from "lucide-react";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
|
||||
export default function AdminEtablissements() {
|
||||
const { data: etablissements, isLoading } = trpc.etablissements.list.useQuery();
|
||||
|
||||
const totalApprenants = etablissements?.reduce((sum, etab) => sum + etab.nombreApprenants, 0) || 0;
|
||||
const totalActifs = etablissements?.reduce((sum, etab) => sum + etab.apprenantsActifs, 0) || 0;
|
||||
const tauxGlobal = totalApprenants > 0 ? Math.round((totalActifs / totalApprenants) * 100) : 0;
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold">Établissements</h1>
|
||||
<p className="text-muted-foreground mt-2">
|
||||
Vue d'ensemble des établissements et de leur participation
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Statistiques globales */}
|
||||
<div className="grid gap-4 md:grid-cols-4">
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">Établissements</CardTitle>
|
||||
<Building2 className="h-4 w-4 text-muted-foreground" />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">{etablissements?.length || 0}</div>
|
||||
<p className="text-xs text-muted-foreground">Nombre total</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">Apprenants</CardTitle>
|
||||
<Users className="h-4 w-4 text-muted-foreground" />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">{totalApprenants}</div>
|
||||
<p className="text-xs text-muted-foreground">Tous établissements</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">Apprenants actifs</CardTitle>
|
||||
<Activity className="h-4 w-4 text-muted-foreground" />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">{totalActifs}</div>
|
||||
<p className="text-xs text-muted-foreground">Avec inscriptions</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">Taux de participation</CardTitle>
|
||||
<TrendingUp className="h-4 w-4 text-muted-foreground" />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">{tauxGlobal}%</div>
|
||||
<p className="text-xs text-muted-foreground">Global</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Tableau des établissements */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Liste des établissements</CardTitle>
|
||||
<CardDescription>
|
||||
Statistiques de participation par établissement
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
{isLoading ? (
|
||||
<div className="space-y-2">
|
||||
<Skeleton className="h-10 w-full" />
|
||||
<Skeleton className="h-10 w-full" />
|
||||
<Skeleton className="h-10 w-full" />
|
||||
</div>
|
||||
) : etablissements && etablissements.length > 0 ? (
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>Code établissement</TableHead>
|
||||
<TableHead className="text-center">Nombre d'apprenants</TableHead>
|
||||
<TableHead className="text-center">Apprenants actifs</TableHead>
|
||||
<TableHead className="text-center">Taux de participation</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{etablissements.map((etab) => (
|
||||
<TableRow key={etab.codeEtablissement}>
|
||||
<TableCell className="font-medium">{etab.codeEtablissement}</TableCell>
|
||||
<TableCell className="text-center">{etab.nombreApprenants}</TableCell>
|
||||
<TableCell className="text-center">{etab.apprenantsActifs}</TableCell>
|
||||
<TableCell className="text-center">
|
||||
<span className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${
|
||||
etab.tauxParticipation >= 70 ? "bg-green-100 text-green-800" :
|
||||
etab.tauxParticipation >= 40 ? "bg-orange-100 text-orange-800" :
|
||||
"bg-red-100 text-red-800"
|
||||
}`}>
|
||||
{etab.tauxParticipation}%
|
||||
</span>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
) : (
|
||||
<p className="text-center text-muted-foreground py-8">
|
||||
Aucun établissement trouvé
|
||||
</p>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user