mirror of
https://github.com/R0m1k3/Regisflow.git
synced 2026-10-11 17:29:48 +02:00
Provide users a detailed sales report in an easily accessible file
Implements sales data export to .xlsx format using the xlsx library and updates related dependencies. Replit-Commit-Author: Agent Replit-Commit-Session-Id: e80fed01-7137-4997-b9af-dad57132d430 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/0715008c-7244-40f4-befc-26c014852236/e80fed01-7137-4997-b9af-dad57132d430/uQbgywo
This commit is contained in:
1 parent
c3c1616e04
commit
a586798a5d
4 files changed
+366
-10
No files matched your search
@@ -12,6 +12,7 @@ import { apiRequest } from '@/lib/queryClient';
|
|||||||
import type { Sale } from '@shared/schema';
|
import type { Sale } from '@shared/schema';
|
||||||
import { History, Download, Trash2, Eye, Filter, FileText, Search, X, Calendar, Users } from 'lucide-react';
|
import { History, Download, Trash2, Eye, Filter, FileText, Search, X, Calendar, Users } from 'lucide-react';
|
||||||
import SaleDetailsModal from '@/components/SaleDetailsModal';
|
import SaleDetailsModal from '@/components/SaleDetailsModal';
|
||||||
|
import { formatDateTime } from '@/lib/export';
|
||||||
|
|
||||||
interface SalesHistoryProps {
|
interface SalesHistoryProps {
|
||||||
canDelete?: boolean;
|
canDelete?: boolean;
|
||||||
@@ -364,6 +365,35 @@ export default function SalesHistory({ canDelete = false }: SalesHistoryProps) {
|
|||||||
setSearchQuery('');
|
setSearchQuery('');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const exportToExcel = async () => {
|
||||||
|
if (filteredSales.length === 0) {
|
||||||
|
toast({
|
||||||
|
title: "Aucune donnée",
|
||||||
|
description: "Aucune vente à exporter",
|
||||||
|
variant: "destructive",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { exportToExcel } = await import('@/lib/export');
|
||||||
|
await exportToExcel(filteredSales);
|
||||||
|
|
||||||
|
toast({
|
||||||
|
title: "Export réussi",
|
||||||
|
description: "Le fichier Excel a été téléchargé",
|
||||||
|
variant: "success",
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erreur lors de l\'export Excel:', error);
|
||||||
|
toast({
|
||||||
|
title: "Erreur d'export",
|
||||||
|
description: "Impossible de générer le fichier Excel",
|
||||||
|
variant: "destructive",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return (
|
return (
|
||||||
<div className="elegant-card">
|
<div className="elegant-card">
|
||||||
@@ -475,12 +505,12 @@ export default function SalesHistory({ canDelete = false }: SalesHistoryProps) {
|
|||||||
Registre PDF Détaillé
|
Registre PDF Détaillé
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={exportToCSV}
|
onClick={exportToExcel}
|
||||||
disabled={filteredSales.length === 0}
|
disabled={filteredSales.length === 0}
|
||||||
className="modern-button modern-button-secondary"
|
className="modern-button modern-button-secondary"
|
||||||
>
|
>
|
||||||
<Download className="h-4 w-4" />
|
<Download className="h-4 w-4" />
|
||||||
Export CSV
|
Export Excel (.xlsx)
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+132
-8
@@ -1,5 +1,137 @@
|
|||||||
import { Sale } from '@/types/sale';
|
import { Sale } from '@/types/sale';
|
||||||
|
|
||||||
|
export async function exportToExcel(sales: Sale[]): Promise<void> {
|
||||||
|
if (sales.length === 0) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const XLSX = await import('xlsx');
|
||||||
|
const { utils, writeFile } = XLSX;
|
||||||
|
|
||||||
|
// Créer un nouveau classeur
|
||||||
|
const workbook = utils.book_new();
|
||||||
|
|
||||||
|
// Préparer les données pour la feuille principale
|
||||||
|
const salesData: any[] = [];
|
||||||
|
|
||||||
|
sales.forEach(sale => {
|
||||||
|
if (sale.products && sale.products.length > 0) {
|
||||||
|
// Pour chaque produit, créer une ligne avec les infos de la vente
|
||||||
|
sale.products.forEach((product, productIndex) => {
|
||||||
|
salesData.push({
|
||||||
|
'ID Vente': sale.id,
|
||||||
|
'Date et Heure': new Date(sale.timestamp).toLocaleString('fr-FR'),
|
||||||
|
'Vendeur': sale.vendeur,
|
||||||
|
'Produit N°': productIndex + 1,
|
||||||
|
'Type Article': product.typeArticle,
|
||||||
|
'Catégorie': product.categorie,
|
||||||
|
'Quantité': product.quantite,
|
||||||
|
'Code Générique': product.gencode || '',
|
||||||
|
'Nom Client': sale.nom,
|
||||||
|
'Prénom Client': sale.prenom,
|
||||||
|
'Date Naissance': sale.dateNaissance || '',
|
||||||
|
'Lieu Naissance': sale.lieuNaissance || '',
|
||||||
|
'Mode Paiement': sale.modePaiement || '',
|
||||||
|
'Type Identité': sale.typeIdentite || '',
|
||||||
|
'Numéro Identité': sale.numeroIdentite || '',
|
||||||
|
'Autorité Délivrance': sale.autoriteDelivrance || '',
|
||||||
|
'Date Délivrance': sale.dateDelivrance || '',
|
||||||
|
'Photo Recto': sale.photoRecto ? 'Oui' : 'Non',
|
||||||
|
'Photo Verso': sale.photoVerso ? 'Oui' : 'Non',
|
||||||
|
'Photo Ticket': sale.photoTicket ? 'Oui' : 'Non'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Fallback pour les ventes sans produits
|
||||||
|
salesData.push({
|
||||||
|
'ID Vente': sale.id,
|
||||||
|
'Date et Heure': new Date(sale.timestamp).toLocaleString('fr-FR'),
|
||||||
|
'Vendeur': sale.vendeur,
|
||||||
|
'Produit N°': 'N/A',
|
||||||
|
'Type Article': 'N/A',
|
||||||
|
'Catégorie': 'N/A',
|
||||||
|
'Quantité': 0,
|
||||||
|
'Code Générique': '',
|
||||||
|
'Nom Client': sale.nom,
|
||||||
|
'Prénom Client': sale.prenom,
|
||||||
|
'Date Naissance': sale.dateNaissance || '',
|
||||||
|
'Lieu Naissance': sale.lieuNaissance || '',
|
||||||
|
'Mode Paiement': sale.modePaiement || '',
|
||||||
|
'Type Identité': sale.typeIdentite || '',
|
||||||
|
'Numéro Identité': sale.numeroIdentite || '',
|
||||||
|
'Autorité Délivrance': sale.autoriteDelivrance || '',
|
||||||
|
'Date Délivrance': sale.dateDelivrance || '',
|
||||||
|
'Photo Recto': sale.photoRecto ? 'Oui' : 'Non',
|
||||||
|
'Photo Verso': sale.photoVerso ? 'Oui' : 'Non',
|
||||||
|
'Photo Ticket': sale.photoTicket ? 'Oui' : 'Non'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Créer la feuille des ventes
|
||||||
|
const salesWorksheet = utils.json_to_sheet(salesData);
|
||||||
|
|
||||||
|
// Ajuster la largeur des colonnes
|
||||||
|
const columnWidths = [
|
||||||
|
{ wch: 10 }, // ID Vente
|
||||||
|
{ wch: 18 }, // Date et Heure
|
||||||
|
{ wch: 15 }, // Vendeur
|
||||||
|
{ wch: 10 }, // Produit N°
|
||||||
|
{ wch: 25 }, // Type Article
|
||||||
|
{ wch: 10 }, // Catégorie
|
||||||
|
{ wch: 8 }, // Quantité
|
||||||
|
{ wch: 15 }, // Code Générique
|
||||||
|
{ wch: 15 }, // Nom Client
|
||||||
|
{ wch: 15 }, // Prénom Client
|
||||||
|
{ wch: 12 }, // Date Naissance
|
||||||
|
{ wch: 15 }, // Lieu Naissance
|
||||||
|
{ wch: 12 }, // Mode Paiement
|
||||||
|
{ wch: 12 }, // Type Identité
|
||||||
|
{ wch: 15 }, // Numéro Identité
|
||||||
|
{ wch: 18 }, // Autorité Délivrance
|
||||||
|
{ wch: 12 }, // Date Délivrance
|
||||||
|
{ wch: 10 }, // Photo Recto
|
||||||
|
{ wch: 10 }, // Photo Verso
|
||||||
|
{ wch: 10 } // Photo Ticket
|
||||||
|
];
|
||||||
|
|
||||||
|
salesWorksheet['!cols'] = columnWidths;
|
||||||
|
|
||||||
|
// Ajouter la feuille au classeur
|
||||||
|
utils.book_append_sheet(workbook, salesWorksheet, 'Ventes Détaillées');
|
||||||
|
|
||||||
|
// Créer une feuille de résumé
|
||||||
|
const summaryData = [
|
||||||
|
{ 'Statistique': 'Nombre total de ventes', 'Valeur': sales.length },
|
||||||
|
{ 'Statistique': 'Nombre total de produits vendus', 'Valeur': salesData.length },
|
||||||
|
{ 'Statistique': 'Date de génération', 'Valeur': new Date().toLocaleString('fr-FR') },
|
||||||
|
{ 'Statistique': 'Ventes avec photos recto', 'Valeur': sales.filter(s => s.photoRecto).length },
|
||||||
|
{ 'Statistique': 'Ventes avec photos verso', 'Valeur': sales.filter(s => s.photoVerso).length },
|
||||||
|
{ 'Statistique': 'Ventes avec photos ticket', 'Valeur': sales.filter(s => s.photoTicket).length }
|
||||||
|
];
|
||||||
|
|
||||||
|
const summaryWorksheet = utils.json_to_sheet(summaryData);
|
||||||
|
summaryWorksheet['!cols'] = [{ wch: 30 }, { wch: 20 }];
|
||||||
|
utils.book_append_sheet(workbook, summaryWorksheet, 'Résumé');
|
||||||
|
|
||||||
|
// Exporter le fichier
|
||||||
|
const fileName = `registre-feux-artifice-${new Date().toISOString().split('T')[0]}.xlsx`;
|
||||||
|
writeFile(workbook, fileName);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erreur lors de l\'export Excel:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatDate(dateString: string): string {
|
||||||
|
return new Date(dateString).toLocaleDateString('fr-FR');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatDateTime(dateString: string): string {
|
||||||
|
return new Date(dateString).toLocaleString('fr-FR');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fonction CSV basique maintenue pour compatibilité si nécessaire
|
||||||
export function exportToCSV(sales: Sale[]): void {
|
export function exportToCSV(sales: Sale[]): void {
|
||||||
if (sales.length === 0) return;
|
if (sales.length === 0) return;
|
||||||
|
|
||||||
@@ -85,11 +217,3 @@ export function exportToCSV(sales: Sale[]): void {
|
|||||||
|
|
||||||
URL.revokeObjectURL(link.href);
|
URL.revokeObjectURL(link.href);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatDate(dateString: string): string {
|
|
||||||
return new Date(dateString).toLocaleDateString('fr-FR');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function formatDateTime(dateString: string): string {
|
|
||||||
return new Date(dateString).toLocaleString('fr-FR');
|
|
||||||
}
|
|
||||||
Generated
+200
@@ -82,6 +82,8 @@
|
|||||||
"vaul": "^1.1.2",
|
"vaul": "^1.1.2",
|
||||||
"wouter": "^3.3.5",
|
"wouter": "^3.3.5",
|
||||||
"ws": "^8.18.0",
|
"ws": "^8.18.0",
|
||||||
|
"xlsx": "^0.18.5",
|
||||||
|
"xlsx-js-style": "^1.2.0",
|
||||||
"zod": "^3.24.2",
|
"zod": "^3.24.2",
|
||||||
"zod-validation-error": "^3.4.0"
|
"zod-validation-error": "^3.4.0"
|
||||||
},
|
},
|
||||||
@@ -3771,6 +3773,15 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/adler-32": {
|
||||||
|
"version": "1.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz",
|
||||||
|
"integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ansi-regex": {
|
"node_modules/ansi-regex": {
|
||||||
"version": "6.1.0",
|
"version": "6.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
|
||||||
@@ -4136,6 +4147,19 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
"node_modules/cfb": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz",
|
||||||
|
"integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"adler-32": "~1.3.0",
|
||||||
|
"crc-32": "~1.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/chokidar": {
|
"node_modules/chokidar": {
|
||||||
"version": "3.6.0",
|
"version": "3.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
|
||||||
@@ -4206,6 +4230,15 @@
|
|||||||
"react-dom": "^18 || ^19 || ^19.0.0-rc"
|
"react-dom": "^18 || ^19 || ^19.0.0-rc"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/codepage": {
|
||||||
|
"version": "1.15.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz",
|
||||||
|
"integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/color-convert": {
|
"node_modules/color-convert": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
@@ -4300,6 +4333,18 @@
|
|||||||
"url": "https://opencollective.com/core-js"
|
"url": "https://opencollective.com/core-js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/crc-32": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
|
||||||
|
"integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"bin": {
|
||||||
|
"crc32": "bin/crc32.njs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.6",
|
"version": "7.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||||
@@ -5439,6 +5484,15 @@
|
|||||||
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
|
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/exit-on-epipe": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/express": {
|
"node_modules/express": {
|
||||||
"version": "4.21.2",
|
"version": "4.21.2",
|
||||||
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
|
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
|
||||||
@@ -5679,6 +5733,15 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/frac": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fraction.js": {
|
"node_modules/fraction.js": {
|
||||||
"version": "4.3.7",
|
"version": "4.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
|
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
|
||||||
@@ -7349,6 +7412,18 @@
|
|||||||
"optional": true,
|
"optional": true,
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
|
"node_modules/printj": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"bin": {
|
||||||
|
"printj": "bin/printj.njs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/prop-types": {
|
"node_modules/prop-types": {
|
||||||
"version": "15.8.1",
|
"version": "15.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||||
@@ -8051,6 +8126,18 @@
|
|||||||
"node": ">= 10.x"
|
"node": ">= 10.x"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ssf": {
|
||||||
|
"version": "0.11.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz",
|
||||||
|
"integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"frac": "~1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/stackblur-canvas": {
|
"node_modules/stackblur-canvas": {
|
||||||
"version": "2.7.0",
|
"version": "2.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.7.0.tgz",
|
||||||
@@ -9545,6 +9632,24 @@
|
|||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/wmf": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/word": {
|
||||||
|
"version": "0.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz",
|
||||||
|
"integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/wouter": {
|
"node_modules/wouter": {
|
||||||
"version": "3.3.5",
|
"version": "3.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/wouter/-/wouter-3.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/wouter/-/wouter-3.3.5.tgz",
|
||||||
@@ -9671,6 +9776,101 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/xlsx": {
|
||||||
|
"version": "0.18.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz",
|
||||||
|
"integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"adler-32": "~1.3.0",
|
||||||
|
"cfb": "~1.2.1",
|
||||||
|
"codepage": "~1.15.0",
|
||||||
|
"crc-32": "~1.2.1",
|
||||||
|
"ssf": "~0.11.2",
|
||||||
|
"wmf": "~1.0.1",
|
||||||
|
"word": "~0.3.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"xlsx": "bin/xlsx.njs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/xlsx-js-style": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/xlsx-js-style/-/xlsx-js-style-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-DDT4FXFSWfT4DXMSok/m3TvmP1gvO3dn0Eu/c+eXHW5Kzmp7IczNkxg/iEPnImbG9X0Vb8QhROda5eatSR/97Q==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"adler-32": "~1.2.0",
|
||||||
|
"cfb": "^1.1.4",
|
||||||
|
"codepage": "~1.14.0",
|
||||||
|
"commander": "~2.17.1",
|
||||||
|
"crc-32": "~1.2.0",
|
||||||
|
"exit-on-epipe": "~1.0.1",
|
||||||
|
"fflate": "^0.3.8",
|
||||||
|
"ssf": "~0.11.2",
|
||||||
|
"wmf": "~1.0.1",
|
||||||
|
"word": "~0.3.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"xlsx": "bin/xlsx.njs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/xlsx-js-style/node_modules/adler-32": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-/vUqU/UY4MVeFsg+SsK6c+/05RZXIHZMGJA+PX5JyWI0ZRcBpupnRuPLU/NXXoFwMYCPCoxIfElM2eS+DUXCqQ==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"exit-on-epipe": "~1.0.1",
|
||||||
|
"printj": "~1.1.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"adler32": "bin/adler32.njs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/xlsx-js-style/node_modules/codepage": {
|
||||||
|
"version": "1.14.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/codepage/-/codepage-1.14.0.tgz",
|
||||||
|
"integrity": "sha512-iz3zJLhlrg37/gYRWgEPkaFTtzmnEv1h+r7NgZum2lFElYQPi0/5bnmuDfODHxfp0INEfnRqyfyeIJDbb7ahRw==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"commander": "~2.14.1",
|
||||||
|
"exit-on-epipe": "~1.0.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"codepage": "bin/codepage.njs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/xlsx-js-style/node_modules/codepage/node_modules/commander": {
|
||||||
|
"version": "2.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz",
|
||||||
|
"integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/xlsx-js-style/node_modules/commander": {
|
||||||
|
"version": "2.17.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
|
||||||
|
"integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/xlsx-js-style/node_modules/fflate": {
|
||||||
|
"version": "0.3.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.3.11.tgz",
|
||||||
|
"integrity": "sha512-Rr5QlUeGN1mbOHlaqcSYMKVpPbgLy0AWT/W0EHxA6NGI12yO1jpoui2zBBvU2G824ltM6Ut8BFgfHSBGfkmS0A==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/xtend": {
|
"node_modules/xtend": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||||
|
|||||||
@@ -84,6 +84,8 @@
|
|||||||
"vaul": "^1.1.2",
|
"vaul": "^1.1.2",
|
||||||
"wouter": "^3.3.5",
|
"wouter": "^3.3.5",
|
||||||
"ws": "^8.18.0",
|
"ws": "^8.18.0",
|
||||||
|
"xlsx": "^0.18.5",
|
||||||
|
"xlsx-js-style": "^1.2.0",
|
||||||
"zod": "^3.24.2",
|
"zod": "^3.24.2",
|
||||||
"zod-validation-error": "^3.4.0"
|
"zod-validation-error": "^3.4.0"
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in new issue
Block a user