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();