feat: aggiunti: loggica random, tema scuro, correzioni mail, miglioramenti generali, cache;

This commit is contained in:
StefanoSalemi
2026-04-17 18:27:37 +02:00
parent a7ef46640d
commit 104ad53a9a
26 changed files with 861 additions and 216 deletions

View File

@@ -4,7 +4,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Gestione Uffici - Parking Manager</title>
<title>Gestione Gruppi - Parking Manager</title>
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<link rel="stylesheet" href="/css/styles.css">
</head>
@@ -42,7 +42,7 @@
<main class="main-content">
<header class="page-header">
<h2>Gestione Uffici</h2>
<h2>Gestione Gruppi</h2>
<div class="header-actions">
</div>
</header>
@@ -50,8 +50,8 @@
<div class="content-wrapper">
<div class="card">
<div style="padding-bottom: 1rem; display: flex; justify-content: space-between; align-items: center;">
<h3 style="margin: 0;">Lista Uffici</h3>
<button class="btn btn-dark" id="addOfficeBtn">Nuovo Ufficio</button>
<h3 style="margin: 0;">Lista Gruppi</h3>
<button class="btn btn-dark" id="addOfficeBtn">Nuovo Gruppo</button>
</div>
<div class="data-table-container">
<table class="data-table" id="officesTable">
@@ -75,7 +75,7 @@
<div class="modal" id="officeModal" style="display: none;">
<div class="modal-content">
<div class="modal-header">
<h3 id="officeModalTitle">Nuovo Ufficio</h3>
<h3 id="officeModalTitle">Nuovo Gruppo</h3>
<button class="modal-close" id="closeOfficeModal">&times;</button>
</div>
<div class="modal-body">
@@ -83,14 +83,14 @@
<input type="hidden" id="officeId">
<div class="form-group">
<label for="officeName">Nome Ufficio</label>
<label for="officeName">Nome Gruppo</label>
<input type="text" id="officeName" required>
</div>
<div class="form-group">
<label for="officeQuota">Quota Parcheggio</label>
<input type="number" id="officeQuota" min="0" value="0" required>
<small class="text-muted">Numero totale di posti auto assegnati a questo ufficio</small>
<small class="text-muted">Numero totale di posti auto assegnati a questo gruppo</small>
</div>
<div class="form-group">

View File

@@ -64,7 +64,7 @@
class="sort-icon"></span></th>
<th class="sortable" data-sort="role" style="cursor: pointer;">Ruolo <span
class="sort-icon"></span></th>
<th class="sortable" data-sort="office_name" style="cursor: pointer;">Ufficio <span
<th class="sortable" data-sort="office_name" style="cursor: pointer;">Gruppo <span
class="sort-icon"></span></th>
<th class="sortable" data-sort="parking_ratio" style="cursor: pointer;">Punteggio <span
class="sort-icon"></span></th>

View File

