Добавлен новый компонент WBWarehouseDemo и соответствующая вкладка в UIKitSection. Обновлен компонент WBWarehouseDashboard: улучшена логика загрузки данных, добавлены новые функции для обработки аналитики и фильтрации товаров. Оптимизирован интерфейс с использованием новых компонентов для поиска и отображения статистики. Обновлены стили и структура кода для повышения удобства использования.

This commit is contained in:
Bivekich
2025-07-24 12:11:52 +03:00
parent 01704d7b20
commit f65e9c42f6
10 changed files with 2198 additions and 864 deletions

View 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>
);
}