856 lines
32 KiB
HTML
856 lines
32 KiB
HTML
<!-- public/admin-doc.html -->
|
||
<!DOCTYPE html>
|
||
<html lang="ru">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Управление группами пользователей | CRM</title>
|
||
<link rel="stylesheet" href="/styles.css">
|
||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||
<style>
|
||
:root {
|
||
--admin-color: #e74c3c;
|
||
--secretary-color: #3498db;
|
||
}
|
||
|
||
.container {
|
||
max-width: 1200px;
|
||
margin: 0 auto;
|
||
padding: 20px;
|
||
}
|
||
|
||
.header {
|
||
background: white;
|
||
padding: 20px;
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.header h1 {
|
||
margin: 0;
|
||
color: #333;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
}
|
||
|
||
.header-actions {
|
||
display: flex;
|
||
gap: 10px;
|
||
margin-top: 15px;
|
||
}
|
||
|
||
.tabs {
|
||
display: flex;
|
||
gap: 5px;
|
||
margin-bottom: 20px;
|
||
background: white;
|
||
padding: 5px;
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
|
||
}
|
||
|
||
.tab {
|
||
padding: 12px 24px;
|
||
border: none;
|
||
background: none;
|
||
cursor: pointer;
|
||
font-size: 16px;
|
||
border-radius: 6px;
|
||
transition: all 0.3s;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
|
||
.tab:hover {
|
||
background: #f5f5f5;
|
||
}
|
||
|
||
.tab.active {
|
||
background: #3498db;
|
||
color: white;
|
||
}
|
||
|
||
.content-section {
|
||
display: none;
|
||
background: white;
|
||
padding: 20px;
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||
}
|
||
|
||
.content-section.active {
|
||
display: block;
|
||
}
|
||
|
||
.group-info {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
margin-bottom: 20px;
|
||
padding: 15px;
|
||
background: #f9f9f9;
|
||
border-radius: 6px;
|
||
}
|
||
|
||
.group-color {
|
||
width: 20px;
|
||
height: 20px;
|
||
border-radius: 50%;
|
||
}
|
||
|
||
.group-color.admin {
|
||
background: var(--admin-color);
|
||
}
|
||
|
||
.group-color.secretary {
|
||
background: var(--secretary-color);
|
||
}
|
||
|
||
.users-container {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||
gap: 15px;
|
||
margin-top: 20px;
|
||
}
|
||
|
||
.user-card {
|
||
background: white;
|
||
border: 1px solid #e0e0e0;
|
||
border-radius: 8px;
|
||
padding: 15px;
|
||
transition: all 0.3s;
|
||
}
|
||
|
||
.user-card:hover {
|
||
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
|
||
transform: translateY(-2px);
|
||
}
|
||
|
||
.user-header {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.user-avatar {
|
||
width: 40px;
|
||
height: 40px;
|
||
background: #3498db;
|
||
color: white;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.user-name {
|
||
font-weight: bold;
|
||
color: #333;
|
||
}
|
||
|
||
.user-role {
|
||
font-size: 12px;
|
||
color: #666;
|
||
margin-top: 2px;
|
||
}
|
||
|
||
.user-details {
|
||
font-size: 14px;
|
||
color: #666;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.group-badges {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 5px;
|
||
margin: 10px 0;
|
||
}
|
||
|
||
.group-badge {
|
||
padding: 4px 8px;
|
||
border-radius: 4px;
|
||
font-size: 12px;
|
||
color: white;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
}
|
||
|
||
.group-badge.admin {
|
||
background: var(--admin-color);
|
||
}
|
||
|
||
.group-badge.secretary {
|
||
background: var(--secretary-color);
|
||
}
|
||
|
||
.user-actions {
|
||
display: flex;
|
||
gap: 10px;
|
||
margin-top: 10px;
|
||
}
|
||
|
||
.btn {
|
||
padding: 8px 16px;
|
||
border: none;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
font-size: 14px;
|
||
transition: all 0.3s;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 5px;
|
||
}
|
||
|
||
.btn-primary {
|
||
background: #3498db;
|
||
color: white;
|
||
}
|
||
|
||
.btn-primary:hover {
|
||
background: #2980b9;
|
||
}
|
||
|
||
.btn-danger {
|
||
background: #e74c3c;
|
||
color: white;
|
||
}
|
||
|
||
.btn-danger:hover {
|
||
background: #c0392b;
|
||
}
|
||
|
||
.btn-success {
|
||
background: #27ae60;
|
||
color: white;
|
||
}
|
||
|
||
.btn-success:hover {
|
||
background: #229954;
|
||
}
|
||
|
||
.loading {
|
||
text-align: center;
|
||
padding: 40px;
|
||
color: #666;
|
||
}
|
||
|
||
.loading i {
|
||
font-size: 24px;
|
||
margin-bottom: 10px;
|
||
color: #3498db;
|
||
}
|
||
|
||
.search-box {
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.search-input {
|
||
width: 100%;
|
||
padding: 10px 15px;
|
||
border: 1px solid #ddd;
|
||
border-radius: 6px;
|
||
font-size: 16px;
|
||
}
|
||
|
||
.stats {
|
||
display: flex;
|
||
gap: 20px;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.stat-card {
|
||
flex: 1;
|
||
background: white;
|
||
padding: 15px;
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
|
||
text-align: center;
|
||
}
|
||
|
||
.stat-number {
|
||
font-size: 24px;
|
||
font-weight: bold;
|
||
color: #3498db;
|
||
margin: 10px 0;
|
||
}
|
||
|
||
.stat-label {
|
||
color: #666;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.no-users {
|
||
text-align: center;
|
||
padding: 40px;
|
||
color: #666;
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.users-container {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
|
||
.stats {
|
||
flex-direction: column;
|
||
}
|
||
|
||
.user-actions {
|
||
flex-direction: column;
|
||
}
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
<div class="header">
|
||
<h1><i class="fas fa-users-cog"></i> Управление группами пользователей</h1>
|
||
<div class="header-actions">
|
||
<button class="btn btn-primary" onclick="refreshAllData()">
|
||
<i class="fas fa-sync-alt"></i> Обновить
|
||
</button>
|
||
<button class="btn btn-success" onclick="goBack()">
|
||
<i class="fas fa-arrow-left"></i> Назад в CRM
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tabs">
|
||
<button class="tab active" onclick="showTab('secretary')">
|
||
<i class="fas fa-file-signature"></i> Секретари
|
||
</button>
|
||
<button class="tab" onclick="showTab('administration')">
|
||
<i class="fas fa-user-shield"></i> Администрация
|
||
</button>
|
||
<button class="tab" onclick="showTab('all-users')">
|
||
<i class="fas fa-users"></i> Все пользователи
|
||
</button>
|
||
</div>
|
||
|
||
<!-- Секретари -->
|
||
<div id="secretary-section" class="content-section active">
|
||
<div class="group-info">
|
||
<div class="group-color secretary"></div>
|
||
<div>
|
||
<h3>Группа "Секретарь"</h3>
|
||
<p>Пользователи этой группы могут согласовывать документы в системе</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="search-box">
|
||
<input type="text" id="secretary-search" class="search-input"
|
||
placeholder="Поиск пользователей..." onkeyup="filterUsers('secretary')">
|
||
</div>
|
||
|
||
<div class="stats">
|
||
<div class="stat-card">
|
||
<div class="stat-number" id="secretary-count">0</div>
|
||
<div class="stat-label">Всего пользователей</div>
|
||
</div>
|
||
<div class="stat-card">
|
||
<div class="stat-number" id="secretary-in-group">0</div>
|
||
<div class="stat-label">В группе "Секретарь"</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="secretary-users" class="users-container">
|
||
<div class="loading">
|
||
<i class="fas fa-spinner fa-spin"></i>
|
||
<p>Загрузка пользователей...</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Администрация -->
|
||
<div id="administration-section" class="content-section">
|
||
<div class="group-info">
|
||
<div class="group-color admin"></div>
|
||
<div>
|
||
<h3>Группа "Администрация"</h3>
|
||
<p>Пользователи этой группы имеют права администратора в системе</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="search-box">
|
||
<input type="text" id="admin-search" class="search-input"
|
||
placeholder="Поиск пользователей..." onkeyup="filterUsers('admin')">
|
||
</div>
|
||
|
||
<div class="stats">
|
||
<div class="stat-card">
|
||
<div class="stat-number" id="admin-count">0</div>
|
||
<div class="stat-label">Всего пользователей</div>
|
||
</div>
|
||
<div class="stat-card">
|
||
<div class="stat-number" id="admin-in-group">0</div>
|
||
<div class="stat-label">В группе "Администрация"</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="admin-users" class="users-container">
|
||
<div class="loading">
|
||
<i class="fas fa-spinner fa-spin"></i>
|
||
<p>Загрузка пользователей...</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Все пользователи -->
|
||
<div id="all-users-section" class="content-section">
|
||
<div class="search-box">
|
||
<input type="text" id="all-search" class="search-input"
|
||
placeholder="Поиск пользователей..." onkeyup="filterUsers('all')">
|
||
</div>
|
||
|
||
<div class="stats">
|
||
<div class="stat-card">
|
||
<div class="stat-number" id="total-users">0</div>
|
||
<div class="stat-label">Всего пользователей</div>
|
||
</div>
|
||
<div class="stat-card">
|
||
<div class="stat-number" id="admins-count">0</div>
|
||
<div class="stat-label">Администраторы</div>
|
||
</div>
|
||
<div class="stat-card">
|
||
<div class="stat-number" id="secretaries-count">0</div>
|
||
<div class="stat-label">Секретари</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="all-users" class="users-container">
|
||
<div class="loading">
|
||
<i class="fas fa-spinner fa-spin"></i>
|
||
<p>Загрузка пользователей...</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
let currentTab = 'secretary';
|
||
let allUsers = [];
|
||
let secretaryGroupId = null;
|
||
let adminGroupId = null;
|
||
|
||
// Проверка авторизации
|
||
async function checkAuth() {
|
||
try {
|
||
const response = await fetch('/api/user');
|
||
if (response.status === 401) {
|
||
window.location.href = '/';
|
||
return false;
|
||
}
|
||
const data = await response.json();
|
||
if (data.user.role !== 'admin') {
|
||
alert('Доступ запрещен. Требуются права администратора.');
|
||
window.location.href = '/';
|
||
return false;
|
||
}
|
||
return true;
|
||
} catch (error) {
|
||
console.error('Ошибка проверки авторизации:', error);
|
||
window.location.href = '/';
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// Загрузка данных
|
||
async function loadData() {
|
||
if (!await checkAuth()) return;
|
||
|
||
try {
|
||
// Загружаем группы
|
||
const groupsResponse = await fetch('/api/groups');
|
||
const groups = await groupsResponse.json();
|
||
|
||
// Находим ID групп
|
||
secretaryGroupId = groups.find(g => g.name === 'Секретарь')?.id;
|
||
adminGroupId = groups.find(g => g.name === 'Администрация')?.id;
|
||
|
||
if (!secretaryGroupId) {
|
||
console.warn('Группа "Секретарь" не найдена');
|
||
}
|
||
|
||
if (!adminGroupId) {
|
||
console.warn('Группа "Администрация" не найдена');
|
||
}
|
||
|
||
// Загружаем всех пользователей
|
||
const usersResponse = await fetch('/api/users/all');
|
||
const users = await usersResponse.json();
|
||
|
||
allUsers = users;
|
||
|
||
// Обновляем статистику
|
||
updateStats();
|
||
|
||
// Отображаем пользователей
|
||
renderUsers();
|
||
|
||
} catch (error) {
|
||
console.error('Ошибка загрузки данных:', error);
|
||
showError('Не удалось загрузить данные');
|
||
}
|
||
}
|
||
|
||
// Обновление статистики
|
||
function updateStats() {
|
||
// Статистика для секретарей
|
||
const secretaryUsers = allUsers.filter(u => u.groups?.some(g => g.group_name === 'Секретарь'));
|
||
document.getElementById('secretary-count').textContent = allUsers.length;
|
||
document.getElementById('secretary-in-group').textContent = secretaryUsers.length;
|
||
|
||
// Статистика для администрации
|
||
const adminUsers = allUsers.filter(u => u.groups?.some(g => g.group_name === 'Администрация'));
|
||
document.getElementById('admin-count').textContent = allUsers.length;
|
||
document.getElementById('admin-in-group').textContent = adminUsers.length;
|
||
|
||
// Общая статистика
|
||
document.getElementById('total-users').textContent = allUsers.length;
|
||
document.getElementById('admins-count').textContent = adminUsers.length;
|
||
document.getElementById('secretaries-count').textContent = secretaryUsers.length;
|
||
}
|
||
|
||
// Отображение пользователей
|
||
function renderUsers() {
|
||
renderSecretaryUsers();
|
||
renderAdminUsers();
|
||
renderAllUsers();
|
||
}
|
||
|
||
// Отображение пользователей для секретарей
|
||
function renderSecretaryUsers() {
|
||
const container = document.getElementById('secretary-users');
|
||
const searchTerm = document.getElementById('secretary-search').value.toLowerCase();
|
||
|
||
const filteredUsers = allUsers.filter(user =>
|
||
user.name.toLowerCase().includes(searchTerm) ||
|
||
user.login.toLowerCase().includes(searchTerm) ||
|
||
user.email.toLowerCase().includes(searchTerm)
|
||
);
|
||
|
||
if (filteredUsers.length === 0) {
|
||
container.innerHTML = `
|
||
<div class="no-users">
|
||
<i class="fas fa-users-slash" style="font-size: 48px; color: #ccc; margin-bottom: 15px;"></i>
|
||
<p>Пользователи не найдены</p>
|
||
</div>
|
||
`;
|
||
return;
|
||
}
|
||
|
||
container.innerHTML = filteredUsers.map(user => {
|
||
const isSecretary = user.groups?.some(g => g.group_name === 'Секретарь');
|
||
const isAdmin = user.groups?.some(g => g.group_name === 'Администрация');
|
||
|
||
return `
|
||
<div class="user-card">
|
||
<div class="user-header">
|
||
<div class="user-avatar">${user.name.charAt(0).toUpperCase()}</div>
|
||
<div>
|
||
<div class="user-name">${user.name}</div>
|
||
<div class="user-role">${user.role === 'admin' ? 'Администратор' : 'Учитель'}</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="user-details">
|
||
<div><i class="fas fa-user"></i> ${user.login}</div>
|
||
<div><i class="fas fa-envelope"></i> ${user.email}</div>
|
||
</div>
|
||
|
||
<div class="group-badges">
|
||
${isSecretary ? '<span class="group-badge secretary"><i class="fas fa-file-signature"></i> Секретарь</span>' : ''}
|
||
${isAdmin ? '<span class="group-badge admin"><i class="fas fa-user-shield"></i> Администрация</span>' : ''}
|
||
</div>
|
||
|
||
<div class="user-actions">
|
||
${isSecretary ?
|
||
`<button class="btn btn-danger" onclick="removeFromGroup(${user.id}, 'secretary')">
|
||
<i class="fas fa-user-minus"></i> Убрать из секретарей
|
||
</button>` :
|
||
`<button class="btn btn-success" onclick="addToGroup(${user.id}, 'secretary')">
|
||
<i class="fas fa-user-plus"></i> Добавить в секретари
|
||
</button>`
|
||
}
|
||
</div>
|
||
</div>
|
||
`;
|
||
}).join('');
|
||
}
|
||
|
||
// Отображение пользователей для администрации
|
||
function renderAdminUsers() {
|
||
const container = document.getElementById('admin-users');
|
||
const searchTerm = document.getElementById('admin-search').value.toLowerCase();
|
||
|
||
const filteredUsers = allUsers.filter(user =>
|
||
user.name.toLowerCase().includes(searchTerm) ||
|
||
user.login.toLowerCase().includes(searchTerm) ||
|
||
user.email.toLowerCase().includes(searchTerm)
|
||
);
|
||
|
||
if (filteredUsers.length === 0) {
|
||
container.innerHTML = `
|
||
<div class="no-users">
|
||
<i class="fas fa-users-slash" style="font-size: 48px; color: #ccc; margin-bottom: 15px;"></i>
|
||
<p>Пользователи не найдены</p>
|
||
</div>
|
||
`;
|
||
return;
|
||
}
|
||
|
||
container.innerHTML = filteredUsers.map(user => {
|
||
const isSecretary = user.groups?.some(g => g.group_name === 'Секретарь');
|
||
const isAdmin = user.groups?.some(g => g.group_name === 'Администрация');
|
||
|
||
return `
|
||
<div class="user-card">
|
||
<div class="user-header">
|
||
<div class="user-avatar">${user.name.charAt(0).toUpperCase()}</div>
|
||
<div>
|
||
<div class="user-name">${user.name}</div>
|
||
<div class="user-role">${user.role === 'admin' ? 'Администратор' : 'Учитель'}</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="user-details">
|
||
<div><i class="fas fa-user"></i> ${user.login}</div>
|
||
<div><i class="fas fa-envelope"></i> ${user.email}</div>
|
||
</div>
|
||
|
||
<div class="group-badges">
|
||
${isSecretary ? '<span class="group-badge secretary"><i class="fas fa-file-signature"></i> Секретарь</span>' : ''}
|
||
${isAdmin ? '<span class="group-badge admin"><i class="fas fa-user-shield"></i> Администрация</span>' : ''}
|
||
</div>
|
||
|
||
<div class="user-actions">
|
||
${isAdmin ?
|
||
`<button class="btn btn-danger" onclick="removeFromGroup(${user.id}, 'admin')">
|
||
<i class="fas fa-user-minus"></i> Убрать из администрации
|
||
</button>` :
|
||
`<button class="btn btn-success" onclick="addToGroup(${user.id}, 'admin')">
|
||
<i class="fas fa-user-plus"></i> Добавить в администрацию
|
||
</button>`
|
||
}
|
||
</div>
|
||
</div>
|
||
`;
|
||
}).join('');
|
||
}
|
||
|
||
// Отображение всех пользователей
|
||
function renderAllUsers() {
|
||
const container = document.getElementById('all-users');
|
||
const searchTerm = document.getElementById('all-search').value.toLowerCase();
|
||
|
||
const filteredUsers = allUsers.filter(user =>
|
||
user.name.toLowerCase().includes(searchTerm) ||
|
||
user.login.toLowerCase().includes(searchTerm) ||
|
||
user.email.toLowerCase().includes(searchTerm)
|
||
);
|
||
|
||
if (filteredUsers.length === 0) {
|
||
container.innerHTML = `
|
||
<div class="no-users">
|
||
<i class="fas fa-users-slash" style="font-size: 48px; color: #ccc; margin-bottom: 15px;"></i>
|
||
<p>Пользователи не найдены</p>
|
||
</div>
|
||
`;
|
||
return;
|
||
}
|
||
|
||
container.innerHTML = filteredUsers.map(user => {
|
||
const isSecretary = user.groups?.some(g => g.group_name === 'Секретарь');
|
||
const isAdmin = user.groups?.some(g => g.group_name === 'Администрация');
|
||
|
||
return `
|
||
<div class="user-card">
|
||
<div class="user-header">
|
||
<div class="user-avatar">${user.name.charAt(0).toUpperCase()}</div>
|
||
<div>
|
||
<div class="user-name">${user.name}</div>
|
||
<div class="user-role">${user.role === 'admin' ? 'Администратор' : 'Учитель'}</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="user-details">
|
||
<div><i class="fas fa-user"></i> ${user.login}</div>
|
||
<div><i class="fas fa-envelope"></i> ${user.email}</div>
|
||
</div>
|
||
|
||
<div class="group-badges">
|
||
${isSecretary ? '<span class="group-badge secretary"><i class="fas fa-file-signature"></i> Секретарь</span>' : ''}
|
||
${isAdmin ? '<span class="group-badge admin"><i class="fas fa-user-shield"></i> Администрация</span>' : ''}
|
||
</div>
|
||
|
||
<div class="user-actions">
|
||
${isSecretary ?
|
||
`<button class="btn btn-danger" onclick="removeFromGroup(${user.id}, 'secretary')">
|
||
<i class="fas fa-user-minus"></i> Убрать из секретарей
|
||
</button>` :
|
||
`<button class="btn btn-success" onclick="addToGroup(${user.id}, 'secretary')">
|
||
<i class="fas fa-user-plus"></i> В секретари
|
||
</button>`
|
||
}
|
||
${isAdmin ?
|
||
`<button class="btn btn-danger" onclick="removeFromGroup(${user.id}, 'admin')">
|
||
<i class="fas fa-user-minus"></i> Убрать из администрации
|
||
</button>` :
|
||
`<button class="btn btn-primary" onclick="addToGroup(${user.id}, 'admin')">
|
||
<i class="fas fa-user-plus"></i> В администрацию
|
||
</button>`
|
||
}
|
||
</div>
|
||
</div>
|
||
`;
|
||
}).join('');
|
||
}
|
||
|
||
// Фильтрация пользователей
|
||
function filterUsers(section) {
|
||
switch(section) {
|
||
case 'secretary':
|
||
renderSecretaryUsers();
|
||
break;
|
||
case 'admin':
|
||
renderAdminUsers();
|
||
break;
|
||
case 'all':
|
||
renderAllUsers();
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Показать вкладку
|
||
function showTab(tabName) {
|
||
currentTab = tabName;
|
||
|
||
// Обновляем активные вкладки
|
||
document.querySelectorAll('.tab').forEach(tab => {
|
||
tab.classList.remove('active');
|
||
});
|
||
document.querySelectorAll('.tab').forEach(tab => {
|
||
if (tab.onclick.toString().includes(tabName)) {
|
||
tab.classList.add('active');
|
||
}
|
||
});
|
||
|
||
// Обновляем активные секции
|
||
document.querySelectorAll('.content-section').forEach(section => {
|
||
section.classList.remove('active');
|
||
});
|
||
|
||
switch(tabName) {
|
||
case 'secretary':
|
||
document.getElementById('secretary-section').classList.add('active');
|
||
break;
|
||
case 'administration':
|
||
document.getElementById('administration-section').classList.add('active');
|
||
break;
|
||
case 'all-users':
|
||
document.getElementById('all-users-section').classList.add('active');
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Добавить пользователя в группу
|
||
async function addToGroup(userId, groupType) {
|
||
if (!await checkAuth()) return;
|
||
|
||
const groupName = groupType === 'secretary' ? 'Секретарь' : 'Администрация';
|
||
const groupId = groupType === 'secretary' ? secretaryGroupId : adminGroupId;
|
||
|
||
if (!groupId) {
|
||
showError(`Группа "${groupName}" не найдена`);
|
||
return;
|
||
}
|
||
|
||
if (!confirm(`Добавить пользователя в группу "${groupName}"?`)) return;
|
||
|
||
try {
|
||
const response = await fetch(`/api/groups/${groupId}/users/${userId}`, {
|
||
method: 'POST'
|
||
});
|
||
|
||
if (response.ok) {
|
||
showSuccess(`Пользователь добавлен в группу "${groupName}"`);
|
||
await refreshAllData();
|
||
} else {
|
||
const error = await response.text();
|
||
showError(error);
|
||
}
|
||
} catch (error) {
|
||
console.error('Ошибка добавления в группу:', error);
|
||
showError('Не удалось добавить пользователя в группу');
|
||
}
|
||
}
|
||
|
||
// Удалить пользователя из группы
|
||
async function removeFromGroup(userId, groupType) {
|
||
if (!await checkAuth()) return;
|
||
|
||
const groupName = groupType === 'secretary' ? 'Секретарь' : 'Администрация';
|
||
const groupId = groupType === 'secretary' ? secretaryGroupId : adminGroupId;
|
||
|
||
if (!groupId) {
|
||
showError(`Группа "${groupName}" не найдена`);
|
||
return;
|
||
}
|
||
|
||
if (!confirm(`Убрать пользователя из группы "${groupName}"?`)) return;
|
||
|
||
try {
|
||
const response = await fetch(`/api/groups/${groupId}/users/${userId}`, {
|
||
method: 'DELETE'
|
||
});
|
||
|
||
if (response.ok) {
|
||
showSuccess(`Пользователь убран из группы "${groupName}"`);
|
||
await refreshAllData();
|
||
} else {
|
||
const error = await response.text();
|
||
showError(error);
|
||
}
|
||
} catch (error) {
|
||
console.error('Ошибка удаления из группы:', error);
|
||
showError('Не удалось убрать пользователя из группы');
|
||
}
|
||
}
|
||
|
||
// Обновить все данные
|
||
async function refreshAllData() {
|
||
await loadData();
|
||
showSuccess('Данные обновлены');
|
||
}
|
||
|
||
// Показать сообщение об ошибке
|
||
function showError(message) {
|
||
alert('Ошибка: ' + message);
|
||
}
|
||
|
||
// Показать сообщение об успехе
|
||
function showSuccess(message) {
|
||
// Можно заменить на более красивый toast
|
||
alert('Успех: ' + message);
|
||
}
|
||
|
||
// Вернуться в CRM
|
||
function goBack() {
|
||
window.location.href = '/';
|
||
}
|
||
|
||
// Инициализация
|
||
document.addEventListener('DOMContentLoaded', async () => {
|
||
if (await checkAuth()) {
|
||
await loadData();
|
||
}
|
||
});
|
||
</script>
|
||
</body>
|
||
</html> |