Update .gitignore to include local environment files and expand README with project details, tech stack, documentation links, and project status.
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
# Frontend
|
||||
|
||||
SPA на **React 19 + Vite + TypeScript**. Общается с бэком по REST (JWT Bearer) и получает
|
||||
живые обновления по SignalR. Типы API генерируются из OpenAPI-схемы бэкенда.
|
||||
|
||||
> **Раздача из единого контейнера.** В проде собранный фронт (`dist/`) кладётся в `wwwroot`
|
||||
> ASP.NET Core и раздаётся тем же приложением (SPA-fallback на `index.html`). Фронт и бек — один
|
||||
> origin, база API — относительный `/api`, SignalR — `/hubs/panel`. В dev Vite-сервер проксирует
|
||||
> `/api` и `/hubs` на бэкенд. Детали упаковки — [architecture.md](architecture.md#развёртывание-единый-контейнер-приложения).
|
||||
|
||||
## Стек
|
||||
|
||||
| Задача | Выбор |
|
||||
| ----------------- | --------------------------------------- |
|
||||
| Сборка/dev | Vite |
|
||||
| Язык | TypeScript (strict) |
|
||||
| Данные с сервера | TanStack Query |
|
||||
| Роутинг | TanStack Router (типобезопасный) |
|
||||
| UI-компоненты | shadcn/ui + Tailwind CSS v4 |
|
||||
| Иконки | lucide-react |
|
||||
| Клиентский стейт | Zustand (auth, тема) |
|
||||
| Формы | react-hook-form + zod |
|
||||
| Realtime | @microsoft/signalr |
|
||||
| Графики | Recharts |
|
||||
| QR-коды | qrcode.react |
|
||||
| Типы API | openapi-typescript / orval (codegen) |
|
||||
| i18n | react-i18next (RU + EN) |
|
||||
| Пакетный менеджер | pnpm |
|
||||
|
||||
## Структура
|
||||
|
||||
```
|
||||
frontend/
|
||||
src/
|
||||
app/ # провайдеры (Query, Router, Auth, Theme), корневой layout
|
||||
routes/ # маршруты TanStack Router (login, dashboard, configs, admin/*)
|
||||
features/
|
||||
auth/ # формы, хуки useLogin/useRegister, стор авторизации
|
||||
configs/ # список/создание/детали конфигов, QR, ссылка-подписка
|
||||
nodes/ # (admin) управление нодами
|
||||
admin/ # пользователи, статистика
|
||||
shared/
|
||||
api/ # http-клиент (fetch + JWT/refresh), сгенерированные типы, query-хуки
|
||||
realtime/ # инициализация SignalR, подписки → инвалидация Query-кэша
|
||||
ui/ # обёртки над shadcn/ui, общие компоненты
|
||||
lib/ # утилиты, форматирование (байты, даты)
|
||||
config/ # env, константы
|
||||
styles/ # tailwind, темы
|
||||
index.html
|
||||
vite.config.ts
|
||||
package.json
|
||||
```
|
||||
|
||||
## Дизайн / UX
|
||||
|
||||
- **Тема оформления**: светлая и тёмная (переключатель в шапке; вариант «системная»). Реализация —
|
||||
Tailwind `dark` (класс на `html`) + shadcn/ui; выбор сохраняется (localStorage).
|
||||
- **Современный и чистый вид**: shadcn/ui + Tailwind, адаптивность, аккуратная типографика.
|
||||
- **Дашборд пользователя**: карточки конфигов (протокол, локация, трафик прогресс-баром, срок, статус),
|
||||
быстрые действия (копировать ссылку, показать QR, перевыпустить, отозвать) + карточка «Общая подписка»
|
||||
(агрегированная ссылка/QR со всеми конфигами). Для неактивированного — экран «запросить активацию».
|
||||
- **Создание конфига**: выбор локации/inbound (по `DisplayName`) + метка + лимит устройств →
|
||||
мгновенная выдача ссылки + QR + краткие инструкции по подключению (iOS/Android/Windows).
|
||||
- **Редактирование конфига**: изменить метку и лимит устройств.
|
||||
- **Настройки аккаунта**: смена пароля, привязка/отвязка Telegram, **удаление аккаунта** (с подтверждением).
|
||||
- **Админка**: таблицы (TanStack Table) с пагинацией/фильтрами для нод, пользователей, конфигов, ролей,
|
||||
журнала аудита; очередь запросов активации; графики трафика (Recharts). Блокировка пользователя — с
|
||||
подтверждением (гасит VPN).
|
||||
- **Состояния**: скелетоны при загрузке, аккуратные пустые состояния и toasts на ошибки/успех.
|
||||
|
||||
## Работа с API
|
||||
|
||||
- HTTP-клиент оборачивает `fetch`: подставляет access-token, при 401 — прозрачно обновляет через
|
||||
refresh-cookie и повторяет запрос; при неуспехе — разлогин.
|
||||
- Все запросы/мутации — через TanStack Query (ключи по фичам, инвалидация после мутаций).
|
||||
- Типы ответов/запросов — из codegen по OpenAPI (никакого ручного дублирования DTO).
|
||||
|
||||
## Авторизация на клиенте
|
||||
|
||||
- **Access-token** — в памяти (не в localStorage), кладётся в `Authorization: Bearer`.
|
||||
- **Refresh-token** — httpOnly Secure cookie (JS не читает), ротация на сервере.
|
||||
- Стор авторизации (Zustand) хранит профиль/роли/`isActivated`; guard-маршруты по роли (`admin` vs обычный)
|
||||
и по активации (неактивированного ведём на экран «запросить активацию»).
|
||||
|
||||
- **Вход — по username** (email не используется). «Забыли пароль?» ведёт: при привязанном
|
||||
Telegram — восстановление через бота; иначе — подсказка обратиться к админу.
|
||||
- **Баннер привязки Telegram**: пока Telegram не привязан, показываем настойчивый, но не блокирующий
|
||||
баннер/напоминание — это единственный self-service способ восстановить доступ. Настройки: смена пароля.
|
||||
|
||||
### Вход и привязка через Telegram
|
||||
- **«Войти через Telegram»**: `POST /api/auth/telegram/login-request` → показать deep-link/QR на
|
||||
бота, затем ждать подтверждения (поллинг `GET …/login-request/{id}` или событие SignalR). При
|
||||
`Approved` — сохранить access, refresh уже в cookie, редирект в панель.
|
||||
- **«Привязать Telegram»** (в настройках, для вошедшего): `POST /api/auth/telegram/link-token` →
|
||||
показать deep-link/QR; статус привязки обновить по факту (поллинг/SignalR). Отвязка — `unlink`.
|
||||
- QR для deep-link — `qrcode.react`.
|
||||
|
||||
## Realtime
|
||||
|
||||
- Одно SignalR-подключение к `/hubs/panel` с JWT; реконнект с бэкоффом.
|
||||
- Обработчики событий (`configTrafficUpdated`, `configStatusChanged`, `nodeStatusChanged`) точечно
|
||||
обновляют/инвалидируют кэш TanStack Query — UI обновляется без перезагрузки.
|
||||
|
||||
## Скрипты (ожидаемые)
|
||||
|
||||
```bash
|
||||
pnpm dev # dev-сервер Vite
|
||||
pnpm build # прод-сборка
|
||||
pnpm preview # предпросмотр сборки
|
||||
pnpm lint # ESLint
|
||||
pnpm typecheck # tsc --noEmit
|
||||
pnpm gen:api # генерация типов из OpenAPI-схемы бэкенда
|
||||
```
|
||||
Reference in New Issue
Block a user