Checkpoint: Amélioration de l'ergonomie de l'encart des signatures formateurs
Modifications apportées : - Regroupement des signatures formateurs par date (au lieu d'une signature par ligne) - Affichage d'une zone par date avec les signatures matin et après-midi à l'intérieur - Ergonomie identique à celle des apprenants pour une meilleure cohérence visuelle - Affichage de "Aucune signature" pour les périodes sans signature - Heure de signature affichée dans un badge pour chaque période - Design distinct avec bordure bleue pour différencier des signatures apprenants - Déployé sur recette (108.143.67.56) et production (98.71.216.234)
This commit is contained in:
@@ -504,51 +504,107 @@ export default function FormateurEmargement() {
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-4">
|
||||
{signaturesFormateurs.map((signature: any) => (
|
||||
<div
|
||||
key={signature.presenceId}
|
||||
className="border border-blue-200 rounded-lg p-4 bg-white space-y-3"
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
{(() => {
|
||||
// Regrouper les signatures par date
|
||||
const signaturesByDate = signaturesFormateurs.reduce((acc: any, signature: any) => {
|
||||
const dateKey = signature.dateFormationId;
|
||||
if (!acc[dateKey]) {
|
||||
acc[dateKey] = {
|
||||
dateDebut: signature.dateDebut,
|
||||
dateFin: signature.dateFin,
|
||||
matin: null,
|
||||
apres_midi: null,
|
||||
};
|
||||
}
|
||||
if (signature.periode === "matin") {
|
||||
acc[dateKey].matin = signature;
|
||||
} else {
|
||||
acc[dateKey].apres_midi = signature;
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
return Object.values(signaturesByDate).map((dateGroup: any) => (
|
||||
<div
|
||||
key={dateGroup.dateDebut}
|
||||
className="border border-blue-200 rounded-lg p-4 bg-white space-y-3"
|
||||
>
|
||||
{/* En-tête de la date */}
|
||||
<div>
|
||||
<p className="font-medium text-blue-900">
|
||||
{new Date(signature.dateDebut).toLocaleDateString("fr-FR", {
|
||||
{new Date(dateGroup.dateDebut).toLocaleDateString("fr-FR", {
|
||||
weekday: "long",
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
})}
|
||||
</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{signature.periode === "matin" ? "🌅 Matin" : "🌆 Après-midi"}
|
||||
</p>
|
||||
</div>
|
||||
<Badge variant="outline" className="bg-blue-100 text-blue-700 border-blue-300">
|
||||
{new Date(signature.heurePresence).toLocaleTimeString("fr-FR", {
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
})}
|
||||
</Badge>
|
||||
</div>
|
||||
{signature.signatureUrl && (
|
||||
<div className="flex flex-col gap-2">
|
||||
<p className="text-xs text-muted-foreground">Signature tactile :</p>
|
||||
<div className="border-2 border-blue-200 rounded-lg p-2 bg-white cursor-pointer hover:border-blue-400 transition-colors"
|
||||
onClick={() => {
|
||||
setSelectedSignature(signature.signatureUrl!);
|
||||
setShowSignatureDialog(true);
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src={signature.signatureUrl}
|
||||
alt="Signature formateur"
|
||||
className="w-full h-24 object-contain"
|
||||
/>
|
||||
|
||||
{/* Signature Matin */}
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<p className="text-sm font-medium text-muted-foreground">🌅 Matin</p>
|
||||
{dateGroup.matin && (
|
||||
<Badge variant="outline" className="bg-blue-100 text-blue-700 border-blue-300 text-xs">
|
||||
{new Date(dateGroup.matin.heurePresence).toLocaleTimeString("fr-FR", {
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
})}
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
{dateGroup.matin?.signatureUrl ? (
|
||||
<div className="border-2 border-blue-200 rounded-lg p-2 bg-white cursor-pointer hover:border-blue-400 transition-colors"
|
||||
onClick={() => {
|
||||
setSelectedSignature(dateGroup.matin.signatureUrl!);
|
||||
setShowSignatureDialog(true);
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src={dateGroup.matin.signatureUrl}
|
||||
alt="Signature formateur matin"
|
||||
className="w-full h-20 object-contain"
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-xs text-muted-foreground italic">Aucune signature</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
|
||||
{/* Signature Après-midi */}
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<p className="text-sm font-medium text-muted-foreground">🌆 Après-midi</p>
|
||||
{dateGroup.apres_midi && (
|
||||
<Badge variant="outline" className="bg-blue-100 text-blue-700 border-blue-300 text-xs">
|
||||
{new Date(dateGroup.apres_midi.heurePresence).toLocaleTimeString("fr-FR", {
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
})}
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
{dateGroup.apres_midi?.signatureUrl ? (
|
||||
<div className="border-2 border-blue-200 rounded-lg p-2 bg-white cursor-pointer hover:border-blue-400 transition-colors"
|
||||
onClick={() => {
|
||||
setSelectedSignature(dateGroup.apres_midi.signatureUrl!);
|
||||
setShowSignatureDialog(true);
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src={dateGroup.apres_midi.signatureUrl}
|
||||
alt="Signature formateur après-midi"
|
||||
className="w-full h-20 object-contain"
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-xs text-muted-foreground italic">Aucune signature</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
));
|
||||
})()}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
Reference in New Issue
Block a user