Обновление системной документации и 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:
@ -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>
|
||||
@ -575,7 +579,7 @@ text-white/50 /* Приглушенный текст */
|
||||
|
||||
**MAIN КОНТЕЙНЕР:**
|
||||
|
||||
- ✅ БЕЗ `px-2 py-2` отступов
|
||||
- ✅ БЕЗ `px-2 py-2` отступов
|
||||
- ✅ Только `overflow-hidden` и `transition-all duration-300`
|
||||
- ✅ Использовать `${getSidebarMargin()}` для отступа от сайдбара
|
||||
|
||||
@ -614,7 +618,7 @@ text-white/50 /* Приглушенный текст */
|
||||
**КРИТЕРИИ СООТВЕТСТВИЯ:**
|
||||
|
||||
1. **Верхний край**: Первый блок начинается на уровне верха сайдбара
|
||||
2. **Нижний край**: Последний блок заканчивается на уровне низа сайдбара
|
||||
2. **Нижний край**: Последний блок заканчивается на уровне низа сайдбара
|
||||
3. **Без отступов**: Отсутствуют `px-* py-*` отступы в main
|
||||
4. **Только gap**: Используется только `gap-2` между блоками
|
||||
|
||||
@ -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,8 +694,8 @@ text-white/50 /* Приглушенный текст */
|
||||
```tsx
|
||||
// ✅ ПРАВИЛЬНАЯ структура страницы с сайдбаром
|
||||
function PageWithSidebar() {
|
||||
const { getSidebarMargin } = useSidebar();
|
||||
|
||||
const { getSidebarMargin } = useSidebar()
|
||||
|
||||
return (
|
||||
<div className="h-screen flex overflow-hidden">
|
||||
<Sidebar />
|
||||
@ -725,7 +722,7 @@ function PageWithSidebar() {
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
@ -743,37 +740,37 @@ function PageWithSidebar() {
|
||||
|
||||
```css
|
||||
/* 1. ПРОДУКТЫ - готовые к отправке */
|
||||
.module-products {
|
||||
.module-products {
|
||||
@apply bg-green-500/20 border-green-400 text-green-100;
|
||||
--icon-color: #10b981; /* emerald-500 */
|
||||
}
|
||||
|
||||
/* 2. ТОВАРЫ - базовые товары */
|
||||
.module-goods {
|
||||
.module-goods {
|
||||
@apply bg-blue-500/20 border-blue-400 text-blue-100;
|
||||
--icon-color: #3b82f6; /* blue-500 */
|
||||
}
|
||||
|
||||
/* 3. БРАК - дефектные товары */
|
||||
.module-defect {
|
||||
.module-defect {
|
||||
@apply bg-red-500/20 border-red-400 text-red-100;
|
||||
--icon-color: #ef4444; /* red-500 */
|
||||
}
|
||||
|
||||
/* 4. ВОЗВРАТЫ С ПВЗ - возвращенные товары */
|
||||
.module-returns {
|
||||
.module-returns {
|
||||
@apply bg-yellow-500/20 border-yellow-400 text-yellow-100;
|
||||
--icon-color: #eab308; /* yellow-500 */
|
||||
}
|
||||
|
||||
/* 5. РАСХОДНИКИ СЕЛЛЕРОВ - материалы клиентов */
|
||||
.module-seller-supplies {
|
||||
.module-seller-supplies {
|
||||
@apply bg-purple-500/20 border-purple-400 text-purple-100;
|
||||
--icon-color: #a855f7; /* purple-500 */
|
||||
}
|
||||
|
||||
/* 6. РАСХОДНИКИ ФУЛФИЛМЕНТА - операционные материалы (КЛИКАБЕЛЬНЫЙ) */
|
||||
.module-ff-supplies {
|
||||
.module-ff-supplies {
|
||||
@apply bg-orange-500/20 border-orange-400 text-orange-100 cursor-pointer hover:bg-orange-400/30;
|
||||
--icon-color: #f97316; /* orange-500 */
|
||||
transition: all 0.2s ease-in-out;
|
||||
@ -791,14 +788,14 @@ function PageWithSidebar() {
|
||||
<div className="w-4 h-4 rounded-full bg-blue-500"></div>
|
||||
<span className="text-blue-100 font-semibold text-lg">ТехноМир</span>
|
||||
</div>
|
||||
|
||||
|
||||
{/* УРОВЕНЬ 2: ТОВАРЫ (зеленый - средние блоки) */}
|
||||
<div className="border-l-4 border-green-500 bg-green-500/10 pl-6 ml-2 mt-2 mb-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-3 h-3 rounded-full bg-green-500"></div>
|
||||
<span className="text-green-100 font-medium">Смартфон iPhone 15</span>
|
||||
</div>
|
||||
|
||||
|
||||
{/* УРОВЕНЬ 3: ВАРИАНТЫ (оранжевый - мелкие блоки) */}
|
||||
<div className="border-l-2 border-orange-500 bg-orange-500/10 pl-4 ml-1 mt-1">
|
||||
<div className="flex items-center gap-2">
|
||||
@ -816,49 +813,49 @@ function PageWithSidebar() {
|
||||
|
||||
```css
|
||||
/* 1. PENDING - ожидает подтверждения */
|
||||
.status-pending {
|
||||
.status-pending {
|
||||
@apply bg-gray-500/20 border-gray-400 text-gray-100;
|
||||
--dot-color: #6b7280;
|
||||
}
|
||||
|
||||
/* 2. SUPPLIER_APPROVED - подтверждено поставщиком */
|
||||
.status-supplier-approved {
|
||||
.status-supplier-approved {
|
||||
@apply bg-blue-500/20 border-blue-400 text-blue-100;
|
||||
--dot-color: #3b82f6;
|
||||
}
|
||||
|
||||
/* 3. CONFIRMED - подтверждено системой */
|
||||
.status-confirmed {
|
||||
.status-confirmed {
|
||||
@apply bg-cyan-500/20 border-cyan-400 text-cyan-100;
|
||||
--dot-color: #06b6d4;
|
||||
}
|
||||
|
||||
/* 4. LOGISTICS_CONFIRMED - подтверждено логистикой */
|
||||
.status-logistics-confirmed {
|
||||
.status-logistics-confirmed {
|
||||
@apply bg-indigo-500/20 border-indigo-400 text-indigo-100;
|
||||
--dot-color: #6366f1;
|
||||
}
|
||||
|
||||
/* 5. SHIPPED - отправлено */
|
||||
.status-shipped {
|
||||
.status-shipped {
|
||||
@apply bg-purple-500/20 border-purple-400 text-purple-100;
|
||||
--dot-color: #a855f7;
|
||||
}
|
||||
|
||||
/* 6. IN_TRANSIT - в пути */
|
||||
.status-in-transit {
|
||||
.status-in-transit {
|
||||
@apply bg-yellow-500/20 border-yellow-400 text-yellow-100;
|
||||
--dot-color: #eab308;
|
||||
}
|
||||
|
||||
/* 7. DELIVERED - доставлено */
|
||||
.status-delivered {
|
||||
.status-delivered {
|
||||
@apply bg-green-500/20 border-green-400 text-green-100;
|
||||
--dot-color: #22c55e;
|
||||
}
|
||||
|
||||
/* 8. COMPLETED - завершено (только для фулфилмента) */
|
||||
.status-completed {
|
||||
.status-completed {
|
||||
@apply bg-emerald-600/20 border-emerald-500 text-emerald-100;
|
||||
--dot-color: #059669;
|
||||
}
|
||||
@ -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 */
|
||||
}
|
||||
```
|
||||
|
||||
@ -941,7 +938,7 @@ const productCreationSteps = [
|
||||
// ✅ ПРАВИЛЬНАЯ архитектура (согласно rules-complete.md)
|
||||
export function SuppliesPage() {
|
||||
const { getSidebarMargin } = useSidebar();
|
||||
|
||||
|
||||
return (
|
||||
<div className="h-screen flex overflow-hidden">
|
||||
<Sidebar />
|
||||
@ -951,12 +948,12 @@ export function SuppliesPage() {
|
||||
<div className="bg-white/10 backdrop-blur-xl border border-white/20 rounded-2xl p-6 mb-2">
|
||||
<TabNavigation />
|
||||
</div>
|
||||
|
||||
|
||||
{/* БЛОК 2: СТАТИСТИКА - контекстные метрики */}
|
||||
<div className="bg-white/10 backdrop-blur-xl border border-white/20 rounded-2xl p-4 mb-2">
|
||||
<SupplyStatistics />
|
||||
</div>
|
||||
|
||||
|
||||
{/* БЛОК 3: ОСНОВНОЙ КОНТЕНТ - до низа sidebar */}
|
||||
<div className="bg-white/10 backdrop-blur-xl border border-white/20 rounded-2xl flex-1 overflow-hidden">
|
||||
<SupplyContent />
|
||||
@ -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',
|
||||
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: 'Расходники селлера',
|
||||
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 Интерфейс рецептуры продукта
|
||||
@ -1040,16 +1043,16 @@ const supplyTypes = [
|
||||
// БЛОК 1: БАЗОВЫЙ ТОВАР (слева)
|
||||
<div className="w-1/3 bg-white/5 border border-white/10 rounded-xl p-4">
|
||||
<h3 className="text-white font-semibold mb-3">1. Базовый товар</h3>
|
||||
<ProductSelector
|
||||
<ProductSelector
|
||||
placeholder="Выберите товар от поставщика"
|
||||
filterType="PRODUCT"
|
||||
filterType="PRODUCT"
|
||||
/>
|
||||
</div>
|
||||
|
||||
// БЛОК 2: УСЛУГИ ФУЛФИЛМЕНТА (центр)
|
||||
<div className="w-1/3 bg-white/5 border border-white/10 rounded-xl p-4">
|
||||
<h3 className="text-white font-semibold mb-3">2. Услуги ФФ</h3>
|
||||
<ServicesSelector
|
||||
<ServicesSelector
|
||||
placeholder="Упаковка, маркировка..."
|
||||
multiSelect={true}
|
||||
/>
|
||||
@ -1058,7 +1061,7 @@ const supplyTypes = [
|
||||
// БЛОК 3: РАСХОДНИКИ (справа)
|
||||
<div className="w-1/3 bg-white/5 border border-white/10 rounded-xl p-4">
|
||||
<h3 className="text-white font-semibold mb-3">3. Расходники</h3>
|
||||
<ConsumablesSelector
|
||||
<ConsumablesSelector
|
||||
placeholder="Материалы для производства"
|
||||
filterType="CONSUMABLE"
|
||||
/>
|
||||
@ -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,8 +1106,9 @@ const supplyTypes = [
|
||||
**📅 ДАТА**: 2025, полная синхронизация с техническими требованиями
|
||||
|
||||
### 🆕 ДОБАВЛЕНИЯ v1.2:
|
||||
|
||||
- ✅ Детальные правила для кабинета селлера (раздел 14.5)
|
||||
- ✅ Трёхблочная архитектура страницы "Мои поставки"
|
||||
- ✅ Трёхблочная архитектура страницы "Мои поставки"
|
||||
- ✅ Контекстная статистика по типам поставок
|
||||
- ✅ Визуальные компоненты создания рецептуры
|
||||
- ✅ WB интеграция и статусы синхронизации
|
||||
|
Reference in New Issue
Block a user