diff --git a/client/src/components/SalesHistory.tsx b/client/src/components/SalesHistory.tsx
index 46c244c..ccee8a5 100644
--- a/client/src/components/SalesHistory.tsx
+++ b/client/src/components/SalesHistory.tsx
@@ -157,6 +157,70 @@ export default function SalesHistory({ canDelete = false }: SalesHistoryProps) {
}
};
+ const exportToCSV = () => {
+ if (filteredSales.length === 0) {
+ toast({
+ title: "Aucune donnée",
+ description: "Aucune vente à exporter",
+ variant: "destructive",
+ });
+ return;
+ }
+
+ try {
+ const headers = [
+ 'Date', 'Vendeur', 'Nom', 'Prénom', 'Date de naissance', 'Lieu de naissance',
+ 'Type article', 'Catégorie', 'Quantité', 'Gencode', 'Mode de paiement',
+ 'Type identité', 'Numéro identité', 'Autorité délivrance', 'Date délivrance'
+ ];
+
+ const csvData = filteredSales.map(sale => [
+ new Date(sale.timestamp).toLocaleDateString('fr-FR'),
+ sale.vendeur,
+ sale.nom,
+ sale.prenom,
+ new Date(sale.dateNaissance).toLocaleDateString('fr-FR'),
+ sale.lieuNaissance || '',
+ sale.typeArticle,
+ sale.categorie,
+ sale.quantite,
+ sale.gencode,
+ sale.modePaiement,
+ sale.typeIdentite,
+ sale.numeroIdentite,
+ sale.autoriteDelivrance || '',
+ new Date(sale.dateDelivrance).toLocaleDateString('fr-FR')
+ ]);
+
+ const csvContent = [headers, ...csvData]
+ .map(row => row.map(field => `"${field}"`).join(';'))
+ .join('\n');
+
+ const blob = new Blob(['\ufeff' + csvContent], { type: 'text/csv;charset=utf-8;' });
+ const link = document.createElement('a');
+ const url = URL.createObjectURL(blob);
+ link.setAttribute('href', url);
+ link.setAttribute('download', `ventes-feux-artifice-${new Date().toISOString().split('T')[0]}.csv`);
+ link.style.visibility = 'hidden';
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+
+ toast({
+ title: "Export réussi",
+ description: "Le fichier CSV a été téléchargé",
+ variant: "success",
+ });
+ } catch (error) {
+ console.error('Erreur lors de l\'export CSV:', error);
+ toast({
+ title: "Erreur d'export",
+ description: "Impossible de générer le fichier CSV",
+ variant: "destructive",
+ });
+ }
+ };
+
const clearFilters = () => {
setStartDate('');
setEndDate('');
@@ -264,14 +328,24 @@ export default function SalesHistory({ canDelete = false }: SalesHistoryProps) {
)}
-
+
+
+
+
diff --git a/client/src/index.css b/client/src/index.css
index 013af38..22d22ea 100644
--- a/client/src/index.css
+++ b/client/src/index.css
@@ -246,11 +246,11 @@ body {
/* Module de recherche */
.search-container {
background: white;
- border: 1px solid hsl(var(--border));
+ border: 2px solid hsl(var(--primary) / 0.3);
border-radius: 12px;
padding: 20px;
margin-bottom: 24px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.search-header {
@@ -283,10 +283,11 @@ body {
/* Filtres élégants */
.filters-container {
background: hsl(var(--muted) / 0.5);
- border: 1px solid hsl(var(--border));
+ border: 2px solid hsl(var(--border));
border-radius: 12px;
padding: 20px;
margin-bottom: 24px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}
.filters-grid {
@@ -421,6 +422,19 @@ body {
animation: slideIn 0.3s ease-out;
}
+/* Sections avec cadres visibles */
+.section-vendor,
+.section-product,
+.section-client,
+.section-identity {
+ border: 2px solid hsl(var(--border));
+ border-radius: 12px;
+ padding: 20px;
+ margin-bottom: 24px;
+ background: white;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
+}
+
/* Responsive design */
@media (max-width: 768px) {
.section-vendor,
@@ -428,6 +442,7 @@ body {
.section-client,
.section-identity {
padding: 16px;
+ margin-bottom: 16px;
}
.filters-grid {
diff --git a/replit.md b/replit.md
index 5529c34..5b2ffad 100644
--- a/replit.md
+++ b/replit.md
@@ -220,6 +220,20 @@ Preferred communication style: Simple, everyday language.
- ✅ Safety confirmation dialogs for manual purge operations
- ✅ Real-time monitoring of data retention status with visual indicators
+### Modern UI Design & Advanced Search (January 10, 2025)
+- ✅ Complete UI redesign with modern, elegant design system
+- ✅ Enhanced visual borders and frames throughout the application for better visibility
+- ✅ Colored sections with animations and smooth transitions
+- ✅ Made "autorité de délivrance" field optional in new sale form as requested
+- ✅ Added comprehensive search module in sales history with multi-field filtering
+- ✅ Real-time search across names, sellers, articles, codes, payment methods, and birth places
+- ✅ Added CSV export functionality alongside existing PDF export
+- ✅ Visible section frames around each category in new sale form
+- ✅ Enhanced cards and containers with stronger visual borders
+- ✅ Improved responsive design for mobile and tablet devices
+- ✅ Modern search interface with clear result counting and active search indicators
+- ✅ Dual export options (PDF and CSV) for regulatory compliance reporting
+
### Docker Configuration & Cleanup (January 9, 2025)
- ✅ Complete Docker setup optimized for external PostgreSQL database
- ✅ Docker Compose configuration with RegisFlow application only