Checkpoint: Menu latéral et tableau de bord harmonisés avec palette pastel + correction bugs "Cannot convert undefined or null to object" sur pages émargement formateur et suivi questionnaires
This commit is contained in:
@@ -20,9 +20,9 @@ export default function Admin() {
|
|||||||
const autres = apprenants.filter(a => a.fonction === "autre").length;
|
const autres = apprenants.filter(a => a.fonction === "autre").length;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{ name: "Directeurs", value: directeurs, color: "#3b82f6" },
|
{ name: "Directeurs", value: directeurs, color: "#93c5fd" },
|
||||||
{ name: "Chefs de service", value: chefsService, color: "#10b981" },
|
{ name: "Chefs de service", value: chefsService, color: "#6ee7b7" },
|
||||||
{ name: "Autres", value: autres, color: "#f59e0b" },
|
{ name: "Autres", value: autres, color: "#fcd34d" },
|
||||||
].filter(item => item.value > 0);
|
].filter(item => item.value > 0);
|
||||||
}, [apprenants]);
|
}, [apprenants]);
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ export default function Admin() {
|
|||||||
etablissementCounts[code] = (etablissementCounts[code] || 0) + 1;
|
etablissementCounts[code] = (etablissementCounts[code] || 0) + 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
const colors = ["#3b82f6", "#10b981", "#f59e0b", "#ef4444", "#8b5cf6", "#ec4899", "#06b6d4", "#84cc16", "#f97316", "#6366f1"];
|
const colors = ["#93c5fd", "#6ee7b7", "#fcd34d", "#fca5a5", "#c4b5fd", "#f9a8d4", "#67e8f9", "#bef264", "#fdba74", "#a5b4fc"];
|
||||||
|
|
||||||
return Object.entries(etablissementCounts)
|
return Object.entries(etablissementCounts)
|
||||||
.map(([name, value], index) => ({
|
.map(([name, value], index) => ({
|
||||||
@@ -53,40 +53,40 @@ export default function Admin() {
|
|||||||
title: "Formations actives",
|
title: "Formations actives",
|
||||||
value: formations?.filter(f => f.actif).length || 0,
|
value: formations?.filter(f => f.actif).length || 0,
|
||||||
icon: GraduationCap,
|
icon: GraduationCap,
|
||||||
gradient: "from-blue-500 to-blue-600",
|
gradient: "from-blue-300 to-blue-400",
|
||||||
borderColor: "border-l-blue-500",
|
borderColor: "border-l-blue-400",
|
||||||
bgColor: "bg-blue-50/50",
|
bgColor: "bg-blue-50/80",
|
||||||
iconBg: "bg-gradient-to-br from-blue-500 to-blue-600",
|
iconBg: "bg-gradient-to-br from-blue-300 to-blue-400",
|
||||||
loading: loadingFormations,
|
loading: loadingFormations,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Séquences ouvertes",
|
title: "Séquences ouvertes",
|
||||||
value: sequences?.filter(s => s.statut === "ouverte").length || 0,
|
value: sequences?.filter(s => s.statut === "ouverte").length || 0,
|
||||||
icon: Calendar,
|
icon: Calendar,
|
||||||
gradient: "from-green-500 to-emerald-600",
|
gradient: "from-green-300 to-emerald-400",
|
||||||
borderColor: "border-l-green-500",
|
borderColor: "border-l-green-400",
|
||||||
bgColor: "bg-green-50/50",
|
bgColor: "bg-green-50/80",
|
||||||
iconBg: "bg-gradient-to-br from-green-500 to-emerald-600",
|
iconBg: "bg-gradient-to-br from-green-300 to-emerald-400",
|
||||||
loading: loadingSessions,
|
loading: loadingSessions,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Apprenants inscrits",
|
title: "Apprenants inscrits",
|
||||||
value: apprenants?.length || 0,
|
value: apprenants?.length || 0,
|
||||||
icon: Users,
|
icon: Users,
|
||||||
gradient: "from-purple-500 to-purple-600",
|
gradient: "from-purple-300 to-purple-400",
|
||||||
borderColor: "border-l-purple-500",
|
borderColor: "border-l-purple-400",
|
||||||
bgColor: "bg-purple-50/50",
|
bgColor: "bg-purple-50/80",
|
||||||
iconBg: "bg-gradient-to-br from-purple-500 to-purple-600",
|
iconBg: "bg-gradient-to-br from-purple-300 to-purple-400",
|
||||||
loading: loadingApprenants,
|
loading: loadingApprenants,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Séquences terminées",
|
title: "Séquences terminées",
|
||||||
value: sequences?.filter(s => s.statut === "terminee").length || 0,
|
value: sequences?.filter(s => s.statut === "terminee").length || 0,
|
||||||
icon: CheckCircle,
|
icon: CheckCircle,
|
||||||
gradient: "from-orange-500 to-orange-600",
|
gradient: "from-orange-300 to-orange-400",
|
||||||
borderColor: "border-l-orange-500",
|
borderColor: "border-l-orange-400",
|
||||||
bgColor: "bg-orange-50/50",
|
bgColor: "bg-orange-50/80",
|
||||||
iconBg: "bg-gradient-to-br from-orange-500 to-orange-600",
|
iconBg: "bg-gradient-to-br from-orange-300 to-orange-400",
|
||||||
loading: loadingSessions,
|
loading: loadingSessions,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@@ -96,7 +96,7 @@ export default function Admin() {
|
|||||||
<div className="space-y-8 animate-in fade-in duration-500">
|
<div className="space-y-8 animate-in fade-in duration-500">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-4xl font-bold tracking-tight bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent">
|
<h1 className="text-4xl font-bold tracking-tight bg-gradient-to-r from-blue-400 to-purple-400 bg-clip-text text-transparent">
|
||||||
Tableau de bord
|
Tableau de bord
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-muted-foreground mt-2 text-lg">
|
<p className="text-muted-foreground mt-2 text-lg">
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ export default function AdminQuestionnaireSuivi() {
|
|||||||
outerRadius={80}
|
outerRadius={80}
|
||||||
label={(entry) => `${entry.formationNom}: ${entry.tauxReponse}%`}
|
label={(entry) => `${entry.formationNom}: ${entry.tauxReponse}%`}
|
||||||
>
|
>
|
||||||
{statsByFormation.map((entry, index) => (
|
{statsByFormation && Array.isArray(statsByFormation) && statsByFormation.map((entry, index) => (
|
||||||
<Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />
|
<Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />
|
||||||
))}
|
))}
|
||||||
</Pie>
|
</Pie>
|
||||||
@@ -201,7 +201,7 @@ export default function AdminQuestionnaireSuivi() {
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{statsByFormateur.map((formateur) => (
|
{statsByFormateur && Array.isArray(statsByFormateur) && statsByFormateur.map((formateur) => (
|
||||||
<tr key={formateur.formateurId} className="border-b">
|
<tr key={formateur.formateurId} className="border-b">
|
||||||
<td className="p-2">{formateur.formateurNom}</td>
|
<td className="p-2">{formateur.formateurNom}</td>
|
||||||
<td className="p-2 text-center">{formateur.totalEnvois}</td>
|
<td className="p-2 text-center">{formateur.totalEnvois}</td>
|
||||||
|
|||||||
15
todo.md
15
todo.md
@@ -1013,7 +1013,7 @@
|
|||||||
- [x] Implémenter indicateur de page active
|
- [x] Implémenter indicateur de page active
|
||||||
- [x] Améliorer les couleurs et gradients
|
- [x] Améliorer les couleurs et gradients
|
||||||
- [x] Tester sur sandbox
|
- [x] Tester sur sandbox
|
||||||
- [ ] Déployer après validation utilisateur
|
- [x] Déployer après validation utilisateur
|
||||||
|
|
||||||
## Correction bug page émargement formateur
|
## Correction bug page émargement formateur
|
||||||
|
|
||||||
@@ -1021,3 +1021,16 @@
|
|||||||
- [x] Identifier la requête tRPC qui échoue
|
- [x] Identifier la requête tRPC qui échoue
|
||||||
- [x] Corriger le bug
|
- [x] Corriger le bug
|
||||||
- [x] Tester la correction
|
- [x] Tester la correction
|
||||||
|
|
||||||
|
## Harmonisation tableau de bord avec palette pastel
|
||||||
|
|
||||||
|
- [x] Adapter les couleurs des cartes statistiques en pastel
|
||||||
|
- [x] Harmoniser les gradients avec le menu latéral
|
||||||
|
- [x] Tester sur sandbox
|
||||||
|
|
||||||
|
## Correction bug page suivi questionnaires
|
||||||
|
|
||||||
|
- [x] Analyser l'erreur "Cannot convert undefined or null to object"
|
||||||
|
- [x] Identifier la requête tRPC qui échoue
|
||||||
|
- [x] Corriger le bug
|
||||||
|
- [x] Tester la correction
|
||||||
|
|||||||
Reference in New Issue
Block a user