189 lines
6.8 KiB
JavaScript
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';
|
|
}
|
|
};
|