"use client"; import { useState } from "react"; import { useMutation } from "@apollo/client"; import { Card } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar"; import { Dialog, DialogContent, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Textarea } from "@/components/ui/textarea"; import { SUPPLIER_APPROVE_ORDER, SUPPLIER_REJECT_ORDER, SUPPLIER_SHIP_ORDER, } from "@/graphql/mutations"; import { GET_SUPPLY_ORDERS } from "@/graphql/queries"; import { toast } from "sonner"; import { Calendar, Package, Truck, User, CheckCircle, Clock, XCircle, MapPin, Phone, Mail, Building, Hash, ChevronDown, ChevronUp, MessageCircle, Loader2, } from "lucide-react"; interface SupplierOrderCardProps { order: { id: string; organizationId: string; partnerId: string; deliveryDate: string; status: | "PENDING" | "SUPPLIER_APPROVED" | "CONFIRMED" | "LOGISTICS_CONFIRMED" | "SHIPPED" | "IN_TRANSIT" | "DELIVERED" | "CANCELLED"; totalAmount: number; totalItems: number; createdAt: string; organization: { id: string; name?: string; fullName?: string; type: string; inn?: string; }; fulfillmentCenter?: { id: string; name?: string; fullName?: string; type: string; }; logisticsPartner?: { id: string; name?: string; fullName?: string; type: string; }; items: Array<{ id: string; quantity: number; price: number; totalPrice: number; product: { id: string; name: string; article: string; description?: string; category?: { id: string; name: string; }; }; }>; }; } export function SupplierOrderCard({ order }: SupplierOrderCardProps) { const [isExpanded, setIsExpanded] = useState(false); const [showRejectModal, setShowRejectModal] = useState(false); const [rejectReason, setRejectReason] = useState(""); // Мутации для действий поставщика const [supplierApproveOrder, { loading: approving }] = useMutation( SUPPLIER_APPROVE_ORDER, { refetchQueries: [{ query: GET_SUPPLY_ORDERS }], onCompleted: (data) => { if (data.supplierApproveOrder.success) { toast.success(data.supplierApproveOrder.message); } else { toast.error(data.supplierApproveOrder.message); } }, onError: (error) => { console.error("Error approving order:", error); toast.error("Ошибка при одобрении заказа"); }, } ); const [supplierRejectOrder, { loading: rejecting }] = useMutation( SUPPLIER_REJECT_ORDER, { refetchQueries: [{ query: GET_SUPPLY_ORDERS }], onCompleted: (data) => { if (data.supplierRejectOrder.success) { toast.success(data.supplierRejectOrder.message); } else { toast.error(data.supplierRejectOrder.message); } setShowRejectModal(false); setRejectReason(""); }, onError: (error) => { console.error("Error rejecting order:", error); toast.error("Ошибка при отклонении заказа"); }, } ); const [supplierShipOrder, { loading: shipping }] = useMutation( SUPPLIER_SHIP_ORDER, { refetchQueries: [{ query: GET_SUPPLY_ORDERS }], onCompleted: (data) => { if (data.supplierShipOrder.success) { toast.success(data.supplierShipOrder.message); } else { toast.error(data.supplierShipOrder.message); } }, onError: (error) => { console.error("Error shipping order:", error); toast.error("Ошибка при отправке заказа"); }, } ); const handleApproveOrder = async () => { try { await supplierApproveOrder({ variables: { id: order.id }, }); } catch (error) { console.error("Error in handleApproveOrder:", error); } }; const handleRejectOrder = async () => { if (!rejectReason.trim()) { toast.error("Укажите причину отклонения заявки"); return; } try { await supplierRejectOrder({ variables: { id: order.id, reason: rejectReason, }, }); } catch (error) { console.error("Error in handleRejectOrder:", error); } }; const handleShipOrder = async () => { try { await supplierShipOrder({ variables: { id: order.id }, }); } catch (error) { console.error("Error in handleShipOrder:", error); } }; const getStatusBadge = (status: string) => { switch (status) { case "PENDING": return ( 🟡 ОЖИДАЕТ ); case "SUPPLIER_APPROVED": return ( 🟢 ОДОБРЕНО ); case "CONFIRMED": case "LOGISTICS_CONFIRMED": return ( 🔵 В РАБОТЕ ); case "SHIPPED": case "IN_TRANSIT": return ( 🟠 В ПУТИ ); case "DELIVERED": return ( ✅ ДОСТАВЛЕНО ); default: return ( {status} ); } }; const formatDate = (dateString: string) => { return new Date(dateString).toLocaleDateString("ru-RU", { day: "2-digit", month: "2-digit", year: "numeric", }); }; const getInitials = (name: string) => { return name .split(" ") .map((word) => word[0]) .join("") .toUpperCase() .slice(0, 2); }; const calculateVolume = () => { // Примерный расчет объема - можно улучшить на основе реальных данных о товарах return (order.totalItems * 0.02).toFixed(1); // 0.02 м³ на единицу товара }; return ( <> {/* Основная информация - структура согласно правилам */}
{/* Шапка заявки */}
СФ-{order.id.slice(-8)}
{formatDate(order.createdAt)}
{getStatusBadge(order.status)}
{/* Информация об участниках */}
{/* Заказчик */}
Заказчик:
{getInitials( order.organization.name || order.organization.fullName || "ОРГ" )}

