Files
magistr/docs/FRONTEND.md
2026-03-27 15:24:29 +03:00

257 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🎨 Frontend
## Общая информация
| Параметр | Значение |
|----------|----------|
| **Фреймворк** | Нет (Vanilla JavaScript) |
| **Модульная система** | ES6 Modules (`import`/`export`) |
| **Стили** | CSS (модульный подход) |
| **Шрифт** | [Inter](https://fonts.google.com/specimen/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:
```html
<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`:
1. Загружает HTML-шаблон из `views/{tab}.html` через `fetch()`
2. Вставляет его в `#app-content`
3. Подключает соответствующий JS-модуль из `js/views/{tab}.js`
4. Обновляет заголовок страницы (`#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()`:
```javascript
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`)
1. Пользователь вводит логин/пароль
2. `script.js` отправляет `POST /api/auth/login`
3. При успехе сохраняет в `localStorage`:
- `token` — UUID-токен
- `role` — роль пользователя
4. Перенаправляет на соответствующий интерфейс:
- `ADMIN``/admin/`
- `TEACHER``/teacher/`
- `STUDENT``/student/`
### Проверка авторизации
На каждой странице проверяется наличие токена и роли:
```javascript
export function isAuthenticatedAsAdmin() {
const role = localStorage.getItem('role');
return token && role === 'ADMIN';
}
```
### Выход
Кнопка «Выйти» находится в dropdown-меню «Настройки» в footer боковой панели. Очищает `localStorage` и перенаправляет на `/`.
---
## CSS-архитектура
### Модульный подход
Стили разделены на модульные файлы (порядок подключения важен):
1. **`main.css`** — CSS-переменные (цвета, шрифты, отступы), глобальные стили, тёмная тема
2. **`layout.css`** — Sidebar, topbar, content area, dropdown настроек, responsive
3. **`components.css`** — Кнопки, таблицы, карточки, badge, формы, theme-toggle
4. **`modals.css`** — Модальные окна
5. **`department.css`** — Стили страницы кафедр
6. **`departments-data.css`** — Стили создания кафедры/специальности
### Темизация
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`
```javascript
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 на всех устройствах
- Таблицы получают горизонтальный скролл