"use client" import React, { useState, useEffect } from 'react' import { useQuery } from '@apollo/client' import { Card } from '@/components/ui/card' import { Button } from '@/components/ui/button' import { Badge } from '@/components/ui/badge' import { Input } from '@/components/ui/input' import { Sidebar } from '@/components/dashboard/sidebar' import { useSidebar } from '@/hooks/useSidebar' import { GET_MY_COUNTERPARTIES, GET_ALL_PRODUCTS } from '@/graphql/queries' import { ArrowLeft, ShoppingCart, Users, Building2, MapPin, Phone, Mail, Star, Plus, Minus, Info, Package, Zap, Heart, Eye, ShoppingBag, Search } from 'lucide-react' import { useRouter } from 'next/navigation' import Image from 'next/image' import { WBProductCards } from './wb-product-cards' interface WholesalerForCreation { id: string inn: string name: string fullName: string address: string phone?: string email?: string rating: number productCount: number avatar?: string specialization: string[] } interface WholesalerProduct { id: string name: string article: string description: string price: number quantity: number category: string brand?: string color?: string size?: string weight?: number dimensions?: string material?: string images: string[] mainImage?: string discount?: number isNew?: boolean isBestseller?: boolean } interface SelectedProduct extends WholesalerProduct { selectedQuantity: number wholesalerId: string wholesalerName: string } interface WildberriesCard { nmID: number vendorCode: string title: string description: string brand: string mediaFiles: string[] sizes: Array<{ chrtID: number techSize: string wbSize: string price: number discountedPrice: number quantity: number }> } interface SelectedCard { card: WildberriesCard selectedQuantity: number selectedMarket: string selectedPlace: string sellerName: string sellerPhone: string deliveryDate: string selectedServices: string[] } // Моковые данные оптовиков const mockWholesalers: WholesalerForCreation[] = [ { id: '1', inn: '7707083893', name: 'ОПТ-Электроника', fullName: 'ООО "ОПТ-Электроника"', address: 'г. Москва, ул. Садовая, д. 15', phone: '+7 (495) 123-45-67', email: 'opt@electronics.ru', rating: 4.8, productCount: 1250, specialization: ['Электроника', 'Бытовая техника'] }, { id: '2', inn: '7707083894', name: 'ТекстильМастер', fullName: 'ООО "ТекстильМастер"', address: 'г. Иваново, пр. Ленина, д. 42', phone: '+7 (4932) 55-66-77', email: 'sales@textilmaster.ru', rating: 4.6, productCount: 850, specialization: ['Текстиль', 'Одежда', 'Домашний текстиль'] }, { id: '3', inn: '7707083895', name: 'МетизКомплект', fullName: 'ООО "МетизКомплект"', address: 'г. Тула, ул. Металлургов, д. 8', phone: '+7 (4872) 33-44-55', email: 'info@metiz.ru', rating: 4.9, productCount: 2100, specialization: ['Крепеж', 'Метизы', 'Инструменты'] } ] // Улучшенные моковые данные товаров const mockProducts: WholesalerProduct[] = [ { id: '1', name: 'iPhone 15 Pro Max', article: 'APL-15PM-256', description: 'Флагманский смартфон Apple с титановым корпусом, камерой 48 МП и чипом A17 Pro', price: 124900, quantity: 45, category: 'Смартфоны', brand: 'Apple', color: 'Натуральный титан', size: '6.7"', weight: 221, dimensions: '159.9 x 76.7 x 8.25 мм', material: 'Титан, стекло', images: ['https://store.storeimages.cdn-apple.com/4982/as-images.apple.com/is/iphone-15-pro-max-naturaltitanium-select?wid=470&hei=556&fmt=jpeg&qlt=99&.v=1692845705224'], mainImage: 'https://store.storeimages.cdn-apple.com/4982/as-images.apple.com/is/iphone-15-pro-max-naturaltitanium-select?wid=470&hei=556&fmt=jpeg&qlt=99&.v=1692845705224', isNew: true, isBestseller: true }, { id: '2', name: 'Sony WH-1000XM5', article: 'SNY-WH1000XM5', description: 'Беспроводные наушники премиум-класса с лучшим в отрасли шумоподавлением', price: 34900, quantity: 128, category: 'Наушники', brand: 'Sony', color: 'Черный', weight: 250, material: 'Пластик, эко-кожа', images: ['https://www.sony.ru/image/5d02da5df552836db894cead8a68f5f3?fmt=pjpeg&wid=330&bgcolor=FFFFFF&bgc=FFFFFF'], mainImage: 'https://www.sony.ru/image/5d02da5df552836db894cead8a68f5f3?fmt=pjpeg&wid=330&bgcolor=FFFFFF&bgc=FFFFFF', discount: 15, isBestseller: true }, { id: '3', name: 'iPad Pro 12.9" M2', article: 'APL-IPADPRO-M2', description: 'Самый мощный iPad с чипом M2, дисплеем Liquid Retina XDR и поддержкой Apple Pencil', price: 109900, quantity: 32, category: 'Планшеты', brand: 'Apple', color: 'Серый космос', size: '12.9"', weight: 682, dimensions: '280.6 x 214.9 x 6.4 мм', material: 'Алюминий', images: ['https://store.storeimages.cdn-apple.com/4982/as-images.apple.com/is/ipad-pro-12-select-wifi-spacegray-202210?wid=470&hei=556&fmt=jpeg&qlt=99&.v=1664411207213'], mainImage: 'https://store.storeimages.cdn-apple.com/4982/as-images.apple.com/is/ipad-pro-12-select-wifi-spacegray-202210?wid=470&hei=556&fmt=jpeg&qlt=99&.v=1664411207213', isNew: true }, { id: '4', name: 'MacBook Pro 16" M3 Max', article: 'APL-MBP16-M3MAX', description: 'Профессиональный ноутбук с чипом M3 Max, 36 ГБ памяти и дисплеем Liquid Retina XDR', price: 329900, quantity: 18, category: 'Ноутбуки', brand: 'Apple', color: 'Серый космос', size: '16"', weight: 2160, dimensions: '355.7 x 248.1 x 16.8 мм', material: 'Алюминий', images: ['https://store.storeimages.cdn-apple.com/4982/as-images.apple.com/is/mbp16-spacegray-select-202310?wid=470&hei=556&fmt=jpeg&qlt=99&.v=1697230830200'], mainImage: 'https://store.storeimages.cdn-apple.com/4982/as-images.apple.com/is/mbp16-spacegray-select-202310?wid=470&hei=556&fmt=jpeg&qlt=99&.v=1697230830200', isNew: true, isBestseller: true }, { id: '5', name: 'Apple Watch Ultra 2', article: 'APL-AWU2-49', description: 'Самые прочные и функциональные умные часы Apple для экстремальных приключений', price: 89900, quantity: 67, category: 'Умные часы', brand: 'Apple', color: 'Натуральный титан', size: '49 мм', weight: 61, dimensions: '49 x 44 x 14.4 мм', material: 'Титан', images: ['https://store.storeimages.cdn-apple.com/4982/as-images.apple.com/is/watch-ultra2-select-202309?wid=470&hei=556&fmt=jpeg&qlt=99&.v=1693967875133'], mainImage: 'https://store.storeimages.cdn-apple.com/4982/as-images.apple.com/is/watch-ultra2-select-202309?wid=470&hei=556&fmt=jpeg&qlt=99&.v=1693967875133', isNew: true }, { id: '6', name: 'Magic Keyboard для iPad Pro', article: 'APL-MK-IPADPRO', description: 'Клавиатура с трекпадом и подсветкой клавиш для iPad Pro 12.9"', price: 36900, quantity: 89, category: 'Аксессуары', brand: 'Apple', color: 'Черный', weight: 710, dimensions: '280.9 x 214.3 x 25 мм', material: 'Алюминий, пластик', images: ['https://store.storeimages.cdn-apple.com/4982/as-images.apple.com/is/MJQJ3?wid=470&hei=556&fmt=jpeg&qlt=99&.v=1639066901000'], mainImage: 'https://store.storeimages.cdn-apple.com/4982/as-images.apple.com/is/MJQJ3?wid=470&hei=556&fmt=jpeg&qlt=99&.v=1639066901000' } ] export function CreateSupplyPage() { const router = useRouter() const { getSidebarMargin } = useSidebar() const [selectedVariant, setSelectedVariant] = useState<'cards' | 'wholesaler' | null>(null) const [selectedWholesaler, setSelectedWholesaler] = useState(null) const [selectedProducts, setSelectedProducts] = useState([]) const [selectedCards, setSelectedCards] = useState([]) const [showSummary, setShowSummary] = useState(false) const [searchQuery, setSearchQuery] = useState('') // Загружаем контрагентов-оптовиков const { data: counterpartiesData, loading: counterpartiesLoading } = useQuery(GET_MY_COUNTERPARTIES) // Загружаем товары для выбранного оптовика const { data: productsData, loading: productsLoading } = useQuery(GET_ALL_PRODUCTS, { skip: !selectedWholesaler, variables: { search: null, category: null } }) // Фильтруем только оптовиков const wholesalers = (counterpartiesData?.myCounterparties || []).filter((org: { type: string }) => org.type === 'WHOLESALE') // Фильтруем оптовиков по поисковому запросу const filteredWholesalers = wholesalers.filter((wholesaler: { name?: string; fullName?: string; inn?: string }) => wholesaler.name?.toLowerCase().includes(searchQuery.toLowerCase()) || wholesaler.fullName?.toLowerCase().includes(searchQuery.toLowerCase()) || wholesaler.inn?.toLowerCase().includes(searchQuery.toLowerCase()) ) // Фильтруем товары по выбранному оптовику const wholesalerProducts = selectedWholesaler ? (productsData?.allProducts || []).filter((product: { organization: { id: string } }) => product.organization.id === selectedWholesaler.id ) : [] // Автоматически показываем корзину если в ней есть товары и мы на этапе выбора оптовиков useEffect(() => { if (selectedVariant === 'wholesaler' && !selectedWholesaler && selectedProducts.length > 0) { setShowSummary(true) } }, [selectedVariant, selectedWholesaler, selectedProducts.length]) const formatCurrency = (amount: number) => { return new Intl.NumberFormat('ru-RU', { style: 'currency', currency: 'RUB', minimumFractionDigits: 0 }).format(amount) } const renderStars = (rating: number) => { return Array.from({ length: 5 }, (_, i) => ( )) } const updateProductQuantity = (productId: string, quantity: number) => { const product = wholesalerProducts.find((p: { id: string }) => p.id === productId) if (!product || !selectedWholesaler) return setSelectedProducts(prev => { const existing = prev.find(p => p.id === productId && p.wholesalerId === selectedWholesaler.id) if (quantity === 0) { return prev.filter(p => !(p.id === productId && p.wholesalerId === selectedWholesaler.id)) } if (existing) { return prev.map(p => p.id === productId && p.wholesalerId === selectedWholesaler.id ? { ...p, selectedQuantity: quantity } : p ) } else { return [...prev, { ...product, selectedQuantity: quantity, wholesalerId: selectedWholesaler.id, wholesalerName: selectedWholesaler.name }] } }) } const getSelectedQuantity = (productId: string): number => { if (!selectedWholesaler) return 0 const selected = selectedProducts.find(p => p.id === productId && p.wholesalerId === selectedWholesaler.id) return selected ? selected.selectedQuantity : 0 } const getTotalAmount = () => { return selectedProducts.reduce((sum, product) => { const discountedPrice = product.discount ? product.price * (1 - product.discount / 100) : product.price return sum + (discountedPrice * product.selectedQuantity) }, 0) } const getTotalItems = () => { return selectedProducts.reduce((sum, product) => sum + product.selectedQuantity, 0) } const handleCardsComplete = (cards: SelectedCard[]) => { setSelectedCards(cards) console.log('Карточки товаров выбраны:', cards) // TODO: Здесь будет создание поставки с данными карточек router.push('/supplies') } const handleCreateSupply = () => { if (selectedVariant === 'cards') { console.log('Создание поставки с карточками Wildberries') // TODO: Здесь будет создание поставки с данными карточек } else { console.log('Создание поставки с товарами:', selectedProducts) // TODO: Здесь будет реальное создание поставки } router.push('/supplies') } const handleGoBack = () => { if (selectedWholesaler) { setSelectedWholesaler(null) // НЕ очищаем корзину! setSelectedProducts([]) setShowSummary(false) } else if (selectedVariant) { setSelectedVariant(null) setSelectedProducts([]) // Очищаем корзину только при полном выходе setShowSummary(false) } else { router.push('/supplies') } } // Рендер товаров оптовика if (selectedWholesaler && selectedVariant === 'wholesaler') { return (