@@ -42,7 +42,7 @@
<main class="main-content">
<header class="page-header">
<h2>Impostazioni Ufficio</h2>
<h2>Impostazioni Gruppo</h2>
</header>
<div class="content-wrapper">
@@ -60,49 +60,54 @@
<div id="settingsContent" style="display: none;">
<!-- Card 1: Batch Scheduling Settings -->
<!-- Card: Algorithm Settings -->
<div class="card">
<div class="card-header">
<h3>Schedulazione Automatica</h3>
<h3>Impostazioni Algoritmo Parcheggio</h3>
</div>
<div class="card-body">
<form id="scheduleForm">
<div class="form-group" style="padding-bottom: 1rem; border-bottom: 1px solid #e5e7eb; margin-bottom: 1rem;">
<label style="font-weight: 500; display: block; margin-bottom: 0.5rem;">Modalità Assegnazione</label>
<p class="text-muted" style="margin-bottom: 0.5rem;">Scegli la modalità con cui assegnare i posti auto ai membri del gruppo.</p>
<select id="assignmentModeSelect" class="form-select" style="max-width: 300px;">
<option value="fairness">Punteggio (Fairness)</option>
<option value="random">Completamente Random</option>
</select>
</div>
<div class="form-group">
<label class="toggle-label">
<span>Abilita Assegnazione Batch</span>
<span style="font-weight: 500;">Abilita Assegnazione Batch</span>
<label class="toggle-switch">
<input type="checkbox" id="bookingWindowEnabled">
<span class="toggle-slider"></span>
</label>
</label>
<small class="text-muted">Se abilitato, l'assegnazione dei posti avverrà solo dopo
l'orario
di cut-off del giorno precedente.</small>
<small class="text-muted">Se abilitato, l'assegnazione dei posti avverrà solo dopo l'orario di cut-off del giorno precedente.</small>
</div>
<div class="form-group" id="cutoffTimeGroup">
<label>Orario di Cut-off (Giorno Precedente)</label>
<div style="display: flex; gap: 0.5rem; align-items: center;">
<label style="font-weight: 500;">Orario di Cut-off (Giorno Precedente)</label>
<div style="display: flex; gap: 0.5rem; align-items: center; margin-top: 0.5rem;">
<select id="bookingWindowHour" style="width: 80px;">
<!-- Populated by JS -->
</select>
<span>:</span>
<select id="bookingWindowMinute" style="width: 80px;">
<!-- Populated by JS -->
</select>
</div>
<small class="text-muted">Le presenze inserite prima di questo orario saranno messe in
attesa.</small>
<small class="text-muted">Le presenze inserite prima di questo orario saranno messe in attesa.</small>
</div>
<div class="form-actions">
<div class="form-actions" style="margin-top: 1.5rem;">
<button type="submit" class="btn btn-dark">Salva Impostazioni</button>
</div>
</form>
</div>
</div>
<!-- Card 2: Testing Tools -->
<!-- Card: Testing Tools -->
<div class="card">
<div class="card-header"
style="display: flex; justify-content: space-between; align-items: center;">

View File

@@ -108,7 +108,7 @@
<!-- Date Navigation (Centered) -->
<div style="display: flex; justify-content: center; margin-bottom: 2rem;">
<div
style="display: flex; align-items: center; gap: 0.5rem; background: white; padding: 0.5rem; border-radius: 8px; border: 1px solid var(--border);">
style="display: flex; align-items: center; gap: 0.5rem; background: transparent; padding: 0.5rem; border-radius: 8px;">
<button class="btn-icon" id="statusPrevDay"
style="border: none; width: 32px; height: 32px;">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
@@ -117,11 +117,11 @@
</svg>
</button>
<div style="position: relative; text-align: center; min-width: 200px;">
<div style="position: relative; text-align: center; min-width: 250px; cursor: pointer;">
<div id="statusDateDisplay"
style="font-weight: 600; font-size: 1rem; text-transform: capitalize;"></div>
style="font-weight: 600; font-size: 1.1rem; text-transform: capitalize; color: var(--text);"></div>
<input type="date" id="statusDatePicker"
style="position: absolute; inset: 0; opacity: 0; cursor: pointer;">
style="position: absolute; inset: 0; opacity: 0; cursor: pointer; width: 100%;">
</div>
<button class="btn-icon" id="statusNextDay"
@@ -139,7 +139,7 @@
<div
style="display: flex; align-items: center; justify-content: flex-start; gap: 1rem; margin-bottom: 1.5rem;">
<div style="font-weight: 600; font-size: 1.1rem; color: var(--text);">
Ufficio: <span id="currentOfficeDisplay" style="color: var(--primary);">...</span>
Gruppo: <span id="currentOfficeDisplay" style="color: var(--primary);">...</span>
</div>
<span class="badge"
style="background: #eff6ff; color: #1d4ed8; border: 1px solid #dbeafe; padding: 0.35rem 0.75rem; font-size: 0.85rem;">
@@ -367,7 +367,30 @@
</div>
<!-- Admin Manual Assign Spot Modal -->
<div class="modal" id="adminAssignSpotModal" style="display: none;">
<div class="modal-content modal-small">
<div class="modal-header">
<h3>Assegna Posto Manualmente</h3>
<button class="modal-close" id="closeAdminAssignModal">&times;</button>
</div>
<div class="modal-body">
<p id="adminAssignSpotInfo" style="margin-bottom: 1rem;"></p>
<form id="adminAssignForm">
<div class="form-group" style="margin-bottom: 1rem;">
<label for="adminAssignUser">Seleziona Utente (Presente in Sede)</label>
<select id="adminAssignUser" class="form-control" required style="width: 100%;">
<option value="">Caricamento utenti...</option>
</select>
</div>
<div class="form-actions">
<button type="button" class="btn btn-secondary" id="cancelAdminAssign">Annulla</button>
<button type="submit" class="btn btn-dark">Assegna</button>
</div>
</form>
</div>
</div>
</div>
<script src="/js/api.js"></script>
<script src="/js/utils.js"></script>
<script src="/js/nav.js"></script>

