mirror of
https://github.com/R0m1k3/Regisflow.git
synced 2026-10-24 15:48:17 +02:00
Improve the user interface and add CSV export to the sales history
Implements UI enhancements with visible section frames and adds CSV export functionality to SalesHistory.tsx and index.css. Replit-Commit-Author: Agent Replit-Commit-Session-Id: dec54137-d5a2-4406-8ad4-5f2f9fb110bf Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/0715008c-7244-40f4-befc-26c014852236/9ba8b033-161d-4888-81d6-a484ee533451.jpg
This commit is contained in:
1 parent
71db65e5b5
commit
79b179f0ee
3 files changed
+114
-11
No files matched your search
@@ -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 = () => {
|
const clearFilters = () => {
|
||||||
setStartDate('');
|
setStartDate('');
|
||||||
setEndDate('');
|
setEndDate('');
|
||||||
@@ -264,14 +328,24 @@ export default function SalesHistory({ canDelete = false }: SalesHistoryProps) {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<button
|
<div className="flex gap-2">
|
||||||
onClick={exportToPDF}
|
<button
|
||||||
disabled={filteredSales.length === 0}
|
onClick={exportToPDF}
|
||||||
className="modern-button modern-button-primary"
|
disabled={filteredSales.length === 0}
|
||||||
>
|
className="modern-button modern-button-primary"
|
||||||
<Download className="h-4 w-4" />
|
>
|
||||||
Exporter en PDF
|
<FileText className="h-4 w-4" />
|
||||||
</button>
|
Export PDF
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={exportToCSV}
|
||||||
|
disabled={filteredSales.length === 0}
|
||||||
|
className="modern-button modern-button-secondary"
|
||||||
|
>
|
||||||
|
<Download className="h-4 w-4" />
|
||||||
|
Export CSV
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+18
-3
@@ -246,11 +246,11 @@ body {
|
|||||||
/* Module de recherche */
|
/* Module de recherche */
|
||||||
.search-container {
|
.search-container {
|
||||||
background: white;
|
background: white;
|
||||||
border: 1px solid hsl(var(--border));
|
border: 2px solid hsl(var(--primary) / 0.3);
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
margin-bottom: 24px;
|
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 {
|
.search-header {
|
||||||
@@ -283,10 +283,11 @@ body {
|
|||||||
/* Filtres élégants */
|
/* Filtres élégants */
|
||||||
.filters-container {
|
.filters-container {
|
||||||
background: hsl(var(--muted) / 0.5);
|
background: hsl(var(--muted) / 0.5);
|
||||||
border: 1px solid hsl(var(--border));
|
border: 2px solid hsl(var(--border));
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
margin-bottom: 24px;
|
margin-bottom: 24px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.filters-grid {
|
.filters-grid {
|
||||||
@@ -421,6 +422,19 @@ body {
|
|||||||
animation: slideIn 0.3s ease-out;
|
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 */
|
/* Responsive design */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.section-vendor,
|
.section-vendor,
|
||||||
@@ -428,6 +442,7 @@ body {
|
|||||||
.section-client,
|
.section-client,
|
||||||
.section-identity {
|
.section-identity {
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
|
margin-bottom: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.filters-grid {
|
.filters-grid {
|
||||||
|
|||||||
@@ -220,6 +220,20 @@ Preferred communication style: Simple, everyday language.
|
|||||||
- ✅ Safety confirmation dialogs for manual purge operations
|
- ✅ Safety confirmation dialogs for manual purge operations
|
||||||
- ✅ Real-time monitoring of data retention status with visual indicators
|
- ✅ 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)
|
### Docker Configuration & Cleanup (January 9, 2025)
|
||||||
- ✅ Complete Docker setup optimized for external PostgreSQL database
|
- ✅ Complete Docker setup optimized for external PostgreSQL database
|
||||||
- ✅ Docker Compose configuration with RegisFlow application only
|
- ✅ Docker Compose configuration with RegisFlow application only
|
||||||
|
|||||||
Reference in new issue
Block a user