"use client"; import React, { useState } from "react"; import { useRouter } from "next/navigation"; import { useQuery, useMutation } from "@apollo/client"; import { Sidebar } from "@/components/dashboard/sidebar"; import { useSidebar } from "@/hooks/useSidebar"; 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 { ArrowLeft, Building2, MapPin, Phone, Mail, Star, Search, Package, Plus, Minus, ShoppingCart, Wrench, Box, } from "lucide-react"; import { GET_MY_COUNTERPARTIES, GET_ALL_PRODUCTS } from "@/graphql/queries"; import { CREATE_SUPPLY_ORDER } from "@/graphql/mutations"; import { OrganizationAvatar } from "@/components/market/organization-avatar"; import { toast } from "sonner"; import Image from "next/image"; interface ConsumableSupplier { id: string; inn: string; name?: string; fullName?: string; type: "FULFILLMENT" | "SELLER" | "LOGIST" | "WHOLESALE"; address?: string; phones?: Array<{ value: string }>; emails?: Array<{ value: string }>; users?: Array<{ id: string; avatar?: string; managerName?: string }>; createdAt: string; } interface ConsumableProduct { id: string; name: string; description?: string; price: number; category?: { name: string }; images: string[]; mainImage?: string; organization: { id: string; name: string; }; stock?: number; unit?: string; } interface SelectedConsumable { id: string; name: string; price: number; selectedQuantity: number; unit?: string; category?: string; supplierId: string; supplierName: string; } export function CreateConsumablesSupplyPage() { const router = useRouter(); const { getSidebarMargin } = useSidebar(); const [selectedSupplier, setSelectedSupplier] = useState(null); const [selectedConsumables, setSelectedConsumables] = useState< SelectedConsumable[] >([]); const [searchQuery, setSearchQuery] = useState(""); const [productSearchQuery, setProductSearchQuery] = useState(""); const [deliveryDate, setDeliveryDate] = useState(""); const [isCreatingSupply, setIsCreatingSupply] = useState(false); // Загружаем контрагентов-поставщиков расходников const { data: counterpartiesData, loading: counterpartiesLoading } = useQuery( GET_MY_COUNTERPARTIES ); // Загружаем товары для выбранного поставщика const { data: productsData, loading: productsLoading } = useQuery( GET_ALL_PRODUCTS, { skip: !selectedSupplier, variables: { search: productSearchQuery || null, category: null }, } ); // Мутация для создания заказа поставки расходников const [createSupplyOrder] = useMutation(CREATE_SUPPLY_ORDER); // Фильтруем только поставщиков расходников (оптовиков) const consumableSuppliers = ( counterpartiesData?.myCounterparties || [] ).filter((org: ConsumableSupplier) => org.type === "WHOLESALE"); // Фильтруем поставщиков по поисковому запросу const filteredSuppliers = consumableSuppliers.filter( (supplier: ConsumableSupplier) => supplier.name?.toLowerCase().includes(searchQuery.toLowerCase()) || supplier.fullName?.toLowerCase().includes(searchQuery.toLowerCase()) || supplier.inn?.toLowerCase().includes(searchQuery.toLowerCase()) ); // Фильтруем товары по выбранному поставщику const supplierProducts = selectedSupplier ? (productsData?.allProducts || []).filter( (product: ConsumableProduct) => product.organization.id === selectedSupplier.id ) : []; const formatCurrency = (amount: number) => { return new Intl.NumberFormat("ru-RU", { style: "currency", currency: "RUB", minimumFractionDigits: 0, }).format(amount); }; const renderStars = (rating: number = 4.5) => { return Array.from({ length: 5 }, (_, i) => ( )); }; const updateConsumableQuantity = (productId: string, quantity: number) => { const product = supplierProducts.find( (p: ConsumableProduct) => p.id === productId ); if (!product || !selectedSupplier) return; setSelectedConsumables((prev) => { const existing = prev.find((p) => p.id === productId); if (quantity === 0) { // Удаляем расходник если количество 0 return prev.filter((p) => p.id !== productId); } if (existing) { // Обновляем количество существующего расходника return prev.map((p) => p.id === productId ? { ...p, selectedQuantity: quantity } : p ); } else { // Добавляем новый расходник return [ ...prev, { id: product.id, name: product.name, price: product.price, selectedQuantity: quantity, unit: product.unit || "шт", category: product.category?.name || "Расходники", supplierId: selectedSupplier.id, supplierName: selectedSupplier.name || selectedSupplier.fullName || "Поставщик", }, ]; } }); }; const getSelectedQuantity = (productId: string): number => { const selected = selectedConsumables.find((p) => p.id === productId); return selected ? selected.selectedQuantity : 0; }; const getTotalAmount = () => { return selectedConsumables.reduce( (sum, consumable) => sum + consumable.price * consumable.selectedQuantity, 0 ); }; const getTotalItems = () => { return selectedConsumables.reduce( (sum, consumable) => sum + consumable.selectedQuantity, 0 ); }; const handleCreateSupply = async () => { if ( !selectedSupplier || selectedConsumables.length === 0 || !deliveryDate ) { toast.error("Заполните все обязательные поля"); return; } setIsCreatingSupply(true); try { const result = await createSupplyOrder({ variables: { input: { partnerId: selectedSupplier.id, deliveryDate: deliveryDate, items: selectedConsumables.map((consumable) => ({ productId: consumable.id, quantity: consumable.selectedQuantity, })), }, }, }); if (result.data?.createSupplyOrder?.success) { toast.success("Поставка расходников создана успешно!"); router.push("/supplies"); } else { toast.error( result.data?.createSupplyOrder?.message || "Ошибка при создании поставки" ); } } catch (error) { console.error("Error creating consumables supply:", error); toast.error("Ошибка при создании поставки расходников"); } finally { setIsCreatingSupply(false); } }; return (
{/* Заголовок */}

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

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

{/* Основной контент с двумя блоками */}
{/* Левая колонка - Поставщики и Расходники */}
{/* Блок "Поставщики" */}

Поставщики

{selectedSupplier && ( )}
setSearchQuery(e.target.value)} className="bg-white/10 border-white/20 text-white placeholder-white/40 pl-10" />
{counterpartiesLoading ? (

Загрузка поставщиков...

) : filteredSuppliers.length === 0 ? (

{searchQuery ? "Поставщики не найдены" : "У вас пока нет партнеров-поставщиков расходников"}

) : (
{filteredSuppliers.map((supplier: ConsumableSupplier) => ( setSelectedSupplier(supplier)} >
({ id: user.id, avatar: user.avatar, })), }} size="sm" />

{supplier.name || supplier.fullName || "Поставщик"}

{renderStars(4.5)} 4.5

ИНН: {supplier.inn}

{selectedSupplier?.id === supplier.id && (
Выбран
)}
))}
)}
{/* Блок "Расходники" */}

