Checkpoint: Ajout d'une confirmation visuelle améliorée après émargement réussi : animations fluides, heure d'enregistrement précise et design moderne

This commit is contained in:
Manus
2026-01-25 15:20:13 -05:00
parent 61f0e81a9d
commit b3b808145c
2 changed files with 38 additions and 8 deletions

View File

@@ -22,6 +22,7 @@ export default function EmargementScan() {
const [selectedDateId, setSelectedDateId] = useState<number | null>(null);
const [selectedPeriode, setSelectedPeriode] = useState<"matin" | "apres_midi">("matin");
const [success, setSuccess] = useState(false);
const [heureEnregistrement, setHeureEnregistrement] = useState<Date | null>(null);
const [error, setError] = useState<string | null>(null);
// Récupérer l'apprenant par email
@@ -42,6 +43,8 @@ export default function EmargementScan() {
// Valider la présence
const { mutate: validerPresence, isPending: validating } = trpc.presences.valider.useMutation({
onSuccess: () => {
const now = new Date();
setHeureEnregistrement(now);
setSuccess(true);
toast.success("Présence validée avec succès !");
},
@@ -81,25 +84,51 @@ export default function EmargementScan() {
if (success) {
return (
<div className="min-h-screen flex items-center justify-center bg-gradient-to-br from-green-50 to-green-100 p-4">
<Card className="max-w-md w-full">
<div className="min-h-screen flex items-center justify-center bg-gradient-to-br from-green-50 via-emerald-50 to-green-100 p-4">
<Card className="max-w-md w-full shadow-2xl border-2 border-green-200 animate-in fade-in zoom-in duration-500">
<CardHeader className="text-center">
<div className="mx-auto mb-4 w-16 h-16 bg-green-500 rounded-full flex items-center justify-center">
<CheckCircle2 className="h-10 w-10 text-white" />
<div className="mx-auto mb-4 w-20 h-20 bg-gradient-to-br from-green-500 to-emerald-600 rounded-full flex items-center justify-center shadow-lg animate-in zoom-in duration-700 delay-150">
<CheckCircle2 className="h-12 w-12 text-white animate-in zoom-in duration-500 delay-300" />
</div>
<CardTitle className="text-2xl text-green-700">Présence validée !</CardTitle>
<CardDescription>
<CardTitle className="text-3xl font-bold text-green-700 animate-in slide-in-from-bottom duration-500 delay-200">
Présence validée !
</CardTitle>
<CardDescription className="text-base mt-2 animate-in slide-in-from-bottom duration-500 delay-300">
Votre présence a é enregistrée avec succès
</CardDescription>
</CardHeader>
<CardContent className="text-center">
<p className="text-sm text-muted-foreground mb-4">
<CardContent className="text-center space-y-4 animate-in slide-in-from-bottom duration-500 delay-400">
{heureEnregistrement && (
<div className="p-4 bg-green-50 border-2 border-green-200 rounded-lg">
<p className="text-sm font-medium text-green-800 mb-1">
🕒 Heure d'enregistrement
</p>
<p className="text-2xl font-bold text-green-700">
{heureEnregistrement.toLocaleTimeString("fr-FR", {
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
})}
</p>
<p className="text-xs text-green-600 mt-1">
{heureEnregistrement.toLocaleDateString("fr-FR", {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
})}
</p>
</div>
)}
<p className="text-sm text-muted-foreground">
Merci d'avoir confirmé votre présence. Vous pouvez maintenant fermer cette page.
</p>
<Button
variant="outline"
className="w-full"
onClick={() => {
setSuccess(false);
setHeureEnregistrement(null);
setEmail("");
setSelectedInscriptionId(null);
setSelectedDateId(null);

View File

@@ -1288,3 +1288,4 @@
- [ ] Déployer sur le VPS
- [x] Corriger le bouton "œil" dans la page apprenants (formateur) qui n'affiche pas le détail
- [x] Corriger la page vide lors de l'émargement via QR code sur smartphone
- [x] Ajouter confirmation visuelle après émargement réussi (animation + heure)