844 lines
36 KiB
TypeScript
844 lines
36 KiB
TypeScript
"use client"
|
||
|
||
import { useState } from 'react'
|
||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
||
import { Badge } from '@/components/ui/badge'
|
||
import { Button } from '@/components/ui/button'
|
||
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
|
||
import { Progress } from '@/components/ui/progress'
|
||
import { Input } from '@/components/ui/input'
|
||
import {
|
||
Select,
|
||
SelectContent,
|
||
SelectItem,
|
||
SelectTrigger,
|
||
SelectValue,
|
||
} from '@/components/ui/select'
|
||
import {
|
||
Calendar,
|
||
Check,
|
||
X,
|
||
Clock,
|
||
User,
|
||
Package,
|
||
Star,
|
||
Heart,
|
||
ShoppingCart,
|
||
Edit,
|
||
Trash2,
|
||
Phone,
|
||
Mail,
|
||
MapPin,
|
||
Building,
|
||
TrendingUp,
|
||
Award,
|
||
Users,
|
||
Briefcase,
|
||
Eye,
|
||
Plus,
|
||
Minus,
|
||
Store,
|
||
Boxes,
|
||
ChevronDown,
|
||
ChevronRight,
|
||
Hash,
|
||
Package2,
|
||
Truck
|
||
} from 'lucide-react'
|
||
|
||
export function BusinessDemo() {
|
||
const [selectedProduct] = useState(null)
|
||
const [cartQuantity, setCartQuantity] = useState(1)
|
||
const [expandedSeller, setExpandedSeller] = useState(false)
|
||
|
||
// Данные для демонстрации
|
||
const scheduleData = Array.from({ length: 30 }, (_, i) => ({
|
||
day: i + 1,
|
||
status: ['work', 'work', 'work', 'work', 'work', 'weekend', 'weekend'][i % 7],
|
||
hours: [8, 8, 8, 8, 8, 0, 0][i % 7]
|
||
}))
|
||
|
||
const products = [
|
||
{
|
||
id: '1',
|
||
name: 'iPhone 15 Pro Max 256GB',
|
||
article: 'APL-IP15PM-256',
|
||
price: 89990,
|
||
oldPrice: 99990,
|
||
quantity: 45,
|
||
category: 'Электроника',
|
||
brand: 'Apple',
|
||
rating: 4.8,
|
||
reviews: 1234,
|
||
image: '/placeholder-phone.jpg',
|
||
seller: 'TechStore Moscow',
|
||
isNew: true,
|
||
inStock: true
|
||
},
|
||
{
|
||
id: '2',
|
||
name: 'Беспроводные наушники AirPods Pro',
|
||
article: 'APL-APP-PRO',
|
||
price: 24990,
|
||
quantity: 23,
|
||
category: 'Аксессуары',
|
||
brand: 'Apple',
|
||
rating: 4.6,
|
||
reviews: 856,
|
||
image: '/placeholder-headphones.jpg',
|
||
seller: 'Audio Expert',
|
||
isNew: false,
|
||
inStock: true
|
||
},
|
||
{
|
||
id: '3',
|
||
name: 'Ноутбук MacBook Air M2',
|
||
article: 'APL-MBA-M2',
|
||
price: 0,
|
||
quantity: 0,
|
||
category: 'Компьютеры',
|
||
brand: 'Apple',
|
||
rating: 4.9,
|
||
reviews: 445,
|
||
image: '/placeholder-laptop.jpg',
|
||
seller: 'Digital World',
|
||
isNew: false,
|
||
inStock: false
|
||
}
|
||
]
|
||
|
||
// Данные для поставки фулфилмента
|
||
const fulfillmentSupply = {
|
||
id: "1",
|
||
supplyNumber: "ФФ-2024-001",
|
||
supplyDate: "2024-01-15",
|
||
seller: {
|
||
id: "seller1",
|
||
name: "TechStore LLC",
|
||
storeName: "ТехноМагазин",
|
||
managerName: "Иванов Иван Иванович",
|
||
phone: "+7 (495) 123-45-67",
|
||
email: "contact@techstore.ru",
|
||
inn: "7701234567",
|
||
},
|
||
itemsQuantity: 150,
|
||
cargoPlaces: 5,
|
||
volume: 12.5,
|
||
responsibleEmployeeId: "emp1",
|
||
logisticsPartnerId: "log1",
|
||
status: "planned",
|
||
totalValue: 2500000,
|
||
}
|
||
|
||
const employees = [
|
||
{ id: "emp1", firstName: "Иван", lastName: "Петров", position: "Менеджер склада" },
|
||
{ id: "emp2", firstName: "Мария", lastName: "Сидорова", position: "Логист" }
|
||
]
|
||
|
||
const logisticsPartners = [
|
||
{ id: "log1", name: "ТК Энергия", fullName: "ООО ТК Энергия" },
|
||
{ id: "log2", name: "СДЭК", fullName: "ООО СДЭК" }
|
||
]
|
||
|
||
const wholesalers = [
|
||
{
|
||
id: '1',
|
||
name: 'ТехноОпт Москва',
|
||
fullName: 'ООО "Технологии Оптом"',
|
||
inn: '7735123456',
|
||
type: 'WHOLESALE',
|
||
avatar: '/placeholder-company.jpg',
|
||
rating: 4.8,
|
||
reviewsCount: 2345,
|
||
productsCount: 15670,
|
||
completedOrders: 8934,
|
||
responseTime: '2 часа',
|
||
categories: ['Электроника', 'Компьютеры', 'Аксессуары'],
|
||
location: 'Москва, Россия',
|
||
workingSince: '2018',
|
||
verifiedBadges: ['verified', 'premium', 'fast-delivery'],
|
||
description: 'Крупнейший поставщик электроники и компьютерной техники в России',
|
||
specialOffers: 3,
|
||
minOrder: 50000
|
||
},
|
||
{
|
||
id: '2',
|
||
name: 'СтройБаза Регион',
|
||
fullName: 'ИП Строительные материалы',
|
||
inn: '7735987654',
|
||
type: 'WHOLESALE',
|
||
avatar: '/placeholder-construction.jpg',
|
||
rating: 4.5,
|
||
reviewsCount: 1876,
|
||
productsCount: 8430,
|
||
completedOrders: 5621,
|
||
responseTime: '4 часа',
|
||
categories: ['Стройматериалы', 'Инструменты', 'Сантехника'],
|
||
location: 'Екатеринбург, Россия',
|
||
workingSince: '2015',
|
||
verifiedBadges: ['verified', 'eco-friendly'],
|
||
description: 'Надежный поставщик строительных материалов по всей России',
|
||
specialOffers: 1,
|
||
minOrder: 30000
|
||
}
|
||
]
|
||
|
||
const getStatusColor = (status: string) => {
|
||
switch (status) {
|
||
case 'work': return 'bg-green-500'
|
||
case 'weekend': return 'bg-gray-400'
|
||
case 'vacation': return 'bg-blue-500'
|
||
case 'sick': return 'bg-yellow-500'
|
||
case 'absent': return 'bg-red-500'
|
||
default: return 'bg-gray-400'
|
||
}
|
||
}
|
||
|
||
const getStatusText = (status: string) => {
|
||
switch (status) {
|
||
case 'work': return 'Работа'
|
||
case 'weekend': return 'Выходной'
|
||
case 'vacation': return 'Отпуск'
|
||
case 'sick': return 'Больничный'
|
||
case 'absent': return 'Прогул'
|
||
default: return 'Неизвестно'
|
||
}
|
||
}
|
||
|
||
const formatPrice = (price: number) => {
|
||
return new Intl.NumberFormat('ru-RU', {
|
||
style: 'currency',
|
||
currency: 'RUB',
|
||
minimumFractionDigits: 0
|
||
}).format(price)
|
||
}
|
||
|
||
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: {
|
||
color: "text-blue-300 border-blue-400/30",
|
||
label: "Запланировано",
|
||
},
|
||
"in-transit": {
|
||
color: "text-yellow-300 border-yellow-400/30",
|
||
label: "В пути",
|
||
},
|
||
delivered: {
|
||
color: "text-green-300 border-green-400/30",
|
||
label: "Доставлено",
|
||
},
|
||
"in-processing": {
|
||
color: "text-purple-300 border-purple-400/30",
|
||
label: "Обрабатывается",
|
||
},
|
||
}
|
||
|
||
const config =
|
||
statusConfig[status as keyof typeof statusConfig] || statusConfig.planned
|
||
|
||
return (
|
||
<Badge variant="outline" className={`glass-secondary ${config.color}`}>
|
||
{config.label}
|
||
</Badge>
|
||
)
|
||
}
|
||
|
||
return (
|
||
<div className="space-y-6">
|
||
{/* Табель рабочего времени */}
|
||
<Card className="glass-card border-white/10">
|
||
<CardHeader>
|
||
<CardTitle className="text-white">Табель рабочего времени</CardTitle>
|
||
</CardHeader>
|
||
<CardContent className="space-y-6">
|
||
{/* Заголовок табеля */}
|
||
<div className="flex items-center justify-between">
|
||
<div className="flex items-center space-x-3">
|
||
<Avatar className="h-10 w-10">
|
||
<AvatarImage src="/placeholder-employee.jpg" />
|
||
<AvatarFallback className="bg-purple-600 text-white">ИИ</AvatarFallback>
|
||
</Avatar>
|
||
<div>
|
||
<h4 className="text-white font-medium">Иванов Иван Иванович</h4>
|
||
<p className="text-white/60 text-sm">Менеджер по продажам • Март 2024</p>
|
||
</div>
|
||
</div>
|
||
<div className="text-right">
|
||
<p className="text-white text-lg font-bold">176 часов</p>
|
||
<p className="text-white/60 text-sm">Отработано в месяце</p>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Календарь */}
|
||
<div className="space-y-4">
|
||
<div className="grid grid-cols-7 gap-2 text-center text-sm text-white/70">
|
||
<div>Пн</div>
|
||
<div>Вт</div>
|
||
<div>Ср</div>
|
||
<div>Чт</div>
|
||
<div>Пт</div>
|
||
<div>Сб</div>
|
||
<div>Вс</div>
|
||
</div>
|
||
|
||
<div className="grid grid-cols-7 gap-2">
|
||
{scheduleData.map((day, index) => (
|
||
<div
|
||
key={index}
|
||
className={`
|
||
relative p-3 rounded-lg border border-white/10 text-center transition-all hover:border-white/30
|
||
${day.status === 'work' ? 'bg-green-500/20' : ''}
|
||
${day.status === 'weekend' ? 'bg-gray-500/20' : ''}
|
||
`}
|
||
>
|
||
<div className="text-white text-sm font-medium">{day.day}</div>
|
||
<div className={`w-2 h-2 rounded-full mx-auto mt-1 ${getStatusColor(day.status)}`}></div>
|
||
{day.hours > 0 && (
|
||
<div className="text-white/60 text-xs mt-1">{day.hours}ч</div>
|
||
)}
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
{/* Легенда */}
|
||
<div className="flex flex-wrap gap-4 text-sm">
|
||
<div className="flex items-center gap-2">
|
||
<div className="w-3 h-3 rounded-full bg-green-500"></div>
|
||
<span className="text-white/70">Работа</span>
|
||
</div>
|
||
<div className="flex items-center gap-2">
|
||
<div className="w-3 h-3 rounded-full bg-gray-400"></div>
|
||
<span className="text-white/70">Выходной</span>
|
||
</div>
|
||
<div className="flex items-center gap-2">
|
||
<div className="w-3 h-3 rounded-full bg-blue-500"></div>
|
||
<span className="text-white/70">Отпуск</span>
|
||
</div>
|
||
<div className="flex items-center gap-2">
|
||
<div className="w-3 h-3 rounded-full bg-yellow-500"></div>
|
||
<span className="text-white/70">Больничный</span>
|
||
</div>
|
||
<div className="flex items-center gap-2">
|
||
<div className="w-3 h-3 rounded-full bg-red-500"></div>
|
||
<span className="text-white/70">Прогул</span>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Статистика */}
|
||
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
|
||
<div className="glass-card p-3 rounded-lg border border-white/10">
|
||
<div className="text-white/60 text-xs">Рабочие дни</div>
|
||
<div className="text-white text-lg font-bold">22</div>
|
||
</div>
|
||
<div className="glass-card p-3 rounded-lg border border-white/10">
|
||
<div className="text-white/60 text-xs">Выходные</div>
|
||
<div className="text-white text-lg font-bold">8</div>
|
||
</div>
|
||
<div className="glass-card p-3 rounded-lg border border-white/10">
|
||
<div className="text-white/60 text-xs">Отпуск</div>
|
||
<div className="text-white text-lg font-bold">0</div>
|
||
</div>
|
||
<div className="glass-card p-3 rounded-lg border border-white/10">
|
||
<div className="text-white/60 text-xs">Опозданий</div>
|
||
<div className="text-white text-lg font-bold">2</div>
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
|
||
{/* Карточки товаров */}
|
||
<Card className="glass-card border-white/10">
|
||
<CardHeader>
|
||
<CardTitle className="text-white">Карточки товаров</CardTitle>
|
||
</CardHeader>
|
||
<CardContent className="space-y-6">
|
||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||
{products.map((product) => (
|
||
<div key={product.id} className="glass-card p-4 rounded-lg border border-white/10 group hover:border-white/30 transition-all">
|
||
{/* Изображение товара */}
|
||
<div className="relative mb-3">
|
||
<div className="w-full h-40 bg-white/10 rounded-lg flex items-center justify-center">
|
||
<Package className="h-16 w-16 text-white/40" />
|
||
</div>
|
||
|
||
{/* Бейджи */}
|
||
<div className="absolute top-2 left-2 flex flex-col gap-1">
|
||
{product.isNew && (
|
||
<Badge className="bg-green-600 text-white text-xs">Новинка</Badge>
|
||
)}
|
||
{product.oldPrice && (
|
||
<Badge className="bg-red-600 text-white text-xs">Скидка</Badge>
|
||
)}
|
||
</div>
|
||
|
||
{/* Кнопки действий */}
|
||
<div className="absolute top-2 right-2 flex flex-col gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
|
||
<Button size="sm" variant="outline" className="bg-white/20 hover:bg-white/30 text-white border-white/30 h-8 w-8 p-0">
|
||
<Heart className="h-3 w-3" />
|
||
</Button>
|
||
<Button size="sm" variant="outline" className="bg-white/20 hover:bg-white/30 text-white border-white/30 h-8 w-8 p-0">
|
||
<Eye className="h-3 w-3" />
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Информация о товаре */}
|
||
<div className="space-y-2">
|
||
<div>
|
||
<h4 className="text-white font-medium text-sm line-clamp-2">{product.name}</h4>
|
||
<p className="text-white/60 text-xs">Артикул: {product.article}</p>
|
||
</div>
|
||
|
||
{/* Рейтинг и отзывы */}
|
||
<div className="flex items-center gap-2">
|
||
<div className="flex items-center gap-1">
|
||
<Star className="h-3 w-3 fill-yellow-400 text-yellow-400" />
|
||
<span className="text-white/80 text-xs">{product.rating}</span>
|
||
</div>
|
||
<span className="text-white/60 text-xs">({product.reviews} отзывов)</span>
|
||
</div>
|
||
|
||
{/* Категория и бренд */}
|
||
<div className="flex flex-wrap gap-1">
|
||
<Badge variant="outline" className="text-xs border-white/30 text-white/70">
|
||
{product.category}
|
||
</Badge>
|
||
<Badge variant="outline" className="text-xs border-white/30 text-white/70">
|
||
{product.brand}
|
||
</Badge>
|
||
</div>
|
||
|
||
{/* Цена */}
|
||
<div className="space-y-1">
|
||
{product.price > 0 ? (
|
||
<div className="flex items-center gap-2">
|
||
<span className="text-white font-bold">{formatPrice(product.price)}</span>
|
||
{product.oldPrice && (
|
||
<span className="text-white/60 text-sm line-through">{formatPrice(product.oldPrice)}</span>
|
||
)}
|
||
</div>
|
||
) : (
|
||
<span className="text-red-400 font-medium">Нет в наличии</span>
|
||
)}
|
||
|
||
{product.inStock && product.quantity > 0 && (
|
||
<p className="text-green-400 text-xs">В наличии: {product.quantity} шт.</p>
|
||
)}
|
||
</div>
|
||
|
||
{/* Продавец */}
|
||
<div className="text-white/60 text-xs">
|
||
Продавец: {product.seller}
|
||
</div>
|
||
|
||
{/* Кнопки */}
|
||
<div className="flex gap-2 pt-2">
|
||
{product.inStock && product.price > 0 ? (
|
||
<>
|
||
<div className="flex items-center border border-white/30 rounded">
|
||
<Button size="sm" variant="ghost" className="h-7 w-7 p-0 text-white hover:bg-white/20">
|
||
<Minus className="h-3 w-3" />
|
||
</Button>
|
||
<span className="px-2 text-white text-sm">{cartQuantity}</span>
|
||
<Button size="sm" variant="ghost" className="h-7 w-7 p-0 text-white hover:bg-white/20">
|
||
<Plus className="h-3 w-3" />
|
||
</Button>
|
||
</div>
|
||
<Button size="sm" className="flex-1 bg-purple-600 hover:bg-purple-700 text-white">
|
||
<ShoppingCart className="h-3 w-3 mr-1" />
|
||
В корзину
|
||
</Button>
|
||
</>
|
||
) : (
|
||
<Button size="sm" disabled className="w-full bg-gray-600 text-white/50">
|
||
Недоступно
|
||
</Button>
|
||
)}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
|
||
{/* Карточка поставки фулфилмента */}
|
||
<Card className="glass-card border-white/10">
|
||
<CardHeader>
|
||
<CardTitle className="text-white">Карточка поставки фулфилмента</CardTitle>
|
||
</CardHeader>
|
||
<CardContent className="space-y-4">
|
||
<Card className="glass-card p-4 hover:bg-white/10 transition-colors">
|
||
<div className="space-y-3">
|
||
{/* Компактный блок с названием магазина */}
|
||
<div className="flex items-center justify-between bg-white/5 rounded-lg p-2">
|
||
<div className="flex items-center gap-3">
|
||
<div className="p-1.5 bg-green-500/20 rounded">
|
||
<Store className="h-3 w-3 text-green-400" />
|
||
</div>
|
||
<div className="flex items-center gap-2">
|
||
<span className="text-white font-medium text-sm">
|
||
{fulfillmentSupply.seller.storeName}
|
||
</span>
|
||
<span className="text-white/60 text-xs"> • </span>
|
||
<span className="text-white/80 text-xs">
|
||
{fulfillmentSupply.seller.managerName}
|
||
</span>
|
||
<span className="text-white/60 text-xs"> • </span>
|
||
<span className="text-white/80 text-xs">
|
||
{fulfillmentSupply.seller.phone}
|
||
</span>
|
||
<span className="text-white/60 text-xs"> • </span>
|
||
<div className="flex items-center gap-1">
|
||
<a
|
||
href={`https://t.me/${fulfillmentSupply.seller.phone.replace(
|
||
/[^\d]/g,
|
||
""
|
||
)}`}
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
className="p-1 bg-blue-500/20 rounded hover:bg-blue-500/30 transition-colors"
|
||
title="Написать в Telegram"
|
||
>
|
||
<svg
|
||
className="h-3 w-3 text-blue-400"
|
||
viewBox="0 0 24 24"
|
||
fill="currentColor"
|
||
>
|
||
<path d="M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z" />
|
||
</svg>
|
||
</a>
|
||
<a
|
||
href={`https://wa.me/${fulfillmentSupply.seller.phone.replace(
|
||
/[^\d]/g,
|
||
""
|
||
)}`}
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
className="p-1 bg-green-500/20 rounded hover:bg-green-500/30 transition-colors"
|
||
title="Написать в WhatsApp"
|
||
>
|
||
<svg
|
||
className="h-3 w-3 text-green-400"
|
||
viewBox="0 0 24 24"
|
||
fill="currentColor"
|
||
>
|
||
<path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893A11.821 11.821 0 0020.885 3.488" />
|
||
</svg>
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<Button
|
||
variant="ghost"
|
||
size="sm"
|
||
onClick={() => setExpandedSeller(!expandedSeller)}
|
||
className="h-6 w-6 p-0 text-white/60 hover:text-white hover:bg-white/10"
|
||
>
|
||
{expandedSeller ? (
|
||
<ChevronDown className="h-3 w-3" />
|
||
) : (
|
||
<ChevronRight className="h-3 w-3" />
|
||
)}
|
||
</Button>
|
||
</div>
|
||
|
||
{/* Скрытая детальная информация о магазине */}
|
||
{expandedSeller && (
|
||
<div className="bg-white/5 rounded-lg p-3 space-y-2">
|
||
<div className="grid grid-cols-2 gap-4">
|
||
<div>
|
||
<p className="text-white/60 text-xs">
|
||
Юридическое название
|
||
</p>
|
||
<p className="text-white text-sm">
|
||
{fulfillmentSupply.seller.name}
|
||
</p>
|
||
</div>
|
||
<div>
|
||
<p className="text-white/60 text-xs">ИНН</p>
|
||
<p className="text-white text-sm font-mono">
|
||
{fulfillmentSupply.seller.inn}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<p className="text-white/60 text-xs">Email</p>
|
||
<p className="text-white text-sm">
|
||
{fulfillmentSupply.seller.email}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{/* Единый блок со всеми параметрами в одной строке */}
|
||
<div className="bg-white/5 rounded-lg p-4">
|
||
<div className="grid grid-cols-2 lg:grid-cols-9 gap-4 items-center">
|
||
{/* Номер поставки */}
|
||
<div className="text-center">
|
||
<p className="text-white/60 text-xs mb-1">Номер</p>
|
||
<p className="text-white font-semibold text-sm">
|
||
{fulfillmentSupply.supplyNumber}
|
||
</p>
|
||
</div>
|
||
|
||
{/* Дата поставки */}
|
||
<div className="text-center">
|
||
<p className="text-white/60 text-xs mb-1">Дата</p>
|
||
<p className="text-white font-semibold text-sm">
|
||
{formatDate(fulfillmentSupply.supplyDate)}
|
||
</p>
|
||
</div>
|
||
|
||
{/* Количество товаров */}
|
||
<div className="text-center">
|
||
<p className="text-white/60 text-xs mb-1">Товаров</p>
|
||
<p className="text-white font-semibold text-sm">
|
||
{fulfillmentSupply.itemsQuantity}
|
||
</p>
|
||
</div>
|
||
|
||
{/* Количество мест */}
|
||
<div className="text-center">
|
||
<p className="text-white/60 text-xs mb-1">Мест</p>
|
||
<p className="text-white font-semibold text-sm">
|
||
{fulfillmentSupply.cargoPlaces}
|
||
</p>
|
||
</div>
|
||
|
||
{/* Объём */}
|
||
<div className="text-center">
|
||
<p className="text-white/60 text-xs mb-1">Объём</p>
|
||
<p className="text-white font-semibold text-sm">
|
||
{fulfillmentSupply.volume} м³
|
||
</p>
|
||
</div>
|
||
|
||
{/* Стоимость */}
|
||
<div className="text-center">
|
||
<p className="text-white/60 text-xs mb-1">Стоимость</p>
|
||
<p className="text-green-400 font-semibold text-sm">
|
||
{formatCurrency(fulfillmentSupply.totalValue)}
|
||
</p>
|
||
</div>
|
||
|
||
{/* Ответственный сотрудник */}
|
||
<div className="col-span-1">
|
||
<p className="text-white/60 text-xs mb-1">
|
||
Ответственный
|
||
</p>
|
||
<Select defaultValue={fulfillmentSupply.responsibleEmployeeId}>
|
||
<SelectTrigger className="h-8 glass-input bg-white/10 border-white/20 text-white hover:bg-white/15 focus:bg-white/15 focus:ring-1 focus:ring-purple-400/50 text-xs">
|
||
<SelectValue placeholder="Выберите" />
|
||
</SelectTrigger>
|
||
<SelectContent className="bg-gray-900/95 backdrop-blur border-white/20 text-white">
|
||
{employees.map((employee) => (
|
||
<SelectItem
|
||
key={employee.id}
|
||
value={employee.id}
|
||
className="text-white hover:bg-white/10 focus:bg-white/10 text-xs"
|
||
>
|
||
<div className="flex flex-col">
|
||
<span className="font-medium">
|
||
{employee.firstName} {employee.lastName}
|
||
</span>
|
||
<span className="text-xs text-white/60">
|
||
{employee.position}
|
||
</span>
|
||
</div>
|
||
</SelectItem>
|
||
))}
|
||
</SelectContent>
|
||
</Select>
|
||
</div>
|
||
|
||
{/* Логистический партнер */}
|
||
<div className="col-span-1">
|
||
<p className="text-white/60 text-xs mb-1">Логистика</p>
|
||
<Select defaultValue={fulfillmentSupply.logisticsPartnerId}>
|
||
<SelectTrigger className="h-8 glass-input bg-white/10 border-white/20 text-white hover:bg-white/15 focus:bg-white/15 focus:ring-1 focus:ring-orange-400/50 text-xs">
|
||
<SelectValue placeholder="Выберите" />
|
||
</SelectTrigger>
|
||
<SelectContent className="bg-gray-900/95 backdrop-blur border-white/20 text-white">
|
||
{logisticsPartners.map((partner) => (
|
||
<SelectItem
|
||
key={partner.id}
|
||
value={partner.id}
|
||
className="text-white hover:bg-white/10 focus:bg-white/10 text-xs"
|
||
>
|
||
<div className="flex flex-col">
|
||
<span className="font-medium">
|
||
{partner.name || partner.fullName || "Без названия"}
|
||
</span>
|
||
<span className="text-xs text-white/60">
|
||
Логистический партнер
|
||
</span>
|
||
</div>
|
||
</SelectItem>
|
||
))}
|
||
</SelectContent>
|
||
</Select>
|
||
</div>
|
||
|
||
{/* Статус */}
|
||
<div className="text-center">
|
||
<p className="text-white/60 text-xs mb-1">Статус</p>
|
||
<div className="flex justify-center">
|
||
{getStatusBadge(fulfillmentSupply.status)}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</Card>
|
||
</CardContent>
|
||
</Card>
|
||
|
||
{/* Карточки оптовиков */}
|
||
<Card className="glass-card border-white/10">
|
||
<CardHeader>
|
||
<CardTitle className="text-white">Карточки оптовиков</CardTitle>
|
||
</CardHeader>
|
||
<CardContent className="space-y-6">
|
||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||
{wholesalers.map((wholesaler) => (
|
||
<div key={wholesaler.id} className="glass-card p-6 rounded-lg border border-white/10 hover:border-white/30 transition-all">
|
||
{/* Заголовок карточки */}
|
||
<div className="flex items-start gap-4 mb-4">
|
||
<Avatar className="h-16 w-16">
|
||
<AvatarImage src={wholesaler.avatar} />
|
||
<AvatarFallback className="bg-purple-600 text-white text-lg">
|
||
{wholesaler.name.charAt(0)}
|
||
</AvatarFallback>
|
||
</Avatar>
|
||
|
||
<div className="flex-1 min-w-0">
|
||
<div className="flex items-center gap-2 mb-1">
|
||
<h4 className="text-white font-semibold text-lg truncate">{wholesaler.name}</h4>
|
||
{wholesaler.verifiedBadges.includes('verified') && (
|
||
<Badge className="bg-green-600 text-white text-xs">Проверен</Badge>
|
||
)}
|
||
{wholesaler.verifiedBadges.includes('premium') && (
|
||
<Badge className="bg-yellow-600 text-white text-xs">Premium</Badge>
|
||
)}
|
||
</div>
|
||
|
||
<p className="text-white/70 text-sm mb-2">{wholesaler.fullName}</p>
|
||
<p className="text-white/60 text-xs">ИНН: {wholesaler.inn}</p>
|
||
|
||
{/* Рейтинг и статистика */}
|
||
<div className="flex items-center gap-4 mt-2 text-sm">
|
||
<div className="flex items-center gap-1">
|
||
<Star className="h-4 w-4 fill-yellow-400 text-yellow-400" />
|
||
<span className="text-white">{wholesaler.rating}</span>
|
||
<span className="text-white/60">({wholesaler.reviewsCount})</span>
|
||
</div>
|
||
<div className="text-white/60">
|
||
{wholesaler.completedOrders} заказов
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Описание */}
|
||
<p className="text-white/70 text-sm mb-4 line-clamp-2">
|
||
{wholesaler.description}
|
||
</p>
|
||
|
||
{/* Статистика */}
|
||
<div className="grid grid-cols-2 gap-4 mb-4">
|
||
<div className="bg-white/5 rounded-lg p-3">
|
||
<div className="flex items-center gap-2 mb-1">
|
||
<Package className="h-4 w-4 text-purple-400" />
|
||
<span className="text-white/70 text-xs">Товаров</span>
|
||
</div>
|
||
<div className="text-white font-bold">{wholesaler.productsCount.toLocaleString()}</div>
|
||
</div>
|
||
|
||
<div className="bg-white/5 rounded-lg p-3">
|
||
<div className="flex items-center gap-2 mb-1">
|
||
<Clock className="h-4 w-4 text-green-400" />
|
||
<span className="text-white/70 text-xs">Ответ</span>
|
||
</div>
|
||
<div className="text-white font-bold">{wholesaler.responseTime}</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Категории */}
|
||
<div className="mb-4">
|
||
<p className="text-white/70 text-xs mb-2">Категории:</p>
|
||
<div className="flex flex-wrap gap-1">
|
||
{wholesaler.categories.map((category, index) => (
|
||
<Badge key={index} variant="outline" className="text-xs border-white/30 text-white/70">
|
||
{category}
|
||
</Badge>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
{/* Дополнительная информация */}
|
||
<div className="space-y-2 mb-4 text-sm">
|
||
<div className="flex items-center gap-2 text-white/60">
|
||
<MapPin className="h-3 w-3" />
|
||
<span>{wholesaler.location}</span>
|
||
</div>
|
||
<div className="flex items-center gap-2 text-white/60">
|
||
<Calendar className="h-3 w-3" />
|
||
<span>Работает с {wholesaler.workingSince} года</span>
|
||
</div>
|
||
<div className="flex items-center gap-2 text-white/60">
|
||
<Briefcase className="h-3 w-3" />
|
||
<span>Мин. заказ: {formatPrice(wholesaler.minOrder)}</span>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Специальные предложения */}
|
||
{wholesaler.specialOffers > 0 && (
|
||
<div className="bg-orange-500/20 border border-orange-500/30 rounded-lg p-3 mb-4">
|
||
<div className="flex items-center gap-2">
|
||
<Award className="h-4 w-4 text-orange-400" />
|
||
<span className="text-orange-200 font-medium text-sm">
|
||
{wholesaler.specialOffers} специальных предложения
|
||
</span>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{/* Кнопки действий */}
|
||
<div className="flex gap-2">
|
||
<Button className="flex-1 bg-purple-600 hover:bg-purple-700 text-white">
|
||
<Eye className="h-4 w-4 mr-2" />
|
||
Смотреть товары
|
||
</Button>
|
||
<Button variant="outline" className="bg-white/10 hover:bg-white/20 text-white border-white/30">
|
||
<Phone className="h-4 w-4" />
|
||
</Button>
|
||
<Button variant="outline" className="bg-white/10 hover:bg-white/20 text-white border-white/30">
|
||
<Mail className="h-4 w-4" />
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
)
|
||
}
|