Files
sfera-new/src/components/supplies/create-supply-page.tsx

274 lines
8.7 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 React, { useState } from "react";
import { Sidebar } from "@/components/dashboard/sidebar";
import { useSidebar } from "@/hooks/useSidebar";
import { useRouter } from "next/navigation";
import { DirectSupplyCreation } from "./direct-supply-creation";
import { WholesalerProductsPage } from "./wholesaler-products-page";
import { TabsHeader } from "./tabs-header";
import { WholesalerGrid } from "./wholesaler-grid";
import { CartSummary } from "./cart-summary";
import { FloatingCart } from "./floating-cart";
import {
WholesalerForCreation,
WholesalerProduct,
SelectedProduct,
CounterpartyWholesaler,
} from "./types";
import { useQuery } from "@apollo/client";
import { GET_MY_COUNTERPARTIES, GET_ALL_PRODUCTS } from "@/graphql/queries";
export function CreateSupplyPage() {
const router = useRouter();
const { getSidebarMargin } = useSidebar();
const [activeTab, setActiveTab] = useState<"cards" | "wholesaler">("cards");
const [selectedWholesaler, setSelectedWholesaler] =
useState<WholesalerForCreation | null>(null);
const [selectedProducts, setSelectedProducts] = useState<SelectedProduct[]>(
[]
);
const [showSummary, setShowSummary] = useState(false);
const [searchQuery, setSearchQuery] = useState("");
const [canCreateSupply, setCanCreateSupply] = useState(false);
const [isCreatingSupply, setIsCreatingSupply] = useState(false);
// Загружаем контрагентов-оптовиков
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: CounterpartyWholesaler[] = (
counterpartiesData?.myCounterparties || []
).filter((org: { type: string }) => org.type === "WHOLESALE");
// Фильтруем товары по выбранному оптовику
const wholesalerProducts: WholesalerProduct[] = selectedWholesaler
? (productsData?.allProducts || []).filter(
(product: { organization: { id: string } }) =>
product.organization.id === selectedWholesaler.id
)
: [];
const formatCurrency = (amount: number) => {
return new Intl.NumberFormat("ru-RU", {
style: "currency",
currency: "RUB",
minimumFractionDigits: 0,
}).format(amount);
};
const updateProductQuantity = (productId: string, quantity: number) => {
const product = wholesalerProducts.find((p) => 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 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 handleCreateSupply = () => {
if (activeTab === "cards") {
console.log("Создание поставки с карточками Wildberries");
} else {
console.log("Создание поставки с товарами:", selectedProducts);
}
router.push("/supplies");
};
const handleGoBack = () => {
if (selectedWholesaler) {
setSelectedWholesaler(null);
setShowSummary(false);
} else {
router.push("/supplies");
}
};
const handleRemoveProduct = (productId: string, wholesalerId: string) => {
setSelectedProducts((prev) =>
prev.filter(
(p) => !(p.id === productId && p.wholesalerId === wholesalerId)
)
);
};
const handleCartQuantityChange = (
productId: string,
wholesalerId: string,
quantity: number
) => {
setSelectedProducts((prev) =>
prev.map((p) =>
p.id === productId && p.wholesalerId === wholesalerId
? { ...p, selectedQuantity: quantity }
: p
)
);
};
const handleSupplyComplete = () => {
router.push("/supplies");
};
const handleCreateSupplyClick = () => {
setIsCreatingSupply(true);
};
const handleCanCreateSupplyChange = (canCreate: boolean) => {
setCanCreateSupply(canCreate);
};
const handleSupplyCompleted = () => {
setIsCreatingSupply(false);
handleSupplyComplete();
};
// Рендер страницы товаров оптовика
if (selectedWholesaler && activeTab === "wholesaler") {
return (
<WholesalerProductsPage
selectedWholesaler={selectedWholesaler}
products={wholesalerProducts}
selectedProducts={selectedProducts}
onQuantityChange={updateProductQuantity}
onBack={handleGoBack}
onCreateSupply={handleCreateSupply}
formatCurrency={formatCurrency}
showSummary={showSummary}
setShowSummary={setShowSummary}
loading={productsLoading}
/>
);
}
// Главная страница с табами
return (
<div className="h-screen flex overflow-hidden">
<Sidebar />
<main
className={`flex-1 ${getSidebarMargin()} overflow-hidden transition-all duration-300`}
style={{ padding: '1rem' }}
>
<div className="flex flex-col" style={{ height: 'calc(100vh - 2rem)' }}>
<TabsHeader
activeTab={activeTab}
onTabChange={setActiveTab}
onBack={() => router.push("/supplies")}
cartInfo={
activeTab === "wholesaler" && selectedProducts.length > 0
? {
itemCount: selectedProducts.length,
totalAmount: getTotalAmount(),
formatCurrency,
}
: undefined
}
onCartClick={() => setShowSummary(true)}
onCreateSupply={handleCreateSupplyClick}
canCreateSupply={canCreateSupply}
isCreatingSupply={isCreatingSupply}
/>
{/* Контент карточек - новый компонент прямого создания поставки */}
{activeTab === "cards" && (
<div className="flex-1 flex flex-col overflow-hidden min-h-0">
<DirectSupplyCreation
onComplete={handleSupplyCompleted}
onCreateSupply={handleCreateSupplyClick}
canCreateSupply={canCreateSupply}
isCreatingSupply={isCreatingSupply}
onCanCreateSupplyChange={handleCanCreateSupplyChange}
/>
</div>
)}
{/* Контент оптовиков */}
{activeTab === "wholesaler" && (
<div>
<CartSummary
selectedProducts={selectedProducts}
onQuantityChange={handleCartQuantityChange}
onRemoveProduct={handleRemoveProduct}
onCreateSupply={handleCreateSupply}
onToggleVisibility={() => setShowSummary(false)}
formatCurrency={formatCurrency}
visible={showSummary && selectedProducts.length > 0}
/>
<WholesalerGrid
wholesalers={wholesalers}
onWholesalerSelect={setSelectedWholesaler}
searchQuery={searchQuery}
onSearchChange={setSearchQuery}
loading={counterpartiesLoading}
/>
<FloatingCart
itemCount={selectedProducts.length}
totalAmount={getTotalAmount()}
formatCurrency={formatCurrency}
onClick={() => setShowSummary(true)}
visible={selectedProducts.length > 0 && !showSummary}
/>
</div>
)}
</div>
</main>
</div>
);
}