feat: reservation modal now usable.

This commit is contained in:
2026-03-12 20:10:42 +00:00
parent c138e8c6a0
commit 0c2186f5d8
2 changed files with 75 additions and 16 deletions

View File

@@ -397,13 +397,14 @@
<div class="bg-white dark:bg-slate-800 rounded-xl shadow-2xl max-w-lg w-full max-h-[90vh] overflow-y-auto" onclick="event.stopPropagation()">
<div class="p-6">
<div class="flex items-center justify-between mb-6">
<h2 class="text-xl font-semibold text-gray-900 dark:text-white">New Reservation</h2>
<h2 class="text-xl font-semibold text-gray-900 dark:text-white" id="modal-title">New Reservation</h2>
<button onclick="closeReservationModal()" class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
</svg>
</button>
</div>
<input type="hidden" id="editing-reservation-id" value="">
<form id="reservation-form" onsubmit="submitReservation(event)">
<!-- Name -->
@@ -522,7 +523,7 @@
class="px-4 py-2 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg">
Cancel
</button>
<button type="submit"
<button type="submit" id="modal-submit-btn"
class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700">
Create Reservation
</button>
@@ -600,27 +601,83 @@ function closeDayPanel() {
let reservationModeActive = false;
function openReservationModal() {
// Reset to "create" mode
document.getElementById('modal-title').textContent = 'New Reservation';
document.getElementById('modal-submit-btn').textContent = 'Create Reservation';
document.getElementById('editing-reservation-id').value = '';
document.getElementById('reservation-form').reset();
document.getElementById('reservation-modal').classList.remove('hidden');
reservationModeActive = true;
// Show reservation legend, hide main legend
document.getElementById('main-legend').classList.add('md:hidden');
document.getElementById('main-legend').classList.remove('md:flex');
document.getElementById('reservation-legend').classList.remove('md:hidden');
document.getElementById('reservation-legend').classList.add('md:flex');
// Trigger availability update
updateCalendarAvailability();
}
async function editReservation(id) {
try {
const response = await fetch(`/api/fleet-calendar/reservations/${id}`);
if (!response.ok) { alert('Failed to load reservation'); return; }
const res = await response.json();
// Switch modal to "edit" mode
document.getElementById('modal-title').textContent = 'Edit Reservation';
document.getElementById('modal-submit-btn').textContent = 'Save Changes';
document.getElementById('editing-reservation-id').value = id;
// Populate fields
const form = document.getElementById('reservation-form');
form.querySelector('input[name="name"]').value = res.name;
form.querySelector('select[name="project_id"]').value = res.project_id || '';
form.querySelector('input[name="start_date"]').value = res.start_date;
form.querySelector('textarea[name="notes"]').value = res.notes || '';
// Color radio
const colorRadio = form.querySelector(`input[name="color"][value="${res.color}"]`);
if (colorRadio) colorRadio.checked = true;
// Assignment type
const atRadio = form.querySelector(`input[name="assignment_type"][value="${res.assignment_type}"]`);
if (atRadio) { atRadio.checked = true; toggleAssignmentType(res.assignment_type); }
if (res.assignment_type === 'quantity') {
form.querySelector('input[name="quantity_needed"]').value = res.quantity_needed || 1;
}
// End date / TBD
const tbdCheckbox = document.getElementById('end_date_tbd');
if (res.end_date_tbd) {
tbdCheckbox.checked = true;
form.querySelector('input[name="estimated_end_date"]').value = res.estimated_end_date || '';
} else {
tbdCheckbox.checked = false;
document.getElementById('end_date_input').value = res.end_date || '';
}
toggleEndDateTBD();
document.getElementById('reservation-modal').classList.remove('hidden');
reservationModeActive = true;
document.getElementById('main-legend').classList.add('md:hidden');
document.getElementById('main-legend').classList.remove('md:flex');
document.getElementById('reservation-legend').classList.remove('md:hidden');
document.getElementById('reservation-legend').classList.add('md:flex');
updateCalendarAvailability();
} catch (error) {
console.error('Error loading reservation:', error);
alert('Error loading reservation');
}
}
function closeReservationModal() {
document.getElementById('reservation-modal').classList.add('hidden');
document.getElementById('reservation-form').reset();
document.getElementById('editing-reservation-id').value = '';
reservationModeActive = false;
// Restore main legend
document.getElementById('main-legend').classList.remove('md:hidden');
document.getElementById('main-legend').classList.add('md:flex');
document.getElementById('reservation-legend').classList.add('md:hidden');
document.getElementById('reservation-legend').classList.remove('md:flex');
// Reset calendar colors
resetCalendarColors();
}
@@ -752,6 +809,7 @@ async function submitReservation(event) {
const form = event.target;
const formData = new FormData(form);
const endDateTbd = formData.get('end_date_tbd') === 'on';
const editingId = document.getElementById('editing-reservation-id').value;
const data = {
name: formData.get('name'),
@@ -766,7 +824,6 @@ async function submitReservation(event) {
notes: formData.get('notes') || null
};
// Validate: need either end_date or TBD checked
if (!data.end_date && !data.end_date_tbd) {
alert('Please enter an end date or check "TBD / Ongoing"');
return;
@@ -778,9 +835,15 @@ async function submitReservation(event) {
data.unit_ids = formData.getAll('unit_ids');
}
const isEdit = editingId !== '';
const url = isEdit
? `/api/fleet-calendar/reservations/${editingId}`
: '/api/fleet-calendar/reservations';
const method = isEdit ? 'PUT' : 'POST';
try {
const response = await fetch('/api/fleet-calendar/reservations', {
method: 'POST',
const response = await fetch(url, {
method,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
@@ -789,14 +852,13 @@ async function submitReservation(event) {
if (result.success) {
closeReservationModal();
// Reload the page to refresh calendar
window.location.reload();
} else {
alert('Error creating reservation: ' + (result.detail || 'Unknown error'));
alert(`Error ${isEdit ? 'saving' : 'creating'} reservation: ` + (result.detail || 'Unknown error'));
}
} catch (error) {
console.error('Error:', error);
alert('Error creating reservation');
alert(`Error ${isEdit ? 'saving' : 'creating'} reservation`);
}
}