This commit is contained in:
Tomas Dvorak
2025-06-11 22:17:58 +02:00
parent 56488e2919
commit 3cd83b9e24
+160 -54
View File
@@ -1252,6 +1252,57 @@
</div>
</div>
<!-- Reservations Management Section -->
<div class="card" style="margin: 2rem auto; max-width: 1200px;">
<h3>Správa rezervací vozidel</h3>
<!-- Filters -->
<div class="mb-6 bg-gray-50 p-4 rounded-lg">
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-4">
<div>
<label for="vehicleFilter" class="block text-sm font-medium text-gray-700 mb-1">Filtrovat dle vozidla:</label>
<select id="vehicleFilter" class="form-control w-full">
<option value="">Všechna vozidla</option>
<!-- Vehicle options will be populated by JavaScript -->
</select>
</div>
<div>
<label for="dateFilter" class="block text-sm font-medium text-gray-700 mb-1">Filtrovat dle data:</label>
<input type="date" id="dateFilter" class="form-control w-full">
</div>
<div class="flex items-end">
<button id="exportButton" class="btn btn-primary w-full">
<i class="fas fa-file-export mr-2"></i>Exportovat do Excelu
</button>
</div>
</div>
</div>
<!-- Reservations Table -->
<div class="overflow-x-auto">
<table id="reservationsTable" class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Řidič</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Vozidlo</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Od</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Do</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Účel</th>
<th scope="col" class="px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">Akce</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
<!-- Rows will be populated by JavaScript -->
<tr>
<td colspan="6" class="px-6 py-4 text-center text-gray-500">
Načítám data o rezervacích...
</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- Icon Picker Modal -->
<div id="iconPickerModal" class="fixed inset-0 z-50 hidden">
<div id="iconPickerContainer" class="bg-white rounded-xl shadow-2xl overflow-hidden flex flex-col">
@@ -4314,38 +4365,34 @@ function displayReservations(reservations) {
return;
}
tbody.innerHTML = reservations.map(res => {
const startDate = new Date(res.start);
const endDate = new Date(res.end);
// Format date as DD.MM.YYYY
const formatDate = (date) => {
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 = (date) => {
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
return `${hours}:${minutes}`;
};
return `
<tr class="hover:bg-gray-50">
<td class="px-6 py-4">${res.driverName || '-'}</td>
<td class="px-6 py-4">${res.vehicle || '-'}</td>
<td class="px-6 py-4 whitespace-nowrap">${formatDate(startDate)}</td>
<td class="px-6 py-4 whitespace-nowrap">${formatTime(startDate)}</td>
<td class="px-6 py-4 whitespace-nowrap">${formatDate(endDate)}</td>
<td class="px-6 py-4 whitespace-nowrap">${formatTime(endDate)}</td>
<td class="px-6 py-4">${res.purpose || '-'}</td>
<td class="px-6 py-4 whitespace-nowrap">${calculateDuration(res)}</td>
</tr>
`;
}).join('');
// 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();
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
return `${day}.${month}.${year} ${hours}:${minutes}`;
};
tbody.innerHTML = reservations.map(res => `
<tr class="hover:bg-gray-50">
<td class="px-6 py-4">${res.driverName || '-'}</td>
<td class="px-6 py-4">${res.vehicle || '-'}</td>
<td class="px-6 py-4 whitespace-nowrap">${formatDateTime(res.start)}</td>
<td class="px-6 py-4 whitespace-nowrap">${formatDateTime(res.end)}</td>
<td class="px-6 py-4">${res.purpose || '-'}</td>
<td class="px-6 py-4 whitespace-nowrap">
<button onclick="editReservation('${res.id}')" class="text-blue-600 hover:text-blue-900 mr-3">
<i class="fas fa-edit"></i> Upravit
</button>
<button onclick="deleteReservation('${res.id}')" class="text-red-600 hover:text-red-900">
<i class="fas fa-trash"></i> Smazat
</button>
</td>
</tr>
`).join('');
}
// Function to filter reservations
@@ -4379,39 +4426,98 @@ function exportReservations() {
const vehicleFilter = document.getElementById('vehicleFilter').value;
const dateFilter = document.getElementById('dateFilter').value;
let dataToExport = window.allReservations;
let dataToExport = [...window.allReservations];
// Apply filters if set
if (vehicleFilter) {
dataToExport = dataToExport.filter(res => res.vehicle === vehicleFilter);
}
if (dateFilter) {
dataToExport = dataToExport.filter(res => res.startDate === dateFilter);
dataToExport = dataToExport.filter(res => {
const resDate = new Date(res.start).toISOString().split('T')[0];
return resDate === dateFilter;
});
}
// Create CSV content
const headers = ['Řidič', 'Vozidlo', 'Datum od', 'Čas od', 'Datum do', 'Čas do', 'Účel', 'Doba trvání'];
const csvContent = [
headers.join(','),
...dataToExport.map(res => [
`"${res.driverName}"`,
`"${res.vehicle}"`,
res.startDate,
res.startTime,
res.endDate,
res.endTime,
`"${res.purpose || ''}"`,
`"${calculateDuration(res)}"`
].join(','))
].join('\n');
// Sort by start date
dataToExport.sort((a, b) => new Date(a.start) - new Date(b.start));
// Create and trigger download
const blob = new Blob(['\ufeff' + csvContent], { type: 'text/csv;charset=utf-8;' });
// Format date as DD.MM.YYYY
const formatDate = (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}`;
};
// 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}`;
};
// 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'
];
const csvContent = [
headers.join(';'),
...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(';');
})
].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;'
});
const link = document.createElement('a');
const date = new Date().toISOString().split('T')[0];
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
link.href = URL.createObjectURL(blob);
link.download = `rezervace_${date}.csv`;
link.download = `rezervace_${timestamp}.csv`;
link.style.display = 'none';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
// Clean up
setTimeout(() => {
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
}, 100);
}
// Helper function to format date and time