Checkpoint: Correction du problème d'aperçu de l'application
Corrections apportées : - Correction des références à heureDebut/heureFin dans AdminRappels.tsx (utilisation de dateDebut/dateFin) - Correction de l'accès à la propriété dates dans EmargementScan.tsx (cast de type) - Ajout de l'import manquant de QrCode dans DashboardLayout.tsx - Correction des erreurs TypeScript dans DashboardLayout.tsx (gestion de subItems) - Ajout de downlevelIteration dans tsconfig.json - Correction de l'utilisation de Set dans DateFormationMultiSelect.tsx (Array.from) - Correction de l'appel à createAttestation (utilisation de enregistrerAttestation) L'application fonctionne maintenant correctement sans erreurs TypeScript.
This commit is contained in:
@@ -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({
|
||||
<SidebarMenu className="px-2 py-1">
|
||||
{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 (
|
||||
<div key={item.path}>
|
||||
<SidebarMenuItem>
|
||||
<SidebarMenuButton
|
||||
isActive={isActive || isSubItemActive}
|
||||
isActive={isActive || Boolean(isSubItemActive)}
|
||||
onClick={() => setLocation(item.path)}
|
||||
tooltip={item.label}
|
||||
className={`h-10 transition-all font-normal`}
|
||||
@@ -379,9 +379,9 @@ function DashboardLayoutContent({
|
||||
<span>{item.label}</span>
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
{hasSubItems && (
|
||||
{(hasSubItems && Array.isArray(item.subItems) ? (
|
||||
<div className="ml-6 mt-1 space-y-1">
|
||||
{item.subItems.map((subItem: any) => {
|
||||
{(item.subItems as any[]).map((subItem: any) => {
|
||||
const isSubActive = location === subItem.path;
|
||||
return (
|
||||
<SidebarMenuItem key={subItem.path}>
|
||||
@@ -397,7 +397,7 @@ function DashboardLayoutContent({
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
) : null)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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,
|
||||
|
||||
11
todo.md
11
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)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
"jsx": "preserve",
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"downlevelIteration": true,
|
||||
"allowImportingTsExtensions": true,
|
||||
"moduleResolution": "bundler",
|
||||
"baseUrl": ".",
|
||||
|
||||
Reference in New Issue
Block a user