Обновлен компонент CreateSupplyPage: улучшена структура кода и стили, добавлены новые функции для обработки товаров и поставок. Оптимизирован интерфейс с использованием новых компонентов и улучшена логика отображения данных. Исправлены ошибки и улучшена читаемость кода.

This commit is contained in:
Veronika Smirnova
2025-07-25 15:23:11 +03:00
parent 072d330202
commit 7d9b76a792
2 changed files with 438 additions and 344 deletions

View File

@ -1,157 +1,184 @@
"use client"
"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,
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'
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 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: counterpartiesData, loading: counterpartiesLoading } = useQuery(
GET_MY_COUNTERPARTIES
);
// Загружаем товары для выбранного оптовика
const { data: productsData, loading: productsLoading } = useQuery(GET_ALL_PRODUCTS, {
skip: !selectedWholesaler,
variables: { search: null, category: null }
})
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 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 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)
}
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
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
);
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))
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 }
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
}]
return [
...prev,
{
...product,
selectedQuantity: quantity,
wholesalerId: selectedWholesaler.id,
wholesalerName: selectedWholesaler.name,
},
];
}
})
}
});
};
const getTotalAmount = () => {
return selectedProducts.reduce((sum, product) => {
const discountedPrice = product.discount
const discountedPrice = product.discount
? product.price * (1 - product.discount / 100)
: product.price
return sum + (discountedPrice * product.selectedQuantity)
}, 0)
}
: product.price;
return sum + discountedPrice * product.selectedQuantity;
}, 0);
};
const getTotalItems = () => {
return selectedProducts.reduce((sum, product) => sum + product.selectedQuantity, 0)
}
return selectedProducts.reduce(
(sum, product) => sum + product.selectedQuantity,
0
);
};
const handleCreateSupply = () => {
if (activeTab === 'cards') {
console.log('Создание поставки с карточками Wildberries')
if (activeTab === "cards") {
console.log("Создание поставки с карточками Wildberries");
} else {
console.log('Создание поставки с товарами:', selectedProducts)
console.log("Создание поставки с товарами:", selectedProducts);
}
router.push('/supplies')
}
router.push("/supplies");
};
const handleGoBack = () => {
if (selectedWholesaler) {
setSelectedWholesaler(null)
setShowSummary(false)
setSelectedWholesaler(null);
setShowSummary(false);
} else {
router.push('/supplies')
router.push("/supplies");
}
}
};
const handleRemoveProduct = (productId: string, wholesalerId: string) => {
setSelectedProducts(prev =>
prev.filter(p => !(p.id === productId && p.wholesalerId === wholesalerId))
)
}
setSelectedProducts((prev) =>
prev.filter(
(p) => !(p.id === productId && p.wholesalerId === wholesalerId)
)
);
};
const handleCartQuantityChange = (productId: string, wholesalerId: string, quantity: number) => {
setSelectedProducts(prev =>
prev.map(p =>
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')
}
router.push("/supplies");
};
const handleCreateSupplyClick = () => {
setIsCreatingSupply(true)
}
setIsCreatingSupply(true);
};
const handleCanCreateSupplyChange = (canCreate: boolean) => {
setCanCreateSupply(canCreate)
}
setCanCreateSupply(canCreate);
};
const handleSupplyCompleted = () => {
setIsCreatingSupply(false)
handleSupplyComplete()
}
setIsCreatingSupply(false);
handleSupplyComplete();
};
// Рендер страницы товаров оптовика
if (selectedWholesaler && activeTab === 'wholesaler') {
if (selectedWholesaler && activeTab === "wholesaler") {
return (
<WholesalerProductsPage
selectedWholesaler={selectedWholesaler}
@ -165,25 +192,28 @@ export function CreateSupplyPage() {
setShowSummary={setShowSummary}
loading={productsLoading}
/>
)
);
}
// Главная страница с табами
return (
<div className="h-screen flex overflow-hidden">
<Sidebar />
<main className={`flex-1 ${getSidebarMargin()} px-4 py-3 overflow-y-auto transition-all duration-300`}>
<div className="p-4 min-h-full">
<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')}
onBack={() => router.push("/supplies")}
cartInfo={
activeTab === 'wholesaler' && selectedProducts.length > 0
activeTab === "wholesaler" && selectedProducts.length > 0
? {
itemCount: selectedProducts.length,
totalAmount: getTotalAmount(),
formatCurrency
formatCurrency,
}
: undefined
}
@ -194,18 +224,20 @@ export function CreateSupplyPage() {
/>
{/* Контент карточек - новый компонент прямого создания поставки */}
{activeTab === 'cards' && (
<DirectSupplyCreation
onComplete={handleSupplyCompleted}
onCreateSupply={handleCreateSupplyClick}
canCreateSupply={canCreateSupply}
isCreatingSupply={isCreatingSupply}
onCanCreateSupplyChange={handleCanCreateSupplyChange}
/>
{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' && (
{activeTab === "wholesaler" && (
<div>
<CartSummary
selectedProducts={selectedProducts}
@ -237,5 +269,5 @@ export function CreateSupplyPage() {
</div>
</main>
</div>
)
}
);
}