Files
org-parking/frontend/js/modal-logic.js
2026-01-13 11:20:12 +01:00

189 lines
6.8 KiB
JavaScript

/**
* 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 = `<strong>Parcheggio:</strong> 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 = '<option value="">Caricamento utenti...</option>';
// 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 = '<option value="">Seleziona utente...</option>';
select.innerHTML += '<option value="auto">Assegna automaticamente</option>';
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';
}
};