Files
sfera/src/components/fulfillment-supplies/goods-supplies/marketplace-supplies-tab.tsx

299 lines
11 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client"
import { useState } from 'react'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { ShoppingCart, Package, Plus, Calendar, TrendingUp, AlertCircle, Building2 } from 'lucide-react'
interface MarketplaceSupply {
id: string
name: string
marketplace: 'wildberries' | 'ozon'
category: string
quantity: number
status: 'planned' | 'in-transit' | 'delivered' | 'accepted'
date: string
warehouse: string
amount: number
sku: string
}
const mockMarketplaceSupplies: MarketplaceSupply[] = [
{
id: '1',
name: 'Наушники AirPods Pro',
marketplace: 'wildberries',
category: 'Аудио',
quantity: 30,
status: 'delivered',
date: '2024-01-20',
warehouse: 'WB Подольск',
amount: 750000,
sku: 'APL-AP-PRO2'
},
{
id: '2',
name: 'Смарт часы Apple Watch',
marketplace: 'ozon',
category: 'Электроника',
quantity: 25,
status: 'in-transit',
date: '2024-01-22',
warehouse: 'Ozon Тверь',
amount: 1250000,
sku: 'APL-AW-S9'
},
{
id: '3',
name: 'Зарядные устройства',
marketplace: 'wildberries',
category: 'Аксессуары',
quantity: 100,
status: 'accepted',
date: '2024-01-18',
warehouse: 'WB Электросталь',
amount: 350000,
sku: 'ACC-CHG-20W'
}
]
export function MarketplaceSuppliesTab() {
const [activeMarketplace, setActiveMarketplace] = useState<'all' | 'wildberries' | 'ozon'>('all')
const formatCurrency = (amount: number) => {
return new Intl.NumberFormat('ru-RU', {
style: 'currency',
currency: 'RUB',
minimumFractionDigits: 0
}).format(amount)
}
const formatDate = (dateString: string) => {
return new Date(dateString).toLocaleDateString('ru-RU', {
day: '2-digit',
month: '2-digit',
year: 'numeric'
})
}
const getStatusBadge = (status: string) => {
const statusConfig = {
planned: { variant: 'outline' as const, color: 'text-blue-300 border-blue-400/30', label: 'Запланировано' },
'in-transit': { variant: 'outline' as const, color: 'text-yellow-300 border-yellow-400/30', label: 'В пути' },
delivered: { variant: 'outline' as const, color: 'text-green-300 border-green-400/30', label: 'Доставлено' },
accepted: { variant: 'outline' as const, color: 'text-purple-300 border-purple-400/30', label: 'Принято' }
}
const config = statusConfig[status as keyof typeof statusConfig] || statusConfig.planned
return (
<Badge variant={config.variant} className={`glass-secondary ${config.color}`}>
{config.label}
</Badge>
)
}
const getMarketplaceBadge = (marketplace: string) => {
if (marketplace === 'wildberries') {
return (
<Badge variant="outline" className="glass-secondary text-purple-300 border-purple-400/30">
Wildberries
</Badge>
)
} else if (marketplace === 'ozon') {
return (
<Badge variant="outline" className="glass-secondary text-blue-300 border-blue-400/30">
Ozon
</Badge>
)
}
return null
}
const filteredSupplies = activeMarketplace === 'all'
? mockMarketplaceSupplies
: mockMarketplaceSupplies.filter(supply => supply.marketplace === activeMarketplace)
const getTotalAmount = () => {
return filteredSupplies.reduce((sum, supply) => sum + supply.amount, 0)
}
const getTotalQuantity = () => {
return filteredSupplies.reduce((sum, supply) => sum + supply.quantity, 0)
}
return (
<div className="h-full flex flex-col space-y-4 p-4">
{/* Компактный заголовок */}
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<ShoppingCart className="h-4 w-4 text-purple-400" />
<span className="text-white font-medium text-sm">Маркетплейсы</span>
</div>
<Button
size="sm"
className="bg-gradient-to-r from-purple-500 to-pink-500 hover:from-purple-600 hover:to-pink-600 text-white text-xs"
>
<Plus className="h-3 w-3 mr-1" />
Создать
</Button>
</div>
{/* Компактная статистика */}
<div className="grid grid-cols-2 lg:grid-cols-4 gap-3">
<Card className="glass-card p-3">
<div className="flex items-center space-x-2">
<div className="p-1.5 bg-purple-500/20 rounded">
<Package className="h-3 w-3 text-purple-400" />
</div>
<div>
<p className="text-white/60 text-xs">Поставок</p>
<p className="text-lg font-bold text-white">{filteredSupplies.length}</p>
</div>
</div>
</Card>
<Card className="glass-card p-4">
<div className="flex items-center space-x-3">
<div className="p-2 bg-green-500/20 rounded-lg">
<TrendingUp className="h-5 w-5 text-green-400" />
</div>
<div>
<p className="text-white/60 text-sm">Общая сумма</p>
<p className="text-xl font-bold text-white">{formatCurrency(getTotalAmount())}</p>
</div>
</div>
</Card>
<Card className="glass-card p-4">
<div className="flex items-center space-x-3">
<div className="p-2 bg-blue-500/20 rounded-lg">
<AlertCircle className="h-5 w-5 text-blue-400" />
</div>
<div>
<p className="text-white/60 text-sm">Единиц товара</p>
<p className="text-xl font-bold text-white">{getTotalQuantity()}</p>
</div>
</div>
</Card>
<Card className="glass-card p-4">
<div className="flex items-center space-x-3">
<div className="p-2 bg-yellow-500/20 rounded-lg">
<Calendar className="h-5 w-5 text-yellow-400" />
</div>
<div>
<p className="text-white/60 text-sm">В пути</p>
<p className="text-xl font-bold text-white">
{filteredSupplies.filter(s => s.status === 'in-transit').length}
</p>
</div>
</div>
</Card>
</div>
{/* Фильтры по маркетплейсу */}
<div className="flex items-center space-x-2">
<span className="text-white/60 text-sm">Маркетплейс:</span>
<div className="flex space-x-2">
<Button
variant={activeMarketplace === 'all' ? 'secondary' : 'ghost'}
size="sm"
onClick={() => setActiveMarketplace('all')}
className={`${activeMarketplace === 'all' ? 'bg-white/20 text-white' : 'text-white/70 hover:bg-white/10'}`}
>
Все
</Button>
<Button
variant={activeMarketplace === 'wildberries' ? 'secondary' : 'ghost'}
size="sm"
onClick={() => setActiveMarketplace('wildberries')}
className={`${activeMarketplace === 'wildberries' ? 'bg-white/20 text-white' : 'text-white/70 hover:bg-white/10'} flex items-center gap-1`}
>
<div className="w-3 h-3 bg-purple-400 rounded-full"></div>
Wildberries
</Button>
<Button
variant={activeMarketplace === 'ozon' ? 'secondary' : 'ghost'}
size="sm"
onClick={() => setActiveMarketplace('ozon')}
className={`${activeMarketplace === 'ozon' ? 'bg-white/20 text-white' : 'text-white/70 hover:bg-white/10'} flex items-center gap-1`}
>
<div className="w-3 h-3 bg-blue-400 rounded-full"></div>
Ozon
</Button>
</div>
</div>
{/* Таблица поставок */}
<Card className="glass-card flex-1 overflow-hidden">
<div className="p-6 h-full flex flex-col">
<div className="overflow-x-auto flex-1">
<table className="w-full">
<thead>
<tr className="border-b border-white/20">
<th className="text-left p-3 text-white font-semibold">Маркетплейс</th>
<th className="text-left p-3 text-white font-semibold">Наименование</th>
<th className="text-left p-3 text-white font-semibold">SKU</th>
<th className="text-left p-3 text-white font-semibold">Категория</th>
<th className="text-left p-3 text-white font-semibold">Количество</th>
<th className="text-left p-3 text-white font-semibold">Склад</th>
<th className="text-left p-3 text-white font-semibold">Дата</th>
<th className="text-left p-3 text-white font-semibold">Сумма</th>
<th className="text-left p-3 text-white font-semibold">Статус</th>
</tr>
</thead>
<tbody>
{filteredSupplies.map((supply) => (
<tr key={supply.id} className="border-b border-white/10 hover:bg-white/5 transition-colors">
<td className="p-3">
{getMarketplaceBadge(supply.marketplace)}
</td>
<td className="p-3">
<span className="text-white font-medium">{supply.name}</span>
</td>
<td className="p-3">
<span className="text-white/80 font-mono text-sm">{supply.sku}</span>
</td>
<td className="p-3">
<span className="text-white/80">{supply.category}</span>
</td>
<td className="p-3">
<span className="text-white font-semibold">{supply.quantity}</span>
</td>
<td className="p-3">
<span className="text-white/80">{supply.warehouse}</span>
</td>
<td className="p-3">
<span className="text-white/80">{formatDate(supply.date)}</span>
</td>
<td className="p-3">
<span className="text-white font-semibold">{formatCurrency(supply.amount)}</span>
</td>
<td className="p-3">
{getStatusBadge(supply.status)}
</td>
</tr>
))}
</tbody>
</table>
{filteredSupplies.length === 0 && (
<div className="flex items-center justify-center p-8">
<div className="text-center">
<ShoppingCart className="h-12 w-12 text-white/20 mx-auto mb-4" />
<p className="text-white/60">Поставки не найдены</p>
<p className="text-white/40 text-sm mt-2">
Измените фильтр или создайте новую поставку
</p>
</div>
</div>
)}
</div>
</div>
</Card>
</div>
)
}