{order.organization.name || order.organization.fullName}

{order.organization.inn && (

ИНН: {order.organization.inn}

)}
{/* Фулфилмент */} {order.fulfillmentCenter && (
Фулфилмент:

{order.fulfillmentCenter.name || order.fulfillmentCenter.fullName}

)} {/* Логистика */} {order.logisticsPartner && (
Логистика:

{order.logisticsPartner.name || order.logisticsPartner.fullName}

)}
{/* Краткая информация о заказе */}
{order.items.length} вид {order.items.length === 1 ? "" : order.items.length < 5 ? "а" : "ов"}{" "} товаров
{order.totalItems} единиц
📏 {calculateVolume()} м³
💰 {order.totalAmount.toLocaleString()}₽
{/* Кнопки действий */}
{/* Действия для PENDING */} {order.status === "PENDING" && ( <> )} {/* Действие для LOGISTICS_CONFIRMED */} {order.status === "LOGISTICS_CONFIRMED" && ( )} {/* Кнопка связаться всегда доступна */}
{/* Срок доставки */}
Доставка: Склад фулфилмента
Срок: {formatDate(order.deliveryDate)}
{/* Расширенная детализация */} {isExpanded && (

📋 ДЕТАЛИ ЗАЯВКИ #{order.id.slice(-8)}

{/* Товары в заявке */}
📦 ТОВАРЫ В ЗАЯВКЕ:
{order.items.map((item) => (
{item.product.name} • {item.quantity} шт • {item.price} ₽/шт = {item.totalPrice.toLocaleString()}₽
Артикул: {item.product.article} {item.product.category && ` • ${item.product.category.name}`}
))}
Общая стоимость: {order.totalAmount.toLocaleString()}₽
{/* Логистическая информация */}
📍 ЛОГИСТИЧЕСКАЯ ИНФОРМАЦИЯ:
• Объем груза: {calculateVolume()} м³
• Предварительная стоимость доставки: ~ {Math.round( parseFloat(calculateVolume()) * 3500 ).toLocaleString()} ₽
• Маршрут: Склад поставщика →{" "} {order.fulfillmentCenter?.name || "Фулфилмент-центр"}
{/* Контактная информация */}
📞 КОНТАКТЫ:
• Заказчик:{" "} {order.organization.name || order.organization.fullName} {order.organization.inn && ` (ИНН: ${order.organization.inn})`}
{order.fulfillmentCenter && (
• Фулфилмент:{" "} {order.fulfillmentCenter.name || order.fulfillmentCenter.fullName}
)}
)}
{/* Модал отклонения заявки */} Отклонить заявку