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:
@@ -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" />
|
||||||
|
|||||||
7
todo.md
7
todo.md
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user