Оптимизирована производительность 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:
@ -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 атрибуты для доступности
|
||||
- ✅ Реализовано автоскрытие полосы прокрутки и навигация клавиатурой
|
||||
|
Reference in New Issue
Block a user