Initial V1 Backup
This commit is contained in:
281
templates/manage_users.html
Normal file
281
templates/manage_users.html
Normal file
@@ -0,0 +1,281 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Manage Users - ScanLook{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="dashboard-container">
|
||||
<div class="dashboard-header">
|
||||
<div class="header-left">
|
||||
<h1 class="page-title">Manage Users</h1>
|
||||
<label class="filter-toggle">
|
||||
<input type="checkbox" id="showInactive" onchange="toggleInactiveUsers()">
|
||||
<span class="filter-label">Show Inactive Users</span>
|
||||
</label>
|
||||
</div>
|
||||
<button class="btn btn-primary" onclick="openAddUser()">
|
||||
<span class="btn-icon">+</span> Add User
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{% if users %}
|
||||
<div class="users-table-container">
|
||||
<table class="users-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Username</th>
|
||||
<th>Full Name</th>
|
||||
<th>Email</th>
|
||||
<th>Role</th>
|
||||
<th>Location</th>
|
||||
<th>Status</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for user in users %}
|
||||
<tr class="{{ 'inactive-user' if not user.is_active else '' }}">
|
||||
<td><strong>{{ user.username }}</strong></td>
|
||||
<td>{{ user.full_name }}</td>
|
||||
<td>{{ user.email or '-' }}</td>
|
||||
<td><span class="role-pill role-{{ user.role }}">{{ user.role }}</span></td>
|
||||
<td>{{ user.branch }}</td>
|
||||
<td>
|
||||
{% if user.is_active %}
|
||||
<span class="status-badge status-success">Active</span>
|
||||
{% else %}
|
||||
<span class="status-badge status-neutral">Inactive</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
<div class="action-buttons">
|
||||
<button class="btn-action btn-edit" onclick="openEditUser({{ user.user_id }})" title="Edit">✏️</button>
|
||||
{% if user.user_id != session.user_id %}
|
||||
<button class="btn-action btn-delete" onclick="deleteUser({{ user.user_id }}, '{{ user.username }}')" title="Delete">🗑️</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="empty-state">
|
||||
<div class="empty-icon">👥</div>
|
||||
<h2 class="empty-title">No Users Found</h2>
|
||||
<p class="empty-text">Add your first user to get started</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Add/Edit User Modal -->
|
||||
<div id="userModal" class="modal">
|
||||
<div class="modal-content modal-large">
|
||||
<div class="modal-header-bar">
|
||||
<h3 class="modal-title" id="modalTitle">Add User</h3>
|
||||
<button type="button" class="btn-close-modal" onclick="closeUserModal()">✕</button>
|
||||
</div>
|
||||
|
||||
<form id="userForm" class="user-form">
|
||||
<input type="hidden" id="userId" value="">
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label class="form-label">Username *</label>
|
||||
<input type="text" id="username" class="form-input" required autocomplete="off">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Password <span id="passwordOptional" style="display:none;">(leave blank to keep current)</span></label>
|
||||
<input type="password" id="password" class="form-input" autocomplete="new-password">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label class="form-label">First Name *</label>
|
||||
<input type="text" id="firstName" class="form-input" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Last Name *</label>
|
||||
<input type="text" id="lastName" class="form-input" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label">Email</label>
|
||||
<input type="email" id="email" class="form-input">
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label class="form-label">Role *</label>
|
||||
<select id="role" class="form-select" required>
|
||||
{% if session.role == 'owner' %}
|
||||
<option value="owner">Owner</option>
|
||||
<option value="admin">Admin</option>
|
||||
{% endif %}
|
||||
<option value="staff">Staff</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Location</label>
|
||||
<input type="text" id="branch" class="form-input" value="Main">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" id="activeToggleGroup" style="display: none;">
|
||||
<label class="form-label">
|
||||
<input type="checkbox" id="isActive" checked> Active
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="modal-actions">
|
||||
<button type="button" class="btn btn-secondary" onclick="closeUserModal()">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary">Save User</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let editingUserId = null;
|
||||
|
||||
// Hide inactive users by default on page load
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
toggleInactiveUsers();
|
||||
});
|
||||
|
||||
function toggleInactiveUsers() {
|
||||
const showInactive = document.getElementById('showInactive').checked;
|
||||
const inactiveRows = document.querySelectorAll('tr.inactive-user');
|
||||
|
||||
inactiveRows.forEach(row => {
|
||||
row.style.display = showInactive ? '' : 'none';
|
||||
});
|
||||
}
|
||||
|
||||
function openAddUser() {
|
||||
editingUserId = null;
|
||||
document.getElementById('modalTitle').textContent = 'Add User';
|
||||
document.getElementById('userForm').reset();
|
||||
document.getElementById('userId').value = '';
|
||||
document.getElementById('passwordOptional').style.display = 'none';
|
||||
document.getElementById('password').required = true;
|
||||
document.getElementById('activeToggleGroup').style.display = 'none';
|
||||
document.getElementById('userModal').style.display = 'flex';
|
||||
}
|
||||
|
||||
function openEditUser(userId) {
|
||||
editingUserId = userId;
|
||||
document.getElementById('modalTitle').textContent = 'Edit User';
|
||||
document.getElementById('passwordOptional').style.display = 'inline';
|
||||
document.getElementById('password').required = false;
|
||||
document.getElementById('activeToggleGroup').style.display = 'block';
|
||||
|
||||
// Fetch user data
|
||||
fetch('/settings/users/' + userId)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
const user = data.user;
|
||||
document.getElementById('userId').value = user.user_id;
|
||||
document.getElementById('username').value = user.username;
|
||||
document.getElementById('firstName').value = user.first_name;
|
||||
document.getElementById('lastName').value = user.last_name;
|
||||
document.getElementById('email').value = user.email || '';
|
||||
document.getElementById('role').value = user.role;
|
||||
document.getElementById('branch').value = user.branch;
|
||||
document.getElementById('isActive').checked = user.is_active == 1;
|
||||
|
||||
// If editing yourself, disable role change
|
||||
const isEditingSelf = user.user_id === {{ session.user_id }};
|
||||
document.getElementById('role').disabled = isEditingSelf;
|
||||
|
||||
document.getElementById('userModal').style.display = 'flex';
|
||||
} else {
|
||||
alert(data.message);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
alert('Error loading user data');
|
||||
console.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
function closeUserModal() {
|
||||
document.getElementById('userModal').style.display = 'none';
|
||||
document.getElementById('userForm').reset();
|
||||
}
|
||||
|
||||
document.getElementById('userForm').addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const userId = document.getElementById('userId').value;
|
||||
const userData = {
|
||||
username: document.getElementById('username').value,
|
||||
password: document.getElementById('password').value,
|
||||
first_name: document.getElementById('firstName').value,
|
||||
last_name: document.getElementById('lastName').value,
|
||||
email: document.getElementById('email').value,
|
||||
role: document.getElementById('role').value,
|
||||
branch: document.getElementById('branch').value,
|
||||
is_active: document.getElementById('isActive').checked ? 1 : 0
|
||||
};
|
||||
|
||||
const url = userId ? `/settings/users/${userId}/update` : '/settings/users/add';
|
||||
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(userData)
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
closeUserModal();
|
||||
location.reload();
|
||||
} else {
|
||||
alert(data.message);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
alert('Error saving user');
|
||||
console.error(error);
|
||||
});
|
||||
});
|
||||
|
||||
function deleteUser(userId, username) {
|
||||
if (!confirm(`Delete user "${username}"? This will deactivate their account.`)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fetch(`/settings/users/${userId}/delete`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
location.reload();
|
||||
} else {
|
||||
alert(data.message);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
alert('Error deleting user');
|
||||
console.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
// Close modal on escape
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Escape') {
|
||||
closeUserModal();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user