//API const API_BASE_URL = "http://localhost:3001/api"; //Login async function loginUser(username, password) { try { const response = await fetch(`${API_BASE_URL}/auth/login`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ username, password }), }); const data = await response.json(); if (response.ok) { return { success: true, ...data }; } else { return { success: false, error: data.error || (data.errors && data.errors[0]?.msg) || "Ошибка авторизации", }; } } catch (err) { return { success: false, error: "Нет соединения с сервером" }; } } document.getElementById("loginForm").addEventListener("submit", async (e) => { e.preventDefault(); const username = document.getElementById("username").value; const password = document.getElementById("password").value; // Call backend login const result = await loginUser(username, password); if (result.success) { // Save user/token in JS (or localStorage) currentUser = result.user; localStorage.setItem("token", result.token); document.getElementById("loginScreen").classList.add("hidden"); if (result.user.role === "admin") { showAdminInterface(); } else { showUserInterface(); } showNotification("Успешная авторизация!"); } else { const errorDiv = document.getElementById("loginError"); errorDiv.textContent = result.error; errorDiv.classList.remove("hidden"); } }); document.addEventListener("DOMContentLoaded", async () => { const token = localStorage.getItem("token"); if (token) { // Try to get user info from backend try { const response = await fetch(`${API_BASE_URL}/auth/me`, { headers: { Authorization: `Bearer ${token}`, }, }); if (response.ok) { const data = await response.json(); currentUser = data.user; document.getElementById("loginScreen").classList.add("hidden"); if (currentUser.role === "admin") { showAdminInterface(); } else { showUserInterface(); } } else { // Token invalid/expired localStorage.removeItem("token"); document.getElementById("loginScreen").classList.remove("hidden"); } } catch (err) { showNotification("Нет соединения с сервером", "error"); } } else { // No token, show login screen document.getElementById("loginScreen").classList.remove("hidden"); } }); function logout() { currentUser = null; localStorage.removeItem("token"); // Show login screen, hide other interfaces document.getElementById("loginScreen").classList.remove("hidden"); document.getElementById("userInterface").classList.add("hidden"); document.getElementById("adminInterface").classList.add("hidden"); document.getElementById("loginForm").reset(); document.getElementById("loginError").classList.add("hidden"); showNotification("Вы вышли из системы", "info"); } document.getElementById("logoutBtn").addEventListener("click", logout); document.getElementById("adminLogoutBtn").addEventListener("click", logout); //Users //GET all users (admin only) async function getAllUsers() { const token = localStorage.getItem("token"); try { const response = await fetch(`${API_BASE_URL}/users`, { method: "GET", headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", }, }); const data = await response.json(); if (response.ok) { return { success: true, users: data.users }; } else { return { success: false, error: data.error || data.message || "Ошибка получения пользователей", }; } } catch (err) { return { success: false, error: "Нет соединения с сервером" }; } } let usersList = []; async function loadUsers() { const tbody = document.getElementById("usersTableBody"); tbody.innerHTML = ""; const result = await getAllUsers(); console.log("getAllUsers result:", result); if (!result.success) { showNotification(result.error, "error"); return; } const users = result.users; usersList = users; users.forEach((user) => { const userStores = user.stores .map((storeId) => { const store = database.stores.find((s) => s.id === storeId); return store ? store.name : "Нет доступа"; }) .join(", ") || "Нет доступа"; const row = document.createElement("tr"); row.className = "hover:bg-gray-50"; row.innerHTML = ` ${user.id} ${user.username} ${user.role === "admin" ? "Администратор" : "Сотрудник"} ${userStores} `; tbody.appendChild(row); }); if (users.length === 0) { showNotification("Нет пользователей для отображения", "info"); } } //add user async function createUser(userData) { const token = localStorage.getItem("token"); try { const response = await fetch(`${API_BASE_URL}/users`, { method: "POST", headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", }, body: JSON.stringify(userData), }); const data = await response.json(); if (response.ok) { return { success: true, ...data }; } else { return { success: false, error: data.error || (data.errors && data.errors[0]?.msg) || "Ошибка создания пользователя", }; } } catch { return { success: false, error: "Нет соединения с сервером" }; } } //edit user async function updateUser(userId, userData) { const token = localStorage.getItem("token"); try { const response = await fetch(`${API_BASE_URL}/users/${userId}`, { method: "PUT", headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", }, body: JSON.stringify(userData), }); const data = await response.json(); if (response.ok) { return { success: true }; } else { return { success: false, error: data.error || (data.errors && data.errors[0]?.msg) || "Ошибка обновления пользователя", }; } } catch { return { success: false, error: "Нет соединения с сервером" }; } } // 1. Create modal on-demand if missing function ensureConfirmModal() { if (document.getElementById("confirmModal")) return; const modal = document.createElement("div"); modal.id = "confirmModal"; modal.className = "hidden fixed inset-0 z-50 bg-black bg-opacity-30 flex items-center justify-center"; modal.innerHTML = `
`; document.body.appendChild(modal); } // 2. Show confirm modal function showConfirmModal(message, onConfirm) { ensureConfirmModal(); const modal = document.getElementById("confirmModal"); const text = document.getElementById("confirmModalText"); const okBtn = document.getElementById("confirmModalOk"); const cancelBtn = document.getElementById("confirmModalCancel"); text.textContent = message; modal.classList.remove("hidden"); function cleanup() { modal.classList.add("hidden"); okBtn.removeEventListener("click", okHandler); cancelBtn.removeEventListener("click", cancelHandler); } function okHandler() { cleanup(); onConfirm(); } function cancelHandler() { cleanup(); } okBtn.addEventListener("click", okHandler); cancelBtn.addEventListener("click", cancelHandler); } // 3. API call to delete user async function apiDeleteUser(userId) { const token = localStorage.getItem("token"); try { const response = await fetch(`${API_BASE_URL}/users/${userId}`, { method: "DELETE", headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", }, }); const data = await response.json(); if (response.ok) { showNotification("Пользователь удален!"); loadUsers(); updateDashboard(); } else { showNotification(data.error || "Ошибка удаления пользователя", "error"); } } catch { showNotification("Нет соединения с сервером", "error"); } } // 4. UI trigger: delete user with modal function deleteUser(userId) { showConfirmModal("Вы уверены, что хотите удалить этого пользователя?", () => apiDeleteUser(userId) ); }