+ | ${u.id} |
+ ${escapeHtml(u.username)} |
+ ${ROLE_LABELS[u.role] || u.role} |
+ |
+
+ `).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();
+})();
diff --git a/frontend/admin/index.html b/frontend/admin/index.html
new file mode 100644
index 0000000..8ceae50
--- /dev/null
+++ b/frontend/admin/index.html
@@ -0,0 +1,119 @@
+
+
+
+
+