View File

@@ -74,9 +74,9 @@
<small class="text-muted">Il ruolo è assegnato dal tuo amministratore</small>
</div>
<div class="form-group">
<label for="manager">Ufficio</label>
<label for="manager">Gruppo</label>
<input type="text" id="manager" disabled>
<small class="text-muted">Il tuo ufficio è assegnato dall'amministratore</small>
<small class="text-muted">Il tuo gruppo è assegnato dall'amministratore</small>
</div>
<div class="form-actions" id="profileActions">
<button type="submit" class="btn btn-dark">Salva Modifiche</button>

View File

@@ -47,7 +47,23 @@
<div class="content-wrapper">
<!-- Theme Settings Card -->
<div class="card" style="margin-bottom: 2rem;">
<div class="card-header">
<h3>Tema</h3>
</div>
<div class="card-body">
<div class="form-group">
<label style="font-weight: 500; display: block; margin-bottom: 0.5rem;">Tema dell'applicazione</label>
<select id="themeSelect" class="form-select" style="max-width: 300px;">
<option value="system">Sistema (Predefinito)</option>
<option value="light">Chiaro</option>
<option value="dark">Scuro</option>
</select>
<small class="text-muted" style="display: block; margin-top: 0.5rem;">Scegli il tema preferito da utilizzare nell'applicazione.</small>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<h3>Notifiche Parcheggio</h3>
@@ -138,6 +154,10 @@
document.getElementById('notifyParkingChanges').checked = currentUser.notify_parking_changes !== 0;
updateDailyTimeVisibility();
// Populate Theme
const savedTheme = localStorage.getItem('theme') || 'system';
document.getElementById('themeSelect').value = savedTheme;
}
function updateDailyTimeVisibility() {
@@ -173,6 +193,15 @@
// Toggle daily time visibility
document.getElementById('notifyDailyParking').addEventListener('change', updateDailyTimeVisibility);
// Save Theme dynamically
document.getElementById('themeSelect').addEventListener('change', (e) => {
const theme = e.target.value;
if (typeof applyTheme === 'function') {
applyTheme(theme);
utils.showMessage('Tema aggiornato', 'success');
}
});
}
</script>
</body>

View File

@@ -55,14 +55,14 @@
<option value="month">Mese</option>
</select>
<select id="officeFilter" class="form-select" style="min-width: 200px;">
<option value="">Tutti gli Uffici</option>
<option value="">Tutti i Gruppi</option>
</select>
</div>
<div id="office-display-header"
style="margin-bottom: 1rem; font-weight: 600; font-size: 1.1rem; color: var(--text);">
Ufficio: <span id="currentOfficeNameDisplay" style="color: var(--primary);">Loading...</span>
Gruppo: <span id="currentOfficeNameDisplay" style="color: var(--primary);">Loading...</span>
</div>
<div class="calendar-header">

View File

@@ -60,6 +60,7 @@
</div>
<div id="rulesContent" style="display: none;">
<!-- Weekly Closing Days -->
<div class="card">
<div class="card-header">
@@ -124,7 +125,7 @@
<div id="noOfficeMessage">
<div class="card">
<div class="card-body text-center">
<p>Seleziona un ufficio sopra per gestirne le regole di parcheggio</p>
<p>Seleziona un gruppo sopra per gestirne le regole di parcheggio</p>
</div>
</div>
</div>