diff --git a/attached_assets/image_1752096341746.png b/attached_assets/image_1752096341746.png new file mode 100644 index 0000000..c283d58 Binary files /dev/null and b/attached_assets/image_1752096341746.png differ diff --git a/client/src/components/SalesHistory.tsx b/client/src/components/SalesHistory.tsx index 0dc93b6..9a2ddca 100644 --- a/client/src/components/SalesHistory.tsx +++ b/client/src/components/SalesHistory.tsx @@ -85,90 +85,99 @@ export default function SalesHistory({ canDelete = false }: SalesHistoryProps) { return; } - const { default: jsPDF } = await import('jspdf'); - await import('jspdf-autotable'); + try { + const { default: jsPDF } = await import('jspdf'); + const { default: autoTable } = await import('jspdf-autotable'); - const doc = new jsPDF() as any; - - // Configuration du document - doc.setFont('helvetica'); - - // Titre du document - doc.setFontSize(16); - doc.text('Historique des Ventes de Feux d\'Artifice', 20, 20); - - // Informations générales - doc.setFontSize(10); - doc.text(`Date d'export: ${new Date().toLocaleDateString('fr-FR')}`, 20, 30); - doc.text(`Nombre de ventes: ${sales.length}`, 20, 35); - - if (startDate || endDate) { - let periodText = 'Période: '; - if (startDate) periodText += `du ${new Date(startDate).toLocaleDateString('fr-FR')} `; - if (endDate) periodText += `au ${new Date(endDate).toLocaleDateString('fr-FR')}`; - doc.text(periodText, 20, 40); + const doc = new jsPDF(); + + // Configuration du document + doc.setFont('helvetica'); + + // Titre du document + doc.setFontSize(16); + doc.text('Historique des Ventes de Feux d\'Artifice', 20, 20); + + // Informations générales + doc.setFontSize(10); + doc.text(`Date d'export: ${new Date().toLocaleDateString('fr-FR')}`, 20, 30); + doc.text(`Nombre de ventes: ${sales.length}`, 20, 35); + + if (startDate || endDate) { + let periodText = 'Période: '; + if (startDate) periodText += `du ${new Date(startDate).toLocaleDateString('fr-FR')} `; + if (endDate) periodText += `au ${new Date(endDate).toLocaleDateString('fr-FR')}`; + doc.text(periodText, 20, 40); + } + + // Données du tableau + const tableData = sales.map(sale => [ + new Date(sale.timestamp!).toLocaleDateString('fr-FR'), + sale.vendeur, + sale.typeArticle, + sale.categorie, + sale.quantite.toString(), + sale.nom + ' ' + sale.prenom, + sale.modePaiement || 'Espèce', + sale.typeIdentite, + sale.numeroIdentite + ]); + + // Configuration du tableau + autoTable(doc, { + head: [['Date', 'Vendeur', 'Article', 'Cat.', 'Qté', 'Client', 'Paiement', 'ID Type', 'N° ID']], + body: tableData, + startY: startDate || endDate ? 50 : 45, + styles: { + fontSize: 8, + cellPadding: 2, + }, + headStyles: { + fillColor: [59, 130, 246], + textColor: 255, + fontSize: 9, + }, + alternateRowStyles: { + fillColor: [248, 250, 252], + }, + columnStyles: { + 0: { cellWidth: 18 }, // Date + 1: { cellWidth: 25 }, // Vendeur + 2: { cellWidth: 35 }, // Article + 3: { cellWidth: 12 }, // Catégorie + 4: { cellWidth: 12 }, // Quantité + 5: { cellWidth: 30 }, // Client + 6: { cellWidth: 20 }, // Paiement + 7: { cellWidth: 15 }, // ID Type + 8: { cellWidth: 25 }, // N° ID + }, + margin: { left: 10, right: 10 }, + }); + + // Pied de page + const pageCount = doc.internal.getNumberOfPages(); + for (let i = 1; i <= pageCount; i++) { + doc.setPage(i); + doc.setFontSize(8); + doc.text(`Page ${i} sur ${pageCount}`, doc.internal.pageSize.width - 30, doc.internal.pageSize.height - 10); + doc.text('RegisFlow - Registre des ventes de feux d\'artifice', 20, doc.internal.pageSize.height - 10); + } + + // Téléchargement + doc.save(`historique_ventes_${new Date().toISOString().split('T')[0]}.pdf`); + + toast({ + title: "Export PDF réussi", + description: `${sales.length} ventes exportées en PDF`, + }); + } catch (error) { + console.error('Erreur lors de l\'export PDF:', error); + toast({ + title: "Erreur d'export", + description: "Impossible de générer le fichier PDF", + variant: "destructive", + }); } - - // Données du tableau - const tableData = sales.map(sale => [ - new Date(sale.timestamp!).toLocaleDateString('fr-FR'), - sale.vendeur, - sale.typeArticle, - sale.categorie, - sale.quantite.toString(), - sale.nom + ' ' + sale.prenom, - sale.modePaiement || 'Espèce', - sale.typeIdentite, - sale.numeroIdentite - ]); - - // Configuration du tableau - doc.autoTable({ - head: [['Date', 'Vendeur', 'Article', 'Cat.', 'Qté', 'Client', 'Paiement', 'ID Type', 'N° ID']], - body: tableData, - startY: startDate || endDate ? 50 : 45, - styles: { - fontSize: 8, - cellPadding: 2, - }, - headStyles: { - fillColor: [59, 130, 246], - textColor: 255, - fontSize: 9, - }, - alternateRowStyles: { - fillColor: [248, 250, 252], - }, - columnStyles: { - 0: { cellWidth: 18 }, // Date - 1: { cellWidth: 25 }, // Vendeur - 2: { cellWidth: 35 }, // Article - 3: { cellWidth: 12 }, // Catégorie - 4: { cellWidth: 12 }, // Quantité - 5: { cellWidth: 30 }, // Client - 6: { cellWidth: 20 }, // Paiement - 7: { cellWidth: 15 }, // ID Type - 8: { cellWidth: 25 }, // N° ID - }, - margin: { left: 10, right: 10 }, - }); - - // Pied de page - const pageCount = doc.internal.getNumberOfPages(); - for (let i = 1; i <= pageCount; i++) { - doc.setPage(i); - doc.setFontSize(8); - doc.text(`Page ${i} sur ${pageCount}`, doc.internal.pageSize.width - 30, doc.internal.pageSize.height - 10); - doc.text('RegisFlow - Registre des ventes de feux d\'artifice', 20, doc.internal.pageSize.height - 10); - } - - // Téléchargement - doc.save(`historique_ventes_${new Date().toISOString().split('T')[0]}.pdf`); - - toast({ - title: "Export PDF réussi", - description: `${sales.length} ventes exportées en PDF`, - }); }; const exportToCSV = () => {