Обновление системной документации и UI Kit админ панели
- Обновлен CLAUDE.md с добавлением принципов качества кода - Расширен interaction-integrity-rules.md новыми правилами взаимодействия - Дополнен rules-complete.md техническими требованиями - Добавлен демо-компонент вариантов кнопки "Назад" в UI Kit - Обновлены компоненты админ панели и страницы создания расходников - Уточнены visual-design-rules.md для компонента BackButton - Исправлены ESLint ошибки и предупреждения 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
24
CLAUDE.md
24
CLAUDE.md
@ -99,6 +99,30 @@ npm run dev
|
||||
|
||||
> ⚠️ **ВАЖНО**: Всегда выполнять эти команды перед завершением задачи!
|
||||
|
||||
## 🔄 КОМАНДЫ ОТКАТА
|
||||
|
||||
### Откат через комментарии:
|
||||
|
||||
**Основная команда:**
|
||||
|
||||
```
|
||||
"откати [описание] через комментарии"
|
||||
```
|
||||
|
||||
**Примеры:**
|
||||
|
||||
- `"откати центрирование поиска через комментарии"`
|
||||
- `"откати изменения кнопки через комментарии"`
|
||||
- `"откати новую логику через комментарии"`
|
||||
|
||||
**Дополнительные команды:**
|
||||
|
||||
- `"очисти комментарии"` - удалить закомментированные варианты
|
||||
- `"переключи на вариант 2"` - активировать закомментированный код
|
||||
- `"покажи варианты"` - показать доступные варианты
|
||||
|
||||
> 📖 **Подробнее**: см. раздел 6.4 в `interaction-integrity-rules.md`
|
||||
|
||||
## 💾 РАБОТА С КОНТЕКСТОМ
|
||||
|
||||
### Файлы для сохранения контекста:
|
||||
|
263
back-button-variants.html
Normal file
263
back-button-variants.html
Normal file
@ -0,0 +1,263 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Варианты кнопки "Назад"</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<style>
|
||||
body {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
min-height: 100vh;
|
||||
}
|
||||
.glass {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
backdrop-filter: blur(16px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
.sidebar-mock {
|
||||
width: 240px;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
backdrop-filter: blur(20px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.block-mock {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
backdrop-filter: blur(16px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
border-radius: 16px;
|
||||
height: 180px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="p-8 text-white">
|
||||
<h1 class="text-3xl font-bold mb-8 text-center">Варианты размещения кнопки "Назад"</h1>
|
||||
|
||||
<!-- ВАРИАНТ 1: ПЛАВАЮЩАЯ КНОПКА СЛЕВА -->
|
||||
<div class="mb-12">
|
||||
<h2 class="text-xl font-semibold mb-4">🌟 Вариант 1: Плавающая кнопка слева</h2>
|
||||
<div class="flex gap-4 h-48">
|
||||
<!-- Sidebar Mock -->
|
||||
<div class="sidebar-mock rounded-2xl p-4 flex flex-col">
|
||||
<div class="flex items-center gap-3 mb-6">
|
||||
<div class="w-8 h-8 bg-purple-500 rounded-full"></div>
|
||||
<span class="text-sm">Rennel</span>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<div class="text-sm opacity-60">Главная</div>
|
||||
<div class="text-sm opacity-60">Маркет</div>
|
||||
<div class="text-sm opacity-60">Мессенджер</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Floating Back Button -->
|
||||
<div class="relative">
|
||||
<button class="absolute left-0 top-6 z-10 w-8 h-8 glass rounded-full flex items-center justify-center transition-all duration-300 hover:scale-110 hover:bg-white/20 group">
|
||||
<svg class="h-4 w-4 text-white/70 group-hover:text-white group-hover:h-5 group-hover:w-5 transition-all" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Block 1 Mock -->
|
||||
<div class="flex-1 block-mock p-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-3">
|
||||
<svg class="h-5 w-5 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"></path>
|
||||
</svg>
|
||||
<h2 class="text-lg font-semibold">Поставщики</h2>
|
||||
</div>
|
||||
<div class="w-64 glass rounded-full px-3 py-1.5 text-sm">
|
||||
<span class="text-white/60">Поиск поставщиков...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ВАРИАНТ 2: ПОЛОСА НАВИГАЦИИ СВЕРХУ -->
|
||||
<div class="mb-12">
|
||||
<h2 class="text-xl font-semibold mb-4">📍 Вариант 2: Полоса навигации сверху</h2>
|
||||
<div class="flex gap-4">
|
||||
<!-- Sidebar Mock -->
|
||||
<div class="sidebar-mock rounded-2xl p-4 flex flex-col h-48">
|
||||
<div class="flex items-center gap-3 mb-6">
|
||||
<div class="w-8 h-8 bg-purple-500 rounded-full"></div>
|
||||
<span class="text-sm">Rennel</span>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<div class="text-sm opacity-60">Главная</div>
|
||||
<div class="text-sm opacity-60">Маркет</div>
|
||||
<div class="text-sm opacity-60">Мессенджер</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Content Area -->
|
||||
<div class="flex-1">
|
||||
<!-- Navigation Bar -->
|
||||
<div class="flex items-center justify-start mb-4">
|
||||
<button class="w-6 h-6 hover:w-8 hover:h-8 bg-gradient-to-r from-purple-500/20 to-blue-500/20 hover:from-purple-500/40 hover:to-blue-500/40 rounded-full flex items-center justify-center transition-all duration-300 backdrop-blur-sm border border-white/10 hover:border-white/30 group">
|
||||
<svg class="h-3 w-3 group-hover:h-4 group-hover:w-4 text-white/60 group-hover:text-white transition-all" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Block 1 Mock -->
|
||||
<div class="block-mock p-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-3">
|
||||
<svg class="h-5 w-5 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"></path>
|
||||
</svg>
|
||||
<h2 class="text-lg font-semibold">Поставщики</h2>
|
||||
</div>
|
||||
<div class="w-64 glass rounded-full px-3 py-1.5 text-sm">
|
||||
<span class="text-white/60">Поиск поставщиков...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ВАРИАНТ 3: КНОПКА В РАЗРЫВЕ -->
|
||||
<div class="mb-12">
|
||||
<h2 class="text-xl font-semibold mb-4">🎯 Вариант 3: Кнопка в разрыве</h2>
|
||||
<div class="flex gap-4 h-48 relative">
|
||||
<!-- Sidebar Mock -->
|
||||
<div class="sidebar-mock rounded-2xl p-4 flex flex-col">
|
||||
<div class="flex items-center gap-3 mb-6">
|
||||
<div class="w-8 h-8 bg-purple-500 rounded-full"></div>
|
||||
<span class="text-sm">Rennel</span>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<div class="text-sm opacity-60">Главная</div>
|
||||
<div class="text-sm opacity-60">Маркет</div>
|
||||
<div class="text-sm opacity-60">Мессенджер</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Button in Gap -->
|
||||
<div class="w-0 flex items-center justify-center relative">
|
||||
<button class="absolute w-10 h-10 glass rounded-xl hover:bg-white/15 flex items-center justify-center transition-all duration-500 hover:scale-125 hover:rotate-12 hover:border-purple-400/50 group backdrop-blur-md">
|
||||
<svg class="h-4 w-4 text-white/50 group-hover:text-purple-300 transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Block 1 Mock -->
|
||||
<div class="flex-1 block-mock p-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-3">
|
||||
<svg class="h-5 w-5 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"></path>
|
||||
</svg>
|
||||
<h2 class="text-lg font-semibold">Поставщики</h2>
|
||||
</div>
|
||||
<div class="w-64 glass rounded-full px-3 py-1.5 text-sm">
|
||||
<span class="text-white/60">Поиск поставщиков...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ВАРИАНТ 4: BREADCRUMB СТИЛЬ -->
|
||||
<div class="mb-12">
|
||||
<h2 class="text-xl font-semibold mb-4">🍞 Вариант 4: Breadcrumb стиль</h2>
|
||||
<div class="flex gap-4">
|
||||
<!-- Sidebar Mock -->
|
||||
<div class="sidebar-mock rounded-2xl p-4 flex flex-col h-48">
|
||||
<div class="flex items-center gap-3 mb-6">
|
||||
<div class="w-8 h-8 bg-purple-500 rounded-full"></div>
|
||||
<span class="text-sm">Rennel</span>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<div class="text-sm opacity-60">Главная</div>
|
||||
<div class="text-sm opacity-60">Маркет</div>
|
||||
<div class="text-sm opacity-60">Мессенджер</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Content Area -->
|
||||
<div class="flex-1">
|
||||
<!-- Breadcrumb -->
|
||||
<div class="flex items-center gap-2 mb-2 pl-2">
|
||||
<button class="p-1 hover:p-2 bg-white/0 hover:bg-white/10 rounded-lg transition-all duration-300 group">
|
||||
<svg class="h-3 w-3 group-hover:h-4 group-hover:w-4 text-white/40 group-hover:text-white transition-all" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<span class="text-white/20 text-sm">•</span>
|
||||
<span class="text-white/60 text-sm">Поставщики</span>
|
||||
</div>
|
||||
|
||||
<!-- Block 1 Mock -->
|
||||
<div class="block-mock p-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-3">
|
||||
<svg class="h-5 w-5 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"></path>
|
||||
</svg>
|
||||
<h2 class="text-lg font-semibold">Поставщики</h2>
|
||||
</div>
|
||||
<div class="w-64 glass rounded-full px-3 py-1.5 text-sm">
|
||||
<span class="text-white/60">Поиск поставщиков...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ВАРИАНТ 5: ВЕРТИКАЛЬНАЯ ПАНЕЛЬ -->
|
||||
<div class="mb-12">
|
||||
<h2 class="text-xl font-semibold mb-4">🔥 Вариант 5: Вертикальная панель</h2>
|
||||
<div class="flex gap-4 h-48">
|
||||
<!-- Sidebar Mock -->
|
||||
<div class="sidebar-mock rounded-2xl p-4 flex flex-col">
|
||||
<div class="flex items-center gap-3 mb-6">
|
||||
<div class="w-8 h-8 bg-purple-500 rounded-full"></div>
|
||||
<span class="text-sm">Rennel</span>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<div class="text-sm opacity-60">Главная</div>
|
||||
<div class="text-sm opacity-60">Маркет</div>
|
||||
<div class="text-sm opacity-60">Мессенджер</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Vertical Panel -->
|
||||
<div class="w-8 flex flex-col items-center py-4">
|
||||
<button class="w-6 h-6 hover:w-7 hover:h-7 bg-gradient-to-b from-purple-500/10 to-transparent hover:from-purple-500/30 hover:to-purple-400/10 rounded-full flex items-center justify-center transition-all duration-300 hover:shadow-lg hover:shadow-purple-500/20 group">
|
||||
<svg class="h-3 w-3 group-hover:h-4 group-hover:w-4 text-white/50 group-hover:text-purple-300 transition-all duration-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Block 1 Mock -->
|
||||
<div class="flex-1 block-mock p-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-3">
|
||||
<svg class="h-5 w-5 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"></path>
|
||||
</svg>
|
||||
<h2 class="text-lg font-semibold">Поставщики</h2>
|
||||
</div>
|
||||
<div class="w-64 glass rounded-full px-3 py-1.5 text-sm">
|
||||
<span class="text-white/60">Поиск поставщиков...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center text-white/60 mt-8">
|
||||
<p>Наведите курсор на кнопки для просмотра hover эффектов</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -470,6 +470,83 @@ ignores: ['diagnostic-script.js', 'legacy-config.js'] // конкретные ф
|
||||
**ПРИ НЕОПРЕДЕЛЕННОСТИ:** СТОП → Вопрос пользователю → Ждать ответа
|
||||
**ПРИ ОШИБКЕ В ПЛАНЕ:** СТОП → Сообщить проблему → Не выполнять до исправления
|
||||
|
||||
### 6.4 🔄 КОМАНДЫ ОТКАТА ЧЕРЕЗ КОММЕНТАРИИ
|
||||
|
||||
#### **ОСНОВНАЯ КОМАНДА:**
|
||||
|
||||
```
|
||||
"откати [описание] через комментарии"
|
||||
```
|
||||
|
||||
**Примеры использования:**
|
||||
|
||||
- `"откати центрирование поиска через комментарии"`
|
||||
- `"откати изменения кнопки через комментарии"`
|
||||
- `"откати новую логику через комментарии"`
|
||||
|
||||
#### **АЛГОРИТМ ВЫПОЛНЕНИЯ:**
|
||||
|
||||
**ЭТАП 1: ВОССТАНОВЛЕНИЕ ИСХОДНОГО КОДА**
|
||||
|
||||
1. Найти измененный код в текущих файлах
|
||||
2. Извлечь исходный код из git истории (`git show HEAD:путь/к/файлу`)
|
||||
3. Восстановить исходную функциональность
|
||||
|
||||
**ЭТАП 2: СОЗДАНИЕ СИСТЕМЫ ПЕРЕКЛЮЧЕНИЯ** 4. Оставить **Вариант 1** (исходный) - активным 5. Добавить **Вариант 2** (измененный) в комментариях 6. Добавить четкие описания для каждого варианта
|
||||
|
||||
**ПРИМЕР СТРУКТУРЫ КОДА:**
|
||||
|
||||
```jsx
|
||||
// Вариант 1: Исходный (активный)
|
||||
<div className="flex items-center justify-between">
|
||||
{/* исходный код */}
|
||||
</div>
|
||||
|
||||
// Вариант 2: Измененный (для быстрого переключения)
|
||||
/*
|
||||
<div className="flex justify-center">
|
||||
{/* измененный код */}
|
||||
</div>
|
||||
*/
|
||||
```
|
||||
|
||||
#### **ДОПОЛНИТЕЛЬНЫЕ КОМАНДЫ:**
|
||||
|
||||
**ОЧИСТКА КОММЕНТАРИЕВ:**
|
||||
|
||||
- `"очисти комментарии"` - удалить все закомментированные варианты
|
||||
- `"удали вариант 2"` - удалить конкретный закомментированный вариант
|
||||
|
||||
**ПЕРЕКЛЮЧЕНИЕ ВАРИАНТОВ:**
|
||||
|
||||
- `"переключи на вариант 2"` - активировать закомментированный код
|
||||
- `"активируй измененный вариант"` - то же самое
|
||||
|
||||
**ИНФОРМАЦИОННЫЕ КОМАНДЫ:**
|
||||
|
||||
- `"покажи варианты"` - показать все доступные варианты в комментариях
|
||||
- `"какие есть варианты кода?"` - перечислить доступные варианты
|
||||
|
||||
#### **ПРЕИМУЩЕСТВА МЕТОДА:**
|
||||
|
||||
✅ **Мгновенный откат** - просто переставить комментарии
|
||||
✅ **Видимость всех вариантов** - код содержит историю изменений
|
||||
✅ **Быстрые эксперименты** - легко переключаться между решениями
|
||||
✅ **Не усложняет архитектуру** - не требует feature flags или конфигов
|
||||
|
||||
#### **ОГРАНИЧЕНИЯ:**
|
||||
|
||||
⚠️ **Временное решение** - не для production кода
|
||||
⚠️ **Увеличивает объем кода** - нужно очищать перед финальным коммитом
|
||||
⚠️ **Только для небольших изменений** - не подходит для кардинальных переработок
|
||||
|
||||
#### **ПРАВИЛА ПРИМЕНЕНИЯ:**
|
||||
|
||||
- ✅ Использовать для UI экспериментов и небольших логических изменений
|
||||
- ✅ Всегда добавлять четкие комментарии с описанием вариантов
|
||||
- ✅ Очищать комментарии перед финальным коммитом
|
||||
- ❌ Не использовать для изменений архитектуры или критической логики
|
||||
|
||||
---
|
||||
|
||||
## 🚀 ЗАКЛЮЧЕНИЕ
|
||||
|
@ -1,7 +1,3 @@
|
||||
|
||||
|
||||
|
||||
>
|
||||
> ❌ **ЗАПРЕЩЕНО РЕДАКТИРОВАТЬ БЕЗ ЯВНОГО РАЗРЕШЕНИЯ ПОЛЬЗОВАТЕЛЯ!**
|
||||
>
|
||||
> 📅 **Дата создания резерва**: 2025-08-08
|
||||
@ -852,6 +848,8 @@ const handleSuppliesClick = () => {
|
||||
|
||||
#### **📄 Структура страницы создания поставки:**
|
||||
|
||||
**ВАЖНО**: Страница НЕ имеет основного заголовка и описания. Сразу начинается с блоков контента.
|
||||
|
||||
**ОБНОВЛЕННАЯ СТРУКТУРА СИСТЕМЫ (4 БЛОКА):**
|
||||
|
||||
**БЛОК 1: ПОСТАВЩИКИ** _(адаптивная сетка)_
|
||||
@ -1981,6 +1979,7 @@ height: calc(100vh - headerHeight - tabsHeight - statsHeight - margins);
|
||||
### 11.4 Правила фулфилмента
|
||||
|
||||
**ОБЯЗАТЕЛЬНО**:
|
||||
|
||||
- Установка цен на расходники перед доступностью селлерам
|
||||
- Контроль качества товаров при приемке
|
||||
- Своевременная обработка возвратов
|
||||
@ -1988,6 +1987,7 @@ height: calc(100vh - headerHeight - tabsHeight - statsHeight - margins);
|
||||
- Управление персоналом и рабочим временем
|
||||
|
||||
**ЗАПРЕЩЕНО**:
|
||||
|
||||
- Отгружать товары без подтверждения наличия
|
||||
- Создавать расходники минуя систему поставок
|
||||
- Изменять цены закупки после поступления товара
|
||||
@ -2246,11 +2246,13 @@ const wholesalePartners = await prisma.counterparty.findMany({
|
||||
**НАЗНАЧЕНИЕ**: Бизнес-партнерство с автоматическим добавлением в контрагенты
|
||||
|
||||
**ФОРМАТ URL**: `?partner=REFERRAL_CODE`
|
||||
|
||||
```
|
||||
http://localhost:3000/register?partner=SF2X9K4M7P
|
||||
```
|
||||
|
||||
**ЧТО ПРОИСХОДИТ**:
|
||||
|
||||
1. ✅ Начисляется 100 сфер (⚡) реферальная награда
|
||||
2. ✅ **Автоматически создается партнерство**: взаимное добавление в контрагенты
|
||||
3. ✅ Устанавливается реферальная связь (`referredById`)
|
||||
@ -2264,11 +2266,13 @@ http://localhost:3000/register?partner=SF2X9K4M7P
|
||||
**НАЗНАЧЕНИЕ**: Маркетинговое привлечение с наградой, БЕЗ автоматического партнерства
|
||||
|
||||
**ФОРМАТ URL**: `?ref=REFERRAL_CODE`
|
||||
|
||||
```
|
||||
http://localhost:3000/register?ref=SF2X9K4M7P
|
||||
```
|
||||
|
||||
**ЧТО ПРОИСХОДИТ**:
|
||||
|
||||
1. ✅ Начисляется 100 сфер (⚡) реферальная награда
|
||||
2. ✅ Устанавливается реферальная связь (`referredById`)
|
||||
3. ❌ **НЕ создается партнерство**: организации НЕ добавляются в контрагенты
|
||||
@ -2303,11 +2307,13 @@ if (referralCode) {
|
||||
**В разделе "Партнеры"**:
|
||||
|
||||
**Вкладка "Мои партнеры"**:
|
||||
|
||||
- Партнерская ссылка: `?partner=CODE` (автоматическое партнерство)
|
||||
- Заголовок: "Пригласить партнера"
|
||||
- Описание: "Для прямого делового сотрудничества"
|
||||
|
||||
**Вкладка "Рефералы"**:
|
||||
|
||||
- Реферальная ссылка: `?ref=CODE` (только маркетинг)
|
||||
- Заголовок: "Реферальная ссылка"
|
||||
- Описание: "Для маркетинговых кампаний"
|
||||
@ -2315,14 +2321,17 @@ if (referralCode) {
|
||||
#### **13.6.5 Правила именования**
|
||||
|
||||
**В коде ВСЕГДА использовать**:
|
||||
|
||||
- `partnerCode` / `partner=` → бизнес-партнерство
|
||||
- `referralCode` / `ref=` → маркетинговое привлечение
|
||||
|
||||
**В комментариях и документации**:
|
||||
|
||||
- "Партнерская ссылка" → автоматическое партнерство
|
||||
- "Реферальная ссылка" → только маркетинг
|
||||
|
||||
**ЗАПРЕЩЕНО**:
|
||||
|
||||
- ❌ Называть партнерские ссылки "реферальными"
|
||||
- ❌ Называть реферальные ссылки "партнерскими"
|
||||
- ❌ Использовать термины взаимозаменяемо
|
||||
@ -2331,6 +2340,7 @@ if (referralCode) {
|
||||
#### **13.6.6 Примеры использования**
|
||||
|
||||
**Сценарий 1 - Деловое партнерство**:
|
||||
|
||||
```
|
||||
Фулфилмент-центр хочет пригласить логистическую компанию
|
||||
→ Использует партнерскую ссылку ?partner=CODE
|
||||
@ -2339,6 +2349,7 @@ if (referralCode) {
|
||||
```
|
||||
|
||||
**Сценарий 2 - Маркетинговая кампания**:
|
||||
|
||||
```
|
||||
Организация запускает рекламу в соцсетях
|
||||
→ Использует реферальную ссылку ?ref=CODE
|
||||
|
@ -43,9 +43,9 @@ const AdminDashboard = React.memo(() => {
|
||||
}, [activeSection])
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gradient-smooth flex">
|
||||
<div className="h-screen bg-gradient-smooth flex overflow-hidden">
|
||||
<AdminSidebar activeSection={activeSection} onSectionChange={handleSectionChange} />
|
||||
<main className="flex-1 ml-64">{renderContent}</main>
|
||||
<main className="flex-1 ml-64 overflow-y-auto">{renderContent}</main>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
@ -5,6 +5,7 @@ import React from 'react'
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
|
||||
|
||||
import { AnimationsDemo } from './ui-kit/animations-demo'
|
||||
import { BackButtonVariantsDemo } from './ui-kit/back-button-variants-demo'
|
||||
import { BusinessDemo } from './ui-kit/business-demo'
|
||||
import { BusinessProcessesDemo } from './ui-kit/business-processes-demo'
|
||||
import { ButtonsDemo } from './ui-kit/buttons-demo'
|
||||
@ -84,6 +85,12 @@ const UIKitSection = React.memo(() => {
|
||||
>
|
||||
Навигация
|
||||
</TabsTrigger>
|
||||
<TabsTrigger
|
||||
value="back-button-variants"
|
||||
className="data-[state=active]:bg-white/20 data-[state=active]:text-white text-white/70 text-xs px-3 py-2"
|
||||
>
|
||||
Кнопки Назад
|
||||
</TabsTrigger>
|
||||
<TabsTrigger
|
||||
value="specialized"
|
||||
className="data-[state=active]:bg-white/20 data-[state=active]:text-white text-white/70 text-xs px-3 py-2"
|
||||
@ -243,6 +250,9 @@ const UIKitSection = React.memo(() => {
|
||||
<TabsContent value="supplies-navigation" className="space-y-6">
|
||||
<SuppliesNavigationDemo />
|
||||
</TabsContent>
|
||||
<TabsContent value="back-button-variants" className="space-y-6">
|
||||
<BackButtonVariantsDemo />
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="business-processes" className="space-y-6">
|
||||
<BusinessProcessesDemo />
|
||||
|
234
src/components/admin/ui-kit/back-button-variants-demo.tsx
Normal file
234
src/components/admin/ui-kit/back-button-variants-demo.tsx
Normal file
@ -0,0 +1,234 @@
|
||||
'use client'
|
||||
|
||||
import { ArrowLeft, Building2 } from 'lucide-react'
|
||||
import React from 'react'
|
||||
|
||||
export function BackButtonVariantsDemo() {
|
||||
return (
|
||||
<div className="space-y-12 p-6">
|
||||
<div>
|
||||
<h2 className="text-2xl font-bold text-white mb-2">Варианты кнопки "Назад"</h2>
|
||||
<p className="text-white/60 mb-8">
|
||||
Интерактивные варианты размещения кнопки навигации между сайдбаром и контентом
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* ВАРИАНТ 1: ПЛАВАЮЩАЯ КНОПКА СЛЕВА */}
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-lg font-semibold text-white">🌟 Вариант 1: Плавающая кнопка слева</h3>
|
||||
<div className="bg-white/5 rounded-lg p-6 border border-white/10">
|
||||
<div className="flex gap-4 h-48">
|
||||
{/* Sidebar Mock */}
|
||||
<div className="w-60 bg-white/5 backdrop-blur-xl border border-white/10 rounded-2xl p-4 flex flex-col">
|
||||
<div className="flex items-center gap-3 mb-6">
|
||||
<div className="w-8 h-8 bg-purple-500 rounded-full"></div>
|
||||
<span className="text-sm text-white">Rennel</span>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<div className="text-sm text-white/60">Главная</div>
|
||||
<div className="text-sm text-white/60">Маркет</div>
|
||||
<div className="text-sm text-white/60">Мессенджер</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Floating Back Button */}
|
||||
<div className="relative">
|
||||
<button className="absolute left-0 top-6 z-10 w-8 h-8 bg-white/10 backdrop-blur-xl border border-white/20 hover:border-white/40 rounded-full flex items-center justify-center transition-all duration-300 hover:scale-110 hover:bg-white/20 group">
|
||||
<ArrowLeft className="h-4 w-4 text-white/70 group-hover:text-white group-hover:h-5 group-hover:w-5 transition-all" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Block 1 Mock */}
|
||||
<div className="flex-1 bg-white/10 backdrop-blur-xl border border-white/20 rounded-2xl p-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<Building2 className="h-5 w-5 text-blue-400" />
|
||||
<h2 className="text-lg font-semibold text-white">Поставщики</h2>
|
||||
</div>
|
||||
<div className="w-64 bg-white/10 border border-white/20 rounded-full px-3 py-1.5 text-sm">
|
||||
<span className="text-white/60">Поиск поставщиков...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ВАРИАНТ 2: ПОЛОСА НАВИГАЦИИ СВЕРХУ */}
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-lg font-semibold text-white">📍 Вариант 2: Полоса навигации сверху</h3>
|
||||
<div className="bg-white/5 rounded-lg p-6 border border-white/10">
|
||||
<div className="flex gap-4">
|
||||
{/* Sidebar Mock */}
|
||||
<div className="w-60 bg-white/5 backdrop-blur-xl border border-white/10 rounded-2xl p-4 flex flex-col h-48">
|
||||
<div className="flex items-center gap-3 mb-6">
|
||||
<div className="w-8 h-8 bg-purple-500 rounded-full"></div>
|
||||
<span className="text-sm text-white">Rennel</span>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<div className="text-sm text-white/60">Главная</div>
|
||||
<div className="text-sm text-white/60">Маркет</div>
|
||||
<div className="text-sm text-white/60">Мессенджер</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Content Area */}
|
||||
<div className="flex-1">
|
||||
{/* Navigation Bar */}
|
||||
<div className="flex items-center justify-start mb-4">
|
||||
<button className="w-6 h-6 hover:w-8 hover:h-8 bg-gradient-to-r from-purple-500/20 to-blue-500/20 hover:from-purple-500/40 hover:to-blue-500/40 rounded-full flex items-center justify-center transition-all duration-300 backdrop-blur-sm border border-white/10 hover:border-white/30 group">
|
||||
<ArrowLeft className="h-3 w-3 group-hover:h-4 group-hover:w-4 text-white/60 group-hover:text-white transition-all" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Block 1 Mock */}
|
||||
<div className="bg-white/10 backdrop-blur-xl border border-white/20 rounded-2xl p-4 h-[180px]">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<Building2 className="h-5 w-5 text-blue-400" />
|
||||
<h2 className="text-lg font-semibold text-white">Поставщики</h2>
|
||||
</div>
|
||||
<div className="w-64 bg-white/10 border border-white/20 rounded-full px-3 py-1.5 text-sm">
|
||||
<span className="text-white/60">Поиск поставщиков...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ВАРИАНТ 3: КНОПКА В РАЗРЫВЕ */}
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-lg font-semibold text-white">🎯 Вариант 3: Кнопка в разрыве</h3>
|
||||
<div className="bg-white/5 rounded-lg p-6 border border-white/10">
|
||||
<div className="flex gap-4 h-48 relative">
|
||||
{/* Sidebar Mock */}
|
||||
<div className="w-60 bg-white/5 backdrop-blur-xl border border-white/10 rounded-2xl p-4 flex flex-col">
|
||||
<div className="flex items-center gap-3 mb-6">
|
||||
<div className="w-8 h-8 bg-purple-500 rounded-full"></div>
|
||||
<span className="text-sm text-white">Rennel</span>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<div className="text-sm text-white/60">Главная</div>
|
||||
<div className="text-sm text-white/60">Маркет</div>
|
||||
<div className="text-sm text-white/60">Мессенджер</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Button in Gap */}
|
||||
<div className="w-0 flex items-center justify-center relative">
|
||||
<button className="absolute w-10 h-10 bg-white/5 hover:bg-white/15 rounded-xl border border-white/10 hover:border-purple-400/50 flex items-center justify-center transition-all duration-500 hover:scale-125 hover:rotate-12 group backdrop-blur-md">
|
||||
<ArrowLeft className="h-4 w-4 text-white/50 group-hover:text-purple-300 transition-colors" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Block 1 Mock */}
|
||||
<div className="flex-1 bg-white/10 backdrop-blur-xl border border-white/20 rounded-2xl p-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<Building2 className="h-5 w-5 text-blue-400" />
|
||||
<h2 className="text-lg font-semibold text-white">Поставщики</h2>
|
||||
</div>
|
||||
<div className="w-64 bg-white/10 border border-white/20 rounded-full px-3 py-1.5 text-sm">
|
||||
<span className="text-white/60">Поиск поставщиков...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ВАРИАНТ 4: BREADCRUMB СТИЛЬ */}
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-lg font-semibold text-white">🍞 Вариант 4: Breadcrumb стиль</h3>
|
||||
<div className="bg-white/5 rounded-lg p-6 border border-white/10">
|
||||
<div className="flex gap-4">
|
||||
{/* Sidebar Mock */}
|
||||
<div className="w-60 bg-white/5 backdrop-blur-xl border border-white/10 rounded-2xl p-4 flex flex-col h-48">
|
||||
<div className="flex items-center gap-3 mb-6">
|
||||
<div className="w-8 h-8 bg-purple-500 rounded-full"></div>
|
||||
<span className="text-sm text-white">Rennel</span>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<div className="text-sm text-white/60">Главная</div>
|
||||
<div className="text-sm text-white/60">Маркет</div>
|
||||
<div className="text-sm text-white/60">Мессенджер</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Content Area */}
|
||||
<div className="flex-1">
|
||||
{/* Breadcrumb */}
|
||||
<div className="flex items-center gap-2 mb-2 pl-2">
|
||||
<button className="p-1 hover:p-2 bg-white/0 hover:bg-white/10 rounded-lg transition-all duration-300 group">
|
||||
<ArrowLeft className="h-3 w-3 group-hover:h-4 group-hover:w-4 text-white/40 group-hover:text-white transition-all" />
|
||||
</button>
|
||||
<span className="text-white/20 text-sm">•</span>
|
||||
<span className="text-white/60 text-sm">Поставщики</span>
|
||||
</div>
|
||||
|
||||
{/* Block 1 Mock */}
|
||||
<div className="bg-white/10 backdrop-blur-xl border border-white/20 rounded-2xl p-4 h-[180px]">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<Building2 className="h-5 w-5 text-blue-400" />
|
||||
<h2 className="text-lg font-semibold text-white">Поставщики</h2>
|
||||
</div>
|
||||
<div className="w-64 bg-white/10 border border-white/20 rounded-full px-3 py-1.5 text-sm">
|
||||
<span className="text-white/60">Поиск поставщиков...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ВАРИАНТ 5: ВЕРТИКАЛЬНАЯ ПАНЕЛЬ */}
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-lg font-semibold text-white">🔥 Вариант 5: Вертикальная панель</h3>
|
||||
<div className="bg-white/5 rounded-lg p-6 border border-white/10">
|
||||
<div className="flex gap-4 h-48">
|
||||
{/* Sidebar Mock */}
|
||||
<div className="w-60 bg-white/5 backdrop-blur-xl border border-white/10 rounded-2xl p-4 flex flex-col">
|
||||
<div className="flex items-center gap-3 mb-6">
|
||||
<div className="w-8 h-8 bg-purple-500 rounded-full"></div>
|
||||
<span className="text-sm text-white">Rennel</span>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<div className="text-sm text-white/60">Главная</div>
|
||||
<div className="text-sm text-white/60">Маркет</div>
|
||||
<div className="text-sm text-white/60">Мессенджер</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Vertical Panel */}
|
||||
<div className="w-8 flex flex-col items-center py-4">
|
||||
<button className="w-6 h-6 hover:w-7 hover:h-7 bg-gradient-to-b from-purple-500/10 to-transparent hover:from-purple-500/30 hover:to-purple-400/10 rounded-full flex items-center justify-center transition-all duration-300 hover:shadow-lg hover:shadow-purple-500/20 group">
|
||||
<ArrowLeft className="h-3 w-3 group-hover:h-4 group-hover:w-4 text-white/50 group-hover:text-purple-300 transition-all duration-300" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Block 1 Mock */}
|
||||
<div className="flex-1 bg-white/10 backdrop-blur-xl border border-white/20 rounded-2xl p-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<Building2 className="h-5 w-5 text-blue-400" />
|
||||
<h2 className="text-lg font-semibold text-white">Поставщики</h2>
|
||||
</div>
|
||||
<div className="w-64 bg-white/10 border border-white/20 rounded-full px-3 py-1.5 text-sm">
|
||||
<span className="text-white/60">Поиск поставщиков...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="text-center text-white/60 mt-8 p-4 bg-white/5 rounded-lg border border-white/10">
|
||||
<p>Наведите курсор на кнопки для просмотра hover эффектов</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
@ -1,16 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import { useQuery, useMutation } from '@apollo/client'
|
||||
import {
|
||||
ArrowLeft,
|
||||
Building2,
|
||||
Search,
|
||||
Package,
|
||||
Plus,
|
||||
Minus,
|
||||
ShoppingCart,
|
||||
Wrench,
|
||||
} from 'lucide-react'
|
||||
import { ArrowLeft, Building2, Search, Package, Plus, Minus, ShoppingCart, Wrench } from 'lucide-react'
|
||||
import Image from 'next/image'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import React, { useState } from 'react'
|
||||
@ -131,7 +122,6 @@ export function CreateConsumablesSupplyPage() {
|
||||
}).format(amount)
|
||||
}
|
||||
|
||||
|
||||
const updateConsumableQuantity = (productId: string, quantity: number) => {
|
||||
const product = supplierProducts.find((p: ConsumableProduct) => p.id === productId)
|
||||
if (!product || !selectedSupplier) return
|
||||
@ -358,12 +348,8 @@ export function CreateConsumablesSupplyPage() {
|
||||
<Sidebar />
|
||||
<main className={`flex-1 ${getSidebarMargin()} overflow-auto transition-all duration-300 p-4`}>
|
||||
<div className="min-h-full w-full flex flex-col gap-4">
|
||||
{/* Заголовок */}
|
||||
<div className="flex items-center justify-between flex-shrink-0">
|
||||
<div>
|
||||
<h1 className="text-xl font-bold text-white mb-1">Создание поставки расходников</h1>
|
||||
<p className="text-white/60 text-sm">Выберите поставщика и добавьте расходники в заказ</p>
|
||||
</div>
|
||||
{/* Кнопка назад без заголовка */}
|
||||
<div className="flex items-center justify-end flex-shrink-0">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
@ -429,10 +415,13 @@ export function CreateConsumablesSupplyPage() {
|
||||
{filteredSuppliers.slice(0, 7).map((supplier: ConsumableSupplier, index) => (
|
||||
<Card
|
||||
key={supplier.id}
|
||||
className={`relative cursor-pointer transition-all duration-300 border flex-shrink-0 rounded-xl overflow-hidden group ${
|
||||
className={`relative cursor-pointer transition-all duration-300 border
|
||||
flex-shrink-0 rounded-xl overflow-hidden group ${
|
||||
selectedSupplier?.id === supplier.id
|
||||
? 'bg-gradient-to-br from-orange-500/30 via-orange-400/20 to-orange-500/30 border-orange-400/60 shadow-lg shadow-orange-500/25'
|
||||
: 'bg-gradient-to-br from-white/10 via-white/5 to-white/10 border-white/20 hover:from-white/20 hover:via-white/10 hover:to-white/20 hover:border-white/40'
|
||||
? 'bg-gradient-to-br from-orange-500/30 via-orange-400/20 to-orange-500/30 ' +
|
||||
'border-orange-400/60 shadow-lg shadow-orange-500/25'
|
||||
: 'bg-gradient-to-br from-white/10 via-white/5 to-white/10 border-white/20 ' +
|
||||
'hover:from-white/20 hover:via-white/10 hover:to-white/20 hover:border-white/40'
|
||||
}`}
|
||||
style={{
|
||||
width: 'calc((100% - 48px) / 7)', // 48px = 6 gaps * 8px each
|
||||
@ -545,10 +534,14 @@ export function CreateConsumablesSupplyPage() {
|
||||
return (
|
||||
<Card
|
||||
key={product.id}
|
||||
className={`relative bg-gradient-to-br from-white/10 via-white/5 to-white/10 backdrop-blur border border-white/20 p-3 rounded-xl overflow-hidden group hover:shadow-xl transition-all duration-300 ${
|
||||
className={`relative bg-gradient-to-br from-white/10 via-white/5
|
||||
to-white/10 backdrop-blur border border-white/20 p-3 rounded-xl
|
||||
overflow-hidden group hover:shadow-xl transition-all duration-300 ${
|
||||
selectedQuantity > 0
|
||||
? 'ring-2 ring-green-400/50 bg-gradient-to-br from-green-500/20 via-green-400/10 to-green-500/20'
|
||||
: 'hover:from-white/20 hover:via-white/10 hover:to-white/20 hover:border-white/40'
|
||||
? 'ring-2 ring-green-400/50 bg-gradient-to-br from-green-500/20 ' +
|
||||
'via-green-400/10 to-green-500/20'
|
||||
: 'hover:from-white/20 hover:via-white/10 hover:to-white/20 ' +
|
||||
'hover:border-white/40'
|
||||
}`}
|
||||
style={{
|
||||
animationDelay: `${index * 50}ms`,
|
||||
|
@ -241,20 +241,26 @@ flex flex-wrap gap-4
|
||||
**КРИТИЧЕСКИ ВАЖНО**: Все вкладки раздела "Партнеры" должны иметь единую структуру:
|
||||
|
||||
#### Обязательные принципы:
|
||||
|
||||
- **Блоки статистики**: `grid grid-cols-4 gap-3` с отдельными `glass-card`
|
||||
- **ЗАПРЕЩЕНО**: Дополнительные обертки `glass-card` в TabsContent
|
||||
- **Цвета ссылок**: желтая схема (`bg-yellow-500/20`)
|
||||
- **Табличный формат**: вместо карточного grid-layout
|
||||
|
||||
#### Структура блоков статистики:
|
||||
|
||||
```tsx
|
||||
{/* ПРАВИЛЬНО */}
|
||||
<div className="grid grid-cols-4 gap-3">
|
||||
{
|
||||
/* ПРАВИЛЬНО */
|
||||
}
|
||||
;<div className="grid grid-cols-4 gap-3">
|
||||
<Card className="glass-card p-3">...</Card>
|
||||
</div>
|
||||
|
||||
{/* ЗАПРЕЩЕНО */}
|
||||
<Card className="glass-card">
|
||||
{
|
||||
/* ЗАПРЕЩЕНО */
|
||||
}
|
||||
;<Card className="glass-card">
|
||||
<div className="grid...">...</div>
|
||||
</Card>
|
||||
```
|
||||
@ -556,9 +562,7 @@ text-white/50 /* Приглушенный текст */
|
||||
<main className={`flex-1 ${getSidebarMargin()} overflow-hidden transition-all duration-300`}>
|
||||
<div className="h-full flex flex-col">
|
||||
{/* Блоки занимают всю доступную область */}
|
||||
<div className="flex-1 flex gap-2 min-h-0">
|
||||
{/* Блоки без внешних отступов */}
|
||||
</div>
|
||||
<div className="flex-1 flex gap-2 min-h-0">{/* Блоки без внешних отступов */}</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
@ -669,11 +673,7 @@ text-white/50 /* Приглушенный текст */
|
||||
### 13.2 Интерактивная кнопка
|
||||
|
||||
```tsx
|
||||
<Button
|
||||
variant="glass"
|
||||
className="hover:scale-105 transition-transform"
|
||||
onClick={handleClick}
|
||||
>
|
||||
<Button variant="glass" className="hover:scale-105 transition-transform" onClick={handleClick}>
|
||||
<Icon className="h-4 w-4 mr-2" />
|
||||
Действие
|
||||
</Button>
|
||||
@ -684,10 +684,7 @@ text-white/50 /* Приглушенный текст */
|
||||
```tsx
|
||||
<div className="space-y-2">
|
||||
<Label className="text-white/90">Поле ввода</Label>
|
||||
<Input
|
||||
className="glass-input text-white placeholder:text-white/50"
|
||||
placeholder="Введите значение..."
|
||||
/>
|
||||
<Input className="glass-input text-white placeholder:text-white/50" placeholder="Введите значение..." />
|
||||
{error && <p className="text-red-300 text-xs">{error}</p>}
|
||||
</div>
|
||||
```
|
||||
@ -697,7 +694,7 @@ text-white/50 /* Приглушенный текст */
|
||||
```tsx
|
||||
// ✅ ПРАВИЛЬНАЯ структура страницы с сайдбаром
|
||||
function PageWithSidebar() {
|
||||
const { getSidebarMargin } = useSidebar();
|
||||
const { getSidebarMargin } = useSidebar()
|
||||
|
||||
return (
|
||||
<div className="h-screen flex overflow-hidden">
|
||||
@ -725,7 +722,7 @@ function PageWithSidebar() {
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
@ -875,25 +872,25 @@ const productCreationSteps = [
|
||||
{ id: 'planning', label: 'Планирование работы', status: 'active' },
|
||||
{ id: 'processing', label: 'Обработка товара', status: 'pending' },
|
||||
{ id: 'quality', label: 'Контроль качества', status: 'pending' },
|
||||
{ id: 'completion', label: 'Завершение', status: 'pending' }
|
||||
];
|
||||
{ id: 'completion', label: 'Завершение', status: 'pending' },
|
||||
]
|
||||
|
||||
// Визуальный компонент
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
;<div className="flex items-center justify-between mb-6">
|
||||
{productCreationSteps.map((step, index) => (
|
||||
<div key={step.id} className="flex items-center">
|
||||
<div className={`
|
||||
<div
|
||||
className={`
|
||||
flex items-center justify-center w-10 h-10 rounded-full border-2 text-sm font-semibold
|
||||
${step.status === 'completed' ? 'bg-green-500 border-green-500 text-white' : ''}
|
||||
${step.status === 'active' ? 'bg-blue-500 border-blue-500 text-white animate-pulse' : ''}
|
||||
${step.status === 'pending' ? 'bg-white/10 border-white/30 text-white/50' : ''}
|
||||
`}>
|
||||
`}
|
||||
>
|
||||
{step.status === 'completed' ? '✓' : index + 1}
|
||||
</div>
|
||||
<span className="ml-2 text-sm text-white/70">{step.label}</span>
|
||||
{index < productCreationSteps.length - 1 && (
|
||||
<div className="w-12 h-0.5 bg-white/20 mx-4"></div>
|
||||
)}
|
||||
{index < productCreationSteps.length - 1 && <div className="w-12 h-0.5 bg-white/20 mx-4"></div>}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
@ -907,25 +904,25 @@ const productCreationSteps = [
|
||||
/* WHOLESALE - поставщики */
|
||||
.partner-wholesale {
|
||||
@apply bg-emerald-500/20 border-emerald-400;
|
||||
--icon: "🏭"; /* factory */
|
||||
--icon: '🏭'; /* factory */
|
||||
}
|
||||
|
||||
/* SELLER - селлеры */
|
||||
.partner-seller {
|
||||
@apply bg-blue-500/20 border-blue-400;
|
||||
--icon: "🛍️"; /* shopping */
|
||||
--icon: '🛍️'; /* shopping */
|
||||
}
|
||||
|
||||
/* FULFILLMENT - фулфилмент центры */
|
||||
.partner-fulfillment {
|
||||
@apply bg-purple-500/20 border-purple-400;
|
||||
--icon: "📦"; /* package */
|
||||
--icon: '📦'; /* package */
|
||||
}
|
||||
|
||||
/* LOGIST - логистические компании */
|
||||
.partner-logist {
|
||||
@apply bg-orange-500/20 border-orange-400;
|
||||
--icon: "🚚"; /* truck */
|
||||
--icon: '🚚'; /* truck */
|
||||
}
|
||||
```
|
||||
|
||||
@ -974,38 +971,42 @@ export function SuppliesPage() {
|
||||
#### 14.5.2 Контекстная статистика по табам
|
||||
|
||||
**Для пути "Фулфилмент → Товар → Карточки/Поставщики":**
|
||||
|
||||
```tsx
|
||||
const suppliesStats = [
|
||||
{ label: "Всего поставок", value: "24", color: "text-blue-400" },
|
||||
{ label: "Активных поставок", value: "8", color: "text-green-400" },
|
||||
{ label: "Сумма активных поставок", value: "₽142,350", color: "text-yellow-400" },
|
||||
{ label: "В пути", value: "3", color: "text-purple-400" }
|
||||
];
|
||||
{ label: 'Всего поставок', value: '24', color: 'text-blue-400' },
|
||||
{ label: 'Активных поставок', value: '8', color: 'text-green-400' },
|
||||
{ label: 'Сумма активных поставок', value: '₽142,350', color: 'text-yellow-400' },
|
||||
{ label: 'В пути', value: '3', color: 'text-purple-400' },
|
||||
]
|
||||
```
|
||||
|
||||
**Для пути "Фулфилмент → Расходники селлера":**
|
||||
|
||||
```tsx
|
||||
const consumablesStats = [
|
||||
{ label: "Всего поставок", value: "12", color: "text-blue-400" },
|
||||
{ label: "Активных поставок", value: "4", color: "text-green-400" },
|
||||
{ label: "Видов расходников", value: "18", color: "text-orange-400" },
|
||||
{ label: "Критические остатки", value: "2", color: "text-red-400" }
|
||||
];
|
||||
{ label: 'Всего поставок', value: '12', color: 'text-blue-400' },
|
||||
{ label: 'Активных поставок', value: '4', color: 'text-green-400' },
|
||||
{ label: 'Видов расходников', value: '18', color: 'text-orange-400' },
|
||||
{ label: 'Критические остатки', value: '2', color: 'text-red-400' },
|
||||
]
|
||||
```
|
||||
|
||||
**Для путей "Маркетплейсы → Wildberries/Ozon":**
|
||||
|
||||
```tsx
|
||||
const marketplaceStats = [
|
||||
{ label: "Поставок на маркетплейс", value: "15", color: "text-blue-400" },
|
||||
{ label: "Товаров отправлено", value: "347", color: "text-green-400" },
|
||||
{ label: "Возвраты за неделю", value: "12", color: "text-yellow-400" },
|
||||
{ label: "Эффективность поставок", value: "94%", color: "text-emerald-400" }
|
||||
];
|
||||
{ label: 'Поставок на маркетплейс', value: '15', color: 'text-blue-400' },
|
||||
{ label: 'Товаров отправлено', value: '347', color: 'text-green-400' },
|
||||
{ label: 'Возвраты за неделю', value: '12', color: 'text-yellow-400' },
|
||||
{ label: 'Эффективность поставок', value: '94%', color: 'text-emerald-400' },
|
||||
]
|
||||
```
|
||||
|
||||
#### 14.5.3 Система создания поставок
|
||||
|
||||
**Выбор типа поставки:**
|
||||
|
||||
```tsx
|
||||
const supplyTypes = [
|
||||
{
|
||||
@ -1013,23 +1014,25 @@ const supplyTypes = [
|
||||
title: 'Карточки товаров',
|
||||
description: 'Импорт через WB API с автосозданием поставки',
|
||||
icon: '📱',
|
||||
color: 'bg-blue-500/20 border-blue-400'
|
||||
color: 'bg-blue-500/20 border-blue-400',
|
||||
},
|
||||
{
|
||||
id: 'goods-suppliers',
|
||||
title: 'Поставщики товаров',
|
||||
description: 'Прямой заказ с указанием рецептуры',
|
||||
icon: '🏭',
|
||||
color: 'bg-emerald-500/20 border-emerald-400'
|
||||
color: 'bg-emerald-500/20 border-emerald-400',
|
||||
},
|
||||
{
|
||||
id: 'consumables',
|
||||
title: 'Расходники селлера',
|
||||
description: 'Материалы для производства',
|
||||
icon: '🔧',
|
||||
color: 'bg-purple-500/20 border-purple-400'
|
||||
}
|
||||
];
|
||||
color: 'bg-purple-500/20 border-purple-400',
|
||||
// ВАЖНО: На странице /supplies/create-consumables НЕ отображается заголовок и описание
|
||||
pageHeader: false,
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
#### 14.5.4 Интерфейс рецептуры продукта
|
||||
@ -1068,30 +1071,31 @@ const supplyTypes = [
|
||||
#### 14.5.5 WB интеграция - визуальные индикаторы
|
||||
|
||||
**Статусы синхронизации с WB API:**
|
||||
|
||||
```css
|
||||
/* Успешная синхронизация */
|
||||
.wb-sync-success {
|
||||
@apply bg-green-500/20 border-green-400 text-green-100;
|
||||
--status-icon: "✅";
|
||||
--status-icon: '✅';
|
||||
}
|
||||
|
||||
/* Ошибка синхронизации */
|
||||
.wb-sync-error {
|
||||
@apply bg-red-500/20 border-red-400 text-red-100;
|
||||
--status-icon: "❌";
|
||||
--status-icon: '❌';
|
||||
}
|
||||
|
||||
/* В процессе синхронизации */
|
||||
.wb-sync-loading {
|
||||
@apply bg-yellow-500/20 border-yellow-400 text-yellow-100;
|
||||
--status-icon: "⏳";
|
||||
--status-icon: '⏳';
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
|
||||
/* Не настроена */
|
||||
.wb-sync-none {
|
||||
@apply bg-gray-500/20 border-gray-400 text-gray-100;
|
||||
--status-icon: "⚠️";
|
||||
--status-icon: '⚠️';
|
||||
}
|
||||
```
|
||||
|
||||
@ -1102,6 +1106,7 @@ const supplyTypes = [
|
||||
**📅 ДАТА**: 2025, полная синхронизация с техническими требованиями
|
||||
|
||||
### 🆕 ДОБАВЛЕНИЯ v1.2:
|
||||
|
||||
- ✅ Детальные правила для кабинета селлера (раздел 14.5)
|
||||
- ✅ Трёхблочная архитектура страницы "Мои поставки"
|
||||
- ✅ Контекстная статистика по типам поставок
|
||||
|
Reference in New Issue
Block a user