Добавил вкладку заявок
This commit is contained in:
@@ -3,7 +3,7 @@ if (!['localhost', '127.0.0.1'].includes(window.location.hostname)) {
|
||||
import('./otel.js').catch(e => console.warn('OTel init skipped:', e.message));
|
||||
}
|
||||
|
||||
import { isAuthenticatedAsAny, logout } from './api.js';
|
||||
import { api, isAuthenticatedAsAny, logout } from './api.js';
|
||||
import { applyRippleEffect, closeAllDropdownsOnOutsideClick } from './utils.js';
|
||||
import { startDropdownAutoObserver, initAllCustomDropdowns } from './dropdown.js';
|
||||
|
||||
@@ -38,6 +38,14 @@ const ROUTES = {
|
||||
await module.initUsers();
|
||||
}
|
||||
},
|
||||
'teacher-requests': {
|
||||
title: 'Заявки',
|
||||
file: '/admin/views/teacher-requests.html',
|
||||
init: async () => {
|
||||
const module = await import('./views/teacher-requests.js');
|
||||
await module.initTeacherRequests();
|
||||
}
|
||||
},
|
||||
groups: {
|
||||
title: 'Управление группами',
|
||||
file: '/admin/views/groups.html',
|
||||
@@ -115,7 +123,7 @@ const ROUTES = {
|
||||
const ROLE_NAVIGATION = {
|
||||
ADMIN: {
|
||||
defaultTab: 'dashboard',
|
||||
tabs: ['dashboard', 'schedule', 'academic-calendar', 'auditorium-workload', 'schedule-view', 'classrooms', 'groups', 'university-structure', 'subjects', 'users']
|
||||
tabs: ['dashboard', 'teacher-requests', 'schedule', 'academic-calendar', 'auditorium-workload', 'schedule-view', 'classrooms', 'groups', 'university-structure', 'subjects', 'users']
|
||||
},
|
||||
EDUCATION_OFFICE: {
|
||||
defaultTab: 'dashboard',
|
||||
@@ -143,6 +151,8 @@ const menuToggle = document.getElementById('menu-toggle');
|
||||
const sidebarCloseBtn = document.getElementById('sidebar-close-btn');
|
||||
const btnLogout = document.getElementById('btn-logout');
|
||||
const main = document.querySelector('.main');
|
||||
const teacherRequestsNavBadge = document.getElementById('teacher-requests-nav-badge');
|
||||
const teacherRequestsTitleBadge = document.getElementById('teacher-requests-title-badge');
|
||||
const roleNavigation = ROLE_NAVIGATION[currentRole] || ROLE_NAVIGATION.SCHEDULE_VIEWER;
|
||||
const allowedTabs = new Set(roleNavigation.tabs);
|
||||
|
||||
@@ -150,6 +160,7 @@ const allowedTabs = new Set(roleNavigation.tabs);
|
||||
applyRippleEffect();
|
||||
closeAllDropdownsOnOutsideClick();
|
||||
configureRoleInterface();
|
||||
refreshTeacherRequestBadge();
|
||||
|
||||
// Init sidebar state from localStorage on load
|
||||
if (window.innerWidth > 768 && localStorage.getItem('sidebar-collapsed') === 'true') {
|
||||
@@ -207,6 +218,10 @@ btnLogout.addEventListener('click', async () => {
|
||||
window.location.href = '/';
|
||||
});
|
||||
|
||||
teacherRequestsTitleBadge?.addEventListener('click', () => {
|
||||
switchTab('teacher-requests');
|
||||
});
|
||||
|
||||
// Navigation
|
||||
navItems.forEach(item => {
|
||||
item.addEventListener('click', (e) => {
|
||||
@@ -271,6 +286,42 @@ function configureRoleInterface() {
|
||||
document.querySelector('.logo span').textContent = firstAllowedTitle;
|
||||
}
|
||||
|
||||
async function refreshTeacherRequestBadge(countOverride = null) {
|
||||
if (currentRole !== 'ADMIN') return;
|
||||
try {
|
||||
const count = countOverride === null
|
||||
? (await api.get('/api/teacher-requests?status=PENDING') || []).length
|
||||
: countOverride;
|
||||
updateTeacherRequestBadge(teacherRequestsNavBadge, count, count > 99 ? '99+' : String(count));
|
||||
updateTeacherRequestBadge(teacherRequestsTitleBadge, count, requestCountLabel(count));
|
||||
} catch (error) {
|
||||
if (teacherRequestsNavBadge) teacherRequestsNavBadge.hidden = true;
|
||||
if (teacherRequestsTitleBadge) teacherRequestsTitleBadge.hidden = true;
|
||||
console.warn('Не удалось загрузить счётчик заявок:', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
function updateTeacherRequestBadge(element, count, label) {
|
||||
if (!element) return;
|
||||
const normalizedCount = Number(count) || 0;
|
||||
element.textContent = label;
|
||||
element.hidden = normalizedCount <= 0;
|
||||
element.setAttribute('aria-hidden', normalizedCount <= 0 ? 'true' : 'false');
|
||||
element.setAttribute('aria-label', normalizedCount > 0 ? `Заявок в очереди: ${normalizedCount}` : 'Заявок в очереди нет');
|
||||
}
|
||||
|
||||
function requestCountLabel(count) {
|
||||
const mod10 = count % 10;
|
||||
const mod100 = count % 100;
|
||||
if (mod10 === 1 && mod100 !== 11) return `${count} заявка`;
|
||||
if (mod10 >= 2 && mod10 <= 4 && (mod100 < 12 || mod100 > 14)) return `${count} заявки`;
|
||||
return `${count} заявок`;
|
||||
}
|
||||
|
||||
document.addEventListener('teacherRequestsChanged', (event) => {
|
||||
refreshTeacherRequestBadge(Number.isFinite(event.detail?.count) ? event.detail.count : null);
|
||||
});
|
||||
|
||||
const hashTab = window.location.hash.replace('#', '');
|
||||
switchTab(allowedTabs.has(hashTab) ? hashTab : roleNavigation.defaultTab);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user