Skip to content

Repository files navigation

Brigade — Staff Manager Portal (Frontend)

Web-портал (back-office) платформи Brigade — заміна AXLR8 для hospitality/event-staffing агентства. Портал відповідає за onboarding, scheduling, compliance, клієнтів та звітність (desktop-first). Детальний бриф — у docs/inbox/2026-07-08_brigade-brief.md.

Статус: проєкт ще не заскафолджено. Цей README фіксує узгоджену структуру папок/архітектуру до створення файлів, щоб розробка одразу йшла за єдиною конвенцією.

Технологічний стек

Категорія Вибір Причина
Build tool Vite швидкий dev-server, нативний ESM, оптимізована prod-збірка
UI-бібліотека React 18 + TypeScript типобезпека критична для CRM-домену (RBAC, compliance, audit)
Лінтер oxlint Rust-based, на порядки швидший за ESLint; підключається як pre-commit / CI gate
Стилі SCSS (CSS Modules) ізоляція стилів по компонентах + дизайн-токени через SCSS-змінні
Роутинг React Router стандарт для SPA з великою кількістю розділів (staff/scheduling/compliance/clients)
Стан (сервер + клієнт) Redux Toolkit + RTK Query RTK Query кешує/рефетчить дані з REST API (staff, shifts, bookings) замість ручних fetch/useEffect; звичайні RTK-слайси — для суто клієнтського стану (auth-сесія, RBAC-права, UI-флаги)
Форми React Hook Form + Zod форм-білдери онбордингу, валідація на клієнті
Форматування Prettier узгоджено з oxlint (lint — правила коду, prettier — форматування)

Остаточний вибір бібліотек стану/форм фіксується при скафолдингу — тут вони позначені як baseline-рекомендація.

Структура проєкту

staffmanager-frontend/
├── public/                        # статичні файли (favicon, robots.txt)
├── docs/                          # бриф, специфікації, копірайтинг (не код)
├── src/
│   ├── app/                       # ініціалізація застосунку
│   │   ├── providers/              # Theme/Auth/QueryClient/Router провайдери
│   │   ├── router/                 # опис маршрутів, guard-и (RBAC per route)
│   │   └── App.tsx
│   │
│   ├── pages/                      # route-level контейнери (1 сторінка = 1 маршрут)
│   │   ├── dashboard/
│   │   ├── staff/
│   │   ├── scheduling/
│   │   ├── compliance/
│   │   ├── clients/
│   │   ├── reports/
│   │   └── auth/
│   │
│   ├── widgets/                    # готові до вставки на сторінку композитні блоки
│   │   ├── AppSidebar/              # навігація + активна роль/RBAC-пункти меню
│   │   ├── StaffProfileCard/        # дані staff (entity) + compliance-бейдж (feature) + дії
│   │   └── ShiftCalendar/           # календар змін (scheduling) + drag-n-drop auto-assign
│   │
│   ├── features/                   # самодостатні бізнес-фічі
│   │   ├── staff-onboarding/
│   │   ├── shift-scheduling/
│   │   ├── auto-assign/
│   │   ├── compliance-tracking/
│   │   ├── notifications/
│   │   └── <feature-name>/
│   │       ├── components/
│   │       ├── hooks/
│   │       ├── api/                # RTK Query endpoints: injectEndpoints(baseApi)
│   │       ├── model/               # RTK-слайс, якщо фічі потрібен власний UI-стан
│   │       ├── types.ts
│   │       └── index.ts            # публічний API фічі (barrel export)
│   │
│   ├── entities/                   # доменні моделі: типи + мінімальна логіка
│   │   ├── staff/
│   │   ├── shift/
│   │   ├── client/
│   │   └── booking/
│   │
│   ├── layouts/                    # лейаути сторінок
│   │   ├── MainLayout/             # sidebar + header, для авторизованого Portal
│   │   ├── AuthLayout/             # login/forgot-password
│   │   └── EmptyLayout/
│   │
│   ├── components/                 # перевикористовувані "тупі" UI-компоненти (design system)
│   │   ├── Button/
│   │   ├── Input/
│   │   ├── Modal/
│   │   ├── Table/
│   │   ├── Badge/
│   │   └── <Component>/
│   │       ├── Component.tsx
│   │       ├── Component.module.scss
│   │       └── index.ts
│   │
│   ├── store/                      # configureStore, rootReducer, типізовані hooks
│   │   ├── slices/                  # клієнтські RTK-слайси (auth, ui)
│   │   ├── hooks.ts                 # useAppDispatch / useAppSelector
│   │   └── index.ts
│   ├── hooks/                      # спільні кастомні хуки (useDebounce, usePermissions...)
│   ├── api/                        # base RTK Query api-слайс (createApi, baseQuery, tagTypes)
│   ├── lib/                        # утиліти/хелпери (форматери дат, чисел, GDPR-маски)
│   ├── constants/                  # константи, enum-и (ролі, статуси compliance)
│   ├── types/                      # глобальні TS-типи, спільні для кількох фіч
│   ├── config/                     # env-конфіг, feature flags
│   ├── assets/
│   │   ├── icons/
│   │   ├── images/
│   │   └── fonts/
│   │
│   └── styles/                     # глобальні SCSS
│       ├── abstracts/
│       │   ├── _variables.scss     # кольори, spacing, typography — дизайн-токени
│       │   ├── _mixins.scss
│       │   ├── _functions.scss
│       │   └── _index.scss         # forward усіх abstracts (@use "abstracts" as *)
│       ├── base/
│       │   ├── _reset.scss
│       │   ├── _typography.scss
│       │   └── _index.scss
│       ├── themes/
│       │   ├── _light.scss
│       │   └── _dark.scss
│       └── main.scss                # єдина точка входу, підключається в main.tsx
│
├── .oxlintrc.json
├── .env.example
├── vite.config.ts
├── tsconfig.json
└── package.json

