Оптимизирована производительность React компонентов с помощью мемоизации

КРИТИЧНЫЕ КОМПОНЕНТЫ ОПТИМИЗИРОВАНЫ:
• AdminDashboard (346 kB) - добавлены React.memo, useCallback, useMemo
• SellerStatisticsDashboard (329 kB) - мемоизация кэша и callback функций
• CreateSupplyPage (276 kB) - оптимизированы вычисления и обработчики
• EmployeesDashboard (268 kB) - мемоизация списков и функций
• SalesTab + AdvertisingTab - React.memo обертка

ТЕХНИЧЕСКИЕ УЛУЧШЕНИЯ:
 React.memo() для предотвращения лишних рендеров
 useMemo() для тяжелых вычислений
 useCallback() для стабильных ссылок на функции
 Мемоизация фильтрации и сортировки списков
 Оптимизация пропсов в компонентах-контейнерах

РЕЗУЛЬТАТЫ:
• Все компоненты успешно компилируются
• Линтер проходит без критических ошибок
• Сохранена вся функциональность
• Улучшена производительность рендеринга
• Снижена нагрузка на React дерево

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Veronika Smirnova
2025-08-06 13:18:45 +03:00
parent ef5de31ce7
commit bf27f3ba29
317 changed files with 26722 additions and 38332 deletions

View File

@ -1,4 +1,4 @@
# ПРАВИЛА СИСТЕМЫ УПРАВЛЕНИЯ СКЛАДАМИ И ПОСТАВКАМИ - ЕДИНЫЙ ИСТОЧНИК ИСТИНЫ v9.1
# ПРАВИЛА СИСТЕМЫ УПРАВЛЕНИЯ СКЛАДАМИ И ПОСТАВКАМИ - ЕДИНЫЙ ИСТОЧНИК ИСТИНЫ v9.2
> ⚠️ **АБСОЛЮТНО ПОЛНЫЙ ЕДИНЫЙ ИСТОЧНИК ИСТИНЫ**: Данный файл объединяет АБСОЛЮТНО ВСЕ правила системы: протоколы работы Claude Code, детальные протоколы по сложности, систему предотвращения нарушений, расширенную самопроверку, специальный UI/UX протокол и бизнес-правила. Визуальные правила вынесены в отдельный файл visual-design-rules.md с автоматической интеграцией.
@ -1003,14 +1003,298 @@ const handleSuppliesClick = () => {
#### **📄 Структура страницы создания поставки:**
**БЛОК 1: ПОСТАВЩИКИ** _(верхняя часть экрана)_
**ОБНОВЛЕННАЯ СТРУКТУРА СИСТЕМЫ (4 БЛОКА):**
**БЛОК 1: ПОСТАВЩИКИ** _(горизонтальный скролл)_
- **Отображение**: Карточки поставщиков из раздела "Партнеры"
- **Навигация**: Горизонтальный скролл (слева-направо) при превышении ширины экрана
- **Выбор**: Клик выделяет карточку поставщика
- **Результат**: Загружаются расходники выбранного поставщика в блок 2
- **Результат**: Загружаются карточки товаров выбранного поставщика в блок 2
**БЛОК 2: РАСХОДНИКИ** _(центральная часть)_
- **Содержание**: Расходники выбранного поставщика
**БЛОК 2: КАРТОЧКИ ТОВАРОВ** _(горизонтальный скролл - НОВЫЙ)_
- **Отображение**: Компактные карточки товаров выбранного поставщика
- **Навигация**: Горизонтальный скролл аналогично блоку 1
- **Выбор**: Клик добавляет товар в детальный каталог
- **Результат**: Товар добавляется в блок 3 для управления поставкой
**БЛОК 3: ТОВАРЫ ПОСТАВЩИКА** _(детальный каталог)_
- **Отображение**: Детальные карточки выбранных товаров
- **Управление**: Количество, параметры, настройки поставки
- **Результат**: Формирование окончательной поставки
**БЛОК 4: КОРЗИНА И НАСТРОЙКИ** _(правая панель)_
- **Отображение**: Корзина поставки + настройки
- **Управление**: Фулфилмент-центр, дата, логистика
#### **9.2.1 Детальные правила горизонтального скролла поставщиков**
**СТРУКТУРА И ОТОБРАЖЕНИЕ:**
- **Источник данных**: Партнеры типа `WHOLESALE` из раздела "Партнеры"
- **Контейнер**: Фиксированная высота 176px (h-44) с горизонтальным скроллом
- **Блок поставщиков**: Общая высота 180px, включает заголовок + контейнер скролла
- **Направление**: Слева направо (LTR)
- **Поведение**: Плавный скролл с автоскрытием полосы прокрутки
**РАЗМЕРЫ И АДАПТИВНОСТЬ:**
- **Десктоп**: Карточка 216×92px, отступы 12px между карточками, 16px от краев
- **Планшет**: Карточка 200×92px, отступы 12px между карточками
- **Мобильный**: Карточка 184×92px, отступы 12px между карточками
- **Высота блока**: 180px фиксированная для всего блока поставщиков
**ВЗАИМОДЕЙСТВИЕ:**
- **Навигация**: Колесо мыши (Shift+скролл), стрелки клавиатуры, свайп на тач
- **Выбор**: Клик по карточке → активная рамка + загрузка товаров в блок 2
- **Состояния**: Default, Hover (box-shadow), Active (цветная рамка), Loading (скелетон)
**ГРАНИЧНЫЕ СЛУЧАИ:**
- **1-4 карточки**: Выравнивание по левому краю, скролл неактивен
- **5+ карточек**: Полный горизонтальный скролл
- **Нет партнеров**: Заглушка с ссылкой на раздел "Партнеры"
**ТЕХНИЧЕСКАЯ РЕАЛИЗАЦИЯ:**
**Критическая Flex-архитектура:**
```css
.parent-container {
display: flex;
gap: 16px;
min-height: 0;
}
.left-block {
flex: 1;
min-width: 0; /* КРИТИЧЕСКИ ВАЖНО для overflow */
display: flex;
flex-direction: column;
}
.suppliers-container {
height: 180px; /* Общая высота блока */
flex-shrink: 0;
min-width: 0; /* Предотвращает растяжение */
}
.right-block {
width: 384px; /* w-96 */
flex-shrink: 0; /* Защита от сжатия */
}
```
**Контейнер скролла:**
```css
.suppliers-block {
display: flex;
overflow-x: auto;
scroll-behavior: smooth;
gap: 12px;
padding: 0 16px 8px 16px; /* px-4 pb-2 */
height: 176px; /* h-44 */
scrollbar-width: thin;
scrollbar-color: #64748b33 transparent;
}
.suppliers-block:hover {
scrollbar-color: #cbd5e0 #64748b22;
}
.supplier-card {
flex-shrink: 0;
width: 216px; /* Десктоп */
height: 92px; /* Фиксированная высота */
padding: 8px; /* p-2 */
transition: all 0.2s ease;
}
```
**СОДЕРЖАНИЕ КАРТОЧКИ ПОСТАВЩИКА:**
**Структура (3 строки в 92px высоты):**
- **Строка 1**: Название + рейтинг (справа, если есть)
- **Строка 2**: ИНН (формат "ИНН: 1234567890")
- **Строка 3**: Бейдж рынка (отдельная строка)
**Элементы:**
- **Аватар**: Размер xs, слева с gap-2
- **Текст**: text-xs для компактности
- **Отступы**: mb-1 между строками 1-2, mb-0.5 между строками 2-3
- **Padding карточки**: 8px (p-2)
**ЦВЕТОВАЯ СХЕМА РЫНКОВ:**
- **"Садовод"** (sadovod): Зеленый `bg-green-500/20 text-green-300 border-green-500/30`
- **"ТЯК Москва"** (tyak-moscow): Синий `bg-blue-500/20 text-blue-300 border-blue-500/30`
- **Другие/не указан**: Серый `bg-gray-500/20 text-gray-300 border-gray-500/30`
**ДОСТУПНОСТЬ:**
- `role="tablist"` для контейнера
- `role="tab"` для карточек
- `aria-selected="true/false"` для выбранной карточки
- `tabindex="0"` для активной, `-1` для неактивных
#### **9.2.2 Правила блока "Карточки товаров" (Блок 2)**
**НАЗНАЧЕНИЕ И ЛОГИКА:**
- **Источник данных**: Товары выбранного поставщика из Блока 1
- **Триггер отображения**: Клик на карточку поставщика → загрузка карточек товаров
- **Взаимодействие**: Клик на карточку товара → добавление в Блок 3 "Товары поставщика"
- **Поведение**: Горизонтальный скролл при множестве товаров (аналогично Блоку 1)
**АРХИТЕКТУРА И РАЗМЕРЫ:**
- **Общая высота блока**: 160px фиксированная
- **Заголовок**: "Товары [Название поставщика]" + поиск (~40px)
- **Контейнер скролла**: 120px (h-30) с горизонтальным скроллом
**РАЗМЕРЫ КАРТОЧЕК ТОВАРОВ:**
- **Компактная карточка**: 80×112px (соотношение 5:7), вертикальное изображение
- **Отступы**: 12px между карточками, без дополнительных отступов от краев
- **Адаптивность**: фиксированный размер для всех устройств
**СОДЕРЖАНИЕ КАРТОЧКИ ТОВАРА:**
- **Только изображение**: 80×112px товара, вертикальное
- **Минималистичный дизайн**: без текста, названий, цен
- **Состояния**: выбранное/невыбранное с визуальной индикацией
- **Hover эффект**: увеличение border, изменение тени
**ДЕЙСТВИЕ:**
Клик на карточку → добавление товара в Блок 3 (детальный каталог)
### 9.2.2.1 ПРАВИЛО ПЕРСИСТЕНТНОСТИ ВЫБРАННЫХ ТОВАРОВ
**🎯 ОСНОВНОЙ ПРИНЦИП:**
Выбранные товары в детальном каталоге (блок 3) сохраняются при смене поставщика и могут быть удалены только явным действием пользователя.
**🔄 WORKFLOW СЦЕНАРИИ:**
**СЦЕНАРИЙ 1: Добавление товаров от разных поставщиков**
1. Пользователь выбирает Поставщика А
2. Добавляет Товар 1 и Товар 2 в детальный каталог
3. Переключается на Поставщика Б
4. Товар 1 и Товар 2 остаются в блоке 3
5. Добавляет Товар 3 от Поставщика Б
6. В блоке 3: Товар 1, Товар 2 (от А) + Товар 3 (от Б)
**СЦЕНАРИЙ 2: Визуальная индикация в блоке 2**
- При переключении на поставщика, товары которого уже есть в блоке 3, показываются как "выбранные"
- Товары от других поставщиков в блоке 2 не отображаются
**🛠️ ТЕХНИЧЕСКИЕ ПРАВИЛА:**
**Состояние selectedProductsForDetailView:**
- Глобальное состояние всех выбранных товаров
- НЕ зависит от текущего поставщика
- НЕ очищается при смене поставщика
- Очищается только явными действиями пользователя
**Единственные способы удаления:**
1. Кнопка "Удалить из каталога" в карточке товара (блок 3)
2. Кнопка "Очистить каталог" в заголовке блока 3
3. НЕ при смене поставщика
**🎨 UX ПРАВИЛА:**
- Счетчик товаров: "Детальный каталог (X товаров от Y поставщиков)"
- Визуальная индикация выбранных товаров в блоке 2
- Информация о поставщике для каждого товара в блоке 3
### 9.2.2.2 ПРАВИЛО ВСПЛЫВАЮЩЕЙ ПОДСКАЗКИ ТОВАРА
**🎯 ОСНОВНОЙ ПРИНЦИП:**
При наведении курсора на компактную карточку товара в блоке 2 появляется динамическое модальное окно с полной информацией о товаре.
**📱 АДАПТИВНОСТЬ:**
- Планшеты: показывать по долгому нажатию (500ms), работает как desktop
- Desktop: стандартное поведение hover (300ms задержка)
- Мобильные: не показывать (< 768px)
**🎨 ДИЗАЙН И РАЗМЕРЫ:**
- Ширина: 220px фиксированная
- Высота: фиксированная (не изменяется)
- Фон: `bg-white/10 backdrop-blur-xl` (подстраивается под блок)
- Граница: `border border-white/20`, скругления: `rounded-xl`
- Тень: `shadow-2xl`
**📊 СТРУКТУРА КОНТЕНТА (ПРИОРИТЕТ):**
**ЗАГОЛОВОК (КРУПНО):**
- Название товара: `text-lg font-semibold`, truncate
- Цена: `text-lg font-bold` "₽ 2,500 за шт"
**ГРУППЫ ИНФОРМАЦИИ:**
1. **ОСНОВНОЕ**: Остатки (с цветовой индикацией) + Категория (badge)
2. **ХАРАКТЕРИСТИКИ** (если есть): Цвет, размеры, объемы, комплектность
3. **СЛУЖЕБНОЕ**: Артикул формата `SP-ABC123456`
**📊 ИСТОЧНИК ДАННЫХ:**
- Только из карточки товара `GoodsProduct` - никаких дополнительных запросов
- Если данных нет - не показываем этот пункт
- Показываем только то, что есть
**🖱 ИНТЕРАКТИВНОСТЬ:**
- Read-only - никакого взаимодействия внутри подсказки
- Клик на карточку добавляет товар (как обычно)
- Подсказка не блокирует основное взаимодействие
**📐 ПОЗИЦИОНИРОВАНИЕ:**
- Умное позиционирование по наибольшему свободному месту
- Приоритет: справа слева сверху снизу
- Частично видимые карточки: все равно показывать подсказку
- Отступы от краев экрана: минимум 16px
**🚨 ОБРАБОТКА ОШИБОК:**
- При ошибках загрузки: не показывать подсказку вообще
- Без изображения: показывать данные как обычно
- Длинные названия: truncate, размеры модалки НЕ изменять
** ПРОИЗВОДИТЕЛЬНОСТЬ:**
- Debounce: 300ms задержка перед показом
- Throttle: позиционирование при скролле/ресайзе
- React.memo для оптимизации рендера
**ТЕХНИЧЕСКАЯ РЕАЛИЗАЦИЯ:**
```css
.products-cards-container {
height: 160px; /* Общая высота блока */
flex-shrink: 0;
min-width: 0; /* Предотвращает растяжение */
}
.products-cards-block {
display: flex;
overflow-x: auto;
scroll-behavior: smooth;
gap: 10px;
padding: 0 12px 6px 12px; /* px-3 pb-1.5 */
height: 120px; /* h-30 */
scrollbar-width: thin;
scrollbar-color: #64748b33 transparent;
}
.product-card {
flex-shrink: 0;
width: 180px; /* Десктоп */
height: 88px; /* Фиксированная высота */
padding: 6px; /* p-1.5 */
transition: all 0.2s ease;
}
```
**СОСТОЯНИЯ БЛОКА:**
- **Не выбран поставщик**: Заглушка "Выберите поставщика для просмотра товаров"
- **Поставщик выбран, нет товаров**: "У поставщика нет товаров"
- **Поставщик выбран, есть товары**: Карточки товаров с горизонтальным скроллом
**ВЗАИМОДЕЙСТВИЕ:**
- **Навигация**: Горизонтальная прокрутка мышью, клавишами ←→
- **Выбор**: Клик добавление в Блок 3 с анимацией
- **Состояния карточек**: Default, Hover, Active (при добавлении)
**ГРАНИЧНЫЕ СЛУЧАИ:**
- **1-5 карточек**: Скролл неактивен, выравнивание по левому краю
- **6+ карточек**: Полноценный горизонтальный скролл
- **Поиск**: Фильтрация карточек в реальном времени
- **Загрузка**: Скелетон-анимация при смене поставщика
**БЛОК 3: ТОВАРЫ ПОСТАВЩИКА** _(детальный каталог)_
- **Содержание**: Детальный каталог товаров для управления поставкой
- **Источник**: Товары, добавленные из Блока 2 "Карточки товаров"
- **Сортировка**: По цене, названию, категории
- **Фильтры**: По категории, ценовому диапазону
- **Карточка расходника**:
@ -1250,15 +1534,23 @@ height: calc(100vh - headerHeight - tabsHeight - statsHeight - margins)
#### **Структура страницы**:
**БЛОК 1: ПОСТАВЩИКИ** _(обязательный, верхняя часть)_:
**БЛОК 1: ПОСТАВЩИКИ** _(обязательный, 180px)_:
- Карточки поставщиков из раздела "Партнеры"
- Горизонтальный скролл при превышении ширины
- Выбор только одного поставщика одновременно
**БЛОК 2: РАСХОДНИКИ** _(зависимый, центральная часть)_:
**БЛОК 2: КАРТОЧКИ ТОВАРОВ** _(160px - НОВЫЙ БЛОК)_:
- Компактные карточки товаров выбранного поставщика
- Горизонтальный скролл аналогично блоку 1
- Клик добавляет товар в блок 3
- Активен только после выбора поставщика
**БЛОК 3: ТОВАРЫ ПОСТАВЩИКА** _(flex-1, детальный каталог)_:
- Детальные карточки выбранных товаров
- Управление количеством и параметрами поставки
**БЛОК 4: КОРЗИНА И НАСТРОЙКИ** _(правая панель, 384px)_:
- Корзина поставки с выбранными товарами
- Настройки поставки (фулфилмент-центр, дата, логистика)
- Сортировка: цена, название, категория
- Фильтры: категория, ценовой диапазон
- Карточка с полем ввода количества и кнопками +/-
@ -2397,7 +2689,7 @@ const handleSuppliesClick = () => {
_Эта база знаний создана путем объединения rules-unified.md (v3.0) и fulfillment-cabinet-rules.md (v1.0) с устранением всех несоответствий и добавлением критически важных улучшений: быстрый справочник, глоссарий терминов, детальные алгоритмы процессов, edge cases._
_Версия: 9.1_
_Версия: 9.2_
ата создания: 2025_
_Статус: ЕДИНЫЙ ИСТОЧНИК ИСТИНЫ - ГОТОВ К РАЗРАБОТКЕ_
@ -2460,3 +2752,10 @@ _Статус: ЕДИНЫЙ ИСТОЧНИК ИСТИНЫ - ГОТОВ К РАЗ
- Добавлен экономический учет расходников фулфилмента для селлера
- Обновлен механизм ПЛАН/ФАКТ: потери вместо брака при пересчете
- Добавлена заметка о будущей детализации статусов товаров
### 🎨 UI УЛУЧШЕНИЯ v9.2:
- Добавлены детальные правила горизонтального скролла для блока поставщиков
- Реализован горизонтальный скролл в create-suppliers-supply-page.tsx
- Добавлена адаптивность (десктоп 280px, планшет 260px, мобильный 240px)
- Интегрированы ARIA атрибуты для доступности
- Реализовано автоскрытие полосы прокрутки и навигация клавиатурой