Switch to server-side data fetching and improve user interface elements

Refactors sales data fetching to use API calls instead of IndexedDB, introduces react-query, updates UI icons, and removes obsolete IndexedDB code.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 91318273-c764-4fd4-be04-bdc12c38af32
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/0715008c-7244-40f4-befc-26c014852236/6e755801-08e8-4492-805e-ac3610de5a2a.jpg
This commit is contained in:
michaelschal committed 2025-07-09 20:14:34 +00:00
1 parent ec38451a81
commit 4ad5b97932
3 files changed
+93 -214

No files matched your search

+61 -114
View File
@@ -1,119 +1,66 @@
// Utilitaires pour l'export et la gestion des données
// L'application utilise PostgreSQL via l'API backend
import { Sale, BackupData } from '@/types/sale';
const DB_NAME = 'VentesPetardsDB';
const DB_VERSION = 1;
const STORE_NAME = 'ventes';
const BACKUP_KEY = 'petards_backup_csv';
export class FireworksDB {
private db: IDBDatabase | null = null;
async init(): Promise<void> {
return new Promise((resolve, reject) => {
const request = indexedDB.open(DB_NAME, DB_VERSION);
request.onerror = () => reject(request.error);
request.onsuccess = () => {
this.db = request.result;
resolve();
};
request.onupgradeneeded = (event) => {
const db = (event.target as IDBOpenDBRequest).result;
if (!db.objectStoreNames.contains(STORE_NAME)) {
const store = db.createObjectStore(STORE_NAME, {
keyPath: 'id',
autoIncrement: true
});
store.createIndex('nom', 'nom', { unique: false });
store.createIndex('dateVente', 'dateVente', { unique: false });
}
};
});
}
async saveSale(sale: Omit<Sale, 'id'>): Promise<Sale> {
if (!this.db) throw new Error('Database not initialized');
return new Promise((resolve, reject) => {
const transaction = this.db!.transaction([STORE_NAME], 'readwrite');
const store = transaction.objectStore(STORE_NAME);
const saleWithTimestamp = {
...sale,
timestamp: new Date().toISOString()
};
const request = store.add(saleWithTimestamp);
request.onerror = () => reject(request.error);
request.onsuccess = () => {
const savedSale = { ...saleWithTimestamp, id: request.result as number };
resolve(savedSale);
};
});
}
async getAllSales(): Promise<Sale[]> {
if (!this.db) throw new Error('Database not initialized');
return new Promise((resolve, reject) => {
const transaction = this.db!.transaction([STORE_NAME], 'readonly');
const store = transaction.objectStore(STORE_NAME);
const request = store.getAll();
request.onerror = () => reject(request.error);
request.onsuccess = () => resolve(request.result);
});
}
async deleteSale(id: number): Promise<void> {
if (!this.db) throw new Error('Database not initialized');
return new Promise((resolve, reject) => {
const transaction = this.db!.transaction([STORE_NAME], 'readwrite');
const store = transaction.objectStore(STORE_NAME);
const request = store.delete(id);
request.onerror = () => reject(request.error);
request.onsuccess = () => resolve();
});
}
}
export async function createAutoBackup(sales: Sale[]): Promise<void> {
const backupData: BackupData = {
timestamp: new Date().toISOString(),
sales,
recordCount: sales.length
};
localStorage.setItem(BACKUP_KEY, JSON.stringify(backupData));
}
export function getAutoBackup(): BackupData | null {
try {
const backup = localStorage.getItem(BACKUP_KEY);
return backup ? JSON.parse(backup) : null;
} catch (error) {
console.error('Error loading backup:', error);
return null;
}
}
export function downloadBackup(): void {
const backup = getAutoBackup();
if (!backup) return;
const blob = new Blob([JSON.stringify(backup, null, 2)], {
type: 'application/json'
});
// Fonction utilitaire pour télécharger des données JSON
export function downloadJSON(data: any, filename: string): void {
const dataStr = JSON.stringify(data, null, 2);
const dataUri = 'data:application/json;charset=utf-8,'+ encodeURIComponent(dataStr);
const linkElement = document.createElement('a');
linkElement.setAttribute('href', dataUri);
linkElement.setAttribute('download', filename);
linkElement.click();
}
// Fonction utilitaire pour créer un CSV des ventes
export function exportSalesToCSV(sales: Sale[]): void {
const csvHeader = [
'Date/Heure',
'Vendeur',
'Date de vente',
'Type d\'article',
'Catégorie',
'Quantité',
'Gencode',
'Nom client',
'Prénom client',
'Date de naissance',
'Lieu de naissance',
'Type identité',
'Numéro identité',
'Autorité délivrance',
'Date délivrance'
];
const csvData = sales.map(sale => [
sale.timestamp ? new Date(sale.timestamp).toLocaleString('fr-FR') : '',
sale.vendeur,
sale.dateVente,
sale.typeArticle,
sale.categorie,
sale.quantite,
sale.gencode,
sale.nom,
sale.prenom,
sale.dateNaissance,
sale.lieuNaissance || '',
sale.typeIdentite,
sale.numeroIdentite,
sale.autoriteDelivrance,
sale.dateDelivrance
]);
const csvContent = [csvHeader, ...csvData]
.map(row => row.map(cell => `"${cell}"`).join(','))
.join('\n');
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = `backup_petards_${new Date().toISOString().split('T')[0]}.json`;
const url = URL.createObjectURL(blob);
link.setAttribute('href', url);
link.setAttribute('download', `ventes_${new Date().toISOString().split('T')[0]}.csv`);
link.click();
URL.revokeObjectURL(link.href);
}
URL.revokeObjectURL(url);
}