Принцип шарування (Feature-Sliced-подібний підхід)

app → pages → widgets → features → entities → shared (components/lib/hooks/api)

Шар справа не імпортує шар зліва (напр. entities нічого не знає про features). Це запобігає циклічним залежностям і дозволяє легко ізолювати/переносити фічі (важливо для full-ownership handover клієнту — код має читатись без контексту авторів).

widgets/ — навіщо окрема папка

widgets — це готові композитні блоки, які збирають докупи кілька entities/features/components, і потім просто вставляються на сторінку одним тегом. Різниця з сусідніми папками:

Папка Що там Приклад Чи знає про бізнес-логіку
components/ "тупий" UI, без даних і бізнес-правил Button, Badge, Table ні — тільки props
entities/ дані/тип домену + мінімальне відображення (напр. StaffAvatar) staff, shift, client тільки про "себе"
features/ одна дія користувача цілком (UI + API-запит + стан) compliance-tracking (перевірка/оновлення статусу) так, про одну дію
widgets/ збірка з кількох entities/features в один блок, що ставиться на сторінку без додаткової збірки StaffProfileCard = аватар staff (entity) + compliance-бейдж (feature) + кнопки "Edit"/"Deactivate" так, але сам нічого не робить — лише компонує
pages/ сторінка = layout + один або кілька widgets/features під конкретний route pages/staff/StaffListPage.tsx рендерить список StaffProfileCard ні — просто розкладає widgets по layout

Практичне правило: якщо блок використовується більш ніж на одній сторінці і складається з кількох дрібніших частин — це widgets. Якщо він логічно прив'язаний до одного місця (наприклад, форма фільтрів тільки на сторінці Scheduling) — це просто локальний компонент усередині pages/scheduling/, окрема папка не потрібна. Якщо для конкретного проєкту такий поділ здається зайвим ускладненням — шар можна прибрати і класти складені блоки прямо в pages/<page>/components/.

Конвенції

  • КомпонентиPascalCase, папка = компонент (Button/Button.tsx, Button/Button.module.scss, Button/index.ts).
  • Хуки/утиліти/файли-не-компонентиcamelCase (useAuth.ts, formatDate.ts).
  • Стилі — CSS Modules (*.module.scss) для локальних стилів компонента; BEM-подібні класи всередині модуля (.card, .card__title, .card--active) для читабельності DOM у devtools.
  • Дизайн-токени — тільки через SCSS-змінні з styles/abstracts/_variables.scss (кольори, spacing, radius, шрифти). Хардкод hex/px у компонентних стилях — заборонений лінтом/рев'ю.
  • Аліаси шляхів@/*src/* (налаштовується у vite.config.ts + tsconfig.json), щоб уникнути ../../../../.
  • Публічний API фічі — імпорт ззовні тільки через features/<feature>/index.ts, а не напряму у внутрішні файли.
  • Тести — колокейтяться поруч із кодом (Component.test.tsx), без окремого __tests__/ дерева.

Деплой (GitHub Pages)

Workflow .github/workflows/deploy-pages.yml білдить і публікує проєкт на GitHub Pages при пуші в main.

  • Base-шлях (/<repo-name>/) підставляється автоматично з назви репозиторію — окремо налаштовувати не треба.
  • Після білду index.html копіюється в 404.html (SPA fallback), бо GitHub Pages не вміє в server-side rewrite, а без цього оновлення сторінки на будь-якому маршруті, крім /, дає 404 (React Router working on BrowserRouter).
  • Перед першим деплоєм: у налаштуваннях репозиторію → Settings → Pages → Source вибрати GitHub Actions.
  • Використовується лише для прев'ю/демо — production-хостинг для клієнта визначається окремо.

Наступні кроки

  1. npm create vite@latest . -- --template react-ts
  2. Підключити sass, oxlint, prettier, @reduxjs/toolkit + react-redux, налаштувати @/* alias
  3. Створити базовий styles/ (reset + токени) і layouts/MainLayout
  4. Завести перші фічі відповідно до модулів SoW: onboarding, scheduling, compliance

About

Brigade — Staff Manager Portal (frontend)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages