This commit is contained in:
2026-02-26 10:09:24 +05:00
parent 908533929b
commit 9d28e67388
4 changed files with 305 additions and 0 deletions

View File

@@ -63,6 +63,7 @@ function showAdminInterface() {
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);
@@ -71,6 +72,10 @@ function setupEventListeners() {
if (editUserForm) {
editUserForm.addEventListener('submit', updateUser);
}
if (createUserForm) {
createUserForm.addEventListener('submit', createUser);
}
}
async function login(event) {
@@ -270,6 +275,101 @@ function renderUsersTable() {
`).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}`);
@@ -447,5 +547,8 @@ 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;

View File

@@ -61,6 +61,7 @@
<div class="search-container">
<input type="text" id="user-search" placeholder="Поиск пользователей по логину, имени или email..." oninput="searchUsers()">
<button onclick="loadUsers()">Сбросить</button>
<button class="create-user-btn" onclick="openCreateUserModal()"> Создать пользователя</button>
</div>
<table class="users-table">
@@ -91,6 +92,7 @@
</div>
</div>
<!-- Модальное окно редактирования пользователя -->
<div id="edit-user-modal" class="modal">
<div class="modal-content modal-lg">
<span class="close" onclick="closeEditUserModal()">&times;</span>
@@ -147,6 +149,67 @@
</div>
</div>
<!-- Модальное окно создания пользователя -->
<div id="create-user-modal" class="modal">
<div class="modal-content modal-lg">
<span class="close" onclick="closeCreateUserModal()">&times;</span>
<h3>Создать нового пользователя</h3>
<form id="create-user-form">
<div class="form-row">
<div class="form-group">
<label for="create-login">Логин *</label>
<input type="text" id="create-login" name="login" required>
</div>
<div class="form-group">
<label for="create-password">Пароль *</label>
<input type="password" id="create-password" name="password" required minlength="6">
<small class="form-hint">Минимум 6 символов</small>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="create-name">Имя *</label>
<input type="text" id="create-name" name="name" required>
</div>
<div class="form-group">
<label for="create-email">Email *</label>
<input type="email" id="create-email" name="email" required>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="create-role">Роль</label>
<select id="create-role" name="role">
<option value="teacher">Учитель</option>
<option value="admin">Администратор</option>
</select>
</div>
<div class="form-group">
<label for="create-auth-type">Тип авторизации</label>
<select id="create-auth-type" name="auth_type">
<option value="local">Локальная</option>
<option value="ldap">LDAP</option>
</select>
</div>
</div>
<div class="form-group">
<label for="create-groups">Группы (JSON)</label>
<input type="text" id="create-groups" name="groups" placeholder='["group1", "group2"]'>
</div>
<div class="form-group">
<label for="create-description">Описание</label>
<textarea id="create-description" name="description" rows="3"></textarea>
</div>
<button type="submit">Создать пользователя</button>
</form>
</div>
</div>
<script src="admin-script.js"></script>
<script src="admin-dashboard.js"></script>
<script src="admin-stats.js"></script>

View File

@@ -4760,4 +4760,142 @@ button.btn-primary {
transform: translateY(0);
opacity: 1;
}
}
/* Стили для кнопки создания пользователя */
.create-user-btn {
background-color: #27ae60;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
font-weight: bold;
margin-left: 10px;
}
.create-user-btn:hover {
background-color: #2ecc71;
}
/* Стили для хинта в форме */
.form-hint {
font-size: 12px;
color: #7f8c8d;
display: block;
margin-top: 4px;
}
/* Обновленные стили для поиска */
.search-container {
display: flex;
gap: 10px;
margin-bottom: 20px;
align-items: center;
}
.search-container input {
flex: 1;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}
.search-container button {
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
background-color: #3498db;
color: white;
}
.search-container button:hover {
opacity: 0.9;
}
/* Стили для кнопок действий */
.user-actions {
display: flex;
gap: 5px;
}
.user-actions button {
padding: 5px 10px;
border: none;
border-radius: 3px;
cursor: pointer;
font-size: 14px;
}
.user-actions .edit-btn {
background-color: #f39c12;
color: white;
}
.user-actions .edit-btn:hover {
background-color: #e67e22;
}
.user-actions .delete-btn {
background-color: #e74c3c;
color: white;
}
.user-actions .delete-btn:hover {
background-color: #c0392b;
}
.user-actions .delete-btn:disabled {
background-color: #bdc3c7;
cursor: not-allowed;
}
/* Стили для бейджей */
.ldap-badge, .admin-badge {
display: inline-block;
padding: 2px 6px;
border-radius: 3px;
font-size: 10px;
font-weight: bold;
margin-left: 5px;
text-transform: uppercase;
}
.ldap-badge {
background-color: #9b59b6;
color: white;
}
.admin-badge {
background-color: #e74c3c;
color: white;
}
/* Стили для модального окна */
.modal-lg {
max-width: 600px;
}
.form-row {
display: flex;
gap: 15px;
margin-bottom: 15px;
}
.form-row .form-group {
flex: 1;
margin-bottom: 0;
}
.close {
float: right;
font-size: 28px;
font-weight: bold;
cursor: pointer;
line-height: 1;
}
.close:hover {
color: #e74c3c;
}