From 2e78f34388960cb03300f0447ac226c04f2673be Mon Sep 17 00:00:00 2001 From: Tomas Dvorak Date: Wed, 11 Jun 2025 23:01:25 +0200 Subject: [PATCH] d --- admin-dashboard.html | 105 +++++++++++++++++++++---------------------- 1 file changed, 50 insertions(+), 55 deletions(-) diff --git a/admin-dashboard.html b/admin-dashboard.html index 0d213ea..882c97c 100644 --- a/admin-dashboard.html +++ b/admin-dashboard.html @@ -4382,7 +4382,7 @@ function filterReservations() { displayReservations(filtered); } -// Function to export reservations to Excel +// Function to export reservations to CSV function exportReservations() { if (!window.allReservations || !window.allReservations.length) { showNotification('Žádné rezervace k exportu', 'warning'); @@ -4390,93 +4390,88 @@ function exportReservations() { } // Get filtered reservations - const vehicleFilter = document.getElementById('vehicleFilter').value; - const dateFilter = document.getElementById('dateFilter').value; + const vehicleFilter = document.getElementById('vehicleFilter')?.value || ''; + const dateFilter = document.getElementById('dateFilter')?.value || ''; let dataToExport = [...window.allReservations]; // Apply filters if set if (vehicleFilter) { - dataToExport = dataToExport.filter(res => res.vehicle === vehicleFilter); + dataToExport = dataToExport.filter(res => res.vehicle && res.vehicle.trim() === vehicleFilter); } if (dateFilter) { dataToExport = dataToExport.filter(res => { - const resDate = new Date(res.start).toISOString().split('T')[0]; - return resDate === dateFilter; + if (!res.start) return false; + const reservationDate = new Date(res.start); + const filterDate = new Date(dateFilter); + + return reservationDate.getFullYear() === filterDate.getFullYear() && + reservationDate.getMonth() === filterDate.getMonth() && + reservationDate.getDate() === filterDate.getDate(); }); } + if (!dataToExport.length) { + showNotification('Žádná data k exportu po aplikování filtrů', 'warning'); + return; + } + // Sort by start date dataToExport.sort((a, b) => new Date(a.start) - new Date(b.start)); - // Format date as DD.MM.YYYY - const formatDate = (dateString) => { + // Format date and time as DD.MM.YYYY HH:MM + const formatDateTime = (dateString) => { const date = new Date(dateString); const day = String(date.getDate()).padStart(2, '0'); const month = String(date.getMonth() + 1).padStart(2, '0'); const year = date.getFullYear(); - return `${day}.${month}.${year}`; - }; - - // Format time as HH:MM - const formatTime = (dateString) => { - const date = new Date(dateString); const hours = String(date.getHours()).padStart(2, '0'); const minutes = String(date.getMinutes()).padStart(2, '0'); - return `${hours}:${minutes}`; + return `${day}.${month}.${year} ${hours}:${minutes}`; }; - // Format date and time for Excel (YYYY-MM-DD HH:MM) - const excelDateTime = (dateString) => { - const date = new Date(dateString); - const year = date.getFullYear(); - const month = String(date.getMonth() + 1).padStart(2, '0'); - const day = String(date.getDate()).padStart(2, '0'); - const hours = String(date.getHours()).padStart(2, '0'); - const minutes = String(date.getMinutes()).padStart(2, '0'); - return `${year}-${month}-${day} ${hours}:${minutes}`; + // Escape CSV values (handles quotes and special characters) + const escapeCsv = (value) => { + if (value === null || value === undefined) return ''; + const stringValue = String(value); + // Escape double quotes by doubling them + const escaped = stringValue.replace(/"/g, '""'); + // Wrap in quotes if contains comma, newline, or quote + if (escaped.includes(',') || escaped.includes('\n') || escaped.includes('"')) { + return `"${escaped}"`; + } + return escaped; }; - // Create CSV content with semicolon as delimiter for better Excel compatibility - const headers = [ - 'Řidič', - 'Vozidlo', - 'Začátek rezervace', - 'Konec rezervace', - 'Doba trvání', - 'Účel cesty' - ]; + // Create CSV content + const headers = ['Řidič', 'Vozidlo', 'Od', 'Do', 'Účel']; - const csvContent = [ - headers.join(';'), + const csvRows = [ + headers.join(';'), // Header row ...dataToExport.map(res => { - const start = new Date(res.start); - const end = new Date(res.end); - - return [ - `"${res.driverName || 'Neznámý řidič'}"`, - `"${res.vehicle || 'Neznámé vozidlo'}"`, - `"${excelDateTime(start)}"`, - `"${excelDateTime(end)}"`, - `"${calculateDuration(res)}"`, - `"${res.purpose || 'Nespecifikováno'}"` - ].join(';'); + const row = [ + escapeCsv(res.driverName || ''), + escapeCsv(res.vehicle || ''), + escapeCsv(formatDateTime(res.start)), + escapeCsv(formatDateTime(res.end)), + escapeCsv(res.purpose || '') + ]; + return row.join(';'); }) - ].join('\r\n'); + ]; - // Create and trigger download with proper encoding for Excel - const blob = new Blob([ - '\ufeff', // UTF-8 BOM for Excel - csvContent - ], { - type: 'text/csv;charset=utf-8;' - }); + // Create CSV string with BOM for Excel + const csvString = '\uFEFF' + csvRows.join('\r\n'); + // Create and trigger download + const blob = new Blob([csvString], { type: 'text/csv;charset=utf-8;' }); const link = document.createElement('a'); - const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); + const timestamp = new Date().toISOString().split('T')[0]; + link.href = URL.createObjectURL(blob); link.download = `rezervace_${timestamp}.csv`; link.style.display = 'none'; + document.body.appendChild(link); link.click();