Добавлен новый компонент WBWarehouseDemo и соответствующая вкладка в UIKitSection. Обновлен компонент WBWarehouseDashboard: улучшена логика загрузки данных, добавлены новые функции для обработки аналитики и фильтрации товаров. Оптимизирован интерфейс с использованием новых компонентов для поиска и отображения статистики. Обновлены стили и структура кода для повышения удобства использования.
This commit is contained in:
315
src/components/admin/ui-kit/wb-warehouse-demo.tsx
Normal file
315
src/components/admin/ui-kit/wb-warehouse-demo.tsx
Normal file
@ -0,0 +1,315 @@
|
||||
"use client";
|
||||
|
||||
import React from 'react';
|
||||
import { StatsCards } from '@/components/wb-warehouse/stats-cards';
|
||||
import { SearchBar } from '@/components/wb-warehouse/search-bar';
|
||||
import { TableHeader } from '@/components/wb-warehouse/table-header';
|
||||
import { LoadingSkeleton } from '@/components/wb-warehouse/loading-skeleton';
|
||||
import { StockTableRow } from '@/components/wb-warehouse/stock-table-row';
|
||||
|
||||
export function WBWarehouseDemo() {
|
||||
// Мок данные для демонстрации
|
||||
const mockStatsData = {
|
||||
totalProducts: 156,
|
||||
totalStocks: 12847,
|
||||
totalReserved: 342,
|
||||
totalFromClient: 28,
|
||||
activeWarehouses: 12,
|
||||
loading: false
|
||||
};
|
||||
|
||||
const mockStockItem = {
|
||||
nmId: 444711032,
|
||||
vendorCode: "V326",
|
||||
title: "Электробритва для бороды с 3D головками триммер беспроводной",
|
||||
brand: "ANNRennel",
|
||||
price: 2990,
|
||||
stocks: [
|
||||
{
|
||||
warehouseId: 120762,
|
||||
warehouseName: "Электросталь",
|
||||
quantity: 188,
|
||||
quantityFull: 188,
|
||||
inWayToClient: 2,
|
||||
inWayFromClient: 1
|
||||
},
|
||||
{
|
||||
warehouseId: 507,
|
||||
warehouseName: "Коледино",
|
||||
quantity: 0,
|
||||
quantityFull: 0,
|
||||
inWayToClient: 3,
|
||||
inWayFromClient: 1
|
||||
},
|
||||
{
|
||||
warehouseId: 208277,
|
||||
warehouseName: "Невинномысск",
|
||||
quantity: 56,
|
||||
quantityFull: 56,
|
||||
inWayToClient: 0,
|
||||
inWayFromClient: 0
|
||||
},
|
||||
{
|
||||
warehouseId: 130744,
|
||||
warehouseName: "Краснодар",
|
||||
quantity: 1,
|
||||
quantityFull: 1,
|
||||
inWayToClient: 0,
|
||||
inWayFromClient: 0
|
||||
}
|
||||
],
|
||||
totalQuantity: 245,
|
||||
totalReserved: 5,
|
||||
photos: [
|
||||
{
|
||||
big: "https://basket-04.wbbasket.ru/vol444/part44471/444711032/images/big/1.webp",
|
||||
c246x328: "https://basket-04.wbbasket.ru/vol444/part44471/444711032/images/c246x328/1.webp"
|
||||
}
|
||||
],
|
||||
mediaFiles: [],
|
||||
characteristics: [
|
||||
{ name: "Способ бритья", value: "сухое" },
|
||||
{ name: "Модель", value: "V326" },
|
||||
{ name: "Время работы от аккумулятора (мин)", value: "60" },
|
||||
{ name: "Гарантийный срок", value: "1 год" },
|
||||
{ name: "Цвет", value: ["синий", "черный"] }
|
||||
],
|
||||
subjectName: "Триммеры",
|
||||
description: "Триммер для бороды - незаменимый помощник для каждого парня и мужчины."
|
||||
};
|
||||
|
||||
const [searchTerm, setSearchTerm] = React.useState("");
|
||||
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
{/* Заголовок секции */}
|
||||
<div>
|
||||
<h2 className="text-2xl font-bold text-white mb-2">WB Warehouse Components</h2>
|
||||
<p className="text-white/70">
|
||||
Компоненты для страницы склада Wildberries
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Stats Cards */}
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-white mb-4">📊 StatsCards - Карточки статистики</h3>
|
||||
<div className="p-4 rounded-lg bg-white/5 border border-white/10">
|
||||
<StatsCards {...mockStatsData} />
|
||||
|
||||
<div className="mt-4 p-3 rounded bg-black/20 border border-white/5">
|
||||
<p className="text-white/60 text-sm mb-2">📝 Код использования:</p>
|
||||
<pre className="text-green-400 text-xs overflow-x-auto">
|
||||
{`<StatsCards
|
||||
totalProducts={156}
|
||||
totalStocks={12847}
|
||||
totalReserved={342}
|
||||
totalFromClient={28}
|
||||
activeWarehouses={12}
|
||||
loading={false}
|
||||
/>`}
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Search Bar */}
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-white mb-4">🔍 SearchBar - Поиск товаров</h3>
|
||||
<div className="p-4 rounded-lg bg-white/5 border border-white/10">
|
||||
<SearchBar
|
||||
searchTerm={searchTerm}
|
||||
onSearchChange={setSearchTerm}
|
||||
/>
|
||||
|
||||
<div className="mt-4 p-3 rounded bg-black/20 border border-white/5">
|
||||
<p className="text-white/60 text-sm mb-2">📝 Код использования:</p>
|
||||
<pre className="text-green-400 text-xs overflow-x-auto">
|
||||
{`<SearchBar
|
||||
searchTerm={searchTerm}
|
||||
onSearchChange={setSearchTerm}
|
||||
/>`}
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Table Header */}
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-white mb-4">📋 TableHeader - Шапка таблицы</h3>
|
||||
<div className="p-4 rounded-lg bg-white/5 border border-white/10">
|
||||
<TableHeader />
|
||||
|
||||
<div className="mt-4 p-3 rounded bg-black/20 border border-white/5">
|
||||
<p className="text-white/60 text-sm mb-2">📝 Код использования:</p>
|
||||
<pre className="text-green-400 text-xs overflow-x-auto">
|
||||
{`<TableHeader />`}
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Loading Skeleton */}
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-white mb-4">⏳ LoadingSkeleton - Скелетоны загрузки</h3>
|
||||
<div className="p-4 rounded-lg bg-white/5 border border-white/10">
|
||||
<div className="max-h-96 overflow-hidden">
|
||||
<LoadingSkeleton />
|
||||
</div>
|
||||
|
||||
<div className="mt-4 p-3 rounded bg-black/20 border border-white/5">
|
||||
<p className="text-white/60 text-sm mb-2">📝 Код использования:</p>
|
||||
<pre className="text-green-400 text-xs overflow-x-auto">
|
||||
{`<LoadingSkeleton />`}
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Stock Table Row */}
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-white mb-4">📦 StockTableRow - Строка товара</h3>
|
||||
<div className="p-4 rounded-lg bg-white/5 border border-white/10">
|
||||
<StockTableRow item={mockStockItem} />
|
||||
|
||||
<div className="mt-4 p-3 rounded bg-black/20 border border-white/5">
|
||||
<p className="text-white/60 text-sm mb-2">📝 Код использования:</p>
|
||||
<pre className="text-green-400 text-xs overflow-x-auto">
|
||||
{`<StockTableRow item={stockItem} />
|
||||
|
||||
// где stockItem содержит:
|
||||
// - nmId, vendorCode, title, brand
|
||||
// - stocks[] - данные по складам
|
||||
// - totalQuantity, totalReserved
|
||||
// - photos[], characteristics[]
|
||||
// - subjectName, description`}
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* States Demo */}
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-white mb-4">🎭 States - Состояния компонентов</h3>
|
||||
<div className="space-y-4">
|
||||
|
||||
{/* Loading State */}
|
||||
<div className="p-4 rounded-lg bg-white/5 border border-white/10">
|
||||
<h4 className="text-white/80 font-medium mb-3">⏳ Loading State</h4>
|
||||
<StatsCards {...mockStatsData} loading={true} />
|
||||
</div>
|
||||
|
||||
{/* Empty State */}
|
||||
<div className="p-4 rounded-lg bg-white/5 border border-white/10">
|
||||
<h4 className="text-white/80 font-medium mb-3">🔍 Search State</h4>
|
||||
<SearchBar
|
||||
searchTerm="электробритва"
|
||||
onSearchChange={() => {}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Multiple Stock Rows */}
|
||||
<div className="p-4 rounded-lg bg-white/5 border border-white/10">
|
||||
<h4 className="text-white/80 font-medium mb-3">📋 Table with Multiple Items</h4>
|
||||
<TableHeader />
|
||||
<div className="space-y-1 mt-3">
|
||||
<StockTableRow item={mockStockItem} />
|
||||
<StockTableRow item={{
|
||||
...mockStockItem,
|
||||
nmId: 444830802,
|
||||
vendorCode: "V319",
|
||||
title: "Электробритва для бороды влагозащитная с дисплеем",
|
||||
totalQuantity: 133,
|
||||
stocks: [
|
||||
{
|
||||
warehouseId: 120762,
|
||||
warehouseName: "Электросталь",
|
||||
quantity: 88,
|
||||
quantityFull: 88,
|
||||
inWayToClient: 1,
|
||||
inWayFromClient: 0
|
||||
},
|
||||
{
|
||||
warehouseId: 208277,
|
||||
warehouseName: "Невинномысск",
|
||||
quantity: 45,
|
||||
quantityFull: 45,
|
||||
inWayToClient: 2,
|
||||
inWayFromClient: 1
|
||||
}
|
||||
]
|
||||
}} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Color Variants */}
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-white mb-4">🎨 Color Variants - Цветовые варианты</h3>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-4">
|
||||
|
||||
{/* Товары - синий */}
|
||||
<div className="p-3 rounded-lg bg-gradient-to-br from-blue-500/20 to-blue-600/10 border border-blue-500/20">
|
||||
<div className="text-blue-400 text-xl font-bold">156</div>
|
||||
<div className="text-blue-300 text-xs">Товаров</div>
|
||||
</div>
|
||||
|
||||
{/* Остаток - зеленый */}
|
||||
<div className="p-3 rounded-lg bg-gradient-to-br from-green-500/20 to-green-600/10 border border-green-500/20">
|
||||
<div className="text-green-400 text-xl font-bold">12,847</div>
|
||||
<div className="text-green-300 text-xs">Остаток</div>
|
||||
</div>
|
||||
|
||||
{/* К клиенту - оранжевый */}
|
||||
<div className="p-3 rounded-lg bg-gradient-to-br from-orange-500/20 to-orange-600/10 border border-orange-500/20">
|
||||
<div className="text-orange-400 text-xl font-bold">342</div>
|
||||
<div className="text-orange-300 text-xs">К клиенту</div>
|
||||
</div>
|
||||
|
||||
{/* От клиента - красный */}
|
||||
<div className="p-3 rounded-lg bg-gradient-to-br from-red-500/20 to-red-600/10 border border-red-500/20">
|
||||
<div className="text-red-400 text-xl font-bold">28</div>
|
||||
<div className="text-red-300 text-xs">От клиента</div>
|
||||
</div>
|
||||
|
||||
{/* Складов - фиолетовый */}
|
||||
<div className="p-3 rounded-lg bg-gradient-to-br from-purple-500/20 to-purple-600/10 border border-purple-500/20">
|
||||
<div className="text-purple-400 text-xl font-bold">12</div>
|
||||
<div className="text-purple-300 text-xs">Складов</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Usage Guidelines */}
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-white mb-4">📚 Usage Guidelines - Рекомендации</h3>
|
||||
<div className="p-4 rounded-lg bg-white/5 border border-white/10">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
|
||||
<div>
|
||||
<h4 className="text-white font-medium mb-2">✅ Правильно</h4>
|
||||
<ul className="text-green-400 text-sm space-y-1">
|
||||
<li>• Используй StatsCards для отображения ключевых метрик</li>
|
||||
<li>• SearchBar всегда размещай перед таблицей</li>
|
||||
<li>• TableHeader обязателен для понимания структуры</li>
|
||||
<li>• LoadingSkeleton соответствует структуре данных</li>
|
||||
<li>• StockTableRow содержит основную и дополнительную информацию</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h4 className="text-white font-medium mb-2">❌ Неправильно</h4>
|
||||
<ul className="text-red-400 text-sm space-y-1">
|
||||
<li>• Не используй StatsCards без данных</li>
|
||||
<li>• Не размещай SearchBar после таблицы</li>
|
||||
<li>• Не показывай данные без TableHeader</li>
|
||||
<li>• Не используй LoadingSkeleton с готовыми данными</li>
|
||||
<li>• Не модифицируй внутреннюю структуру StockTableRow</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
Reference in New Issue
Block a user