Files
minicrm/public/admin-doc.html
2026-01-29 17:08:15 +05:00

1307 lines
55 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- 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;
--help-color: #27ae60;
--doc-color: #9b59b6;
--ahch-color: #e67e22;
}
.container {
max-width: 1400px;
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;
flex-wrap: wrap;
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 20px;
border: none;
background: none;
cursor: pointer;
font-size: 14px;
border-radius: 6px;
transition: all 0.3s;
display: flex;
align-items: center;
gap: 8px;
white-space: nowrap;
}
.tab:hover {
background: #f5f5f5;
}
.tab.active {
color: white;
}
.tab.secretary.active { background: var(--secretary-color); }
.tab.administration.active { background: var(--admin-color); }
.tab.help.active { background: var(--help-color); }
.tab.doc.active { background: var(--doc-color); }
.tab.ahch.active { background: var(--ahch-color); }
.tab.all-users.active { background: #2c3e50; }
.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); }
.group-color.help { background: var(--help-color); }
.group-color.doc { background: var(--doc-color); }
.group-color.ahch { background: var(--ahch-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;
position: relative;
}
.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: 11px;
color: white;
display: flex;
align-items: center;
gap: 4px;
}
.group-badge.admin { background: var(--admin-color); }
.group-badge.secretary { background: var(--secretary-color); }
.group-badge.help { background: var(--help-color); }
.group-badge.doc { background: var(--doc-color); }
.group-badge.ahch { background: var(--ahch-color); }
.user-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 10px;
}
.btn {
padding: 6px 12px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
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;
}
.btn-help { background: var(--help-color); color: white; }
.btn-help:hover { background: #219653; }
.btn-doc { background: var(--doc-color); color: white; }
.btn-doc:hover { background: #8e44ad; }
.btn-ahch { background: var(--ahch-color); color: white; }
.btn-ahch:hover { background: #d35400; }
.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: grid;
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
gap: 15px;
margin-bottom: 20px;
}
.stat-card {
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;
margin: 10px 0;
}
.stat-label {
color: #666;
font-size: 14px;
}
.no-users {
text-align: center;
padding: 40px;
color: #666;
}
.all-groups-badges {
display: flex;
flex-wrap: wrap;
gap: 5px;
margin-top: 5px;
}
@media (max-width: 768px) {
.users-container {
grid-template-columns: 1fr;
}
.user-actions {
flex-direction: column;
}
.tab {
padding: 10px 15px;
font-size: 13px;
}
.stats {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 480px) {
.stats {
grid-template-columns: 1fr;
}
.tab {
padding: 8px 12px;
font-size: 12px;
}
}
</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 secretary active" onclick="showTab('secretary')">
<i class="fas fa-file-signature"></i> Секретари
</button>
<button class="tab administration" onclick="showTab('administration')">
<i class="fas fa-user-shield"></i> Администрация
</button>
<button class="tab help" onclick="showTab('help')">
<i class="fas fa-hands-helping"></i> Help
</button>
<button class="tab doc" onclick="showTab('doc')">
<i class="fas fa-file-alt"></i> Doc
</button>
<button class="tab ahch" onclick="showTab('ahch')">
<i class="fas fa-school"></i> AHCH
</button>
<button class="tab all-users" 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>
<!-- Help группа -->
<div id="help-section" class="content-section">
<div class="group-info">
<div class="group-color help"></div>
<div>
<h3>Группа "Help"</h3>
<p>Пользователи этой группы получают заявки поддержки</p>
</div>
</div>
<div class="search-box">
<input type="text" id="help-search" class="search-input"
placeholder="Поиск пользователей..." onkeyup="filterUsers('help')">
</div>
<div class="stats">
<div class="stat-card">
<div class="stat-number" id="help-count">0</div>
<div class="stat-label">Всего пользователей</div>
</div>
<div class="stat-card">
<div class="stat-number" id="help-in-group">0</div>
<div class="stat-label">В группе "Help"</div>
</div>
</div>
<div id="help-users" class="users-container">
<div class="loading">
<i class="fas fa-spinner fa-spin"></i>
<p>Загрузка пользователей...</p>
</div>
</div>
</div>
<!-- Doc группа -->
<div id="doc-section" class="content-section">
<div class="group-info">
<div class="group-color doc"></div>
<div>
<h3>Группа "Doc"</h3>
<p>Пользователи этой группы работают с документами</p>
</div>
</div>
<div class="search-box">
<input type="text" id="doc-search" class="search-input"
placeholder="Поиск пользователей..." onkeyup="filterUsers('doc')">
</div>
<div class="stats">
<div class="stat-card">
<div class="stat-number" id="doc-count">0</div>
<div class="stat-label">Всего пользователей</div>
</div>
<div class="stat-card">
<div class="stat-number" id="doc-in-group">0</div>
<div class="stat-label">В группе "Doc"</div>
</div>
</div>
<div id="doc-users" class="users-container">
<div class="loading">
<i class="fas fa-spinner fa-spin"></i>
<p>Загрузка пользователей...</p>
</div>
</div>
</div>
<!-- AHCH группа -->
<div id="ahch-section" class="content-section">
<div class="group-info">
<div class="group-color ahch"></div>
<div>
<h3>Группа "AHCH"</h3>
<p>Пользователи этой группы работают с AHCH задачами</p>
</div>
</div>
<div class="search-box">
<input type="text" id="ahch-search" class="search-input"
placeholder="Поиск пользователей..." onkeyup="filterUsers('ahch')">
</div>
<div class="stats">
<div class="stat-card">
<div class="stat-number" id="ahch-count">0</div>
<div class="stat-label">Всего пользователей</div>
</div>
<div class="stat-card">
<div class="stat-number" id="ahch-in-group">0</div>
<div class="stat-label">В группе "AHCH"</div>
</div>
</div>
<div id="ahch-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 class="stat-card">
<div class="stat-number" id="help-count-all">0</div>
<div class="stat-label">Help</div>
</div>
<div class="stat-card">
<div class="stat-number" id="doc-count-all">0</div>
<div class="stat-label">Doc</div>
</div>
<div class="stat-card">
<div class="stat-number" id="ahch-count-all">0</div>
<div class="stat-label">AHCH</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 groupIds = {
'secretary': null,
'admin': null,
'help': null,
'doc': null,
'ahch': 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 всех групп
groupIds.secretary = groups.find(g => g.name === 'Секретарь')?.id;
groupIds.admin = groups.find(g => g.name === 'Администрация')?.id;
groupIds.help = groups.find(g => g.name === 'help')?.id;
groupIds.doc = groups.find(g => g.name === 'doc')?.id;
groupIds.ahch = groups.find(g => g.name === 'ahch')?.id;
// Загружаем всех пользователей
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;
// Статистика для help
const helpUsers = allUsers.filter(u => u.groups?.some(g => g.group_name === 'help'));
document.getElementById('help-count').textContent = allUsers.length;
document.getElementById('help-in-group').textContent = helpUsers.length;
// Статистика для doc
const docUsers = allUsers.filter(u => u.groups?.some(g => g.group_name === 'doc'));
document.getElementById('doc-count').textContent = allUsers.length;
document.getElementById('doc-in-group').textContent = docUsers.length;
// Статистика для ahch
const ahchUsers = allUsers.filter(u => u.groups?.some(g => g.group_name === 'ahch'));
document.getElementById('ahch-count').textContent = allUsers.length;
document.getElementById('ahch-in-group').textContent = ahchUsers.length;
// Общая статистика
document.getElementById('total-users').textContent = allUsers.length;
document.getElementById('admins-count').textContent = adminUsers.length;
document.getElementById('secretaries-count').textContent = secretaryUsers.length;
document.getElementById('help-count-all').textContent = helpUsers.length;
document.getElementById('doc-count-all').textContent = docUsers.length;
document.getElementById('ahch-count-all').textContent = ahchUsers.length;
}
// Отображение пользователей
function renderUsers() {
renderSecretaryUsers();
renderAdminUsers();
renderHelpUsers();
renderDocUsers();
renderAhchUsers();
renderAllUsers();
}
// Проверка, состоит ли пользователь в группе
function isUserInGroup(user, groupName) {
return user.groups?.some(g => g.group_name === groupName);
}
// Получение иконки для группы
function getGroupIcon(groupName) {
const icons = {
'Секретарь': 'fa-file-signature',
'Администрация': 'fa-user-shield',
'help': 'fa-hands-helping',
'doc': 'fa-file-alt',
'ahch': 'fa-school'
};
return icons[groupName] || 'fa-users';
}
// Отображение пользователей для секретарей
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 = isUserInGroup(user, 'Секретарь');
const isAdmin = isUserInGroup(user, 'Администрация');
const isHelp = isUserInGroup(user, 'help');
const isDoc = isUserInGroup(user, 'doc');
const isAhch = isUserInGroup(user, 'ahch');
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>' : ''}
${isHelp ? '<span class="group-badge help"><i class="fas fa-hands-helping"></i> help</span>' : ''}
${isDoc ? '<span class="group-badge doc"><i class="fas fa-file-alt"></i> doc</span>' : ''}
${isAhch ? '<span class="group-badge ahch"><i class="fas fa-school"></i> ahch</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 = isUserInGroup(user, 'Секретарь');
const isAdmin = isUserInGroup(user, 'Администрация');
const isHelp = isUserInGroup(user, 'help');
const isDoc = isUserInGroup(user, 'doc');
const isAhch = isUserInGroup(user, 'ahch');
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>' : ''}
${isHelp ? '<span class="group-badge help"><i class="fas fa-hands-helping"></i> help</span>' : ''}
${isDoc ? '<span class="group-badge doc"><i class="fas fa-file-alt"></i> doc</span>' : ''}
${isAhch ? '<span class="group-badge ahch"><i class="fas fa-school"></i> ahch</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('');
}
// Отображение пользователей для help
function renderHelpUsers() {
const container = document.getElementById('help-users');
const searchTerm = document.getElementById('help-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 = isUserInGroup(user, 'Секретарь');
const isAdmin = isUserInGroup(user, 'Администрация');
const isHelp = isUserInGroup(user, 'help');
const isDoc = isUserInGroup(user, 'doc');
const isAhch = isUserInGroup(user, 'ahch');
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>' : ''}
${isHelp ? '<span class="group-badge help"><i class="fas fa-hands-helping"></i> help</span>' : ''}
${isDoc ? '<span class="group-badge doc"><i class="fas fa-file-alt"></i> doc</span>' : ''}
${isAhch ? '<span class="group-badge ahch"><i class="fas fa-school"></i> ahch</span>' : ''}
</div>
<div class="user-actions">
${isHelp ?
`<button class="btn btn-danger" onclick="removeFromGroup(${user.id}, 'help')">
<i class="fas fa-user-minus"></i> Убрать
</button>` :
`<button class="btn btn-help" onclick="addToGroup(${user.id}, 'help')">
<i class="fas fa-user-plus"></i> Добавить
</button>`
}
</div>
</div>
`;
}).join('');
}
// Отображение пользователей для doc
function renderDocUsers() {
const container = document.getElementById('doc-users');
const searchTerm = document.getElementById('doc-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 = isUserInGroup(user, 'Секретарь');
const isAdmin = isUserInGroup(user, 'Администрация');
const isHelp = isUserInGroup(user, 'help');
const isDoc = isUserInGroup(user, 'doc');
const isAhch = isUserInGroup(user, 'ahch');
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>' : ''}
${isHelp ? '<span class="group-badge help"><i class="fas fa-hands-helping"></i> help</span>' : ''}
${isDoc ? '<span class="group-badge doc"><i class="fas fa-file-alt"></i> doc</span>' : ''}
${isAhch ? '<span class="group-badge ahch"><i class="fas fa-school"></i> ahch</span>' : ''}
</div>
<div class="user-actions">
${isDoc ?
`<button class="btn btn-danger" onclick="removeFromGroup(${user.id}, 'doc')">
<i class="fas fa-user-minus"></i> Убрать
</button>` :
`<button class="btn btn-doc" onclick="addToGroup(${user.id}, 'doc')">
<i class="fas fa-user-plus"></i> Добавить
</button>`
}
</div>
</div>
`;
}).join('');
}
// Отображение пользователей для ahch
function renderAhchUsers() {
const container = document.getElementById('ahch-users');
const searchTerm = document.getElementById('ahch-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 = isUserInGroup(user, 'Секретарь');
const isAdmin = isUserInGroup(user, 'Администрация');
const isHelp = isUserInGroup(user, 'help');
const isDoc = isUserInGroup(user, 'doc');
const isAhch = isUserInGroup(user, 'ahch');
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>' : ''}
${isHelp ? '<span class="group-badge help"><i class="fas fa-hands-helping"></i> help</span>' : ''}
${isDoc ? '<span class="group-badge doc"><i class="fas fa-file-alt"></i> doc</span>' : ''}
${isAhch ? '<span class="group-badge ahch"><i class="fas fa-school"></i> ahch</span>' : ''}
</div>
<div class="user-actions">
${isAhch ?
`<button class="btn btn-danger" onclick="removeFromGroup(${user.id}, 'ahch')">
<i class="fas fa-user-minus"></i> Убрать
</button>` :
`<button class="btn btn-ahch" onclick="addToGroup(${user.id}, 'ahch')">
<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 = isUserInGroup(user, 'Секретарь');
const isAdmin = isUserInGroup(user, 'Администрация');
const isHelp = isUserInGroup(user, 'help');
const isDoc = isUserInGroup(user, 'doc');
const isAhch = isUserInGroup(user, 'ahch');
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="all-groups-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>' : ''}
${isHelp ? '<span class="group-badge help"><i class="fas fa-hands-helping"></i> help</span>' : ''}
${isDoc ? '<span class="group-badge doc"><i class="fas fa-file-alt"></i> doc</span>' : ''}
${isAhch ? '<span class="group-badge ahch"><i class="fas fa-school"></i> ahch</span>' : ''}
</div>
<div class="user-actions">
${isSecretary ?
`<button class="btn btn-danger" onclick="removeFromGroup(${user.id}, 'secretary')" title="Убрать из секретарей">
<i class="fas fa-user-minus"></i>
</button>` :
`<button class="btn btn-success" onclick="addToGroup(${user.id}, 'secretary')" title="Добавить в секретари">
<i class="fas fa-user-plus"></i>
</button>`
}
${isAdmin ?
`<button class="btn btn-danger" onclick="removeFromGroup(${user.id}, 'admin')" title="Убрать из администрации">
<i class="fas fa-user-minus"></i>
</button>` :
`<button class="btn btn-primary" onclick="addToGroup(${user.id}, 'admin')" title="Добавить в администрацию">
<i class="fas fa-user-plus"></i>
</button>`
}
${isHelp ?
`<button class="btn btn-danger" onclick="removeFromGroup(${user.id}, 'help')" title="Убрать из help">
<i class="fas fa-user-minus"></i>
</button>` :
`<button class="btn btn-help" onclick="addToGroup(${user.id}, 'help')" title="Добавить в help">
<i class="fas fa-user-plus"></i>
</button>`
}
${isDoc ?
`<button class="btn btn-danger" onclick="removeFromGroup(${user.id}, 'doc')" title="Убрать из doc">
<i class="fas fa-user-minus"></i>
</button>` :
`<button class="btn btn-doc" onclick="addToGroup(${user.id}, 'doc')" title="Добавить в doc">
<i class="fas fa-user-plus"></i>
</button>`
}
${isAhch ?
`<button class="btn btn-danger" onclick="removeFromGroup(${user.id}, 'ahch')" title="Убрать из ahch">
<i class="fas fa-user-minus"></i>
</button>` :
`<button class="btn btn-ahch" onclick="addToGroup(${user.id}, 'ahch')" title="Добавить в ahch">
<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 'help':
renderHelpUsers();
break;
case 'doc':
renderDocUsers();
break;
case 'ahch':
renderAhchUsers();
break;
case 'all':
renderAllUsers();
break;
}
}
// Показать вкладку
function showTab(tabName) {
currentTab = tabName;
// Обновляем активные вкладки
document.querySelectorAll('.tab').forEach(tab => {
tab.classList.remove('active');
});
document.querySelectorAll('.content-section').forEach(section => {
section.classList.remove('active');
});
// Активируем выбранную вкладку
document.querySelector(`.tab.${tabName}`).classList.add('active');
document.getElementById(`${tabName}-section`).classList.add('active');
}
// Добавить пользователя в группу
async function addToGroup(userId, groupType) {
if (!await checkAuth()) return;
const groupNames = {
'secretary': 'Секретарь',
'admin': 'Администрация',
'help': 'help',
'doc': 'doc',
'ahch': 'ahch'
};
const groupName = groupNames[groupType];
const groupId = groupIds[groupType];
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 groupNames = {
'secretary': 'Секретарь',
'admin': 'Администрация',
'help': 'help',
'doc': 'doc',
'ahch': 'ahch'
};
const groupName = groupNames[groupType];
const groupId = groupIds[groupType];
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>