sistema de usuarios completo
This commit is contained in:
@@ -41,6 +41,10 @@
|
||||
<button id="exportCsv">Exportar CSV</button>
|
||||
<button id="addUser">Añadir usuario</button>
|
||||
</div>
|
||||
<h3>Usuarios</h3>
|
||||
<div id="users"></div>
|
||||
<hr />
|
||||
<h3>Eventos</h3>
|
||||
<div id="list" class="list"></div>
|
||||
<div id="modal" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,0.4); align-items:center; justify-content:center;">
|
||||
<div style="background:#fff; color:#222; padding:16px; border-radius:8px; min-width:300px; max-width:90%;">
|
||||
@@ -60,6 +64,7 @@
|
||||
|
||||
<script>
|
||||
const list = document.getElementById('list');
|
||||
const usersDiv = document.getElementById('users');
|
||||
const statusEl = document.getElementById('status');
|
||||
const countEl = document.getElementById('count');
|
||||
const btnRefresh = document.getElementById('refresh');
|
||||
@@ -110,6 +115,63 @@ async function loadHistory() {
|
||||
history.forEach(renderItem);
|
||||
}
|
||||
|
||||
async function loadUsers() {
|
||||
const r = await fetch('/api/users');
|
||||
const data = await r.json();
|
||||
const users = data.items || [];
|
||||
usersDiv.innerHTML = '';
|
||||
const table = document.createElement('table');
|
||||
table.style.width = '100%';
|
||||
table.cellPadding = 6;
|
||||
table.innerHTML = `<tr><th>Usuario</th><th>VLAN</th><th>Estado</th><th>Acciones</th></tr>`;
|
||||
users.forEach(u => {
|
||||
const tr = document.createElement('tr');
|
||||
tr.innerHTML = `
|
||||
<td>${u.username}</td>
|
||||
<td>${u.vlan}</td>
|
||||
<td>${u.disabled ? 'Desactivado' : 'Activo'}</td>
|
||||
<td>
|
||||
<button data-edit="${u.username}">Editar</button>
|
||||
<button data-toggle="${u.username}">${u.disabled ? 'Activar' : 'Desactivar'}</button>
|
||||
<button data-del="${u.username}">Eliminar</button>
|
||||
</td>`;
|
||||
table.appendChild(tr);
|
||||
});
|
||||
usersDiv.appendChild(table);
|
||||
usersDiv.querySelectorAll('button[data-edit]').forEach(btn => btn.addEventListener('click', () => editUser(btn.getAttribute('data-edit'))));
|
||||
usersDiv.querySelectorAll('button[data-toggle]').forEach(btn => btn.addEventListener('click', () => toggleUser(btn.getAttribute('data-toggle'))));
|
||||
usersDiv.querySelectorAll('button[data-del]').forEach(btn => btn.addEventListener('click', () => deleteUser(btn.getAttribute('data-del'))));
|
||||
}
|
||||
|
||||
async function editUser(username) {
|
||||
const r = await fetch('/api/users');
|
||||
const data = await r.json();
|
||||
const u = (data.items || []).find(x => x.username === username);
|
||||
if (!u) return alert('Usuario no encontrado');
|
||||
modal.style.display = 'flex';
|
||||
u_username.value = u.username;
|
||||
u_password.value = u.password || '';
|
||||
u_vlan.value = u.vlan || '2';
|
||||
}
|
||||
|
||||
async function toggleUser(username) {
|
||||
const r = await fetch('/api/users');
|
||||
const data = await r.json();
|
||||
const u = (data.items || []).find(x => x.username === username);
|
||||
if (!u) return alert('Usuario no encontrado');
|
||||
await fetch(`/api/users/${encodeURIComponent(username)}`, {
|
||||
method: 'PATCH', headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ disabled: !u.disabled })
|
||||
});
|
||||
await loadUsers();
|
||||
}
|
||||
|
||||
async function deleteUser(username) {
|
||||
if (!confirm(`¿Eliminar usuario ${username}?`)) return;
|
||||
await fetch(`/api/users/${encodeURIComponent(username)}`, { method: 'DELETE' });
|
||||
await loadUsers();
|
||||
}
|
||||
|
||||
btnRefresh.addEventListener('click', loadHistory);
|
||||
|
||||
btnSelfTest.addEventListener('click', async () => {
|
||||
@@ -196,6 +258,7 @@ saveUser.addEventListener('click', async () => {
|
||||
if (!data.ok) throw new Error(data.error || 'Error desconocido');
|
||||
modal.style.display = 'none';
|
||||
alert('Usuario guardado');
|
||||
await loadUsers();
|
||||
} catch (e) {
|
||||
alert('Error al guardar: ' + e.message);
|
||||
}
|
||||
@@ -218,7 +281,7 @@ function connectSSE() {
|
||||
es.addEventListener('clear', () => { loadHistory(); });
|
||||
}
|
||||
|
||||
loadHistory().then(connectSSE);
|
||||
Promise.all([loadUsers(), loadHistory()]).then(connectSSE);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user