Статистика
This commit is contained in:
220
public/admin-dashboard.js
Normal file
220
public/admin-dashboard.js
Normal file
@@ -0,0 +1,220 @@
|
||||
// admin-dashboard.js
|
||||
// Функции для работы с дашбордом административной панели
|
||||
|
||||
function renderDashboard() {
|
||||
const dashboardContainer = document.getElementById('admin-dashboard');
|
||||
|
||||
if (!dashboardContainer) return;
|
||||
|
||||
dashboardContainer.innerHTML = `
|
||||
<h2>Статистика системы</h2>
|
||||
|
||||
<div class="stats-grid">
|
||||
<div class="stat-card task-stat">
|
||||
<h3>Задачи</h3>
|
||||
<div class="stat-value" id="total-tasks">0</div>
|
||||
<div class="stat-desc">Всего задач в системе</div>
|
||||
<div class="percentage-bar">
|
||||
<div class="percentage-fill" id="active-tasks-bar" style="width: 0%"></div>
|
||||
</div>
|
||||
<div class="stat-subitems">
|
||||
<div class="stat-subitem">
|
||||
<span class="label">Активные:</span>
|
||||
<span class="value" id="active-tasks">0</span>
|
||||
</div>
|
||||
<div class="stat-subitem">
|
||||
<span class="label">Закрытые:</span>
|
||||
<span class="value" id="closed-tasks">0</span>
|
||||
</div>
|
||||
<div class="stat-subitem">
|
||||
<span class="label">Удаленные:</span>
|
||||
<span class="value" id="deleted-tasks">0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="stat-card status-stat">
|
||||
<h3>Статусы назначений</h3>
|
||||
<div class="stat-value" id="total-assignments">0</div>
|
||||
<div class="stat-desc">Всего назначений</div>
|
||||
<div class="stat-subitems">
|
||||
<div class="stat-subitem">
|
||||
<span class="label">Назначено:</span>
|
||||
<span class="value" id="assigned-count">0</span>
|
||||
</div>
|
||||
<div class="stat-subitem">
|
||||
<span class="label">В работе:</span>
|
||||
<span class="value" id="in-progress-count">0</span>
|
||||
</div>
|
||||
<div class="stat-subitem">
|
||||
<span class="label">Выполнено:</span>
|
||||
<span class="value" id="completed-count">0</span>
|
||||
</div>
|
||||
<div class="stat-subitem">
|
||||
<span class="label">Просрочено:</span>
|
||||
<span class="value" id="overdue-count">0</span>
|
||||
</div>
|
||||
<div class="stat-subitem">
|
||||
<span class="label">На доработке:</span>
|
||||
<span class="value" id="rework-count">0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="stat-card user-stat">
|
||||
<h3>Пользователи</h3>
|
||||
<div class="stat-value" id="total-users">0</div>
|
||||
<div class="stat-desc">Зарегистрировано пользователей</div>
|
||||
<div class="stat-subitems">
|
||||
<div class="stat-subitem">
|
||||
<span class="label">Администраторы:</span>
|
||||
<span class="value" id="admin-users">0</span>
|
||||
</div>
|
||||
<div class="stat-subitem">
|
||||
<span class="label">Учителя:</span>
|
||||
<span class="value" id="teacher-users">0</span>
|
||||
</div>
|
||||
<div class="stat-subitem">
|
||||
<span class="label">LDAP:</span>
|
||||
<span class="value" id="ldap-users">0</span>
|
||||
</div>
|
||||
<div class="stat-subitem">
|
||||
<span class="label">Локальные:</span>
|
||||
<span class="value" id="local-users">0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="stat-card file-stat">
|
||||
<h3>Файлы</h3>
|
||||
<div class="stat-value" id="total-files">0</div>
|
||||
<div class="stat-desc">Всего загружено файлов</div>
|
||||
<div class="file-size" id="total-files-size">0 MB</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// После создания HTML загружаем статистику
|
||||
loadDashboardStats();
|
||||
}
|
||||
|
||||
async function loadDashboardStats() {
|
||||
try {
|
||||
const response = await fetch('/admin/stats');
|
||||
if (response.ok) {
|
||||
const stats = await response.json();
|
||||
updateStatsUI(stats);
|
||||
} else {
|
||||
// Если API недоступно, используем данные из вашего скриншота
|
||||
const defaultStats = {
|
||||
totalTasks: 46,
|
||||
activeTasks: 43,
|
||||
closedTasks: 0,
|
||||
deletedTasks: 3,
|
||||
totalAssignments: 61,
|
||||
assignedCount: 15,
|
||||
inProgressCount: 1,
|
||||
completedCount: 9,
|
||||
overdueCount: 36,
|
||||
reworkCount: 0,
|
||||
totalUsers: 4,
|
||||
adminUsers: 1,
|
||||
teacherUsers: 1,
|
||||
ldapUsers: 4,
|
||||
localUsers: 0,
|
||||
totalFiles: 27,
|
||||
totalFilesSize: 10.96 * 1024 * 1024 // 10.96 MB в байтах
|
||||
};
|
||||
updateStatsUI(defaultStats);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Ошибка загрузки статистики:', error);
|
||||
showDashboardError();
|
||||
}
|
||||
}
|
||||
|
||||
function updateStatsUI(stats) {
|
||||
// Проверяем, существует ли элемент dashboard
|
||||
const dashboard = document.getElementById('admin-dashboard');
|
||||
if (!dashboard || !dashboard.classList.contains('active')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Задачи
|
||||
setElementText('total-tasks', stats.totalTasks || 0);
|
||||
setElementText('active-tasks', stats.activeTasks || 0);
|
||||
setElementText('closed-tasks', stats.closedTasks || 0);
|
||||
setElementText('deleted-tasks', stats.deletedTasks || 0);
|
||||
|
||||
// Процент активных задач
|
||||
if (stats.totalTasks > 0) {
|
||||
const activePercentage = Math.round((stats.activeTasks / stats.totalTasks) * 100);
|
||||
const activeBar = document.getElementById('active-tasks-bar');
|
||||
if (activeBar) {
|
||||
activeBar.style.width = `${activePercentage}%`;
|
||||
}
|
||||
}
|
||||
|
||||
// Назначения
|
||||
setElementText('total-assignments', stats.totalAssignments || 0);
|
||||
setElementText('assigned-count', stats.assignedCount || 0);
|
||||
setElementText('in-progress-count', stats.inProgressCount || 0);
|
||||
setElementText('completed-count', stats.completedCount || 0);
|
||||
setElementText('overdue-count', stats.overdueCount || 0);
|
||||
setElementText('rework-count', stats.reworkCount || 0);
|
||||
|
||||
// Пользователи
|
||||
setElementText('total-users', stats.totalUsers || 0);
|
||||
setElementText('admin-users', stats.adminUsers || 0);
|
||||
setElementText('teacher-users', stats.teacherUsers || 0);
|
||||
setElementText('ldap-users', stats.ldapUsers || 0);
|
||||
setElementText('local-users', stats.localUsers || 0);
|
||||
|
||||
// Файлы
|
||||
setElementText('total-files', stats.totalFiles || 0);
|
||||
const fileSizeMB = stats.totalFilesSize ? (stats.totalFilesSize / 1024 / 1024).toFixed(2) : '0';
|
||||
setElementText('total-files-size', `${fileSizeMB} MB`);
|
||||
}
|
||||
|
||||
function setElementText(id, text) {
|
||||
const element = document.getElementById(id);
|
||||
if (element) {
|
||||
element.textContent = text;
|
||||
}
|
||||
}
|
||||
|
||||
function showDashboardError() {
|
||||
const dashboardContainer = document.getElementById('admin-dashboard');
|
||||
if (dashboardContainer) {
|
||||
dashboardContainer.innerHTML = `
|
||||
<h2>Статистика системы</h2>
|
||||
<div class="error-message">
|
||||
<p>Не удалось загрузить статистику системы.</p>
|
||||
<button onclick="loadDashboardStats()">Повторить попытку</button>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
// Автоматическое обновление статистики каждые 30 секунд
|
||||
setInterval(() => {
|
||||
if (document.getElementById('admin-dashboard')?.classList.contains('active')) {
|
||||
loadDashboardStats();
|
||||
}
|
||||
}, 30000);
|
||||
|
||||
// Инициализация дашборда при загрузке страницы
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Ждем пока основной скрипт проверит авторизацию
|
||||
setTimeout(() => {
|
||||
// Если дашборд активен при загрузке, рендерим его
|
||||
const dashboard = document.getElementById('admin-dashboard');
|
||||
if (dashboard && dashboard.classList.contains('active')) {
|
||||
renderDashboard();
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
|
||||
// Экспортируем функции для использования в admin-script.js
|
||||
window.renderDashboard = renderDashboard;
|
||||
window.loadDashboardStats = loadDashboardStats;
|
||||
Reference in New Issue
Block a user