102 lines
3.4 KiB
JavaScript
102 lines
3.4 KiB
JavaScript
import { isAuthenticatedAsAdmin } from './api.js';
|
|
import { applyRippleEffect, closeAllDropdownsOnOutsideClick } from './utils.js';
|
|
|
|
import { initUsers } from './views/users.js';
|
|
import { initGroups } from './views/groups.js';
|
|
import { initEduForms } from './views/edu-forms.js';
|
|
import { initEquipments } from './views/equipments.js';
|
|
import { initClassrooms } from './views/classrooms.js';
|
|
import { initSubjects } from './views/subjects.js';
|
|
|
|
// Configuration
|
|
const ROUTES = {
|
|
users: { title: 'Управление пользователями', file: 'views/users.html', init: initUsers },
|
|
groups: { title: 'Управление группами', file: 'views/groups.html', init: initGroups },
|
|
'edu-forms': { title: 'Формы обучения', file: 'views/edu-forms.html', init: initEduForms },
|
|
equipments: { title: 'Оборудование', file: 'views/equipments.html', init: initEquipments },
|
|
classrooms: { title: 'Аудитории', file: 'views/classrooms.html', init: initClassrooms },
|
|
subjects: { title: 'Дисциплины и преподаватели', file: 'views/subjects.html', init: initSubjects },
|
|
};
|
|
|
|
let currentTab = null;
|
|
|
|
// DOM Elements
|
|
const appContent = document.getElementById('app-content');
|
|
const pageTitle = document.getElementById('page-title');
|
|
const navItems = document.querySelectorAll('.nav-item[data-tab]');
|
|
const sidebar = document.querySelector('.sidebar');
|
|
const sidebarOverlay = document.getElementById('sidebar-overlay');
|
|
const menuToggle = document.getElementById('menu-toggle');
|
|
const btnLogout = document.getElementById('btn-logout');
|
|
|
|
// Initial auth check
|
|
if (!isAuthenticatedAsAdmin()) {
|
|
window.location.href = '/';
|
|
}
|
|
|
|
// Setup Global Effects
|
|
applyRippleEffect();
|
|
closeAllDropdownsOnOutsideClick();
|
|
|
|
// Menu Toggle
|
|
menuToggle.addEventListener('click', () => {
|
|
sidebar.classList.toggle('open');
|
|
sidebarOverlay.classList.toggle('open');
|
|
});
|
|
sidebarOverlay.addEventListener('click', () => {
|
|
sidebar.classList.remove('open');
|
|
sidebarOverlay.classList.remove('open');
|
|
});
|
|
|
|
// Logout
|
|
btnLogout.addEventListener('click', () => {
|
|
localStorage.removeItem('token');
|
|
localStorage.removeItem('role');
|
|
window.location.href = '/';
|
|
});
|
|
|
|
// Navigation
|
|
navItems.forEach(item => {
|
|
item.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
const tab = item.dataset.tab;
|
|
switchTab(tab);
|
|
});
|
|
});
|
|
|
|
async function switchTab(tab) {
|
|
if (currentTab === tab || !ROUTES[tab]) return;
|
|
|
|
// UI Update
|
|
navItems.forEach(n => n.classList.remove('active'));
|
|
document.querySelector(`.nav-item[data-tab="${tab}"]`)?.classList.add('active');
|
|
pageTitle.textContent = ROUTES[tab].title;
|
|
|
|
// Load template
|
|
try {
|
|
appContent.innerHTML = '<div class="loading-row">Загрузка...</div>';
|
|
const response = await fetch(ROUTES[tab].file);
|
|
if (!response.ok) throw new Error('Failed to load view');
|
|
|
|
const html = await response.text();
|
|
appContent.innerHTML = html;
|
|
|
|
// Initialize logic for the tab
|
|
if (ROUTES[tab].init) {
|
|
ROUTES[tab].init();
|
|
}
|
|
|
|
currentTab = tab;
|
|
} catch (e) {
|
|
appContent.innerHTML = `<div class="form-alert error">Ошибка загрузки вкладки: ${e.message}</div>`;
|
|
console.error(e);
|
|
}
|
|
|
|
// Close mobile menu if open
|
|
sidebar.classList.remove('open');
|
|
sidebarOverlay.classList.remove('open');
|
|
}
|
|
|
|
// Load default tab
|
|
switchTab('users');
|