import { apiClient } from '../shared/api-client.js'; import { capabilitiesForRole } from '../../admin/js/role-capabilities.js'; // Вкладки, перенесённые на React (см. react-tabs.js), хранят только заголовок: // их содержимое рендерят React-компоненты, HTML-фрагменты не загружаются. export const ADMIN_ROUTES = Object.freeze({ dashboard: { title: 'Дашборд' }, users: { title: 'Управление пользователями' }, 'teacher-requests': { title: 'Заявки' }, groups: { title: 'Управление группами' }, classrooms: { title: 'Аудиторный фонд' }, subjects: { title: 'Дисциплины' }, 'university-structure': { title: 'Структура вуза' }, 'department-workspace': { title: 'Кабинет кафедры' }, 'schedule-view': { title: 'Просмотр расписаний' }, schedule: { title: 'Конструктор правил' }, 'schedule-versions': { title: 'Версии расписания' }, 'schedule-quality': { title: 'Анализ качества расписания' }, 'academic-calendar': { title: 'Календарный учебный график' }, 'auditorium-workload': { title: 'Загруженность' }, 'teacher-absences': { title: 'Запросы преподавателей' } }); const NAV_ITEMS = Object.freeze({ dashboard: { navLabel: 'Дашборд' }, 'teacher-requests': { navLabel: 'Заявки' }, 'department-workspace': { navLabel: 'Кабинет кафедры' }, schedule: { navLabel: 'Конструктор правил' }, 'schedule-versions': { navLabel: 'Версии расписания' }, 'schedule-quality': { navLabel: 'Качество расписания' }, 'academic-calendar': { navLabel: 'Календарный график' }, 'auditorium-workload': { navLabel: 'Загруженность' }, 'schedule-view': { navLabel: 'Просмотр расписаний' }, 'teacher-absences': { navLabel: 'Запросы преподавателей' }, classrooms: { navLabel: 'Аудиторный фонд' }, groups: { navLabel: 'Группы обучения' }, 'university-structure': { navLabel: 'Структура вуза' }, subjects: { navLabel: 'Дисциплины' }, users: { navLabel: 'Пользователи' } }); const NAV_SECTIONS = Object.freeze([ { title: '', items: Object.freeze(['dashboard', 'teacher-requests', 'department-workspace']) }, { title: 'Расписание', items: Object.freeze([ 'schedule', 'schedule-versions', 'schedule-quality', 'academic-calendar', 'auditorium-workload', 'schedule-view', 'teacher-absences' ]) }, { title: 'Ресурсы', items: Object.freeze(['classrooms', 'groups', 'university-structure', 'subjects']) }, { title: 'Система', items: Object.freeze(['users']) } ]); const LOGO_TITLES = Object.freeze({ ADMIN: 'Magistr', EDUCATION_OFFICE: 'Учебный отдел', DEPARTMENT: 'Кафедра', SCHEDULE_VIEWER: 'Расписания' }); export function allowedAdminTabs(role) { const capabilities = capabilitiesForRole(role); return new Set(capabilities ? capabilities.adminTabs : []); } export function navSectionsForRole(role) { const allowed = allowedAdminTabs(role); return NAV_SECTIONS .map(section => ({ title: section.title, items: section.items .filter(tab => allowed.has(tab)) .map(tab => ({ id: tab, label: NAV_ITEMS[tab].navLabel })) })) .filter(section => section.items.length > 0); } export function logoTitleForRole(role) { return LOGO_TITLES[role] || 'Magistr'; } export function defaultAdminTabForRole(role) { const capabilities = capabilitiesForRole(role); return capabilities ? capabilities.defaultAdminTab : null; } export function tabFromHash(hash, role) { const allowed = allowedAdminTabs(role); const candidate = String(hash || '').replace('#', ''); if (candidate && allowed.has(candidate)) return candidate; return defaultAdminTabForRole(role); } export function requestCountLabel(count) { const value = Number(count) || 0; const mod10 = value % 10; const mod100 = value % 100; if (mod10 === 1 && mod100 !== 11) return `${value} заявка`; if (mod10 >= 2 && mod10 <= 4 && (mod100 < 12 || mod100 > 14)) return `${value} заявки`; return `${value} заявок`; } export function navBadgeLabel(count) { const value = Number(count) || 0; return value > 99 ? '99+' : String(value); } export function badgeVisibility(count) { const value = Number(count) || 0; return { hidden: value <= 0, ariaLabel: value > 0 ? `Заявок в очереди: ${value}` : 'Заявок в очереди нет' }; } export async function fetchPendingRequestsCount(client = apiClient) { const page = await client.get( '/api/teacher-requests/page?status=PENDING&page=0&size=1', { errorMessage: 'Не удалось загрузить счётчик заявок' } ); return Number(page?.totalItems || 0); }