/** * Shared logic for the Day/Presence Modal * Handles UI interactions, assignments, and integrated reassign form. */ const ModalLogic = { // Configuration holding callbacks config: { onMarkPresence: async (status, date, userId) => { }, onClearPresence: async (date, userId) => { }, onReleaseParking: async (assignmentId) => { }, onReassignParking: async (assignmentId, newUserId) => { }, onReload: async () => { } // Callback to reload calendar data }, // State currentAssignmentId: null, currentDate: null, currentUserId: null, init(config) { this.config = { ...this.config, ...config }; this.setupEventListeners(); }, setupEventListeners() { // Close buttons document.getElementById('closeDayModal')?.addEventListener('click', () => { document.getElementById('dayModal').style.display = 'none'; }); // Status buttons document.querySelectorAll('#dayModal .status-btn').forEach(btn => { btn.addEventListener('click', () => { if (this.currentDate) { this.config.onMarkPresence(btn.dataset.status, this.currentDate, this.currentUserId); } }); }); // Actions document.getElementById('clearDayBtn')?.addEventListener('click', () => { if (this.currentDate) { this.config.onClearPresence(this.currentDate, this.currentUserId); } }); document.getElementById('releaseParkingBtn')?.addEventListener('click', () => { if (this.currentAssignmentId) { this.config.onReleaseParking(this.currentAssignmentId); } }); document.getElementById('reassignParkingBtn')?.addEventListener('click', () => { this.showReassignForm(); }); // Reassign Form document.getElementById('cancelReassign')?.addEventListener('click', () => { this.hideReassignForm(); }); document.getElementById('confirmReassign')?.addEventListener('click', () => { const select = document.getElementById('reassignUser'); this.config.onReassignParking(this.currentAssignmentId, select.value); }); // Close on click outside window.addEventListener('click', (e) => { const modal = document.getElementById('dayModal'); if (e.target === modal) { modal.style.display = 'none'; } }); }, openModal(data) { const { dateStr, userName, presence, parking, userId, isReadOnly } = data; this.currentDate = dateStr; this.currentUserId = userId; // Optional, for team view this.currentAssignmentId = parking ? parking.id : null; const modal = document.getElementById('dayModal'); const title = document.getElementById('dayModalTitle'); const userLabel = document.getElementById('dayModalUser'); title.textContent = utils.formatDateDisplay(dateStr); // Show/Hide User Name (for Team Calendar) if (userName && userLabel) { userLabel.textContent = userName; userLabel.style.display = 'block'; } else if (userLabel) { userLabel.style.display = 'none'; } // Highlight status document.querySelectorAll('#dayModal .status-btn').forEach(btn => { const status = btn.dataset.status; if (presence && presence.status === status) { btn.classList.add('active'); } else { btn.classList.remove('active'); } }); // Clear button visibility const clearBtn = document.getElementById('clearDayBtn'); if (presence) { clearBtn.style.display = 'block'; } else { clearBtn.style.display = 'none'; } // Parking Section & Reset Form this.hideReassignForm(); // Reset view to actions const parkingSection = document.getElementById('parkingSection'); const parkingInfo = document.getElementById('parkingInfo'); if (parking) { parkingSection.style.display = 'block'; const spotName = parking.spot_display_name || parking.spot_id; parkingInfo.innerHTML = `Parcheggio: Posto ${spotName}`; } else { parkingSection.style.display = 'none'; } modal.style.display = 'flex'; }, async showReassignForm() { if (!this.currentAssignmentId) return; const actionsDiv = document.getElementById('parkingActions'); const formDiv = document.getElementById('reassignForm'); actionsDiv.style.display = 'none'; formDiv.style.display = 'flex'; const select = document.getElementById('reassignUser'); select.innerHTML = ''; // Load eligible users (Global API function assumed available) try { const response = await api.get(`/api/parking/eligible-users/${this.currentAssignmentId}`); if (!response || !response.ok) { const error = await response.json(); alert(error.detail || 'Impossibile caricare gli utenti idonei'); this.hideReassignForm(); return; } const users = await response.json(); select.innerHTML = ''; select.innerHTML += ''; if (users.length === 0) { const option = document.createElement('option'); option.disabled = true; option.textContent = "Nessun altro utente disponibile"; select.appendChild(option); } else { users.forEach(user => { const option = document.createElement('option'); option.value = user.id; const officeInfo = user.office_name ? ` (${user.office_name})` : ''; option.textContent = user.name + officeInfo; select.appendChild(option); }); } } catch (e) { console.error(e); alert('Errore di rete'); this.hideReassignForm(); } }, hideReassignForm() { document.getElementById('reassignForm').style.display = 'none'; document.getElementById('parkingActions').style.display = 'flex'; }, closeModal() { document.getElementById('dayModal').style.display = 'none'; } };