Primo commit
This commit is contained in:
113
frontend/pages/admin-offices.html
Normal file
113
frontend/pages/admin-offices.html
Normal file
@@ -0,0 +1,113 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Gestione Uffici - Parking Manager</title>
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||
<link rel="stylesheet" href="/css/styles.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<h1>Gestione Parcheggi</h1>
|
||||
</div>
|
||||
<nav class="sidebar-nav"></nav>
|
||||
<div class="sidebar-footer">
|
||||
<div class="user-menu">
|
||||
<button class="user-button" id="userMenuButton">
|
||||
<div class="user-avatar">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2">
|
||||
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path>
|
||||
<circle cx="12" cy="7" r="4"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="user-info">
|
||||
<div class="user-name" id="userName">Caricamento...</div>
|
||||
<div class="user-role" id="userRole">-</div>
|
||||
</div>
|
||||
</button>
|
||||
<div class="user-dropdown" id="userDropdown" style="display: none;">
|
||||
<a href="/profile" class="dropdown-item">Profilo</a>
|
||||
<a href="/settings" class="dropdown-item">Impostazioni</a>
|
||||
<hr class="dropdown-divider">
|
||||
<button class="dropdown-item" id="logoutButton">Esci</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main class="main-content">
|
||||
<header class="page-header">
|
||||
<h2>Gestione Uffici</h2>
|
||||
<div class="header-actions">
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<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>
|
||||
</div>
|
||||
<div class="data-table-container">
|
||||
<table class="data-table" id="officesTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Nome</th>
|
||||
<th>Quota Posti</th>
|
||||
<th>Prefisso</th>
|
||||
<th>Utenti</th>
|
||||
<th>Azioni</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="officesBody"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Office Modal -->
|
||||
<div class="modal" id="officeModal" style="display: none;">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3 id="officeModalTitle">Nuovo Ufficio</h3>
|
||||
<button class="modal-close" id="closeOfficeModal">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="officeForm">
|
||||
<input type="hidden" id="officeId">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="officeName">Nome Ufficio</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>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="form-actions">
|
||||
<button type="button" class="btn btn-secondary" id="cancelOffice">Annulla</button>
|
||||
<button type="submit" class="btn btn-dark" id="saveOfficeBtn">Salva</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/js/api.js"></script>
|
||||
<script src="/js/utils.js"></script>
|
||||
<script src="/js/nav.js"></script>
|
||||
<script src="/js/admin-offices.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,5 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
@@ -7,31 +8,33 @@
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||
<link rel="stylesheet" href="/css/styles.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<h1>Parking Manager</h1>
|
||||
<h1>Gestione Parcheggi</h1>
|
||||
</div>
|
||||
<nav class="sidebar-nav"></nav>
|
||||
<div class="sidebar-footer">
|
||||
<div class="user-menu">
|
||||
<button class="user-button" id="userMenuButton">
|
||||
<div class="user-avatar">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2">
|
||||
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path>
|
||||
<circle cx="12" cy="7" r="4"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="user-info">
|
||||
<div class="user-name" id="userName">Loading...</div>
|
||||
<div class="user-name" id="userName">Caricamento...</div>
|
||||
<div class="user-role" id="userRole">-</div>
|
||||
</div>
|
||||
</button>
|
||||
<div class="user-dropdown" id="userDropdown" style="display: none;">
|
||||
<a href="/profile" class="dropdown-item">Profile</a>
|
||||
<a href="/settings" class="dropdown-item">Settings</a>
|
||||
<a href="/profile" class="dropdown-item">Profilo</a>
|
||||
<a href="/settings" class="dropdown-item">Impostazioni</a>
|
||||
<hr class="dropdown-divider">
|
||||
<button class="dropdown-item" id="logoutButton">Logout</button>
|
||||
<button class="dropdown-item" id="logoutButton">Esci</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -39,23 +42,33 @@
|
||||
|
||||
<main class="main-content">
|
||||
<header class="page-header">
|
||||
<h2>Manage Users</h2>
|
||||
<h2>Gestione Utenti</h2>
|
||||
<div class="header-actions">
|
||||
<input type="text" id="searchInput" class="form-input" placeholder="Search users...">
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<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 Utenti</h3>
|
||||
<input type="text" id="searchInput" class="form-input" placeholder="Cerca utenti..."
|
||||
style="max-width: 300px;">
|
||||
</div>
|
||||
<div class="data-table-container">
|
||||
<table class="data-table" id="usersTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Email</th>
|
||||
<th>Role</th>
|
||||
<th>Manager</th>
|
||||
<th>Actions</th>
|
||||
<th class="sortable" data-sort="name" style="cursor: pointer;">Nome <span
|
||||
class="sort-icon"></span></th>
|
||||
<th class="sortable" data-sort="email" style="cursor: pointer;">Email <span
|
||||
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
|
||||
class="sort-icon"></span></th>
|
||||
<th class="sortable" data-sort="parking_ratio" style="cursor: pointer;">Punteggio <span
|
||||
class="sort-icon"></span></th>
|
||||
<th>Azioni</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="usersBody"></tbody>
|
||||
@@ -69,7 +82,7 @@
|
||||
<div class="modal" id="userModal" style="display: none;">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3 id="userModalTitle">Edit User</h3>
|
||||
<h3 id="userModalTitle">Modifica Utente</h3>
|
||||
<button class="modal-close" id="closeUserModal">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
@@ -78,54 +91,42 @@
|
||||
|
||||
<!-- LDAP notice -->
|
||||
<div id="ldapNotice" class="form-notice" style="display: none;">
|
||||
<small>This user is managed by LDAP. Some fields cannot be edited.</small>
|
||||
<small>Questo utente è gestito da LDAP. Alcuni campi non possono essere modificati.</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="editName">Name</label>
|
||||
<label for="editName">Nome</label>
|
||||
<input type="text" id="editName" required>
|
||||
<small id="nameHelp" class="text-muted" style="display: none;">Managed by LDAP</small>
|
||||
<small id="nameHelp" class="text-muted" style="display: none;">Gestito da LDAP</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="editEmail">Email</label>
|
||||
<input type="email" id="editEmail" disabled>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="editRole">Role</label>
|
||||
<label for="editRole">Ruolo</label>
|
||||
<select id="editRole" required>
|
||||
<option value="employee">Employee</option>
|
||||
<option value="employee">Dipendente</option>
|
||||
<option value="manager">Manager</option>
|
||||
<option value="admin">Admin</option>
|
||||
</select>
|
||||
<small id="roleHelp" class="text-muted" style="display: none;">Admin role is managed by LDAP group</small>
|
||||
<small id="roleHelp" class="text-muted" style="display: none;">Il ruolo admin è gestito dal
|
||||
gruppo LDAP</small>
|
||||
</div>
|
||||
<div class="form-group" id="managerGroup">
|
||||
<label for="editManager">Manager</label>
|
||||
<select id="editManager">
|
||||
<option value="">No manager</option>
|
||||
<div class="form-group" id="officeGroup">
|
||||
<label for="editOffice">Ufficio</label>
|
||||
<select id="editOffice">
|
||||
<option value="">Nessun ufficio</option>
|
||||
</select>
|
||||
<small class="text-muted">Who manages this user</small>
|
||||
<small class="text-muted">Ufficio di appartenenza</small>
|
||||
</div>
|
||||
|
||||
<!-- Manager-specific fields -->
|
||||
<div id="managerFields" style="display: none;">
|
||||
<hr>
|
||||
<h4>Manager Settings</h4>
|
||||
<div class="form-group">
|
||||
<label for="editQuota">Parking Quota</label>
|
||||
<input type="number" id="editQuota" min="0" value="0">
|
||||
<small class="text-muted">Number of parking spots this manager controls</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="editPrefix">Spot Prefix</label>
|
||||
<input type="text" id="editPrefix" maxlength="2" placeholder="A, B, C...">
|
||||
<small class="text-muted">Letter prefix for parking spots (e.g., A for spots A1, A2...)</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-actions">
|
||||
<button type="button" class="btn btn-secondary" id="cancelUser">Cancel</button>
|
||||
<button type="submit" class="btn btn-dark">Save</button>
|
||||
<button type="button" class="btn btn-secondary" id="cancelUser">Annulla</button>
|
||||
<button type="submit" class="btn btn-dark">Salva</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -137,4 +138,5 @@
|
||||
<script src="/js/nav.js"></script>
|
||||
<script src="/js/admin-users.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</html>
|
||||
@@ -11,13 +11,13 @@
|
||||
<div class="auth-container">
|
||||
<div class="auth-card">
|
||||
<div class="auth-header">
|
||||
<h1>Parking Manager</h1>
|
||||
<p>Manage team presence and parking assignments</p>
|
||||
<h1>Gestione Parcheggi</h1>
|
||||
<p>Gestisci la presenza del team e le assegnazioni dei parcheggi</p>
|
||||
</div>
|
||||
|
||||
<div id="authButtons" style="display: flex; flex-direction: column; gap: 1rem;">
|
||||
<!-- Buttons will be populated by JavaScript based on auth mode -->
|
||||
<div class="loading">Loading...</div>
|
||||
<div class="loading">Caricamento...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -56,30 +56,30 @@
|
||||
if (config.login_url) {
|
||||
// Redirect to Authelia login with return URL
|
||||
const returnUrl = encodeURIComponent(window.location.origin + '/presence');
|
||||
buttons += `<a href="${config.login_url}?rd=${returnUrl}" class="btn btn-dark btn-full">Sign In</a>`;
|
||||
buttons += `<a href="${config.login_url}?rd=${returnUrl}" class="btn btn-dark btn-full">Accedi</a>`;
|
||||
} else {
|
||||
// No login URL configured - just try to access the app (Authelia will intercept)
|
||||
buttons += `<a href="/presence" class="btn btn-dark btn-full">Sign In</a>`;
|
||||
buttons += `<a href="/presence" class="btn btn-dark btn-full">Accedi</a>`;
|
||||
}
|
||||
|
||||
if (config.registration_url) {
|
||||
buttons += `<a href="${config.registration_url}" class="btn btn-secondary btn-full" target="_blank">Create Account</a>`;
|
||||
buttons += `<p class="auth-footer" style="margin-top: 0.5rem; text-align: center; font-size: 0.875rem; color: #666;">Registration requires admin approval</p>`;
|
||||
buttons += `<a href="${config.registration_url}" class="btn btn-secondary btn-full" target="_blank">Crea Account</a>`;
|
||||
buttons += `<p class="auth-footer" style="margin-top: 0.5rem; text-align: center; font-size: 0.875rem; color: #666;">La registrazione richiede l'approvazione dell'amministratore</p>`;
|
||||
}
|
||||
|
||||
buttonsDiv.innerHTML = buttons;
|
||||
} else {
|
||||
// Standalone mode: Local login and registration
|
||||
buttonsDiv.innerHTML = `
|
||||
<a href="/login" class="btn btn-dark btn-full">Sign In</a>
|
||||
<a href="/register" class="btn btn-secondary btn-full">Create Account</a>
|
||||
<a href="/login" class="btn btn-dark btn-full">Accedi</a>
|
||||
<a href="/register" class="btn btn-secondary btn-full">Crea Account</a>
|
||||
`;
|
||||
}
|
||||
} catch (e) {
|
||||
// Fallback to standalone mode
|
||||
buttonsDiv.innerHTML = `
|
||||
<a href="/login" class="btn btn-dark btn-full">Sign In</a>
|
||||
<a href="/register" class="btn btn-secondary btn-full">Create Account</a>
|
||||
<a href="/login" class="btn btn-dark btn-full">Accedi</a>
|
||||
<a href="/register" class="btn btn-secondary btn-full">Crea Account</a>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
@@ -7,12 +8,13 @@
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||
<link rel="stylesheet" href="/css/styles.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="auth-container">
|
||||
<div class="auth-card">
|
||||
<div class="auth-header">
|
||||
<h1>Welcome Back</h1>
|
||||
<p>Sign in to your account</p>
|
||||
<h1>Bentornato</h1>
|
||||
<p>Accedi al tuo account</p>
|
||||
</div>
|
||||
|
||||
<div id="errorMessage"></div>
|
||||
@@ -26,11 +28,11 @@
|
||||
<label for="password">Password</label>
|
||||
<input type="password" id="password" required autocomplete="current-password">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-dark btn-full">Sign In</button>
|
||||
<button type="submit" class="btn btn-dark btn-full">Accedi</button>
|
||||
</form>
|
||||
|
||||
<div class="auth-footer">
|
||||
Don't have an account? <a href="/register">Sign up</a>
|
||||
Non hai un account? <a href="/register">Registrati</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -80,4 +82,5 @@
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</html>
|
||||
155
frontend/pages/parking-settings.html
Normal file
155
frontend/pages/parking-settings.html
Normal file
@@ -0,0 +1,155 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Office Settings - Parking Manager</title>
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||
<link rel="stylesheet" href="/css/styles.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<h1>Gestione Parcheggi</h1>
|
||||
</div>
|
||||
<nav class="sidebar-nav"></nav>
|
||||
<div class="sidebar-footer">
|
||||
<div class="user-menu">
|
||||
<button class="user-button" id="userMenuButton">
|
||||
<div class="user-avatar">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2">
|
||||
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path>
|
||||
<circle cx="12" cy="7" r="4"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="user-info">
|
||||
<div class="user-name" id="userName">Caricamento...</div>
|
||||
<div class="user-role" id="userRole">-</div>
|
||||
</div>
|
||||
</button>
|
||||
<div class="user-dropdown" id="userDropdown" style="display: none;">
|
||||
<a href="/profile" class="dropdown-item">Profilo</a>
|
||||
<a href="/settings" class="dropdown-item">Impostazioni</a>
|
||||
<hr class="dropdown-divider">
|
||||
<button class="dropdown-item" id="logoutButton">Esci</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main class="main-content">
|
||||
<header class="page-header">
|
||||
<h2>Impostazioni Ufficio</h2>
|
||||
</header>
|
||||
|
||||
<div class="content-wrapper">
|
||||
|
||||
<!-- Office Selection Card (Admin Only) -->
|
||||
<div class="card" id="officeSelectionCard" style="margin-bottom: 1.5rem; display: none;">
|
||||
<div style="display: flex; align-items: center; gap: 1rem;">
|
||||
<label for="officeSelect" style="font-weight: 500; min-width: max-content;">Seleziona
|
||||
Ufficio:</label>
|
||||
<select id="officeSelect" class="form-select" style="flex: 1; max-width: 300px;">
|
||||
<option value="">Seleziona Ufficio</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="settingsContent" style="display: none;">
|
||||
|
||||
<!-- Card 1: Batch Scheduling Settings -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Schedulazione Automatica</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form id="scheduleForm">
|
||||
<div class="form-group">
|
||||
<label class="toggle-label">
|
||||
<span>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>
|
||||
</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;">
|
||||
<select id="bookingWindowHour" style="width: 80px;">
|
||||
<!-- Populated by JS -->
|
||||
</select>
|
||||
<span>:</span>
|
||||
<select id="bookingWindowMinute" style="width: 80px;">
|
||||
<option value="0">00</option>
|
||||
<option value="15">15</option>
|
||||
<option value="30">30</option>
|
||||
<option value="45">45</option>
|
||||
</select>
|
||||
</div>
|
||||
<small class="text-muted">Le presenze inserite prima di questo orario saranno messe in
|
||||
attesa.</small>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn btn-dark">Salva Impostazioni</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Card 2: Testing Tools -->
|
||||
<div class="card">
|
||||
<div class="card-header"
|
||||
style="display: flex; justify-content: space-between; align-items: center;">
|
||||
<h3>Strumenti di Test</h3>
|
||||
<span class="badge badge-warning">Testing Only</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="text-muted" style="margin-bottom: 1rem;">Usa questi strumenti per verificare il
|
||||
funzionamento dell'assegnazione automatica.</p>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Range di Date di Test</label>
|
||||
<div style="display: flex; gap: 1rem;">
|
||||
<div>
|
||||
<small>Da:</small>
|
||||
<input type="date" id="testDateStart" class="form-control" style="width: 160px;">
|
||||
</div>
|
||||
<div>
|
||||
<small>A (incluso):</small>
|
||||
<input type="date" id="testDateEnd" class="form-control" style="width: 160px;">
|
||||
</div>
|
||||
</div>
|
||||
<small class="text-muted">Lascia "A" vuoto per eseguire su un singolo giorno.</small>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; gap: 1rem; margin-top: 1rem;">
|
||||
<button id="runAllocationBtn" class="btn btn-primary">
|
||||
Esegui Assegnazione Ora
|
||||
</button>
|
||||
<button id="clearAssignmentsBtn" class="btn btn-danger">
|
||||
Elimina Tutte le Assegnazioni
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div> <!-- End settingsContent -->
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script src="/js/api.js"></script>
|
||||
<script src="/js/utils.js"></script>
|
||||
<script src="/js/nav.js"></script>
|
||||
<script src="/js/parking-settings.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,5 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
@@ -7,31 +8,33 @@
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||
<link rel="stylesheet" href="/css/styles.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<h1>Parking Manager</h1>
|
||||
<h1>Gestione Parcheggi</h1>
|
||||
</div>
|
||||
<nav class="sidebar-nav"></nav>
|
||||
<div class="sidebar-footer">
|
||||
<div class="user-menu">
|
||||
<button class="user-button" id="userMenuButton">
|
||||
<div class="user-avatar">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2">
|
||||
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path>
|
||||
<circle cx="12" cy="7" r="4"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="user-info">
|
||||
<div class="user-name" id="userName">Loading...</div>
|
||||
<div class="user-name" id="userName">Caricamento...</div>
|
||||
<div class="user-role" id="userRole">-</div>
|
||||
</div>
|
||||
</button>
|
||||
<div class="user-dropdown" id="userDropdown" style="display: none;">
|
||||
<a href="/profile" class="dropdown-item">Profile</a>
|
||||
<a href="/settings" class="dropdown-item">Settings</a>
|
||||
<a href="/profile" class="dropdown-item">Profilo</a>
|
||||
<a href="/settings" class="dropdown-item">Impostazioni</a>
|
||||
<hr class="dropdown-divider">
|
||||
<button class="dropdown-item" id="logoutButton">Logout</button>
|
||||
<button class="dropdown-item" id="logoutButton">Esci</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -39,26 +42,36 @@
|
||||
|
||||
<main class="main-content">
|
||||
<header class="page-header">
|
||||
<h2>My Presence</h2>
|
||||
<h2>Dashboard</h2>
|
||||
<div class="header-actions">
|
||||
<button class="btn btn-secondary" id="bulkMarkBtn">Bulk Mark</button>
|
||||
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="content-wrapper">
|
||||
<div class="card presence-card">
|
||||
<div style="margin-bottom: 1.5rem;">
|
||||
<h3>Calendario</h3>
|
||||
</div>
|
||||
<div class="calendar-header">
|
||||
<button class="btn-icon" id="prevMonth">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2">
|
||||
<polyline points="15 18 9 12 15 6"></polyline>
|
||||
</svg>
|
||||
</button>
|
||||
<h3 id="currentMonth">Loading...</h3>
|
||||
<h3 id="currentMonth">Caricamento...</h3>
|
||||
<button class="btn-icon" id="nextMonth">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2">
|
||||
<polyline points="9 18 15 12 9 6"></polyline>
|
||||
</svg>
|
||||
</button>
|
||||
<div style="display: flex; gap: 0.5rem; align-items: center;">
|
||||
<button class="btn btn-dark btn-sm" id="quickEntryBtn" style="font-size: 0.85rem;">
|
||||
Inserimento Veloce
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="calendar-grid" id="calendarGrid"></div>
|
||||
@@ -66,121 +79,211 @@
|
||||
<div class="legend">
|
||||
<div class="legend-item">
|
||||
<div class="legend-color status-present"></div>
|
||||
<span>Present (Office)</span>
|
||||
<span>In sede</span>
|
||||
</div>
|
||||
<div class="legend-item">
|
||||
<div class="legend-color status-remote"></div>
|
||||
<span>Remote</span>
|
||||
<span>Remoto</span>
|
||||
</div>
|
||||
<div class="legend-item">
|
||||
<div class="legend-color status-absent"></div>
|
||||
<span>Absent</span>
|
||||
<span>Assente</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Parking Status Section -->
|
||||
<div class="card" id="parkingStatusCard" style="margin-top: 2rem;">
|
||||
<div style="margin-bottom: 1.5rem;">
|
||||
<h3>Stato Parcheggio</h3>
|
||||
</div>
|
||||
|
||||
<!-- Daily View Controls -->
|
||||
<div id="dailyViewControls">
|
||||
|
||||
<!-- 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);">
|
||||
<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"
|
||||
stroke-width="2">
|
||||
<polyline points="15 18 9 12 15 6"></polyline>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<div style="position: relative; text-align: center; min-width: 200px;">
|
||||
<div id="statusDateDisplay"
|
||||
style="font-weight: 600; font-size: 1rem; text-transform: capitalize;"></div>
|
||||
<input type="date" id="statusDatePicker"
|
||||
style="position: absolute; inset: 0; opacity: 0; cursor: pointer;">
|
||||
</div>
|
||||
|
||||
<button class="btn-icon" id="statusNextDay"
|
||||
style="border: none; width: 32px; height: 32px;">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2">
|
||||
<polyline points="9 18 15 12 9 6"></polyline>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Office Header (No Logo) -->
|
||||
<!-- Office Header (No Logo) -->
|
||||
<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>
|
||||
</div>
|
||||
<span class="badge"
|
||||
style="background: #eff6ff; color: #1d4ed8; border: 1px solid #dbeafe; padding: 0.35rem 0.75rem; font-size: 0.85rem;">
|
||||
Liberi: <span id="spotsCountBadge">0/0</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Spots Grid -->
|
||||
<div id="spotsGrid" style="display: flex; gap: 1rem; flex-wrap: wrap; margin-bottom: 0;">
|
||||
<!-- Spots injected here -->
|
||||
<div style="width: 100%; text-align: center; color: var(--text-secondary); padding: 2rem;">
|
||||
Caricamento posti...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="card parking-map-card" style="margin-top: 2rem;">
|
||||
<h3>Mappa Parcheggio</h3>
|
||||
<img src="/assets/parking-map.png" alt="Mappa Parcheggio"
|
||||
style="width: 100%; height: auto; border-radius: 4px; border: 1px solid var(--border);">
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Day Modal -->
|
||||
<div class="modal" id="dayModal" style="display: none;">
|
||||
<!-- Quick Entry Modal -->
|
||||
<div class="modal" id="quickEntryModal" style="display: none;">
|
||||
<div class="modal-content modal-small">
|
||||
<div class="modal-header">
|
||||
<h3 id="dayModalTitle">Mark Presence</h3>
|
||||
<button class="modal-close" id="closeDayModal">×</button>
|
||||
<h3>Inserimento Veloce</h3>
|
||||
<button class="modal-close" id="closeQuickEntryModal">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="status-buttons">
|
||||
<button class="status-btn" data-status="present">
|
||||
<div class="status-icon status-present"></div>
|
||||
<span>Present</span>
|
||||
</button>
|
||||
<button class="status-btn" data-status="remote">
|
||||
<div class="status-icon status-remote"></div>
|
||||
<span>Remote</span>
|
||||
</button>
|
||||
<button class="status-btn" data-status="absent">
|
||||
<div class="status-icon status-absent"></div>
|
||||
<span>Absent</span>
|
||||
</button>
|
||||
</div>
|
||||
<div id="parkingSection" style="display: none; margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--border);">
|
||||
<div id="parkingInfo" style="margin-bottom: 0.75rem; font-size: 0.9rem;"></div>
|
||||
<div style="display: flex; gap: 0.5rem;">
|
||||
<button class="btn btn-secondary" style="flex: 1;" id="reassignParkingBtn">Reassign</button>
|
||||
<button class="btn btn-secondary" style="flex: 1;" id="releaseParkingBtn">Release</button>
|
||||
<form id="quickEntryForm">
|
||||
<div class="form-group">
|
||||
<label>Range di Date</label>
|
||||
<div style="display: flex; gap: 1rem;">
|
||||
<div style="flex: 1;">
|
||||
<small>Da:</small>
|
||||
<input type="date" id="qeStartDate" class="form-control" required>
|
||||
</div>
|
||||
<div style="flex: 1;">
|
||||
<small>A (incluso):</small>
|
||||
<input type="date" id="qeEndDate" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-secondary btn-full" id="clearDayBtn" style="margin-top: 1rem;">Clear Presence</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Reassign Parking Modal -->
|
||||
<div class="modal" id="reassignModal" style="display: none;">
|
||||
<div class="modal-content modal-small">
|
||||
<div class="modal-header">
|
||||
<h3>Reassign Parking Spot</h3>
|
||||
<button class="modal-close" id="closeReassignModal">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p id="reassignSpotInfo" style="margin-bottom: 1rem; font-size: 0.9rem;"></p>
|
||||
<div class="form-group">
|
||||
<label for="reassignUser">Assign to</label>
|
||||
<select id="reassignUser" required>
|
||||
<option value="">Select user...</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button type="button" class="btn btn-secondary" id="cancelReassign">Cancel</button>
|
||||
<button type="button" class="btn btn-dark" id="confirmReassign">Reassign</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Stato da applicare</label>
|
||||
<div class="status-buttons">
|
||||
<button type="button" class="status-btn qe-status-btn" data-status="present">
|
||||
<div class="status-icon status-present"></div>
|
||||
<span>In sede</span>
|
||||
</button>
|
||||
<button type="button" class="status-btn qe-status-btn" data-status="remote">
|
||||
<div class="status-icon status-remote"></div>
|
||||
<span>Remoto</span>
|
||||
</button>
|
||||
<button type="button" class="status-btn qe-status-btn" data-status="absent">
|
||||
<div class="status-icon status-absent"></div>
|
||||
<span>Assente</span>
|
||||
</button>
|
||||
<button type="button" class="status-btn qe-status-btn" data-status="clear">
|
||||
<div class="status-icon"
|
||||
style="border: 2px solid #ef4444; background: #fee2e2; display: flex; align-items: center; justify-content: center;">
|
||||
<span style="color: #ef4444; font-weight: bold; font-size: 1.2rem;">×</span>
|
||||
</div>
|
||||
<span>Rimuovi</span>
|
||||
</button>
|
||||
</div>
|
||||
<input type="hidden" id="qeStatus" required>
|
||||
</div>
|
||||
|
||||
<!-- Bulk Mark Modal -->
|
||||
<div class="modal" id="bulkMarkModal" style="display: none;">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3>Bulk Mark Presence</h3>
|
||||
<button class="modal-close" id="closeBulkModal">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="bulkMarkForm">
|
||||
<div class="form-group">
|
||||
<label for="startDate">Start Date</label>
|
||||
<input type="date" id="startDate" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="endDate">End Date</label>
|
||||
<input type="date" id="endDate" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="bulkStatus">Status</label>
|
||||
<select id="bulkStatus" required>
|
||||
<option value="present">Present (Office)</option>
|
||||
<option value="remote">Remote</option>
|
||||
<option value="absent">Absent</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group checkbox-group">
|
||||
<label class="checkbox-label">
|
||||
<input type="checkbox" id="weekdaysOnly">
|
||||
<span>Weekdays only (Mon-Fri)</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button type="button" class="btn btn-secondary" id="cancelBulk">Cancel</button>
|
||||
<button type="submit" class="btn btn-dark">Mark Dates</button>
|
||||
<button type="button" class="btn btn-secondary" id="cancelQuickEntry">Annulla</button>
|
||||
<button type="submit" class="btn btn-dark">Applica</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Day Modal -->
|
||||
<div class="modal" id="dayModal" style="display: none;">
|
||||
<div class="modal-content modal-small">
|
||||
<div class="modal-header">
|
||||
<h3 id="dayModalTitle">Segna presenza</h3>
|
||||
<button class="modal-close" id="closeDayModal">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p id="dayModalUser" style="display:none; margin-bottom: 1rem; font-weight: 500;"></p>
|
||||
<div class="status-buttons">
|
||||
<button class="status-btn" data-status="present">
|
||||
<div class="status-icon status-present"></div>
|
||||
<span>In sede</span>
|
||||
</button>
|
||||
<button class="status-btn" data-status="remote">
|
||||
<div class="status-icon status-remote"></div>
|
||||
<span>Remoto</span>
|
||||
</button>
|
||||
<button class="status-btn" data-status="absent">
|
||||
<div class="status-icon status-absent"></div>
|
||||
<span>Assente</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-secondary btn-full" id="clearDayBtn" style="margin-top: 1rem;">Cancella
|
||||
presenza</button>
|
||||
|
||||
<div id="parkingSection"
|
||||
style="display: none; margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--border);">
|
||||
<div id="parkingInfo" style="margin-bottom: 0.75rem; font-size: 0.9rem;"></div>
|
||||
|
||||
<div id="parkingActions" style="display: flex; gap: 0.5rem;">
|
||||
<button class="btn btn-secondary" style="flex: 1;" id="reassignParkingBtn">Cedi posto</button>
|
||||
<button class="btn btn-secondary" style="flex: 1;" id="releaseParkingBtn">Lascia libero</button>
|
||||
</div>
|
||||
|
||||
<div id="reassignForm"
|
||||
style="display: none; flex-direction: column; gap: 0.5rem; margin-top: 0.5rem;">
|
||||
<div class="form-group" style="margin-bottom: 0.5rem;">
|
||||
<label for="reassignUser" style="font-size: 0.9rem;">Assegna a</label>
|
||||
<select id="reassignUser" class="form-control" style="width: 100%;">
|
||||
<option value="">Seleziona utente...</option>
|
||||
</select>
|
||||
</div>
|
||||
<div style="display: flex; gap: 0.5rem;">
|
||||
<button type="button" class="btn btn-secondary" style="flex: 1;"
|
||||
id="cancelReassign">Annulla</button>
|
||||
<button type="button" class="btn btn-dark" style="flex: 1;"
|
||||
id="confirmReassign">Riassegna</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script src="/js/api.js"></script>
|
||||
<script src="/js/utils.js"></script>
|
||||
<script src="/js/nav.js"></script>
|
||||
<script src="/js/modal-logic.js"></script>
|
||||
<script src="/js/presence.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</html>
|
||||
@@ -1,5 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
@@ -7,31 +8,33 @@
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||
<link rel="stylesheet" href="/css/styles.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<h1>Parking Manager</h1>
|
||||
<h1>Gestione Parcheggi</h1>
|
||||
</div>
|
||||
<nav class="sidebar-nav"></nav>
|
||||
<div class="sidebar-footer">
|
||||
<div class="user-menu">
|
||||
<button class="user-button" id="userMenuButton">
|
||||
<div class="user-avatar">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2">
|
||||
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path>
|
||||
<circle cx="12" cy="7" r="4"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="user-info">
|
||||
<div class="user-name" id="userName">Loading...</div>
|
||||
<div class="user-name" id="userName">Caricamento...</div>
|
||||
<div class="user-role" id="userRole">-</div>
|
||||
</div>
|
||||
</button>
|
||||
<div class="user-dropdown" id="userDropdown" style="display: none;">
|
||||
<a href="/profile" class="dropdown-item">Profile</a>
|
||||
<a href="/settings" class="dropdown-item">Settings</a>
|
||||
<a href="/profile" class="dropdown-item">Profilo</a>
|
||||
<a href="/settings" class="dropdown-item">Impostazioni</a>
|
||||
<hr class="dropdown-divider">
|
||||
<button class="dropdown-item" id="logoutButton">Logout</button>
|
||||
<button class="dropdown-item" id="logoutButton">Esci</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -39,43 +42,44 @@
|
||||
|
||||
<main class="main-content">
|
||||
<header class="page-header">
|
||||
<h2>Profile</h2>
|
||||
<h2>Profilo</h2>
|
||||
</header>
|
||||
|
||||
<div class="content-wrapper">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Personal Information</h3>
|
||||
<h3>Informazioni Personali</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<!-- LDAP Notice -->
|
||||
<div id="ldapNotice" class="form-notice" style="display: none; margin-bottom: 1rem;">
|
||||
<small>Your account is managed by LDAP. Some information cannot be changed here.</small>
|
||||
<small>Il tuo account è gestito da LDAP. Alcune informazioni non possono essere modificate
|
||||
qui.</small>
|
||||
</div>
|
||||
|
||||
<form id="profileForm">
|
||||
<div class="form-group">
|
||||
<label for="name">Full Name</label>
|
||||
<label for="name">Nome Completo</label>
|
||||
<input type="text" id="name" required>
|
||||
<small id="nameHelp" class="text-muted" style="display: none;">Managed by LDAP</small>
|
||||
<small id="nameHelp" class="text-muted" style="display: none;">Gestito da LDAP</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="email">Email</label>
|
||||
<input type="email" id="email" disabled>
|
||||
<small class="text-muted">Email cannot be changed</small>
|
||||
<small class="text-muted">L'email non può essere modificata</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="role">Role</label>
|
||||
<label for="role">Ruolo</label>
|
||||
<input type="text" id="role" disabled>
|
||||
<small class="text-muted">Role is assigned by your administrator</small>
|
||||
<small class="text-muted">Il ruolo è assegnato dal tuo amministratore</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="manager">Manager</label>
|
||||
<input type="text" id="manager" disabled>
|
||||
<small class="text-muted">Your manager is assigned by the administrator</small>
|
||||
<small class="text-muted">Il tuo manager è assegnato dall'amministratore</small>
|
||||
</div>
|
||||
<div class="form-actions" id="profileActions">
|
||||
<button type="submit" class="btn btn-dark">Save Changes</button>
|
||||
<button type="submit" class="btn btn-dark">Salva Modifiche</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -84,25 +88,25 @@
|
||||
<!-- Password section - hidden for LDAP users -->
|
||||
<div class="card" id="passwordCard">
|
||||
<div class="card-header">
|
||||
<h3>Change Password</h3>
|
||||
<h3>Cambia Password</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form id="passwordForm">
|
||||
<div class="form-group">
|
||||
<label for="currentPassword">Current Password</label>
|
||||
<label for="currentPassword">Password Attuale</label>
|
||||
<input type="password" id="currentPassword" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="newPassword">New Password</label>
|
||||
<label for="newPassword">Nuova Password</label>
|
||||
<input type="password" id="newPassword" required minlength="8">
|
||||
<small>Minimum 8 characters</small>
|
||||
<small>Minimo 8 caratteri</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="confirmPassword">Confirm New Password</label>
|
||||
<label for="confirmPassword">Conferma Nuova Password</label>
|
||||
<input type="password" id="confirmPassword" required>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn btn-dark">Change Password</button>
|
||||
<button type="submit" class="btn btn-dark">Cambia Password</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -135,7 +139,7 @@
|
||||
document.getElementById('name').value = profile.name || '';
|
||||
document.getElementById('email').value = profile.email;
|
||||
document.getElementById('role').value = profile.role;
|
||||
document.getElementById('manager').value = profile.manager_name || 'None';
|
||||
document.getElementById('manager').value = profile.manager_name || 'Nessuno';
|
||||
|
||||
// LDAP mode adjustments
|
||||
if (isLdapUser) {
|
||||
@@ -154,7 +158,7 @@
|
||||
e.preventDefault();
|
||||
|
||||
if (isLdapUser) {
|
||||
utils.showMessage('Profile is managed by LDAP', 'error');
|
||||
utils.showMessage('Il profilo è gestito da LDAP', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -164,13 +168,13 @@
|
||||
|
||||
const response = await api.put('/api/users/me/profile', data);
|
||||
if (response && response.ok) {
|
||||
utils.showMessage('Profile updated successfully', 'success');
|
||||
utils.showMessage('Profilo aggiornato con successo', 'success');
|
||||
// Update nav display
|
||||
const nameEl = document.getElementById('userName');
|
||||
if (nameEl) nameEl.textContent = data.name;
|
||||
} else {
|
||||
const error = await response.json();
|
||||
utils.showMessage(error.detail || 'Failed to update profile', 'error');
|
||||
utils.showMessage(error.detail || 'Impossibile aggiornare il profilo', 'error');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -182,7 +186,7 @@
|
||||
const confirmPassword = document.getElementById('confirmPassword').value;
|
||||
|
||||
if (newPassword !== confirmPassword) {
|
||||
utils.showMessage('Passwords do not match', 'error');
|
||||
utils.showMessage('Le password non corrispondono', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -193,14 +197,15 @@
|
||||
|
||||
const response = await api.post('/api/users/me/change-password', data);
|
||||
if (response && response.ok) {
|
||||
utils.showMessage('Password changed successfully', 'success');
|
||||
utils.showMessage('Password cambiata con successo', 'success');
|
||||
document.getElementById('passwordForm').reset();
|
||||
} else {
|
||||
const error = await response.json();
|
||||
utils.showMessage(error.detail || 'Failed to change password', 'error');
|
||||
utils.showMessage(error.detail || 'Impossibile cambiare la password', 'error');
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</html>
|
||||
@@ -1,5 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
@@ -7,19 +8,20 @@
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||
<link rel="stylesheet" href="/css/styles.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="auth-container">
|
||||
<div class="auth-card">
|
||||
<div class="auth-header">
|
||||
<h1>Create Account</h1>
|
||||
<p>Sign up for a new account</p>
|
||||
<h1>Crea Account</h1>
|
||||
<p>Registrati per un nuovo account</p>
|
||||
</div>
|
||||
|
||||
<div id="errorMessage"></div>
|
||||
|
||||
<form id="registerForm">
|
||||
<div class="form-group">
|
||||
<label for="name">Full Name</label>
|
||||
<label for="name">Nome Completo</label>
|
||||
<input type="text" id="name" required autocomplete="name">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@@ -29,13 +31,13 @@
|
||||
<div class="form-group">
|
||||
<label for="password">Password</label>
|
||||
<input type="password" id="password" required autocomplete="new-password" minlength="8">
|
||||
<small>Minimum 8 characters</small>
|
||||
<small>Minimo 8 caratteri</small>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-dark btn-full">Create Account</button>
|
||||
<button type="submit" class="btn btn-dark btn-full">Crea Account</button>
|
||||
</form>
|
||||
|
||||
<div class="auth-footer">
|
||||
Already have an account? <a href="/login">Sign in</a>
|
||||
Hai già un account? <a href="/login">Accedi</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -85,4 +87,5 @@
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</html>
|
||||
@@ -1,5 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
@@ -7,31 +8,33 @@
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||
<link rel="stylesheet" href="/css/styles.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<h1>Parking Manager</h1>
|
||||
<h1>Gestione Parcheggi</h1>
|
||||
</div>
|
||||
<nav class="sidebar-nav"></nav>
|
||||
<div class="sidebar-footer">
|
||||
<div class="user-menu">
|
||||
<button class="user-button" id="userMenuButton">
|
||||
<div class="user-avatar">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2">
|
||||
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path>
|
||||
<circle cx="12" cy="7" r="4"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="user-info">
|
||||
<div class="user-name" id="userName">Loading...</div>
|
||||
<div class="user-name" id="userName">Caricamento...</div>
|
||||
<div class="user-role" id="userRole">-</div>
|
||||
</div>
|
||||
</button>
|
||||
<div class="user-dropdown" id="userDropdown" style="display: none;">
|
||||
<a href="/profile" class="dropdown-item">Profile</a>
|
||||
<a href="/settings" class="dropdown-item">Settings</a>
|
||||
<a href="/profile" class="dropdown-item">Profilo</a>
|
||||
<a href="/settings" class="dropdown-item">Impostazioni</a>
|
||||
<hr class="dropdown-divider">
|
||||
<button class="dropdown-item" id="logoutButton">Logout</button>
|
||||
<button class="dropdown-item" id="logoutButton">Esci</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -39,58 +42,41 @@
|
||||
|
||||
<main class="main-content">
|
||||
<header class="page-header">
|
||||
<h2>Settings</h2>
|
||||
<h2>Impostazioni</h2>
|
||||
</header>
|
||||
|
||||
<div class="content-wrapper">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Preferences</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form id="settingsForm">
|
||||
<div class="form-group">
|
||||
<label for="weekStartDay">Week Starts On</label>
|
||||
<select id="weekStartDay">
|
||||
<option value="0">Sunday</option>
|
||||
<option value="1">Monday</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn btn-dark">Save Settings</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Parking Notifications</h3>
|
||||
<h3>Notifiche Parcheggio</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form id="notificationForm">
|
||||
<div class="form-group">
|
||||
<label class="toggle-label">
|
||||
<span>Weekly Summary</span>
|
||||
<span>Riepilogo Settimanale</span>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="notifyWeeklyParking">
|
||||
<span class="toggle-slider"></span>
|
||||
</label>
|
||||
</label>
|
||||
<small class="text-muted">Receive weekly parking assignments summary every Friday at 12:00</small>
|
||||
<small class="text-muted">Ricevi il riepilogo settimanale delle assegnazioni parcheggio ogni
|
||||
Venerdì alle 12:00</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="toggle-label">
|
||||
<span>Daily Reminder</span>
|
||||
<span>Promemoria Giornaliero</span>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="notifyDailyParking">
|
||||
<span class="toggle-slider"></span>
|
||||
</label>
|
||||
</label>
|
||||
<small class="text-muted">Receive daily parking reminder on working days</small>
|
||||
<small class="text-muted">Ricevi promemoria giornaliero nei giorni lavorativi</small>
|
||||
</div>
|
||||
<div class="form-group" id="dailyTimeGroup" style="margin-left: 1rem;">
|
||||
<label>Reminder Time</label>
|
||||
<label>Orario Promemoria</label>
|
||||
<div style="display: flex; gap: 0.5rem; align-items: center;">
|
||||
<select id="notifyDailyHour" style="width: 80px;">
|
||||
<!-- Hours populated by JS -->
|
||||
@@ -106,16 +92,17 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="toggle-label">
|
||||
<span>Assignment Changes</span>
|
||||
<span>Cambiamenti Assegnazione</span>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="notifyParkingChanges">
|
||||
<span class="toggle-slider"></span>
|
||||
</label>
|
||||
</label>
|
||||
<small class="text-muted">Receive immediate notifications when your parking assignment changes</small>
|
||||
<small class="text-muted">Ricevi notifiche immediate quando la tua assegnazione del
|
||||
parcheggio cambia</small>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn btn-dark">Save Notifications</button>
|
||||
<button type="submit" class="btn btn-dark">Salva Notifiche</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -151,7 +138,7 @@
|
||||
}
|
||||
|
||||
function populateForm() {
|
||||
document.getElementById('weekStartDay').value = currentUser.week_start_day || 0;
|
||||
// Notification settings
|
||||
|
||||
// Notification settings
|
||||
document.getElementById('notifyWeeklyParking').checked = currentUser.notify_weekly_parking !== 0;
|
||||
@@ -170,22 +157,7 @@
|
||||
|
||||
function setupEventListeners() {
|
||||
// Settings form
|
||||
document.getElementById('settingsForm').addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const data = {
|
||||
week_start_day: parseInt(document.getElementById('weekStartDay').value)
|
||||
};
|
||||
|
||||
const response = await api.put('/api/users/me/settings', data);
|
||||
if (response && response.ok) {
|
||||
utils.showMessage('Settings saved successfully', 'success');
|
||||
currentUser = await api.getCurrentUser();
|
||||
} else {
|
||||
const error = await response.json();
|
||||
utils.showMessage(error.detail || 'Failed to save settings', 'error');
|
||||
}
|
||||
});
|
||||
|
||||
// Notification form
|
||||
document.getElementById('notificationForm').addEventListener('submit', async (e) => {
|
||||
@@ -201,11 +173,11 @@
|
||||
|
||||
const response = await api.put('/api/users/me/settings', data);
|
||||
if (response && response.ok) {
|
||||
utils.showMessage('Notification settings saved', 'success');
|
||||
utils.showMessage('Impostazioni notifiche salvate', 'success');
|
||||
currentUser = await api.getCurrentUser();
|
||||
} else {
|
||||
const error = await response.json();
|
||||
utils.showMessage(error.detail || 'Failed to save notifications', 'error');
|
||||
utils.showMessage(error.detail || 'Impossibile salvare le notifiche', 'error');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -214,4 +186,5 @@
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</html>
|
||||
@@ -1,5 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
@@ -7,31 +8,33 @@
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||
<link rel="stylesheet" href="/css/styles.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<h1>Parking Manager</h1>
|
||||
<h1>Gestione Parcheggi</h1>
|
||||
</div>
|
||||
<nav class="sidebar-nav"></nav>
|
||||
<div class="sidebar-footer">
|
||||
<div class="user-menu">
|
||||
<button class="user-button" id="userMenuButton">
|
||||
<div class="user-avatar">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2">
|
||||
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path>
|
||||
<circle cx="12" cy="7" r="4"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="user-info">
|
||||
<div class="user-name" id="userName">Loading...</div>
|
||||
<div class="user-name" id="userName">Caricamento...</div>
|
||||
<div class="user-role" id="userRole">-</div>
|
||||
</div>
|
||||
</button>
|
||||
<div class="user-dropdown" id="userDropdown" style="display: none;">
|
||||
<a href="/profile" class="dropdown-item">Profile</a>
|
||||
<a href="/settings" class="dropdown-item">Settings</a>
|
||||
<a href="/profile" class="dropdown-item">Profilo</a>
|
||||
<a href="/settings" class="dropdown-item">Impostazioni</a>
|
||||
<hr class="dropdown-divider">
|
||||
<button class="dropdown-item" id="logoutButton">Logout</button>
|
||||
<button class="dropdown-item" id="logoutButton">Esci</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -39,36 +42,46 @@
|
||||
|
||||
<main class="main-content">
|
||||
<header class="page-header">
|
||||
<h2>Team Calendar</h2>
|
||||
<h2>Calendario del Team</h2>
|
||||
<div class="header-actions">
|
||||
<select id="viewToggle" class="form-select" style="min-width: 100px;">
|
||||
<option value="week">Week</option>
|
||||
<option value="month">Month</option>
|
||||
</select>
|
||||
<select id="managerFilter" class="form-select">
|
||||
<option value="">All Managers</option>
|
||||
</select>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="content-wrapper">
|
||||
<div class="card">
|
||||
<div style="display: flex; gap: 1rem; margin-bottom: 1.5rem;">
|
||||
<select id="viewToggle" class="form-select" style="min-width: 150px;">
|
||||
<option value="week">Settimana</option>
|
||||
<option value="month">Mese</option>
|
||||
</select>
|
||||
<select id="officeFilter" class="form-select" style="min-width: 200px;">
|
||||
<option value="">Tutti gli Uffici</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>
|
||||
</div>
|
||||
|
||||
<div class="calendar-header">
|
||||
<button class="btn-icon" id="prevWeek">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2">
|
||||
<polyline points="15 18 9 12 15 6"></polyline>
|
||||
</svg>
|
||||
</button>
|
||||
<h3 id="currentWeek">Loading...</h3>
|
||||
<h3 id="currentWeek">Caricamento...</h3>
|
||||
<button class="btn-icon" id="nextWeek">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2">
|
||||
<polyline points="9 18 15 12 9 6"></polyline>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="team-calendar-container">
|
||||
<table class="team-calendar-table" id="teamCalendarTable">
|
||||
<table class="team-calendar team-calendar-table" id="teamCalendarTable">
|
||||
<thead>
|
||||
<tr id="calendarHeader"></tr>
|
||||
</thead>
|
||||
@@ -79,71 +92,71 @@
|
||||
<div class="legend">
|
||||
<div class="legend-item">
|
||||
<div class="legend-color status-present"></div>
|
||||
<span>Present</span>
|
||||
<span>In sede</span>
|
||||
</div>
|
||||
<div class="legend-item">
|
||||
<div class="legend-color status-remote"></div>
|
||||
<span>Remote</span>
|
||||
<span>Remoto</span>
|
||||
</div>
|
||||
<div class="legend-item">
|
||||
<div class="legend-color status-absent"></div>
|
||||
<span>Absent</span>
|
||||
<span>Assente</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Day Status Modal -->
|
||||
<!-- Day Status Modal (Shared Structure) -->
|
||||
<div class="modal" id="dayModal" style="display: none;">
|
||||
<div class="modal-content modal-small">
|
||||
<div class="modal-header">
|
||||
<h3 id="dayModalTitle">Mark Presence</h3>
|
||||
<h3 id="dayModalTitle">Segna Presenza</h3>
|
||||
<button class="modal-close" id="closeDayModal">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p id="dayModalUser" style="margin-bottom: 1rem; font-weight: 500;"></p>
|
||||
<p id="dayModalUser" style="display:none; margin-bottom: 1rem; font-weight: 500;"></p>
|
||||
<div class="status-buttons">
|
||||
<button class="status-btn" data-status="present">
|
||||
<div class="status-icon status-present"></div>
|
||||
<span>Present</span>
|
||||
<span>In sede</span>
|
||||
</button>
|
||||
<button class="status-btn" data-status="remote">
|
||||
<div class="status-icon status-remote"></div>
|
||||
<span>Remote</span>
|
||||
<span>Remoto</span>
|
||||
</button>
|
||||
<button class="status-btn" data-status="absent">
|
||||
<div class="status-icon status-absent"></div>
|
||||
<span>Absent</span>
|
||||
<span>Assente</span>
|
||||
</button>
|
||||
</div>
|
||||
<div id="parkingSection" style="display: none; margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--border);">
|
||||
<div id="parkingInfo" style="margin-bottom: 0.75rem; font-size: 0.9rem;"></div>
|
||||
<button class="btn btn-secondary btn-full" id="reassignParkingBtn">Reassign Spot</button>
|
||||
</div>
|
||||
<button class="btn btn-secondary btn-full" id="clearDayBtn" style="margin-top: 1rem;">Clear Presence</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-secondary btn-full" id="clearDayBtn" style="margin-top: 1rem;">Cancella
|
||||
Presenza</button>
|
||||
|
||||
<!-- Reassign Parking Modal -->
|
||||
<div class="modal" id="reassignModal" style="display: none;">
|
||||
<div class="modal-content modal-small">
|
||||
<div class="modal-header">
|
||||
<h3>Reassign Parking Spot</h3>
|
||||
<button class="modal-close" id="closeReassignModal">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p id="reassignSpotInfo" style="margin-bottom: 1rem; font-size: 0.9rem;"></p>
|
||||
<div class="form-group">
|
||||
<label for="reassignUser">Assign to</label>
|
||||
<select id="reassignUser" required>
|
||||
<option value="">Select user...</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button type="button" class="btn btn-secondary" id="cancelReassign">Cancel</button>
|
||||
<button type="button" class="btn btn-dark" id="confirmReassign">Reassign</button>
|
||||
<div id="parkingSection"
|
||||
style="display: none; margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--border);">
|
||||
<div id="parkingInfo" style="margin-bottom: 0.75rem; font-size: 0.9rem;"></div>
|
||||
|
||||
<div id="parkingActions" style="display: flex; gap: 0.5rem;">
|
||||
<button class="btn btn-secondary" style="flex: 1;" id="reassignParkingBtn">Cedi posto</button>
|
||||
<button class="btn btn-secondary" style="flex: 1;" id="releaseParkingBtn">Lascia libero</button>
|
||||
</div>
|
||||
|
||||
<div id="reassignForm"
|
||||
style="display: none; flex-direction: column; gap: 0.5rem; margin-top: 0.5rem;">
|
||||
<div class="form-group" style="margin-bottom: 0.5rem;">
|
||||
<label for="reassignUser" style="font-size: 0.9rem;">Assegna a</label>
|
||||
<select id="reassignUser" class="form-control" style="width: 100%;">
|
||||
<option value="">Seleziona utente...</option>
|
||||
</select>
|
||||
</div>
|
||||
<div style="display: flex; gap: 0.5rem;">
|
||||
<button type="button" class="btn btn-secondary" style="flex: 1;"
|
||||
id="cancelReassign">Annulla</button>
|
||||
<button type="button" class="btn btn-dark" style="flex: 1;"
|
||||
id="confirmReassign">Riassegna</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -152,6 +165,8 @@
|
||||
<script src="/js/api.js"></script>
|
||||
<script src="/js/utils.js"></script>
|
||||
<script src="/js/nav.js"></script>
|
||||
<script src="/js/modal-logic.js"></script>
|
||||
<script src="/js/team-calendar.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</html>
|
||||
@@ -1,37 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Team Rules - Parking Manager</title>
|
||||
<title>Regole Parcheggio - Parking Manager</title>
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||
<link rel="stylesheet" href="/css/styles.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<h1>Parking Manager</h1>
|
||||
<h1>Gestione Parcheggi</h1>
|
||||
</div>
|
||||
<nav class="sidebar-nav"></nav>
|
||||
<div class="sidebar-footer">
|
||||
<div class="user-menu">
|
||||
<button class="user-button" id="userMenuButton">
|
||||
<div class="user-avatar">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2">
|
||||
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path>
|
||||
<circle cx="12" cy="7" r="4"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="user-info">
|
||||
<div class="user-name" id="userName">Loading...</div>
|
||||
<div class="user-name" id="userName">Caricamento...</div>
|
||||
<div class="user-role" id="userRole">-</div>
|
||||
</div>
|
||||
</button>
|
||||
<div class="user-dropdown" id="userDropdown" style="display: none;">
|
||||
<a href="/profile" class="dropdown-item">Profile</a>
|
||||
<a href="/settings" class="dropdown-item">Settings</a>
|
||||
<a href="/profile" class="dropdown-item">Profilo</a>
|
||||
<a href="/settings" class="dropdown-item">Impostazioni</a>
|
||||
<hr class="dropdown-divider">
|
||||
<button class="dropdown-item" id="logoutButton">Logout</button>
|
||||
<button class="dropdown-item" id="logoutButton">Esci</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -39,100 +42,120 @@
|
||||
|
||||
<main class="main-content">
|
||||
<header class="page-header">
|
||||
<h2>Team Rules</h2>
|
||||
<h2>Regole Parcheggio</h2>
|
||||
<div class="header-actions">
|
||||
<select id="managerSelect" class="form-select">
|
||||
<option value="">Select Manager</option>
|
||||
</select>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="content-wrapper" id="rulesContent" style="display: none;">
|
||||
<!-- Weekly Closing Days -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Weekly Closing Days</h3>
|
||||
<div class="content-wrapper">
|
||||
<!-- Office Selection Card -->
|
||||
<div class="card" id="officeSelectionCard" style="margin-bottom: 1.5rem;">
|
||||
<div style="display: flex; align-items: center; gap: 1rem;">
|
||||
<label for="officeSelect" style="font-weight: 500; min-width: max-content;">Seleziona
|
||||
Ufficio:</label>
|
||||
<select id="officeSelect" class="form-select" style="flex: 1; max-width: 300px;">
|
||||
<option value="">Seleziona Ufficio</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="text-muted" style="margin-bottom: 1rem;">Days of the week parking is unavailable</p>
|
||||
<div class="weekday-checkboxes" id="weeklyClosingDays">
|
||||
<label><input type="checkbox" data-weekday="0"> Sunday</label>
|
||||
<label><input type="checkbox" data-weekday="1"> Monday</label>
|
||||
<label><input type="checkbox" data-weekday="2"> Tuesday</label>
|
||||
<label><input type="checkbox" data-weekday="3"> Wednesday</label>
|
||||
<label><input type="checkbox" data-weekday="4"> Thursday</label>
|
||||
<label><input type="checkbox" data-weekday="5"> Friday</label>
|
||||
<label><input type="checkbox" data-weekday="6"> Saturday</label>
|
||||
</div>
|
||||
|
||||
<div id="rulesContent" style="display: none;">
|
||||
<!-- Weekly Closing Days -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Giorni di Chiusura Settimanale</h3>
|
||||
<button class="btn btn-primary btn-sm" id="saveWeeklyClosingDaysBtn">Salva</button>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="text-muted" style="margin-bottom: 1rem;">Giorni della settimana in cui il parcheggio
|
||||
non è
|
||||
disponibile</p>
|
||||
<div class="weekday-checkboxes" id="weeklyClosingDays">
|
||||
<label><input type="checkbox" data-weekday="1"> Lunedì</label>
|
||||
<label><input type="checkbox" data-weekday="2"> Martedì</label>
|
||||
<label><input type="checkbox" data-weekday="3"> Mercoledì</label>
|
||||
<label><input type="checkbox" data-weekday="4"> Giovedì</label>
|
||||
<label><input type="checkbox" data-weekday="5"> Venerdì</label>
|
||||
<label><input type="checkbox" data-weekday="6"> Sabato</label>
|
||||
<label><input type="checkbox" data-weekday="0"> Domenica</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Specific Closing Days -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Specific Closing Days</h3>
|
||||
<button class="btn btn-secondary btn-sm" id="addClosingDayBtn">Add</button>
|
||||
<!-- Specific Closing Days -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Giorni di Chiusura Specifici</h3>
|
||||
<button class="btn btn-secondary btn-sm" id="addClosingDayBtn">Aggiungi</button>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="text-muted">Date specifiche in cui il parcheggio non è disponibile (festività, ecc.)
|
||||
</p>
|
||||
<div id="closingDaysList" class="rules-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="text-muted">Specific dates when parking is unavailable (holidays, etc.)</p>
|
||||
<div id="closingDaysList" class="rules-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Parking Guarantees -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Parking Guarantees</h3>
|
||||
<button class="btn btn-secondary btn-sm" id="addGuaranteeBtn">Add</button>
|
||||
<!-- Parking Guarantees -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Garanzie di Parcheggio</h3>
|
||||
<button class="btn btn-secondary btn-sm" id="addGuaranteeBtn">Aggiungi</button>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="text-muted">Utenti a cui è garantito un posto auto quando sono presenti</p>
|
||||
<div id="guaranteesList" class="rules-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="text-muted">Users guaranteed a parking spot when present</p>
|
||||
<div id="guaranteesList" class="rules-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Parking Exclusions -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Parking Exclusions</h3>
|
||||
<button class="btn btn-secondary btn-sm" id="addExclusionBtn">Add</button>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="text-muted">Users excluded from parking assignment</p>
|
||||
<div id="exclusionsList" class="rules-list"></div>
|
||||
<!-- Parking Exclusions -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Esclusioni Parcheggio</h3>
|
||||
<button class="btn btn-secondary btn-sm" id="addExclusionBtn">Aggiungi</button>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="text-muted">Utenti esclusi dall'assegnazione del parcheggio</p>
|
||||
<div id="exclusionsList" class="rules-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-wrapper" id="noManagerMessage">
|
||||
<div id="noOfficeMessage">
|
||||
<div class="card">
|
||||
<div class="card-body text-center">
|
||||
<p>Select a manager to manage their parking rules</p>
|
||||
<p>Seleziona un ufficio sopra per gestirne le regole di parcheggio</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Add Closing Day Modal -->
|
||||
<div class="modal" id="closingDayModal" style="display: none;">
|
||||
<div class="modal-content modal-small">
|
||||
<div class="modal-header">
|
||||
<h3>Add Closing Day</h3>
|
||||
<h3>Aggiungi Giorno di Chiusura</h3>
|
||||
<button class="modal-close" id="closeClosingDayModal">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="closingDayForm">
|
||||
<div class="form-group">
|
||||
<label for="closingDate">Date</label>
|
||||
<label for="closingDate">Data Inizio</label>
|
||||
<input type="date" id="closingDate" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="closingReason">Reason (optional)</label>
|
||||
<input type="text" id="closingReason" placeholder="e.g., Company holiday">
|
||||
<label for="closingEndDate">Data Fine (opzionale)</label>
|
||||
<input type="date" id="closingEndDate">
|
||||
<small>Lascia vuoto per singolo giorno</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="closingReason">Motivo (opzionale)</label>
|
||||
<input type="text" id="closingReason" placeholder="es. Ferie aziendali">
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button type="button" class="btn btn-secondary" id="cancelClosingDay">Cancel</button>
|
||||
<button type="submit" class="btn btn-dark">Add</button>
|
||||
<button type="button" class="btn btn-secondary" id="cancelClosingDay">Annulla</button>
|
||||
<button type="submit" class="btn btn-dark">Aggiungi</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -143,30 +166,33 @@
|
||||
<div class="modal" id="guaranteeModal" style="display: none;">
|
||||
<div class="modal-content modal-small">
|
||||
<div class="modal-header">
|
||||
<h3>Add Parking Guarantee</h3>
|
||||
<h3>Aggiungi Garanzia Parcheggio</h3>
|
||||
<button class="modal-close" id="closeGuaranteeModal">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="guaranteeForm">
|
||||
<div class="form-group">
|
||||
<label for="guaranteeUser">User</label>
|
||||
<label for="guaranteeUser">Utente</label>
|
||||
<select id="guaranteeUser" required>
|
||||
<option value="">Select user...</option>
|
||||
<option value="">Seleziona utente...</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="guaranteeStartDate">Start Date (optional)</label>
|
||||
<label for="guaranteeStartDate">Data Inizio (opzionale)</label>
|
||||
<input type="date" id="guaranteeStartDate">
|
||||
<small>Leave empty for no start limit</small>
|
||||
<small>Lascia vuoto per nessun limite inziale</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="guaranteeEndDate">End Date (optional)</label>
|
||||
<input type="date" id="guaranteeEndDate">
|
||||
<small>Leave empty for no end limit</small>
|
||||
<small>Lascia vuoto per nessun limite finale</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="guaranteeNotes">Note (opzionale)</label>
|
||||
<textarea id="guaranteeNotes" class="form-control" rows="2"></textarea>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button type="button" class="btn btn-secondary" id="cancelGuarantee">Cancel</button>
|
||||
<button type="submit" class="btn btn-dark">Add</button>
|
||||
<button type="button" class="btn btn-secondary" id="cancelGuarantee">Annulla</button>
|
||||
<button type="submit" class="btn btn-dark">Aggiungi</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -177,30 +203,33 @@
|
||||
<div class="modal" id="exclusionModal" style="display: none;">
|
||||
<div class="modal-content modal-small">
|
||||
<div class="modal-header">
|
||||
<h3>Add Parking Exclusion</h3>
|
||||
<h3>Aggiungi Esclusione Parcheggio</h3>
|
||||
<button class="modal-close" id="closeExclusionModal">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="exclusionForm">
|
||||
<div class="form-group">
|
||||
<label for="exclusionUser">User</label>
|
||||
<label for="exclusionUser">Utente</label>
|
||||
<select id="exclusionUser" required>
|
||||
<option value="">Select user...</option>
|
||||
<option value="">Seleziona utente...</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="exclusionStartDate">Start Date (optional)</label>
|
||||
<label for="exclusionStartDate">Data Inizio (opzionale)</label>
|
||||
<input type="date" id="exclusionStartDate">
|
||||
<small>Leave empty for no start limit</small>
|
||||
<small>Lascia vuoto per nessun limite iniziale</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="exclusionEndDate">End Date (optional)</label>
|
||||
<input type="date" id="exclusionEndDate">
|
||||
<small>Leave empty for no end limit</small>
|
||||
<small>Lascia vuoto per nessun limite finale</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="exclusionNotes">Note (opzionale)</label>
|
||||
<textarea id="exclusionNotes" class="form-control" rows="2"></textarea>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button type="button" class="btn btn-secondary" id="cancelExclusion">Cancel</button>
|
||||
<button type="submit" class="btn btn-dark">Add</button>
|
||||
<button type="button" class="btn btn-secondary" id="cancelExclusion">Annulla</button>
|
||||
<button type="submit" class="btn btn-dark">Aggiungi</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -212,4 +241,5 @@
|
||||
<script src="/js/nav.js"></script>
|
||||
<script src="/js/team-rules.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user