Расходники {selectedSupplier && ( - {selectedSupplier.name || selectedSupplier.fullName} )}

{selectedSupplier && (
setProductSearchQuery(e.target.value)} className="bg-white/10 border-white/20 text-white placeholder-white/40 pl-10" />
)}
{!selectedSupplier ? (

Выберите поставщика для просмотра расходников

) : productsLoading ? (

Загрузка расходников...

) : supplierProducts.length === 0 ? (

У данного поставщика нет доступных расходников

) : (
{supplierProducts.map((product: ConsumableProduct) => { const selectedQuantity = getSelectedQuantity( product.id ); return (
{/* Изображение товара */}
{product.images && product.images.length > 0 && product.images[0] ? ( {product.name} ) : product.mainImage ? ( {product.name} ) : (
)}
{/* Информация о товаре */}

{product.name}

{product.category && ( {product.category.name} )}

{product.description || "Описание отсутствует"}

{formatCurrency(product.price)} {product.unit && ( / {product.unit} )} {product.stock && ( В наличии: {product.stock} )}
{/* Управление количеством */}
{selectedQuantity}
{selectedQuantity > 0 && ( {formatCurrency( product.price * selectedQuantity )} )}
); })}
)}
{/* Правая колонка - Корзина */} {selectedConsumables.length > 0 && (

Корзина ({getTotalItems()} шт)

{selectedConsumables.map((consumable) => (

{consumable.name}

{formatCurrency(consumable.price)} ×{" "} {consumable.selectedQuantity}

{formatCurrency( consumable.price * consumable.selectedQuantity )}
))}
setDeliveryDate(e.target.value)} className="bg-white/10 border-white/20 text-white" min={new Date().toISOString().split("T")[0]} required />
Итого: {formatCurrency(getTotalAmount())}
)}
); }