Товары оптовика

{selectedWholesaler.name} • {wholesalerProducts.length} товаров

{showSummary && selectedProducts.length > 0 && (

Корзина ({selectedProducts.length})

{/* Текущий оптовик */}
{selectedWholesaler?.name} {selectedProducts.filter(p => p.wholesalerId === selectedWholesaler?.id).length} товар(ов)
{selectedProducts.filter(p => p.wholesalerId === selectedWholesaler?.id).map((product) => { const discountedPrice = product.discount ? product.price * (1 - product.discount / 100) : product.price const totalPrice = discountedPrice * product.selectedQuantity return (
{product.name}

{product.name}

{product.article}

× {product.selectedQuantity}
{formatCurrency(totalPrice)}
{product.discount && (
{formatCurrency(product.price * product.selectedQuantity)}
)}
) })}
{/* Другие оптовики в корзине */} {Object.entries( selectedProducts.filter(p => p.wholesalerId !== selectedWholesaler?.id).reduce((acc, product) => { if (!acc[product.wholesalerId]) { acc[product.wholesalerId] = { wholesaler: product.wholesalerName, products: [] } } acc[product.wholesalerId].products.push(product) return acc }, {} as Record) ).map(([wholesalerId, group]) => (
{group.wholesaler} {group.products.length} товар(ов)
{group.products.map((product) => { const discountedPrice = product.discount ? product.price * (1 - product.discount / 100) : product.price const totalPrice = discountedPrice * product.selectedQuantity return (
{product.name}

{product.name}

{product.article}

× {product.selectedQuantity}
{formatCurrency(totalPrice)}
{product.discount && (
{formatCurrency(product.price * product.selectedQuantity)}
)}
) })}
))} {/* Итого */}
Итого: {getTotalItems()} товаров {formatCurrency(getTotalAmount())}
)} {productsLoading ? (

Загружаем товары...

) : wholesalerProducts.length === 0 ? (

У этого оптовика нет товаров

Выберите другого оптовика

) : (
{wholesalerProducts.map((product: { id: string; name: string; article: string; description?: string; price: number; quantity: number; category?: { name: string }; brand?: string; color?: string; size?: string; mainImage?: string; images?: string[] }) => { const selectedQuantity = getSelectedQuantity(product.id) const discountedPrice = product.price // Убираем discount так как его нет в схеме return (
{product.name} {/* Количество в наличии */}
50 ? 'bg-green-500/80' : product.quantity > 10 ? 'bg-yellow-500/80' : 'bg-red-500/80'} text-white border-0 backdrop-blur text-xs`}> {product.quantity}
{/* Убираем discount badge так как поля нет в схеме */} {/* Overlay с кнопками */}
{/* Заголовок и бренд */}
{product.brand && ( {product.brand} )} {/* Убираем isNew и isBestseller так как этих полей нет в схеме */}

{product.name}

{/* Основная характеристика */}
{product.color && {product.color}} {product.size && {product.size}}
{/* Цена */}
{formatCurrency(discountedPrice)}
{/* Убираем отображение оригинальной цены так как discount нет */}
{/* Управление количеством */}
{ const value = e.target.value.replace(/[^0-9]/g, '') const numValue = Math.max(0, Math.min(product.quantity, parseInt(value) || 0)) updateProductQuantity(product.id, numValue) }} onFocus={(e) => e.target.select()} className="h-8 w-12 text-center bg-white/10 border border-white/20 text-white text-sm rounded focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none" /> {selectedQuantity > 0 && ( {selectedQuantity} )}
{/* Сумма для выбранного товара */} {selectedQuantity > 0 && (
{formatCurrency(discountedPrice * selectedQuantity)}
)}
) })}
)} {/* Floating корзина */} {selectedProducts.length > 0 && (
)}
) } // Рендер карточек Wildberries if (selectedVariant === 'cards') { return ( setSelectedVariant(null)} onComplete={handleCardsComplete} /> ) } // Рендер выбора оптовиков if (selectedVariant === 'wholesaler') { return (

Выбор оптовика

{selectedProducts.length > 0 ? `Выберите еще оптовика или перейдите к оформлению (${selectedProducts.length} товаров в корзине)` : "Выберите оптовика для создания поставки" }

{selectedProducts.length > 0 && ( )}
{/* Корзина */} {showSummary && selectedProducts.length > 0 && (

Корзина

{selectedProducts.length} товаров от {Object.keys(selectedProducts.reduce((acc, p) => ({ ...acc, [p.wholesalerId]: true }), {})).length} поставщиков

{/* Группировка по оптовикам */} {Object.entries( selectedProducts.reduce((acc, product) => { if (!acc[product.wholesalerId]) { acc[product.wholesalerId] = { wholesaler: product.wholesalerName, products: [] } } acc[product.wholesalerId].products.push(product) return acc }, {} as Record) ).map(([wholesalerId, group]) => (
{group.wholesaler} {group.products.length} товар(ов)
{group.products.map((product) => { const discountedPrice = product.discount ? product.price * (1 - product.discount / 100) : product.price const totalPrice = discountedPrice * product.selectedQuantity return (
{product.name}

{product.name}

{product.article}

{product.selectedQuantity}
{formatCurrency(totalPrice)}
{product.discount && (
{formatCurrency(product.price * product.selectedQuantity)}
)}
) })}
))} {/* Итого */}
Итого: {getTotalItems()} товаров {formatCurrency(getTotalAmount())}
)} {/* Поиск */}
setSearchQuery(e.target.value)} className="pl-10 glass-input text-white placeholder:text-white/40" />
{counterpartiesLoading ? (

Загружаем оптовиков...

) : filteredWholesalers.length === 0 ? (

{searchQuery ? 'Оптовики не найдены' : 'У вас нет контрагентов-оптовиков'}

{searchQuery ? 'Попробуйте изменить условия поиска' : 'Добавьте оптовиков в разделе "Партнеры"'}

) : (
{filteredWholesalers.map((wholesaler: { id: string; name?: string; fullName?: string; inn?: string; address?: string; phones?: { value: string }[]; emails?: { value: string }[] }) => ( { // Адаптируем данные под существующий интерфейс const adaptedWholesaler = { id: wholesaler.id, inn: wholesaler.inn || '', name: wholesaler.name || 'Неизвестная организация', fullName: wholesaler.fullName || wholesaler.name || 'Неизвестная организация', address: wholesaler.address || 'Адрес не указан', phone: wholesaler.phones?.[0]?.value, email: wholesaler.emails?.[0]?.value, rating: 4.5, // Временное значение productCount: 0, // Временное значение specialization: ['Оптовая торговля'] // Временное значение } setSelectedWholesaler(adaptedWholesaler) }} >

{wholesaler.name || 'Неизвестная организация'}

{wholesaler.fullName || wholesaler.name}

{wholesaler.inn && (

ИНН: {wholesaler.inn}

)}
{wholesaler.address && (
{wholesaler.address}
)} {wholesaler.phones?.[0]?.value && (
{wholesaler.phones[0].value}
)} {wholesaler.emails?.[0]?.value && (
{wholesaler.emails[0].value}
)}
Контрагент

ИНН: {wholesaler.inn}

))}
)} {/* Floating корзина */} {selectedProducts.length > 0 && !showSummary && (
)}
) } // Главная страница выбора варианта return (

Создание поставки

Выберите способ создания поставки

setSelectedVariant('cards')} >

Карточки

Создание поставки через выбор товаров по карточкам Wildberries

Доступно
setSelectedVariant('wholesaler')} >

Оптовик

Создание поставки через выбор товаров у оптовиков

Доступно
) }