diff --git a/client/src/components/DashboardLayout.tsx b/client/src/components/DashboardLayout.tsx index cec5282..1085b6b 100644 --- a/client/src/components/DashboardLayout.tsx +++ b/client/src/components/DashboardLayout.tsx @@ -21,7 +21,7 @@ import { } from "@/components/ui/sidebar"; import { APP_LOGO, APP_TITLE, getLoginUrl } from "@/const"; import { useIsMobile } from "@/hooks/useMobile"; -import { LayoutDashboard, LogOut, PanelLeft, Users, GraduationCap, Calendar, CalendarDays, Bell, BarChart3, UserCog, Mail, Settings, TrendingUp, Building2, FileSpreadsheet, ClipboardList, ChevronDown, User, FileText } from "lucide-react"; +import { LayoutDashboard, LogOut, PanelLeft, Users, GraduationCap, Calendar, CalendarDays, Bell, BarChart3, UserCog, Mail, Settings, TrendingUp, Building2, FileSpreadsheet, ClipboardList, ChevronDown, User, FileText, QrCode } from "lucide-react"; import { CSSProperties, useEffect, useRef, useState } from "react"; import { useLocation } from "wouter"; import { DashboardLayoutSkeleton } from './DashboardLayoutSkeleton'; @@ -362,13 +362,13 @@ function DashboardLayoutContent({ {section.items.map(item => { const isActive = location === item.path; - const hasSubItems = 'subItems' in item && item.subItems && item.subItems.length > 0; - const isSubItemActive = hasSubItems && item.subItems.some((sub: any) => location === sub.path); + const hasSubItems = 'subItems' in item && item.subItems && Array.isArray(item.subItems) && item.subItems.length > 0; + const isSubItemActive = hasSubItems && Array.isArray(item.subItems) && item.subItems.some((sub: any) => location === sub.path); return (
setLocation(item.path)} tooltip={item.label} className={`h-10 transition-all font-normal`} @@ -379,9 +379,9 @@ function DashboardLayoutContent({ {item.label} - {hasSubItems && ( + {(hasSubItems && Array.isArray(item.subItems) ? (
- {item.subItems.map((subItem: any) => { + {(item.subItems as any[]).map((subItem: any) => { const isSubActive = location === subItem.path; return ( @@ -397,7 +397,7 @@ function DashboardLayoutContent({ ); })}
- )} + ) : null)}
); })} diff --git a/client/src/components/DateFormationMultiSelect.tsx b/client/src/components/DateFormationMultiSelect.tsx index e3c4465..7cda780 100644 --- a/client/src/components/DateFormationMultiSelect.tsx +++ b/client/src/components/DateFormationMultiSelect.tsx @@ -62,7 +62,7 @@ export function DateFormationMultiSelect({ onSelectionChange(selectedDateIds.filter((id) => !sequenceDateIds.includes(id))); } else { // Sélectionner toutes les dates de cette séquence - const newSelection = [...new Set([...selectedDateIds, ...sequenceDateIds])]; + const newSelection = Array.from(new Set([...selectedDateIds, ...sequenceDateIds])); onSelectionChange(newSelection); } }; diff --git a/client/src/pages/AdminRappels.tsx b/client/src/pages/AdminRappels.tsx index 8e6cc89..25d5d3d 100644 --- a/client/src/pages/AdminRappels.tsx +++ b/client/src/pages/AdminRappels.tsx @@ -596,11 +596,11 @@ export default function AdminRappels() { id: seq.id, nom: seq.nom, formationNom: seq.formation?.nom || '', - dates: seq.dates?.map(d => ({ + dates: seq.dates?.map((d: any) => ({ id: d.id, - date: d.dateDebut, - heureDebut: d.heureDebut || '', - heureFin: d.heureFin || '', + date: d.dateDebut ? new Date(d.dateDebut).toISOString() : '', + heureDebut: d.dateDebut ? new Date(d.dateDebut).toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' }) : '', + heureFin: d.dateFin ? new Date(d.dateFin).toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' }) : '', })) || [], })) || []} selectedDateIds={formData.dateFormationIds} @@ -744,9 +744,9 @@ export default function AdminRappels() { formationNom: seq.formation?.nom || '', dates: seq.dates?.map(d => ({ id: d.id, - date: d.dateDebut, - heureDebut: d.heureDebut || '', - heureFin: d.heureFin || '', + date: d.dateDebut ? new Date(d.dateDebut).toISOString() : '', + heureDebut: d.dateDebut ? new Date(d.dateDebut).toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' }) : '', + heureFin: d.dateFin ? new Date(d.dateFin).toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' }) : '', })) || [], })) || []} selectedDateIds={formData.dateFormationIds} diff --git a/client/src/pages/EmargementScan.tsx b/client/src/pages/EmargementScan.tsx index 2e3607e..ae5beb3 100644 --- a/client/src/pages/EmargementScan.tsx +++ b/client/src/pages/EmargementScan.tsx @@ -75,7 +75,7 @@ export default function EmargementScan() { }; // Déterminer les dates disponibles - const datesDisponibles = selectedInscription?.sequence?.dates || []; + const datesDisponibles = (selectedInscription?.sequence as any)?.dates || []; if (success) { return ( diff --git a/server/routers.ts b/server/routers.ts index 79ff99b..d1a1b32 100644 --- a/server/routers.ts +++ b/server/routers.ts @@ -2132,18 +2132,26 @@ export const appRouter = router({ // Si toutes les présences sont validées, générer l'attestation automatiquement if (allValidated) { try { - const { genererAttestationPDF } = await import("./attestationService"); - const { createAttestation } = await import("./attestationService"); + const { genererAttestationPDF, enregistrerAttestation } = await import("./attestationService"); // Générer le PDF const { s3Key, pdfUrl } = await genererAttestationPDF(input.inscriptionId); - // Enregistrer l'attestation en base - await createAttestation({ - inscriptionId: input.inscriptionId, - s3Key, - pdfUrl, - }); + // Récupérer les données de l'inscription + const db = await getDb(); + if (db) { + const inscriptionData = await db.select().from(inscriptions).where(eq(inscriptions.id, input.inscriptionId)).limit(1); + if (inscriptionData.length > 0) { + // Enregistrer l'attestation en base + await enregistrerAttestation( + input.inscriptionId, + inscriptionData[0].apprenantId, + inscriptionData[0].sequenceId, + s3Key, + pdfUrl + ); + } + } return { ...result, diff --git a/todo.md b/todo.md index c7dcee3..f0ddacc 100644 --- a/todo.md +++ b/todo.md @@ -668,3 +668,14 @@ - [x] Générer automatiquement après validation de toutes les présences - [x] Envoyer par email aux apprenants - [x] Permettre le téléchargement depuis l'espace formateur + +## Corrections techniques + +- [x] Corriger le problème d'aperçu de l'application (erreurs TypeScript) +- [x] Corriger les références à heureDebut/heureFin dans AdminRappels.tsx +- [x] Corriger l'accès à la propriété dates dans EmargementScan.tsx +- [x] Corriger l'import manquant de QrCode dans DashboardLayout.tsx +- [x] Corriger les erreurs TypeScript dans DashboardLayout.tsx (subItems) +- [x] Ajouter downlevelIteration dans tsconfig.json +- [x] Corriger l'utilisation de Set dans DateFormationMultiSelect.tsx +- [x] Corriger l'appel à createAttestation (utiliser enregistrerAttestation) diff --git a/tsconfig.json b/tsconfig.json index a0203ee..931c7b4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,6 +11,7 @@ "jsx": "preserve", "esModuleInterop": true, "skipLibCheck": true, + "downlevelIteration": true, "allowImportingTsExtensions": true, "moduleResolution": "bundler", "baseUrl": ".",