147 lines
4.3 KiB
JavaScript
147 lines
4.3 KiB
JavaScript
(() => {
|
|
'use strict';
|
|
|
|
const token = localStorage.getItem('token');
|
|
const role = localStorage.getItem('role');
|
|
|
|
if (!token || role !== 'ADMIN') {
|
|
window.location.href = '/';
|
|
return;
|
|
}
|
|
|
|
const tbody = document.getElementById('users-tbody');
|
|
const createForm = document.getElementById('create-form');
|
|
const createAlert = document.getElementById('create-alert');
|
|
const btnLogout = document.getElementById('btn-logout');
|
|
|
|
const ROLE_LABELS = {
|
|
ADMIN: 'Администратор',
|
|
TEACHER: 'Преподаватель',
|
|
STUDENT: 'Студент',
|
|
};
|
|
|
|
const ROLE_BADGE = {
|
|
ADMIN: 'badge-admin',
|
|
TEACHER: 'badge-teacher',
|
|
STUDENT: 'badge-student',
|
|
};
|
|
|
|
// ---- Load Users ----
|
|
async function loadUsers() {
|
|
try {
|
|
const res = await fetch('/api/users', {
|
|
headers: { 'Authorization': 'Bearer ' + token },
|
|
});
|
|
const users = await res.json();
|
|
renderUsers(users);
|
|
} catch (e) {
|
|
tbody.innerHTML = '<tr><td colspan="4" class="loading-row">Ошибка загрузки</td></tr>';
|
|
}
|
|
}
|
|
|
|
function renderUsers(users) {
|
|
if (!users.length) {
|
|
tbody.innerHTML = '<tr><td colspan="4" class="loading-row">Нет пользователей</td></tr>';
|
|
return;
|
|
}
|
|
|
|
tbody.innerHTML = users.map(u => `
|
|
<tr>
|
|
<td>${u.id}</td>
|
|
<td>${escapeHtml(u.username)}</td>
|
|
<td><span class="badge ${ROLE_BADGE[u.role] || ''}">${ROLE_LABELS[u.role] || u.role}</span></td>
|
|
<td><button class="btn-delete" data-id="${u.id}">Удалить</button></td>
|
|
</tr>
|
|
`).join('');
|
|
}
|
|
|
|
function escapeHtml(str) {
|
|
const div = document.createElement('div');
|
|
div.textContent = str;
|
|
return div.innerHTML;
|
|
}
|
|
|
|
// ---- Create User ----
|
|
createForm.addEventListener('submit', async (e) => {
|
|
e.preventDefault();
|
|
hideAlert();
|
|
|
|
const username = document.getElementById('new-username').value.trim();
|
|
const password = document.getElementById('new-password').value;
|
|
const role = document.getElementById('new-role').value;
|
|
|
|
if (!username || !password) {
|
|
showAlert('Заполните все поля', 'error');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const res = await fetch('/api/users', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Authorization': 'Bearer ' + token,
|
|
},
|
|
body: JSON.stringify({ username, password, role }),
|
|
});
|
|
|
|
const data = await res.json();
|
|
|
|
if (res.ok) {
|
|
showAlert(`Пользователь "${data.username}" создан`, 'success');
|
|
createForm.reset();
|
|
loadUsers();
|
|
} else {
|
|
showAlert(data.message || 'Ошибка создания', 'error');
|
|
}
|
|
} catch (e) {
|
|
showAlert('Ошибка соединения', 'error');
|
|
}
|
|
});
|
|
|
|
// ---- Delete User ----
|
|
tbody.addEventListener('click', async (e) => {
|
|
const btn = e.target.closest('.btn-delete');
|
|
if (!btn) return;
|
|
|
|
const id = btn.dataset.id;
|
|
if (!confirm('Удалить пользователя?')) return;
|
|
|
|
try {
|
|
const res = await fetch('/api/users/' + id, {
|
|
method: 'DELETE',
|
|
headers: { 'Authorization': 'Bearer ' + token },
|
|
});
|
|
|
|
if (res.ok) {
|
|
loadUsers();
|
|
} else {
|
|
alert('Ошибка удаления');
|
|
}
|
|
} catch (e) {
|
|
alert('Ошибка соединения');
|
|
}
|
|
});
|
|
|
|
// ---- Logout ----
|
|
btnLogout.addEventListener('click', () => {
|
|
localStorage.removeItem('token');
|
|
localStorage.removeItem('role');
|
|
window.location.href = '/';
|
|
});
|
|
|
|
// ---- Helpers ----
|
|
function showAlert(msg, type) {
|
|
createAlert.className = 'form-alert ' + type;
|
|
createAlert.textContent = msg;
|
|
}
|
|
|
|
function hideAlert() {
|
|
createAlert.className = 'form-alert';
|
|
createAlert.textContent = '';
|
|
}
|
|
|
|
// Init
|
|
loadUsers();
|
|
})();
|