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";
|
} from "@/components/ui/sidebar";
|
||||||
import { APP_LOGO, APP_TITLE, getLoginUrl } from "@/const";
|
import { APP_LOGO, APP_TITLE, getLoginUrl } from "@/const";
|
||||||
import { useIsMobile } from "@/hooks/useMobile";
|
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 { CSSProperties, useEffect, useRef, useState } from "react";
|
||||||
import { useLocation } from "wouter";
|
import { useLocation } from "wouter";
|
||||||
import { DashboardLayoutSkeleton } from './DashboardLayoutSkeleton';
|
import { DashboardLayoutSkeleton } from './DashboardLayoutSkeleton';
|
||||||
@@ -362,13 +362,13 @@ function DashboardLayoutContent({
|
|||||||
<SidebarMenu className="px-2 py-1">
|
<SidebarMenu className="px-2 py-1">
|
||||||
{section.items.map(item => {
|
{section.items.map(item => {
|
||||||
const isActive = location === item.path;
|
const isActive = location === item.path;
|
||||||
const hasSubItems = 'subItems' in item && item.subItems && item.subItems.length > 0;
|
const hasSubItems = 'subItems' in item && item.subItems && Array.isArray(item.subItems) && item.subItems.length > 0;
|
||||||
const isSubItemActive = hasSubItems && item.subItems.some((sub: any) => location === sub.path);
|
const isSubItemActive = hasSubItems && Array.isArray(item.subItems) && item.subItems.some((sub: any) => location === sub.path);
|
||||||
return (
|
return (
|
||||||
<div key={item.path}>
|
<div key={item.path}>
|
||||||
<SidebarMenuItem>
|
<SidebarMenuItem>
|
||||||
<SidebarMenuButton
|
<SidebarMenuButton
|
||||||
isActive={isActive || isSubItemActive}
|
isActive={isActive || Boolean(isSubItemActive)}
|
||||||
onClick={() => setLocation(item.path)}
|
onClick={() => setLocation(item.path)}
|
||||||
tooltip={item.label}
|
tooltip={item.label}
|
||||||
className={`h-10 transition-all font-normal`}
|
className={`h-10 transition-all font-normal`}
|
||||||
@@ -379,9 +379,9 @@ function DashboardLayoutContent({
|
|||||||
<span>{item.label}</span>
|
<span>{item.label}</span>
|
||||||
</SidebarMenuButton>
|
</SidebarMenuButton>
|
||||||
</SidebarMenuItem>
|
</SidebarMenuItem>
|
||||||
{hasSubItems && (
|
{(hasSubItems && Array.isArray(item.subItems) ? (
|
||||||
<div className="ml-6 mt-1 space-y-1">
|
<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;
|
const isSubActive = location === subItem.path;
|
||||||
return (
|
return (
|
||||||
<SidebarMenuItem key={subItem.path}>
|
<SidebarMenuItem key={subItem.path}>
|
||||||
@@ -397,7 +397,7 @@ function DashboardLayoutContent({
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
)}
|
) : null)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ export function DateFormationMultiSelect({
|
|||||||
onSelectionChange(selectedDateIds.filter((id) => !sequenceDateIds.includes(id)));
|
onSelectionChange(selectedDateIds.filter((id) => !sequenceDateIds.includes(id)));
|
||||||
} else {
|
} else {
|
||||||
// Sélectionner toutes les dates de cette séquence
|
// 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);
|
onSelectionChange(newSelection);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -596,11 +596,11 @@ export default function AdminRappels() {
|
|||||||
id: seq.id,
|
id: seq.id,
|
||||||
nom: seq.nom,
|
nom: seq.nom,
|
||||||
formationNom: seq.formation?.nom || '',
|
formationNom: seq.formation?.nom || '',
|
||||||
dates: seq.dates?.map(d => ({
|
dates: seq.dates?.map((d: any) => ({
|
||||||
id: d.id,
|
id: d.id,
|
||||||
date: d.dateDebut,
|
date: d.dateDebut ? new Date(d.dateDebut).toISOString() : '',
|
||||||
heureDebut: d.heureDebut || '',
|
heureDebut: d.dateDebut ? new Date(d.dateDebut).toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' }) : '',
|
||||||
heureFin: d.heureFin || '',
|
heureFin: d.dateFin ? new Date(d.dateFin).toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' }) : '',
|
||||||
})) || [],
|
})) || [],
|
||||||
})) || []}
|
})) || []}
|
||||||
selectedDateIds={formData.dateFormationIds}
|
selectedDateIds={formData.dateFormationIds}
|
||||||
@@ -744,9 +744,9 @@ export default function AdminRappels() {
|
|||||||
formationNom: seq.formation?.nom || '',
|
formationNom: seq.formation?.nom || '',
|
||||||
dates: seq.dates?.map(d => ({
|
dates: seq.dates?.map(d => ({
|
||||||
id: d.id,
|
id: d.id,
|
||||||
date: d.dateDebut,
|
date: d.dateDebut ? new Date(d.dateDebut).toISOString() : '',
|
||||||
heureDebut: d.heureDebut || '',
|
heureDebut: d.dateDebut ? new Date(d.dateDebut).toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' }) : '',
|
||||||
heureFin: d.heureFin || '',
|
heureFin: d.dateFin ? new Date(d.dateFin).toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' }) : '',
|
||||||
})) || [],
|
})) || [],
|
||||||
})) || []}
|
})) || []}
|
||||||
selectedDateIds={formData.dateFormationIds}
|
selectedDateIds={formData.dateFormationIds}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ export default function EmargementScan() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Déterminer les dates disponibles
|
// Déterminer les dates disponibles
|
||||||
const datesDisponibles = selectedInscription?.sequence?.dates || [];
|
const datesDisponibles = (selectedInscription?.sequence as any)?.dates || [];
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -2132,18 +2132,26 @@ export const appRouter = router({
|
|||||||
// Si toutes les présences sont validées, générer l'attestation automatiquement
|
// Si toutes les présences sont validées, générer l'attestation automatiquement
|
||||||
if (allValidated) {
|
if (allValidated) {
|
||||||
try {
|
try {
|
||||||
const { genererAttestationPDF } = await import("./attestationService");
|
const { genererAttestationPDF, enregistrerAttestation } = await import("./attestationService");
|
||||||
const { createAttestation } = await import("./attestationService");
|
|
||||||
|
|
||||||
// Générer le PDF
|
// Générer le PDF
|
||||||
const { s3Key, pdfUrl } = await genererAttestationPDF(input.inscriptionId);
|
const { s3Key, pdfUrl } = await genererAttestationPDF(input.inscriptionId);
|
||||||
|
|
||||||
|
// 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
|
// Enregistrer l'attestation en base
|
||||||
await createAttestation({
|
await enregistrerAttestation(
|
||||||
inscriptionId: input.inscriptionId,
|
input.inscriptionId,
|
||||||
|
inscriptionData[0].apprenantId,
|
||||||
|
inscriptionData[0].sequenceId,
|
||||||
s3Key,
|
s3Key,
|
||||||
pdfUrl,
|
pdfUrl
|
||||||
});
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...result,
|
...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] Générer automatiquement après validation de toutes les présences
|
||||||
- [x] Envoyer par email aux apprenants
|
- [x] Envoyer par email aux apprenants
|
||||||
- [x] Permettre le téléchargement depuis l'espace formateur
|
- [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",
|
"jsx": "preserve",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
|
"downlevelIteration": true,
|
||||||
"allowImportingTsExtensions": true,
|
"allowImportingTsExtensions": true,
|
||||||
"moduleResolution": "bundler",
|
"moduleResolution": "bundler",
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
|
|||||||
Reference in New Issue
Block a user