// admin-script.js (обновленный) let currentUser = null; let users = []; let filteredUsers = []; document.addEventListener('DOMContentLoaded', function() { checkAuth(); setupEventListeners(); }); async function checkAuth() { try { const response = await fetch('/api/user'); if (response.ok) { const data = await response.json(); currentUser = data.user; if (currentUser.role !== 'admin') { window.location.href = '/'; return; } showAdminInterface(); } else { showLoginInterface(); } } catch (error) { showLoginInterface(); } } function showLoginInterface() { document.getElementById('login-modal').style.display = 'block'; document.querySelector('.admin-container').style.display = 'none'; } function showAdminInterface() { document.getElementById('login-modal').style.display = 'none'; document.querySelector('.admin-container').style.display = 'block'; let userInfo = `Администратор: ${currentUser.name}`; if (currentUser.auth_type === 'ldap') { userInfo += ` (LDAP)`; } document.getElementById('current-user').textContent = userInfo; loadUsers(); // Если дашборд активен, рендерим его if (document.getElementById('admin-dashboard').classList.contains('active')) { if (typeof renderDashboard === 'function') { renderDashboard(); } } // Если статистика активна, рендерим ее if (document.getElementById('admin-stats-section').classList.contains('active')) { if (typeof renderStatsSection === 'function') { renderStatsSection(); } } } function setupEventListeners() { const loginForm = document.getElementById('login-form'); const editUserForm = document.getElementById('edit-user-form'); const createUserForm = document.getElementById('create-user-form'); if (loginForm) { loginForm.addEventListener('submit', login); } if (editUserForm) { editUserForm.addEventListener('submit', updateUser); } if (createUserForm) { createUserForm.addEventListener('submit', createUser); } } async function login(event) { event.preventDefault(); const login = document.getElementById('login').value; const password = document.getElementById('password').value; try { const response = await fetch('/api/login', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ login, password }) }); if (response.ok) { const data = await response.json(); currentUser = data.user; if (currentUser.role !== 'admin') { window.location.href = '/'; return; } showAdminInterface(); } else { const error = await response.json(); alert(error.error || 'Ошибка входа'); } } catch (error) { console.error('Ошибка:', error); alert('Ошибка подключения к серверу'); } } async function logout() { try { await fetch('/api/logout', { method: 'POST' }); currentUser = null; showLoginInterface(); } catch (error) { console.error('Ошибка выхода:', error); } } function showAdminSection(sectionName) { console.log('showAdminSection called with:', sectionName); // Убираем активный класс у всех вкладок document.querySelectorAll('.admin-tab').forEach(tab => { tab.classList.remove('active'); }); // Убираем активный класс у всех секций document.querySelectorAll('.admin-section').forEach(section => { section.classList.remove('active'); }); // Находим и активируем соответствующую вкладку const tabs = document.querySelectorAll('.admin-tab'); let tabFound = false; tabs.forEach(tab => { const onclick = tab.getAttribute('onclick'); if (onclick && onclick.includes(`showAdminSection('${sectionName}')`)) { tab.classList.add('active'); tabFound = true; } }); // Если не нашли по onclick, ищем по тексту if (!tabFound) { tabs.forEach(tab => { const tabText = tab.textContent.toLowerCase(); if (tabText.includes(sectionName.toLowerCase())) { tab.classList.add('active'); } }); } // Активируем соответствующую секцию const sectionId = `admin-${sectionName}-section`; let section = document.getElementById(sectionId); // Если не нашли по такому ID, пробуем другие варианты if (!section) { if (sectionName === 'users') { section = document.getElementById('admin-users-section'); } else if (sectionName === 'dashboard') { section = document.getElementById('admin-dashboard'); } else if (sectionName === 'stats') { section = document.getElementById('admin-stats-section'); } else { // Пробуем найти по частичному совпадению const sections = document.querySelectorAll('.admin-section'); sections.forEach(s => { if (s.id.includes(sectionName)) { section = s; } }); } } if (section) { section.classList.add('active'); console.log('Activated section:', section.id); } else { console.error('Section not found for:', sectionName); } // Загружаем данные для активной секции setTimeout(() => { if (sectionName === 'users') { console.log('Loading users...'); loadUsers(); } else if (sectionName === 'dashboard') { console.log('Loading dashboard...'); if (typeof renderDashboard === 'function') { renderDashboard(); } } else if (sectionName === 'stats') { console.log('Loading stats...'); if (typeof renderStatsSection === 'function') { renderStatsSection(); } } }, 50); } async function loadUsers() { try { const tbody = document.getElementById('users-table-body'); if (tbody) { tbody.innerHTML = 'Загрузка пользователей...'; } const response = await fetch('/admin/users'); if (!response.ok) { throw new Error('Ошибка загрузки пользователей'); } users = await response.json(); filteredUsers = [...users]; renderUsersTable(); } catch (error) { console.error('Ошибка загрузки пользователей:', error); showError('users-table-body', 'Ошибка загрузки пользователей'); } } function searchUsers() { const searchInput = document.getElementById('user-search'); if (!searchInput) return; const search = searchInput.value.toLowerCase(); filteredUsers = users.filter(user => (user.login && user.login.toLowerCase().includes(search)) || (user.name && user.name.toLowerCase().includes(search)) || (user.email && user.email.toLowerCase().includes(search)) || (user.role && user.role.toLowerCase().includes(search)) || (user.auth_type && user.auth_type.toLowerCase().includes(search)) ); renderUsersTable(); } /** * Преобразует внутреннее имя роли в отображаемое. * Для известных ролей возвращает локализованное название, * для неизвестных – само имя роли. */ function formatRole(role) { const roleMap = { 'admin': 'Администратор', 'teacher': 'Учитель' // при необходимости можно добавить другие соответствия }; return roleMap[role] || role; } function renderUsersTable() { const tbody = document.getElementById('users-table-body'); if (!tbody) return; if (!filteredUsers || filteredUsers.length === 0) { tbody.innerHTML = 'Пользователи не найдены'; return; } tbody.innerHTML = filteredUsers.map(user => ` ${user.id} ${user.login || 'Нет логина'} ${user.auth_type === 'ldap' ? 'LDAP' : ''} ${user.name || 'Не указано'} ${user.email || 'Нет email'} ${formatRole(user.role)} ${user.role === 'admin' ? 'ADMIN' : ''} ${user.auth_type === 'ldap' ? 'LDAP' : 'Локальная'} ${formatDate(user.created_at)} ${user.last_login ? formatDateTime(user.last_login) : 'Никогда'} `).join(''); } // Функция для открытия модального окна создания пользователя function openCreateUserModal() { const modal = document.getElementById('create-user-modal'); if (modal) { // Сбрасываем форму const form = document.getElementById('create-user-form'); if (form) { form.reset(); } modal.style.display = 'block'; } } // Функция для закрытия модального окна создания пользователя function closeCreateUserModal() { const modal = document.getElementById('create-user-modal'); if (modal) { modal.style.display = 'none'; } } // Функция для создания нового пользователя async function createUser(event) { event.preventDefault(); const login = document.getElementById('create-login').value; const password = document.getElementById('create-password').value; const name = document.getElementById('create-name').value; const email = document.getElementById('create-email').value; const role = document.getElementById('create-role').value; const auth_type = document.getElementById('create-auth-type').value; const groups = document.getElementById('create-groups').value; const description = document.getElementById('create-description').value; // Валидация if (!login || !password || !name || !email) { alert('Заполните все обязательные поля'); return; } if (password.length < 6) { alert('Пароль должен содержать не менее 6 символов'); return; } const userData = { login, password, name, email, role, auth_type, groups: groups || '[]', description }; try { const response = await fetch('/admin/users', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(userData) }); if (response.ok) { const result = await response.json(); alert(`Пользователь успешно создан! ID: ${result.id}`); closeCreateUserModal(); loadUsers(); // Перезагружаем список пользователей // Обновляем статистику если она видна if (document.getElementById('admin-dashboard')?.classList.contains('active')) { if (typeof loadDashboardStats === 'function') { loadDashboardStats(); } } if (document.getElementById('admin-stats-section')?.classList.contains('active')) { if (typeof loadUsersStats === 'function') { loadUsersStats(); } if (typeof loadOverallStats === 'function') { loadOverallStats(); } } } else { const error = await response.json(); alert(error.error || 'Ошибка создания пользователя'); } } catch (error) { console.error('Ошибка:', error); alert('Ошибка создания пользователя'); } } async function openEditUserModal(userId) { try { const response = await fetch(`/admin/users/${userId}`); if (!response.ok) { throw new Error('Ошибка загрузки пользователя'); } const user = await response.json(); document.getElementById('edit-user-id').value = user.id; document.getElementById('edit-login').value = user.login; document.getElementById('edit-name').value = user.name; document.getElementById('edit-email').value = user.email; document.getElementById('edit-role').value = user.role; document.getElementById('edit-auth-type').value = user.auth_type; document.getElementById('edit-groups').value = user.groups || '[]'; document.getElementById('edit-description').value = user.description || ''; const modal = document.getElementById('edit-user-modal'); if (modal) { modal.style.display = 'block'; } } catch (error) { console.error('Ошибка:', error); alert('Ошибка загрузки пользователя'); } } function closeEditUserModal() { const modal = document.getElementById('edit-user-modal'); if (modal) { modal.style.display = 'none'; } } async function updateUser(event) { event.preventDefault(); const userId = document.getElementById('edit-user-id').value; const login = document.getElementById('edit-login').value; const name = document.getElementById('edit-name').value; const email = document.getElementById('edit-email').value; const role = document.getElementById('edit-role').value; const auth_type = document.getElementById('edit-auth-type').value; const groups = document.getElementById('edit-groups').value; const description = document.getElementById('edit-description').value; if (!login || !name || !email) { alert('Заполните обязательные поля'); return; } const userData = { login, name, email, role, auth_type, groups: groups || '[]', description }; try { const response = await fetch(`/admin/users/${userId}`, { method: 'PUT', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(userData) }); if (response.ok) { alert('Пользователь успешно обновлен!'); closeEditUserModal(); loadUsers(); // Обновляем статистику если она видна if (document.getElementById('admin-dashboard')?.classList.contains('active')) { if (typeof loadDashboardStats === 'function') { loadDashboardStats(); } } if (document.getElementById('admin-stats-section')?.classList.contains('active')) { if (typeof loadUsersStats === 'function') { loadUsersStats(); } if (typeof loadOverallStats === 'function') { loadOverallStats(); } } } else { const error = await response.json(); alert(error.error || 'Ошибка обновления пользователя'); } } catch (error) { console.error('Ошибка:', error); alert('Ошибка обновления пользователя'); } } async function deleteUser(userId) { if (userId === currentUser?.id) { alert('Нельзя удалить самого себя'); return; } if (!confirm('Вы уверены, что хотите удалить этого пользователя?')) { return; } try { const response = await fetch(`/admin/users/${userId}`, { method: 'DELETE' }); if (response.ok) { alert('Пользователь успешно удален!'); loadUsers(); // Обновляем статистику если она видна if (document.getElementById('admin-dashboard')?.classList.contains('active')) { if (typeof loadDashboardStats === 'function') { loadDashboardStats(); } } if (document.getElementById('admin-stats-section')?.classList.contains('active')) { if (typeof loadUsersStats === 'function') { loadUsersStats(); } if (typeof loadOverallStats === 'function') { loadOverallStats(); } } } else { const error = await response.json(); alert(error.error || 'Ошибка удаления пользователя'); } } catch (error) { console.error('Ошибка:', error); alert('Ошибка удаления пользователя'); } } function formatDateTime(dateTimeString) { if (!dateTimeString) return ''; try { const date = new Date(dateTimeString); return date.toLocaleString('ru-RU'); } catch (e) { return dateTimeString; } } function formatDate(dateString) { if (!dateString) return ''; try { const date = new Date(dateString); return date.toLocaleDateString('ru-RU'); } catch (e) { return dateString; } } function showError(elementId, message) { const element = document.getElementById(elementId); if (element) { element.innerHTML = `${message}`; } } // Делаем функции глобально доступными window.logout = logout; window.showAdminSection = showAdminSection; window.searchUsers = searchUsers; window.loadUsers = loadUsers; window.openEditUserModal = openEditUserModal; window.closeEditUserModal = closeEditUserModal; window.openCreateUserModal = openCreateUserModal; window.closeCreateUserModal = closeCreateUserModal; window.createUser = createUser; window.updateUser = updateUser; window.deleteUser = deleteUser;