11 KiB
🎨 Frontend
Общая информация
| Параметр | Значение |
|---|---|
| Фреймворк | Нет (Vanilla JavaScript) |
| Модульная система | ES6 Modules (import/export) |
| Стили | CSS (модульный подход) |
| Шрифт | Inter (Google Fonts) |
| Веб-сервер | Apache httpd:alpine |
Структура файлов
frontend/
├── index.html # 🔐 Страница авторизации (общая)
├── script.js # Логика авторизации
├── style.css # Стили страницы авторизации
├── theme-toggle.js # Переключение светлой/тёмной темы
├── Dockerfile # httpd:alpine
│
├── admin/ # 👨💼 Интерфейс администратора
│ ├── index.html # SPA-оболочка с sidebar
│ ├── css/
│ │ ├── main.css # CSS-переменные, цвета, типографика
│ │ ├── layout.css # Раскладка (sidebar, topbar, content)
│ │ ├── components.css # Кнопки, таблицы, карточки, формы
│ │ ├── modals.css # Модальные окна
│ │ ├── department.css # Стили кафедры
│ │ └── departments-data.css # Стили создания кафедры/специальности
│ ├── js/
│ │ ├── main.js # Инициализация, маршрутизация, навигация
│ │ ├── api.js # HTTP-обёртка (fetch + Authorization)
│ │ ├── utils.js # Утилиты
│ │ ├── otel.js # OpenTelemetry (клиентская телеметрия, только прод)
│ │ └── views/ # Модули представлений
│ │ ├── users.js # Управление пользователями
│ │ ├── groups.js # Управление группами
│ │ ├── classrooms.js # Управление аудиториями
│ │ ├── subjects.js # Управление дисциплинами
│ │ ├── equipments.js # Управление оборудованием
│ │ ├── edu-forms.js # Формы обучения
│ │ ├── schedule.js # Расписание занятий
│ │ ├── database.js # Управление тенантами
│ │ ├── department.js # Кафедры
│ │ └── departments-data.js # Создание кафедры/специальности
│ ├── views/ # HTML-шаблоны представлений
│ │ ├── users.html
│ │ ├── groups.html
│ │ ├── classrooms.html
│ │ ├── subjects.html
│ │ ├── equipments.html
│ │ ├── edu-forms.html
│ │ ├── schedule.html
│ │ ├── database.html
│ │ ├── department.html
│ │ └── departments-data.html
│ │
│ └── settings/ # ⚙️ Страница настроек (отдельный SPA)
│ ├── index.html # Оболочка с собственной sidebar
│ ├── css/
│ │ ├── main.css # CSS-переменные, базовые стили
│ │ └── layout.css # Sidebar, topbar, content
│ ├── js/
│ │ └── main.js # Навигация по вкладкам настроек
│ └── views/
│ └── general.html # Общие настройки (заглушка)
│
├── teacher/ # 👩🏫 Интерфейс преподавателя
│ └── index.html # Просмотр расписания
│
└── student/ # 🎓 Интерфейс студента
└── index.html # Просмотр расписания (read-only)
Система маршрутизации (Admin SPA)
Админ-панель работает как Single Page Application без фреймворка.
Навигация реализована через data-tab атрибуты на элементах sidebar:
<a href="#" class="nav-item" data-tab="users">Пользователи</a>
<a href="#" class="nav-item" data-tab="groups">Группы</a>
<a href="#" class="nav-item" data-tab="schedule">Расписание занятий</a>
При клике на пункт меню main.js:
- Загружает HTML-шаблон из
views/{tab}.htmlчерезfetch() - Вставляет его в
#app-content - Подключает соответствующий JS-модуль из
js/views/{tab}.js - Обновляет заголовок страницы (
#page-title)
Разделы админ-панели
| Tab | Описание | API |
|---|---|---|
users |
CRUD пользователей | /api/users |
groups |
CRUD групп | /api/groups |
edu-forms |
Формы обучения | /api/education-forms |
equipments |
Оборудование | /api/equipments |
classrooms |
Аудитории | /api/classrooms |
subjects |
Дисциплины | /api/subjects |
schedule |
Расписание | /api/users/lessons |
database |
Тенанты | /api/database |
department |
Кафедры | /api/departments |
departments-data |
Создание кафедры/специальности | /api/departments |
Страница настроек (/admin/settings/)
Настройки — это отдельный SPA со своей боковой панелью и вкладками, не связанными с основной админ-панелью.
- Доступ: через dropdown «Настройки» в footer боковой панели админки
- Кнопка «Назад в панель» для возврата в
/admin/ - Текущие вкладки:
- Общие настройки — заглушка (в разработке)
API-клиент (api.js)
Все HTTP-запросы проходят через обёртку apiFetch():
export async function apiFetch(endpoint, method = 'GET', body = null) {
const response = await fetch(endpoint, {
method,
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: body ? JSON.stringify(body) : null
});
if (!response.ok) {
throw new Error(data?.message || `Ошибка HTTP: ${response.status}`);
}
return await response.json();
}
// Shortcut-методы
export const api = {
get: (url) => apiFetch(url, 'GET'),
post: (url, body) => apiFetch(url, 'POST', body),
put: (url, body) => apiFetch(url, 'PUT', body),
delete: (url, body) => apiFetch(url, 'DELETE', body)
};
Токен берётся из localStorage.getItem('token').
Аутентификация (Frontend)
Страница входа (/index.html)
- Пользователь вводит логин/пароль
script.jsотправляетPOST /api/auth/login- При успехе сохраняет в
localStorage:token— UUID-токенrole— роль пользователя
- Перенаправляет на соответствующий интерфейс:
ADMIN→/admin/TEACHER→/teacher/STUDENT→/student/
Проверка авторизации
На каждой странице проверяется наличие токена и роли:
export function isAuthenticatedAsAdmin() {
const role = localStorage.getItem('role');
return token && role === 'ADMIN';
}
Выход
Кнопка «Выйти» находится в dropdown-меню «Настройки» в footer боковой панели. Очищает localStorage и перенаправляет на /.
CSS-архитектура
Модульный подход
Стили разделены на модульные файлы (порядок подключения важен):
main.css— CSS-переменные (цвета, шрифты, отступы), глобальные стили, тёмная темаlayout.css— Sidebar, topbar, content area, dropdown настроек, responsivecomponents.css— Кнопки, таблицы, карточки, badge, формы, theme-togglemodals.css— Модальные окнаdepartment.css— Стили страницы кафедрdepartments-data.css— Стили создания кафедры/специальности
Темизация
CSS-переменные позволяют поддерживать светлую/тёмную тему:
:root {
--bg-primary: #ffffff;
--text-primary: #1a1a2e;
--accent: #6366f1;
}
[data-theme="dark"] {
--bg-primary: #0f0f23;
--text-primary: #e2e8f0;
--accent: #818cf8;
}
Переключение — через theme-toggle.js.
Боковая панель (Sidebar)
- Скрытие/раскрытие — кнопка-крестик в правом верхнем углу sidebar
- Десктоп (
>768px): sidebar складывается влево, контент расширяется; состояние сохраняется вlocalStorage(sidebar-collapsed) - Мобильные (
≤768px): sidebar скрывается за кнопкой-гамбургер, выезжает как overlay с затемнением - Dropdown «Настройки» в footer sidebar — содержит ссылку на страницу настроек и кнопку выхода
OpenTelemetry (otel.js)
Клиентская телеметрия (document-load, fetch, XHR) отправляется через BatchSpanProcessor на /otel/v1/traces.
- На production — загружается автоматически через динамический
import() - На localhost — пропускается, чтобы избежать таймаутов CDN
esm.sh
if (!['localhost', '127.0.0.1'].includes(window.location.hostname)) {
import('./otel.js').catch(e => console.warn('OTel init skipped:', e.message));
}
Адаптивность
Интерфейс адаптирован под мобильные устройства:
- Sidebar скрывается на экранах < 768px, выезжает как overlay
- Появляется кнопка-гамбургер (
#menu-toggle) - Кнопка-крестик закрывает sidebar на всех устройствах
- Таблицы получают горизонтальный скролл