Checkpoint: Modification de l'affichage de la gestion des attestations pour regrouper les apprenants par séquence:

- Ajout d'en-têtes visuels pour chaque séquence avec nom et compteur d'apprenants
- Badge affichant le nombre d'attestations envoyées par séquence
- Amélioration de l'organisation et de la lisibilité pour les formateurs
- Suppression de la colonne "Séquence" devenue redondante
This commit is contained in:
Manus
2026-01-25 08:50:50 -05:00
parent 964b83d4d1
commit 63e8ea17d1
2 changed files with 60 additions and 24 deletions

View File

@@ -455,31 +455,56 @@ export default function AdminGestionAttestations() {
{loadingApprenants ? ( {loadingApprenants ? (
<p className="text-center text-muted-foreground py-8">Chargement...</p> <p className="text-center text-muted-foreground py-8">Chargement...</p>
) : apprenants && apprenants.length > 0 ? ( ) : apprenants && apprenants.length > 0 ? (
<Table> <div className="space-y-6">
<TableHeader> {/* Regrouper les apprenants par séquence */}
<TableRow> {Object.entries(
<TableHead>Nom</TableHead> apprenants.reduce((acc: Record<string, typeof apprenants>, item) => {
<TableHead>Prénom</TableHead> const sequenceKey = `${item.sequence.id}-${item.sequence.nom}`;
<TableHead>Email</TableHead> if (!acc[sequenceKey]) acc[sequenceKey] = [];
<TableHead>Séquence</TableHead> acc[sequenceKey].push(item);
<TableHead>Statut attestation</TableHead> return acc;
<TableHead>Actions</TableHead> }, {})
</TableRow> ).map(([sequenceKey, sequenceApprenants]) => {
</TableHeader> const sequenceName = sequenceKey.split('-').slice(1).join('-');
<TableBody> return (
{apprenants.map((item, index) => { <div key={sequenceKey} className="border rounded-lg overflow-hidden">
const hasAttestation = !!item.attestation; {/* En-tête de séquence */}
const hasDocument = hasAttestation && (item.attestation.urlPdf || item.attestation.documentUrl); <div className="bg-gradient-to-r from-blue-50 to-indigo-50 border-b px-4 py-3">
const isSent = hasAttestation && item.attestation.emailEnvoye; <div className="flex items-center justify-between">
const documentUrl = item.attestation?.documentUrl || item.attestation?.urlPdf; <div>
<h3 className="font-semibold text-lg text-blue-900">{sequenceName}</h3>
<p className="text-sm text-blue-700">{sequenceApprenants.length} apprenant(s)</p>
</div>
<Badge variant="outline" className="bg-white">
{sequenceApprenants.filter(a => a.attestation?.emailEnvoye).length} / {sequenceApprenants.length} envoyé(es)
</Badge>
</div>
</div>
{/* Tableau des apprenants de cette séquence */}
<Table>
<TableHeader>
<TableRow>
<TableHead>Nom</TableHead>
<TableHead>Prénom</TableHead>
<TableHead>Email</TableHead>
<TableHead>Statut attestation</TableHead>
<TableHead>Actions</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{sequenceApprenants.map((item, index) => {
const hasAttestation = !!item.attestation;
const hasDocument = hasAttestation && (item.attestation.urlPdf || item.attestation.documentUrl);
const isSent = hasAttestation && item.attestation.emailEnvoye;
const documentUrl = item.attestation?.documentUrl || item.attestation?.urlPdf;
return ( return (
<TableRow key={item.inscription.id} className={index % 2 === 1 ? "bg-blue-50/70" : ""}> <TableRow key={item.inscription.id} className={index % 2 === 1 ? "bg-blue-50/30" : ""}>
<TableCell>{item.apprenant.nom}</TableCell> <TableCell>{item.apprenant.nom}</TableCell>
<TableCell>{item.apprenant.prenom}</TableCell> <TableCell>{item.apprenant.prenom}</TableCell>
<TableCell>{item.apprenant.email}</TableCell> <TableCell>{item.apprenant.email}</TableCell>
<TableCell>{item.sequence.nom}</TableCell> <TableCell>
<TableCell>
{!hasDocument && ( {!hasDocument && (
<Badge variant="outline" className="bg-gray-50"> <Badge variant="outline" className="bg-gray-50">
Aucune attestation Aucune attestation
@@ -547,6 +572,10 @@ export default function AdminGestionAttestations() {
})} })}
</TableBody> </TableBody>
</Table> </Table>
</div>
);
})}
</div>
) : ( ) : (
<div className="text-center py-8"> <div className="text-center py-8">
<FileText className="h-12 w-12 text-gray-400 mx-auto mb-3" /> <FileText className="h-12 w-12 text-gray-400 mx-auto mb-3" />

View File

@@ -1265,4 +1265,11 @@
- [x] Identifier le fichier de gestion des attestations - [x] Identifier le fichier de gestion des attestations
- [x] Analyser les procédures backend concernées - [x] Analyser les procédures backend concernées
- [x] Corriger les restrictions d'accès pour les formateurs (getApprenantsWithStatus) - [x] Corriger les restrictions d'accès pour les formateurs (getApprenantsWithStatus)
- [x] Déployer sur le VPS
## Regrouper les apprenants par séquence dans la gestion des attestations
- [x] Analyser l'affichage actuel (regroupement par formation)
- [x] Vérifier le backend (données de séquence déjà présentes)
- [x] Adapter l'interface pour afficher les apprenants regroupés par séquence
- [ ] Déployer sur le VPS - [ ] Déployer sur le VPS