Обновлен компонент CreateSupplyPage: улучшена структура кода и стили, добавлены новые функции для обработки товаров и поставок. Оптимизирован интерфейс с использованием новых компонентов и улучшена логика отображения данных. Исправлены ошибки и улучшена читаемость кода.
This commit is contained in:
@ -1,157 +1,184 @@
|
|||||||
"use client"
|
"use client";
|
||||||
|
|
||||||
import React, { useState } from 'react'
|
import React, { useState } from "react";
|
||||||
import { Sidebar } from '@/components/dashboard/sidebar'
|
import { Sidebar } from "@/components/dashboard/sidebar";
|
||||||
import { useSidebar } from '@/hooks/useSidebar'
|
import { useSidebar } from "@/hooks/useSidebar";
|
||||||
import { useRouter } from 'next/navigation'
|
import { useRouter } from "next/navigation";
|
||||||
import { DirectSupplyCreation } from './direct-supply-creation'
|
import { DirectSupplyCreation } from "./direct-supply-creation";
|
||||||
import { WholesalerProductsPage } from './wholesaler-products-page'
|
import { WholesalerProductsPage } from "./wholesaler-products-page";
|
||||||
import { TabsHeader } from './tabs-header'
|
import { TabsHeader } from "./tabs-header";
|
||||||
import { WholesalerGrid } from './wholesaler-grid'
|
import { WholesalerGrid } from "./wholesaler-grid";
|
||||||
import { CartSummary } from './cart-summary'
|
import { CartSummary } from "./cart-summary";
|
||||||
import { FloatingCart } from './floating-cart'
|
import { FloatingCart } from "./floating-cart";
|
||||||
import {
|
import {
|
||||||
WholesalerForCreation,
|
WholesalerForCreation,
|
||||||
WholesalerProduct,
|
WholesalerProduct,
|
||||||
SelectedProduct,
|
SelectedProduct,
|
||||||
CounterpartyWholesaler
|
CounterpartyWholesaler,
|
||||||
} from './types'
|
} from "./types";
|
||||||
import { useQuery } from '@apollo/client'
|
import { useQuery } from "@apollo/client";
|
||||||
import { GET_MY_COUNTERPARTIES, GET_ALL_PRODUCTS } from '@/graphql/queries'
|
import { GET_MY_COUNTERPARTIES, GET_ALL_PRODUCTS } from "@/graphql/queries";
|
||||||
|
|
||||||
export function CreateSupplyPage() {
|
export function CreateSupplyPage() {
|
||||||
const router = useRouter()
|
const router = useRouter();
|
||||||
const { getSidebarMargin } = useSidebar()
|
const { getSidebarMargin } = useSidebar();
|
||||||
const [activeTab, setActiveTab] = useState<'cards' | 'wholesaler'>('cards')
|
const [activeTab, setActiveTab] = useState<"cards" | "wholesaler">("cards");
|
||||||
const [selectedWholesaler, setSelectedWholesaler] = useState<WholesalerForCreation | null>(null)
|
const [selectedWholesaler, setSelectedWholesaler] =
|
||||||
const [selectedProducts, setSelectedProducts] = useState<SelectedProduct[]>([])
|
useState<WholesalerForCreation | null>(null);
|
||||||
const [showSummary, setShowSummary] = useState(false)
|
const [selectedProducts, setSelectedProducts] = useState<SelectedProduct[]>(
|
||||||
const [searchQuery, setSearchQuery] = useState('')
|
[]
|
||||||
const [canCreateSupply, setCanCreateSupply] = useState(false)
|
);
|
||||||
const [isCreatingSupply, setIsCreatingSupply] = useState(false)
|
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, {
|
const { data: productsData, loading: productsLoading } = useQuery(
|
||||||
|
GET_ALL_PRODUCTS,
|
||||||
|
{
|
||||||
skip: !selectedWholesaler,
|
skip: !selectedWholesaler,
|
||||||
variables: { search: null, category: null }
|
variables: { search: null, category: null },
|
||||||
})
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// Фильтруем только оптовиков
|
// Фильтруем только оптовиков
|
||||||
const wholesalers: CounterpartyWholesaler[] = (counterpartiesData?.myCounterparties || [])
|
const wholesalers: CounterpartyWholesaler[] = (
|
||||||
.filter((org: { type: string }) => org.type === 'WHOLESALE')
|
counterpartiesData?.myCounterparties || []
|
||||||
|
).filter((org: { type: string }) => org.type === "WHOLESALE");
|
||||||
|
|
||||||
// Фильтруем товары по выбранному оптовику
|
// Фильтруем товары по выбранному оптовику
|
||||||
const wholesalerProducts: WholesalerProduct[] = selectedWholesaler
|
const wholesalerProducts: WholesalerProduct[] = selectedWholesaler
|
||||||
? (productsData?.allProducts || []).filter((product: { organization: { id: string } }) =>
|
? (productsData?.allProducts || []).filter(
|
||||||
|
(product: { organization: { id: string } }) =>
|
||||||
product.organization.id === selectedWholesaler.id
|
product.organization.id === selectedWholesaler.id
|
||||||
)
|
)
|
||||||
: []
|
: [];
|
||||||
|
|
||||||
const formatCurrency = (amount: number) => {
|
const formatCurrency = (amount: number) => {
|
||||||
return new Intl.NumberFormat('ru-RU', {
|
return new Intl.NumberFormat("ru-RU", {
|
||||||
style: 'currency',
|
style: "currency",
|
||||||
currency: 'RUB',
|
currency: "RUB",
|
||||||
minimumFractionDigits: 0
|
minimumFractionDigits: 0,
|
||||||
}).format(amount)
|
}).format(amount);
|
||||||
}
|
};
|
||||||
|
|
||||||
const updateProductQuantity = (productId: string, quantity: number) => {
|
const updateProductQuantity = (productId: string, quantity: number) => {
|
||||||
const product = wholesalerProducts.find((p) => p.id === productId)
|
const product = wholesalerProducts.find((p) => p.id === productId);
|
||||||
if (!product || !selectedWholesaler) return
|
if (!product || !selectedWholesaler) return;
|
||||||
|
|
||||||
setSelectedProducts(prev => {
|
setSelectedProducts((prev) => {
|
||||||
const existing = prev.find(p => p.id === productId && p.wholesalerId === selectedWholesaler.id)
|
const existing = prev.find(
|
||||||
|
(p) => p.id === productId && p.wholesalerId === selectedWholesaler.id
|
||||||
|
);
|
||||||
|
|
||||||
if (quantity === 0) {
|
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) {
|
if (existing) {
|
||||||
return prev.map(p =>
|
return prev.map((p) =>
|
||||||
p.id === productId && p.wholesalerId === selectedWholesaler.id
|
p.id === productId && p.wholesalerId === selectedWholesaler.id
|
||||||
? { ...p, selectedQuantity: quantity }
|
? { ...p, selectedQuantity: quantity }
|
||||||
: p
|
: p
|
||||||
)
|
);
|
||||||
} else {
|
} else {
|
||||||
return [...prev, {
|
return [
|
||||||
|
...prev,
|
||||||
|
{
|
||||||
...product,
|
...product,
|
||||||
selectedQuantity: quantity,
|
selectedQuantity: quantity,
|
||||||
wholesalerId: selectedWholesaler.id,
|
wholesalerId: selectedWholesaler.id,
|
||||||
wholesalerName: selectedWholesaler.name
|
wholesalerName: selectedWholesaler.name,
|
||||||
}]
|
},
|
||||||
}
|
];
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const getTotalAmount = () => {
|
const getTotalAmount = () => {
|
||||||
return selectedProducts.reduce((sum, product) => {
|
return selectedProducts.reduce((sum, product) => {
|
||||||
const discountedPrice = product.discount
|
const discountedPrice = product.discount
|
||||||
? product.price * (1 - product.discount / 100)
|
? product.price * (1 - product.discount / 100)
|
||||||
: product.price
|
: product.price;
|
||||||
return sum + (discountedPrice * product.selectedQuantity)
|
return sum + discountedPrice * product.selectedQuantity;
|
||||||
}, 0)
|
}, 0);
|
||||||
}
|
};
|
||||||
|
|
||||||
const getTotalItems = () => {
|
const getTotalItems = () => {
|
||||||
return selectedProducts.reduce((sum, product) => sum + product.selectedQuantity, 0)
|
return selectedProducts.reduce(
|
||||||
}
|
(sum, product) => sum + product.selectedQuantity,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const handleCreateSupply = () => {
|
const handleCreateSupply = () => {
|
||||||
if (activeTab === 'cards') {
|
if (activeTab === "cards") {
|
||||||
console.log('Создание поставки с карточками Wildberries')
|
console.log("Создание поставки с карточками Wildberries");
|
||||||
} else {
|
} else {
|
||||||
console.log('Создание поставки с товарами:', selectedProducts)
|
console.log("Создание поставки с товарами:", selectedProducts);
|
||||||
}
|
|
||||||
router.push('/supplies')
|
|
||||||
}
|
}
|
||||||
|
router.push("/supplies");
|
||||||
|
};
|
||||||
|
|
||||||
const handleGoBack = () => {
|
const handleGoBack = () => {
|
||||||
if (selectedWholesaler) {
|
if (selectedWholesaler) {
|
||||||
setSelectedWholesaler(null)
|
setSelectedWholesaler(null);
|
||||||
setShowSummary(false)
|
setShowSummary(false);
|
||||||
} else {
|
} else {
|
||||||
router.push('/supplies')
|
router.push("/supplies");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleRemoveProduct = (productId: string, wholesalerId: string) => {
|
const handleRemoveProduct = (productId: string, wholesalerId: string) => {
|
||||||
setSelectedProducts(prev =>
|
setSelectedProducts((prev) =>
|
||||||
prev.filter(p => !(p.id === productId && p.wholesalerId === wholesalerId))
|
prev.filter(
|
||||||
|
(p) => !(p.id === productId && p.wholesalerId === wholesalerId)
|
||||||
)
|
)
|
||||||
}
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const handleCartQuantityChange = (productId: string, wholesalerId: string, quantity: number) => {
|
const handleCartQuantityChange = (
|
||||||
setSelectedProducts(prev =>
|
productId: string,
|
||||||
prev.map(p =>
|
wholesalerId: string,
|
||||||
|
quantity: number
|
||||||
|
) => {
|
||||||
|
setSelectedProducts((prev) =>
|
||||||
|
prev.map((p) =>
|
||||||
p.id === productId && p.wholesalerId === wholesalerId
|
p.id === productId && p.wholesalerId === wholesalerId
|
||||||
? { ...p, selectedQuantity: quantity }
|
? { ...p, selectedQuantity: quantity }
|
||||||
: p
|
: p
|
||||||
)
|
)
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
const handleSupplyComplete = () => {
|
const handleSupplyComplete = () => {
|
||||||
router.push('/supplies')
|
router.push("/supplies");
|
||||||
}
|
};
|
||||||
|
|
||||||
const handleCreateSupplyClick = () => {
|
const handleCreateSupplyClick = () => {
|
||||||
setIsCreatingSupply(true)
|
setIsCreatingSupply(true);
|
||||||
}
|
};
|
||||||
|
|
||||||
const handleCanCreateSupplyChange = (canCreate: boolean) => {
|
const handleCanCreateSupplyChange = (canCreate: boolean) => {
|
||||||
setCanCreateSupply(canCreate)
|
setCanCreateSupply(canCreate);
|
||||||
}
|
};
|
||||||
|
|
||||||
const handleSupplyCompleted = () => {
|
const handleSupplyCompleted = () => {
|
||||||
setIsCreatingSupply(false)
|
setIsCreatingSupply(false);
|
||||||
handleSupplyComplete()
|
handleSupplyComplete();
|
||||||
}
|
};
|
||||||
|
|
||||||
// Рендер страницы товаров оптовика
|
// Рендер страницы товаров оптовика
|
||||||
if (selectedWholesaler && activeTab === 'wholesaler') {
|
if (selectedWholesaler && activeTab === "wholesaler") {
|
||||||
return (
|
return (
|
||||||
<WholesalerProductsPage
|
<WholesalerProductsPage
|
||||||
selectedWholesaler={selectedWholesaler}
|
selectedWholesaler={selectedWholesaler}
|
||||||
@ -165,25 +192,28 @@ export function CreateSupplyPage() {
|
|||||||
setShowSummary={setShowSummary}
|
setShowSummary={setShowSummary}
|
||||||
loading={productsLoading}
|
loading={productsLoading}
|
||||||
/>
|
/>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Главная страница с табами
|
// Главная страница с табами
|
||||||
return (
|
return (
|
||||||
<div className="h-screen flex overflow-hidden">
|
<div className="h-screen flex overflow-hidden">
|
||||||
<Sidebar />
|
<Sidebar />
|
||||||
<main className={`flex-1 ${getSidebarMargin()} px-4 py-3 overflow-y-auto transition-all duration-300`}>
|
<main
|
||||||
<div className="p-4 min-h-full">
|
className={`flex-1 ${getSidebarMargin()} overflow-hidden transition-all duration-300`}
|
||||||
|
style={{ padding: '1rem' }}
|
||||||
|
>
|
||||||
|
<div className="flex flex-col" style={{ height: 'calc(100vh - 2rem)' }}>
|
||||||
<TabsHeader
|
<TabsHeader
|
||||||
activeTab={activeTab}
|
activeTab={activeTab}
|
||||||
onTabChange={setActiveTab}
|
onTabChange={setActiveTab}
|
||||||
onBack={() => router.push('/supplies')}
|
onBack={() => router.push("/supplies")}
|
||||||
cartInfo={
|
cartInfo={
|
||||||
activeTab === 'wholesaler' && selectedProducts.length > 0
|
activeTab === "wholesaler" && selectedProducts.length > 0
|
||||||
? {
|
? {
|
||||||
itemCount: selectedProducts.length,
|
itemCount: selectedProducts.length,
|
||||||
totalAmount: getTotalAmount(),
|
totalAmount: getTotalAmount(),
|
||||||
formatCurrency
|
formatCurrency,
|
||||||
}
|
}
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
@ -194,7 +224,8 @@ export function CreateSupplyPage() {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Контент карточек - новый компонент прямого создания поставки */}
|
{/* Контент карточек - новый компонент прямого создания поставки */}
|
||||||
{activeTab === 'cards' && (
|
{activeTab === "cards" && (
|
||||||
|
<div className="flex-1 flex flex-col overflow-hidden min-h-0">
|
||||||
<DirectSupplyCreation
|
<DirectSupplyCreation
|
||||||
onComplete={handleSupplyCompleted}
|
onComplete={handleSupplyCompleted}
|
||||||
onCreateSupply={handleCreateSupplyClick}
|
onCreateSupply={handleCreateSupplyClick}
|
||||||
@ -202,10 +233,11 @@ export function CreateSupplyPage() {
|
|||||||
isCreatingSupply={isCreatingSupply}
|
isCreatingSupply={isCreatingSupply}
|
||||||
onCanCreateSupplyChange={handleCanCreateSupplyChange}
|
onCanCreateSupplyChange={handleCanCreateSupplyChange}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Контент оптовиков */}
|
{/* Контент оптовиков */}
|
||||||
{activeTab === 'wholesaler' && (
|
{activeTab === "wholesaler" && (
|
||||||
<div>
|
<div>
|
||||||
<CartSummary
|
<CartSummary
|
||||||
selectedProducts={selectedProducts}
|
selectedProducts={selectedProducts}
|
||||||
@ -237,5 +269,5 @@ export function CreateSupplyPage() {
|
|||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
@ -668,14 +668,14 @@ export function DirectSupplyCreation({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<style>{lineClampStyles}</style>
|
<style>{lineClampStyles}</style>
|
||||||
<div className="space-y-3 w-full">
|
<div className="flex flex-col h-full space-y-2 w-full min-h-0">
|
||||||
{/* НОВЫЙ БЛОК СОЗДАНИЯ ПОСТАВКИ */}
|
{/* НОВЫЙ БЛОК СОЗДАНИЯ ПОСТАВКИ */}
|
||||||
<Card className="bg-white/10 backdrop-blur-xl border border-white/20 p-3">
|
<Card className="bg-white/10 backdrop-blur-xl border border-white/20 p-2">
|
||||||
{/* Первая строка */}
|
{/* Первая строка */}
|
||||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-2 items-end mb-0.5">
|
<div className="grid grid-cols-1 md:grid-cols-4 gap-1.5 items-end mb-0.5">
|
||||||
{/* 1. Модуль выбора даты */}
|
{/* 1. Модуль выбора даты */}
|
||||||
<div>
|
<div>
|
||||||
<Label className="text-white/80 text-xs mb-1 block flex items-center gap-1">
|
<Label className="text-white/80 text-xs mb-0.5 block flex items-center gap-1">
|
||||||
<CalendarIcon className="h-3 w-3" />
|
<CalendarIcon className="h-3 w-3" />
|
||||||
Дата
|
Дата
|
||||||
</Label>
|
</Label>
|
||||||
@ -684,7 +684,7 @@ export function DirectSupplyCreation({
|
|||||||
type="date"
|
type="date"
|
||||||
value={deliveryDate}
|
value={deliveryDate}
|
||||||
onChange={(e) => setDeliveryDate(e.target.value)}
|
onChange={(e) => setDeliveryDate(e.target.value)}
|
||||||
className="w-full h-8 rounded-lg border-0 bg-white/20 backdrop-blur px-2 py-1 text-white placeholder:text-white/50 focus:bg-white/30 focus:outline-none focus:ring-1 focus:ring-white/20 text-xs font-medium"
|
className="w-full h-7 rounded-lg border-0 bg-white/20 backdrop-blur px-2 py-1 text-white placeholder:text-white/50 focus:bg-white/30 focus:outline-none focus:ring-1 focus:ring-white/20 text-xs font-medium"
|
||||||
min={new Date().toISOString().split("T")[0]}
|
min={new Date().toISOString().split("T")[0]}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -692,7 +692,7 @@ export function DirectSupplyCreation({
|
|||||||
|
|
||||||
{/* 2. Модуль выбора фулфилмента */}
|
{/* 2. Модуль выбора фулфилмента */}
|
||||||
<div>
|
<div>
|
||||||
<Label className="text-white/80 text-xs mb-1 block flex items-center gap-1">
|
<Label className="text-white/80 text-xs mb-0.5 block flex items-center gap-1">
|
||||||
<Building className="h-3 w-3" />
|
<Building className="h-3 w-3" />
|
||||||
Фулфилмент
|
Фулфилмент
|
||||||
</Label>
|
</Label>
|
||||||
@ -700,7 +700,7 @@ export function DirectSupplyCreation({
|
|||||||
value={selectedFulfillment}
|
value={selectedFulfillment}
|
||||||
onValueChange={setSelectedFulfillment}
|
onValueChange={setSelectedFulfillment}
|
||||||
>
|
>
|
||||||
<SelectTrigger className="w-full h-8 py-0 px-2 bg-white/20 border-0 text-white focus:bg-white/30 focus:ring-1 focus:ring-white/20 text-xs">
|
<SelectTrigger className="w-full h-7 py-0 px-2 bg-white/20 border-0 text-white focus:bg-white/30 focus:ring-1 focus:ring-white/20 text-xs">
|
||||||
<SelectValue placeholder="ФУЛФИЛМЕНТ ИВАНОВО" />
|
<SelectValue placeholder="ФУЛФИЛМЕНТ ИВАНОВО" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
@ -715,7 +715,7 @@ export function DirectSupplyCreation({
|
|||||||
|
|
||||||
{/* 3. Объём товаров */}
|
{/* 3. Объём товаров */}
|
||||||
<div>
|
<div>
|
||||||
<Label className="text-white/80 text-xs mb-1 block">
|
<Label className="text-white/80 text-xs mb-0.5 block">
|
||||||
Объём товаров
|
Объём товаров
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
@ -725,13 +725,13 @@ export function DirectSupplyCreation({
|
|||||||
setGoodsVolume(parseFloat(e.target.value) || 0)
|
setGoodsVolume(parseFloat(e.target.value) || 0)
|
||||||
}
|
}
|
||||||
placeholder="м³"
|
placeholder="м³"
|
||||||
className="h-8 bg-white/20 border-0 text-white placeholder:text-white/50 focus:bg-white/30 focus:ring-1 focus:ring-white/20 text-xs"
|
className="h-7 bg-white/20 border-0 text-white placeholder:text-white/50 focus:bg-white/30 focus:ring-1 focus:ring-white/20 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 4. Грузовые места */}
|
{/* 4. Грузовые места */}
|
||||||
<div>
|
<div>
|
||||||
<Label className="text-white/80 text-xs mb-1 block">
|
<Label className="text-white/80 text-xs mb-0.5 block">
|
||||||
Грузовые места
|
Грузовые места
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
@ -739,16 +739,16 @@ export function DirectSupplyCreation({
|
|||||||
value={cargoPlaces || ""}
|
value={cargoPlaces || ""}
|
||||||
onChange={(e) => setCargoPlaces(parseInt(e.target.value) || 0)}
|
onChange={(e) => setCargoPlaces(parseInt(e.target.value) || 0)}
|
||||||
placeholder="шт"
|
placeholder="шт"
|
||||||
className="h-8 bg-white/20 border-0 text-white placeholder:text-white/50 focus:bg-white/30 focus:ring-1 focus:ring-white/20 text-xs"
|
className="h-7 bg-white/20 border-0 text-white placeholder:text-white/50 focus:bg-white/30 focus:ring-1 focus:ring-white/20 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Вторая строка */}
|
{/* Вторая строка */}
|
||||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-2 items-end">
|
<div className="grid grid-cols-1 md:grid-cols-4 gap-1.5 items-end">
|
||||||
{/* 5. Цена товаров */}
|
{/* 5. Цена товаров */}
|
||||||
<div>
|
<div>
|
||||||
<Label className="text-white/80 text-xs mb-1 block">
|
<Label className="text-white/80 text-xs mb-0.5 block">
|
||||||
Цена товаров
|
Цена товаров
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
@ -756,13 +756,13 @@ export function DirectSupplyCreation({
|
|||||||
value={goodsPrice || ""}
|
value={goodsPrice || ""}
|
||||||
onChange={(e) => setGoodsPrice(parseFloat(e.target.value) || 0)}
|
onChange={(e) => setGoodsPrice(parseFloat(e.target.value) || 0)}
|
||||||
placeholder="₽"
|
placeholder="₽"
|
||||||
className="h-8 bg-white/20 border-0 text-white placeholder:text-white/50 focus:bg-white/30 focus:ring-1 focus:ring-white/20 text-xs"
|
className="h-7 bg-white/20 border-0 text-white placeholder:text-white/50 focus:bg-white/30 focus:ring-1 focus:ring-white/20 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 6. Цена услуг фулфилмента */}
|
{/* 6. Цена услуг фулфилмента */}
|
||||||
<div>
|
<div>
|
||||||
<Label className="text-white/80 text-xs mb-1 block">
|
<Label className="text-white/80 text-xs mb-0.5 block">
|
||||||
Цена услуг фулфилмент
|
Цена услуг фулфилмент
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
@ -772,13 +772,13 @@ export function DirectSupplyCreation({
|
|||||||
setFulfillmentServicesPrice(parseFloat(e.target.value) || 0)
|
setFulfillmentServicesPrice(parseFloat(e.target.value) || 0)
|
||||||
}
|
}
|
||||||
placeholder="₽"
|
placeholder="₽"
|
||||||
className="h-8 bg-white/20 border-0 text-white placeholder:text-white/50 focus:bg-white/30 focus:ring-1 focus:ring-white/20 text-xs"
|
className="h-7 bg-white/20 border-0 text-white placeholder:text-white/50 focus:bg-white/30 focus:ring-1 focus:ring-white/20 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 7. Цена логистики */}
|
{/* 7. Цена логистики */}
|
||||||
<div>
|
<div>
|
||||||
<Label className="text-white/80 text-xs mb-1 block">
|
<Label className="text-white/80 text-xs mb-0.5 block">
|
||||||
Логистика до фулфилмента
|
Логистика до фулфилмента
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
@ -788,14 +788,16 @@ export function DirectSupplyCreation({
|
|||||||
setLogisticsPrice(parseFloat(e.target.value) || 0)
|
setLogisticsPrice(parseFloat(e.target.value) || 0)
|
||||||
}
|
}
|
||||||
placeholder="₽"
|
placeholder="₽"
|
||||||
className="h-8 bg-white/20 border-0 text-white placeholder:text-white/50 focus:bg-white/30 focus:ring-1 focus:ring-white/20 text-xs"
|
className="h-7 bg-white/20 border-0 text-white placeholder:text-white/50 focus:bg-white/30 focus:ring-1 focus:ring-white/20 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 8. Итоговая сумма */}
|
{/* 8. Итоговая сумма */}
|
||||||
<div>
|
<div>
|
||||||
<Label className="text-white/80 text-xs mb-1 block">Итого</Label>
|
<Label className="text-white/80 text-xs mb-0.5 block">
|
||||||
<div className="h-8 bg-white/10 rounded-lg flex items-center justify-center">
|
Итого
|
||||||
|
</Label>
|
||||||
|
<div className="h-7 bg-white/10 rounded-lg flex items-center justify-center">
|
||||||
<span className="text-white font-bold text-sm">
|
<span className="text-white font-bold text-sm">
|
||||||
{formatCurrency(getTotalSum()).replace(" ₽", " ₽")}
|
{formatCurrency(getTotalSum()).replace(" ₽", " ₽")}
|
||||||
</span>
|
</span>
|
||||||
@ -804,143 +806,187 @@ export function DirectSupplyCreation({
|
|||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
{/* Блок поиска товаров - оптимизированное расположение */}
|
{/* Элегантный блок поиска и товаров */}
|
||||||
<Card className="bg-white/10 backdrop-blur-xl border border-white/20 p-3">
|
<div className="relative">
|
||||||
<div className="mb-1">
|
{/* Главная карточка с градиентом */}
|
||||||
<Label className="text-white/80 text-xs mb-2 block flex items-center gap-1">
|
<div className="bg-gradient-to-br from-white/15 via-white/10 to-white/5 backdrop-blur-xl border border-white/20 rounded-2xl p-4 shadow-2xl">
|
||||||
<Search className="h-3 w-3" />
|
{/* Компактный заголовок с поиском */}
|
||||||
Поиск товаров Wildberries
|
<div className="flex items-center justify-between mb-2">
|
||||||
</Label>
|
<div className="flex items-center space-x-3">
|
||||||
<div className="flex items-center space-x-2">
|
<div className="w-8 h-8 bg-gradient-to-r from-purple-500 to-blue-500 rounded-lg flex items-center justify-center shadow-lg">
|
||||||
|
<Search className="h-4 w-4 text-white" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 className="text-white font-semibold text-base">
|
||||||
|
Каталог товаров
|
||||||
|
</h3>
|
||||||
|
<p className="text-white/60 text-xs">
|
||||||
|
Найдено: {wbCards.length}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Поиск в заголовке */}
|
||||||
|
<div className="flex items-center space-x-3 flex-1 max-w-md ml-4">
|
||||||
|
<div className="relative flex-1">
|
||||||
<Input
|
<Input
|
||||||
placeholder="Введите название товара, артикул или бренд..."
|
placeholder="Поиск товаров..."
|
||||||
value={searchTerm}
|
value={searchTerm}
|
||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
className="bg-white/20 border-0 text-white placeholder-white/60 h-8 text-xs flex-1 focus:bg-white/30 focus:ring-1 focus:ring-white/20"
|
className="pl-3 pr-16 py-2 bg-white/10 border border-white/20 rounded-lg text-white placeholder-white/50 focus:bg-white/15 focus:border-white/40 text-sm h-8"
|
||||||
onKeyPress={(e) => e.key === "Enter" && searchCards()}
|
onKeyPress={(e) => e.key === "Enter" && searchCards()}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
onClick={searchCards}
|
onClick={searchCards}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
className="h-8 px-4 bg-white/20 hover:bg-white/30 border-0 text-white text-xs font-medium backdrop-blur"
|
className="absolute right-1 top-1 h-6 px-2 bg-gradient-to-r from-purple-500 to-blue-500 hover:from-purple-600 hover:to-blue-600 text-white border-0 rounded text-xs"
|
||||||
>
|
>
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<div className="animate-spin rounded-full h-3 w-3 border-b-2 border-white"></div>
|
<div className="animate-spin rounded-full h-3 w-3 border border-white/30 border-t-white"></div>
|
||||||
) : (
|
) : (
|
||||||
<>
|
"Найти"
|
||||||
<Search className="h-3 w-3 mr-1" />
|
|
||||||
Поиск
|
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Карточки товаров - увеличенный размер и единообразность */}
|
{/* Статистика в поставке */}
|
||||||
<div className="space-y-1">
|
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
<span className="text-white/80 text-xs font-medium">
|
|
||||||
Найдено товаров: {wbCards.length}
|
|
||||||
</span>
|
|
||||||
{supplyItems.length > 0 && (
|
{supplyItems.length > 0 && (
|
||||||
<Badge
|
<div className="bg-gradient-to-r from-purple-500/20 to-blue-500/20 backdrop-blur border border-purple-400/30 rounded-lg px-3 py-1 ml-3">
|
||||||
variant="secondary"
|
<div className="flex items-center space-x-2">
|
||||||
className="bg-purple-500/20 text-purple-200 text-xs"
|
<div className="w-1.5 h-1.5 bg-purple-400 rounded-full animate-pulse"></div>
|
||||||
>
|
<span className="text-purple-200 font-medium text-xs">
|
||||||
В поставке: {supplyItems.length}
|
В поставке: {supplyItems.length}
|
||||||
</Badge>
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-3 sm:grid-cols-4 md:grid-cols-6 lg:grid-cols-8 xl:grid-cols-10 gap-2">
|
{/* Сетка товаров */}
|
||||||
{loading
|
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 xl:grid-cols-8 gap-3">
|
||||||
? [...Array(12)].map((_, i) => (
|
{loading ? (
|
||||||
<div
|
// Красивые skeleton-карточки
|
||||||
key={i}
|
[...Array(16)].map((_, i) => (
|
||||||
className="aspect-[3/4] bg-white/5 rounded-lg animate-pulse"
|
<div key={i} className="group">
|
||||||
></div>
|
<div className="aspect-[3/4] bg-gradient-to-br from-white/10 to-white/5 rounded-xl animate-pulse">
|
||||||
|
<div className="w-full h-full bg-white/5 rounded-xl"></div>
|
||||||
|
</div>
|
||||||
|
<div className="mt-1 px-1">
|
||||||
|
<div className="h-3 bg-white/10 rounded animate-pulse"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
))
|
))
|
||||||
: wbCards.map((card) => {
|
) : wbCards.length > 0 ? (
|
||||||
|
// Красивые карточки товаров
|
||||||
|
wbCards.map((card) => {
|
||||||
const isInSupply = supplyItems.some(
|
const isInSupply = supplyItems.some(
|
||||||
(item) => item.card.nmID === card.nmID
|
(item) => item.card.nmID === card.nmID
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={card.nmID}
|
key={card.nmID}
|
||||||
className={`group relative cursor-pointer transition-all duration-200 hover:scale-105 hover:z-10 ${
|
className={`group cursor-pointer transition-all duration-300 hover:scale-105 ${
|
||||||
isInSupply
|
isInSupply ? "scale-105" : ""
|
||||||
? "ring-2 ring-purple-400 ring-offset-1 ring-offset-transparent"
|
|
||||||
: ""
|
|
||||||
}`}
|
}`}
|
||||||
onClick={() => addToSupply(card)}
|
onClick={() => addToSupply(card)}
|
||||||
>
|
>
|
||||||
<div className="aspect-[3/4] bg-white/10 rounded-lg overflow-hidden backdrop-blur-sm border border-white/20 hover:border-white/40 transition-all">
|
{/* Карточка товара */}
|
||||||
|
<div
|
||||||
|
className={`relative aspect-[3/4] rounded-xl overflow-hidden shadow-lg transition-all duration-300 ${
|
||||||
|
isInSupply
|
||||||
|
? "ring-2 ring-purple-400 shadow-purple-400/25 bg-gradient-to-br from-purple-500/20 to-blue-500/20"
|
||||||
|
: "bg-white/10 hover:bg-white/15 hover:shadow-xl"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
<img
|
<img
|
||||||
src={
|
src={
|
||||||
WildberriesService.getCardImage(
|
WildberriesService.getCardImage(card, "c516x688") ||
|
||||||
card,
|
"/api/placeholder/200/267"
|
||||||
"c516x688"
|
|
||||||
) || "/api/placeholder/120/160"
|
|
||||||
}
|
}
|
||||||
alt={card.title}
|
alt={card.title}
|
||||||
className="w-full h-full object-cover transition-transform group-hover:scale-110"
|
className="w-full h-full object-cover transition-transform duration-500 group-hover:scale-110"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Оверлей с информацией */}
|
{/* Градиентный оверлей */}
|
||||||
<div className="absolute inset-0 bg-gradient-to-t from-black/80 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity">
|
<div className="absolute inset-0 bg-gradient-to-t from-black/60 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300" />
|
||||||
<div className="absolute bottom-2 left-2 right-2">
|
|
||||||
<div className="text-white text-xs font-medium line-clamp-2 mb-1">
|
{/* Информация при наведении */}
|
||||||
|
<div className="absolute bottom-0 left-0 right-0 p-3 transform translate-y-full group-hover:translate-y-0 transition-transform duration-300">
|
||||||
|
<h4 className="text-white font-medium text-sm line-clamp-2 mb-1">
|
||||||
{card.title}
|
{card.title}
|
||||||
</div>
|
</h4>
|
||||||
<div className="text-white/70 text-[10px]">
|
<p className="text-white/80 text-xs mb-1">
|
||||||
Арт: {card.vendorCode}
|
Арт: {card.vendorCode}
|
||||||
</div>
|
</p>
|
||||||
{card.sizes && card.sizes[0] && (
|
{card.sizes && card.sizes[0] && (
|
||||||
<div className="text-purple-300 text-[10px] font-medium">
|
<p className="text-purple-300 font-semibold text-sm">
|
||||||
от{" "}
|
от{" "}
|
||||||
{card.sizes[0].discountedPrice ||
|
{card.sizes[0].discountedPrice ||
|
||||||
card.sizes[0].price}{" "}
|
card.sizes[0].price}{" "}
|
||||||
₽
|
₽
|
||||||
</div>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Индикатор добавления в поставку */}
|
{/* Индикаторы */}
|
||||||
{isInSupply && (
|
{isInSupply ? (
|
||||||
<div className="absolute top-2 right-2 bg-purple-500 text-white rounded-full w-6 h-6 flex items-center justify-center text-xs font-bold shadow-lg">
|
<div className="absolute top-3 right-3 w-8 h-8 bg-gradient-to-r from-purple-500 to-blue-500 rounded-full flex items-center justify-center shadow-lg">
|
||||||
✓
|
<svg
|
||||||
|
className="w-4 h-4 text-white"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
||||||
|
clipRule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="absolute top-3 right-3 w-8 h-8 bg-white/20 backdrop-blur rounded-full flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-300">
|
||||||
|
<Plus className="w-4 h-4 text-white" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Индикатор при наведении */}
|
{/* Эффект при клике */}
|
||||||
<div className="absolute top-2 left-2 bg-white/20 backdrop-blur text-white rounded-full w-6 h-6 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity">
|
<div className="absolute inset-0 bg-white/20 opacity-0 group-active:opacity-100 transition-opacity duration-150" />
|
||||||
<Plus className="h-3 w-3" />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Название под карточкой */}
|
||||||
|
<div className="mt-1 px-1">
|
||||||
|
<h4 className="text-white/90 font-medium text-xs line-clamp-2 leading-tight">
|
||||||
|
{card.title}
|
||||||
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})
|
||||||
|
) : (
|
||||||
|
// Пустое состояние
|
||||||
|
<div className="col-span-full flex flex-col items-center justify-center py-8">
|
||||||
|
<div className="w-16 h-16 bg-gradient-to-r from-purple-500/20 to-blue-500/20 rounded-2xl flex items-center justify-center mb-3">
|
||||||
|
<Package className="w-8 h-8 text-white/40" />
|
||||||
|
</div>
|
||||||
|
<h3 className="text-white/80 font-medium text-base mb-1">
|
||||||
|
{searchTerm ? "Товары не найдены" : "Начните поиск товаров"}
|
||||||
|
</h3>
|
||||||
|
<p className="text-white/50 text-sm text-center max-w-md">
|
||||||
|
{searchTerm
|
||||||
|
? "Попробуйте изменить поисковый запрос"
|
||||||
|
: "Введите название товара в поле поиска"}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!loading && wbCards.length === 0 && (
|
{/* Декоративные элементы */}
|
||||||
<div className="text-center py-4">
|
<div className="absolute -top-1 -left-1 w-4 h-4 bg-gradient-to-r from-purple-500 to-blue-500 rounded-full opacity-60 animate-pulse" />
|
||||||
<Package className="h-8 w-8 text-white/20 mx-auto mb-2" />
|
<div className="absolute -bottom-1 -right-1 w-3 h-3 bg-gradient-to-r from-blue-500 to-purple-500 rounded-full opacity-40 animate-pulse delay-700" />
|
||||||
<p className="text-white/60 text-xs">
|
|
||||||
{searchTerm
|
|
||||||
? "Товары не найдены"
|
|
||||||
: "Введите запрос для поиска товаров"}
|
|
||||||
</p>
|
|
||||||
{searchTerm && (
|
|
||||||
<p className="text-white/40 text-[10px] mt-1">
|
|
||||||
Попробуйте изменить условия поиска
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
{/* Услуги и расходники в одной строке */}
|
{/* Услуги и расходники в одной строке */}
|
||||||
{selectedFulfillmentOrg && (
|
{selectedFulfillmentOrg && (
|
||||||
@ -1027,44 +1073,37 @@ export function DirectSupplyCreation({
|
|||||||
</Card>
|
</Card>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Модуль товаров в поставке - новый дизайн */}
|
{/* Модуль товаров в поставке - растягивается до низа */}
|
||||||
<Card className="bg-white/10 backdrop-blur border-white/20 p-3">
|
<Card className="bg-white/10 backdrop-blur border-white/20 p-2 flex-1 flex flex-col min-h-0">
|
||||||
<div className="flex items-center justify-between mb-3">
|
<div className="flex items-center justify-between mb-2 flex-shrink-0">
|
||||||
<span className="text-white font-medium text-sm">
|
<span className="text-white font-medium text-sm">
|
||||||
Товары в поставке
|
Товары в поставке
|
||||||
</span>
|
</span>
|
||||||
<Button
|
|
||||||
onClick={() => setShowSupplierModal(true)}
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
className="bg-white/5 border-white/20 text-white hover:bg-white/10 h-7 px-3 text-xs"
|
|
||||||
>
|
|
||||||
<Plus className="h-3 w-3 mr-1" />
|
|
||||||
Поставщик
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{supplyItems.length === 0 ? (
|
{supplyItems.length === 0 ? (
|
||||||
<div className="text-center py-6">
|
<div className="flex-1 flex items-center justify-center">
|
||||||
|
<div className="text-center">
|
||||||
<Package className="h-8 w-8 text-white/20 mx-auto mb-2" />
|
<Package className="h-8 w-8 text-white/20 mx-auto mb-2" />
|
||||||
<p className="text-white/60 text-xs">
|
<p className="text-white/60 text-xs">
|
||||||
Добавьте товары из карточек выше
|
Добавьте товары из карточек выше
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="space-y-4">
|
<div className="flex-1 overflow-y-auto space-y-1">
|
||||||
{supplyItems.map((item) => (
|
{supplyItems.map((item) => (
|
||||||
<Card
|
<Card
|
||||||
key={item.card.nmID}
|
key={item.card.nmID}
|
||||||
className="bg-white/5 border-white/10 p-3"
|
className="bg-white/5 border-white/10 p-1.5"
|
||||||
>
|
>
|
||||||
{/* Заголовок товара с кнопкой удаления */}
|
{/* Компактный заголовок товара */}
|
||||||
<div className="flex items-center justify-between mb-3">
|
<div className="flex items-center justify-between mb-1">
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2 min-w-0">
|
||||||
<div className="text-white font-medium text-sm line-clamp-1">
|
<div className="text-white font-medium text-xs line-clamp-1 truncate">
|
||||||
{item.card.title}
|
{item.card.title}
|
||||||
</div>
|
</div>
|
||||||
<div className="text-white/60 text-xs">
|
<div className="text-white/60 text-[10px] flex-shrink-0">
|
||||||
Арт: {item.card.vendorCode}
|
Арт: {item.card.vendorCode}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -1072,47 +1111,44 @@ export function DirectSupplyCreation({
|
|||||||
onClick={() => removeFromSupply(item.card.nmID)}
|
onClick={() => removeFromSupply(item.card.nmID)}
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
className="h-6 w-6 p-0 text-white/60 hover:text-red-400"
|
className="h-5 w-5 p-0 text-white/60 hover:text-red-400 flex-shrink-0"
|
||||||
>
|
>
|
||||||
<X className="h-4 w-4" />
|
<X className="h-3 w-3" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Названия блоков */}
|
{/* Компактные названия блоков */}
|
||||||
<div
|
<div className="grid grid-cols-8 gap-1 mb-1">
|
||||||
className="grid grid-cols-8 gap-2"
|
<div className="text-white/80 text-[9px] font-medium text-center">
|
||||||
style={{ marginBottom: "4px" }}
|
|
||||||
>
|
|
||||||
<div className="text-white/80 text-xs font-medium text-center">
|
|
||||||
Товар
|
Товар
|
||||||
</div>
|
</div>
|
||||||
<div className="text-white/80 text-xs font-medium text-center">
|
<div className="text-white/80 text-[9px] font-medium text-center">
|
||||||
Параметры
|
Параметры
|
||||||
</div>
|
</div>
|
||||||
<div className="text-white/80 text-xs font-medium text-center">
|
<div className="text-white/80 text-[9px] font-medium text-center">
|
||||||
Заказать
|
Заказать
|
||||||
</div>
|
</div>
|
||||||
<div className="text-white/80 text-xs font-medium text-center">
|
<div className="text-white/80 text-[9px] font-medium text-center">
|
||||||
Цена
|
Цена
|
||||||
</div>
|
</div>
|
||||||
<div className="text-white/80 text-xs font-medium text-center">
|
<div className="text-white/80 text-[9px] font-medium text-center">
|
||||||
Услуги фулфилмента
|
Услуги фф
|
||||||
</div>
|
</div>
|
||||||
<div className="text-white/80 text-xs font-medium text-center">
|
<div className="text-white/80 text-[9px] font-medium text-center">
|
||||||
Поставщик
|
Поставщик
|
||||||
</div>
|
</div>
|
||||||
<div className="text-white/80 text-xs font-medium text-center">
|
<div className="text-white/80 text-[9px] font-medium text-center">
|
||||||
Расходники фулфилмента
|
Расходники фф
|
||||||
</div>
|
</div>
|
||||||
<div className="text-white/80 text-xs font-medium text-center">
|
<div className="text-white/80 text-[9px] font-medium text-center">
|
||||||
Расходники селлера
|
Расходники
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Оптимизированная сетка для 13" - все блоки в одну строку */}
|
{/* Компактная сетка блоков */}
|
||||||
<div className="grid grid-cols-8 gap-2">
|
<div className="grid grid-cols-8 gap-1">
|
||||||
{/* Блок 1: Картинка товара */}
|
{/* Блок 1: Картинка товара */}
|
||||||
<div className="bg-white/10 rounded-lg overflow-hidden relative">
|
<div className="bg-white/10 rounded-lg overflow-hidden relative h-20">
|
||||||
<img
|
<img
|
||||||
src={
|
src={
|
||||||
WildberriesService.getCardImage(
|
WildberriesService.getCardImage(
|
||||||
@ -1126,16 +1162,16 @@ export function DirectSupplyCreation({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Блок 2: Параметры */}
|
{/* Блок 2: Параметры */}
|
||||||
<div className="bg-white/10 rounded-lg p-2 flex flex-col justify-center">
|
<div className="bg-white/10 rounded-lg p-2 flex flex-col justify-center h-20">
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<div className="text-white/70 text-[9px] text-center">
|
<div className="text-white/70 text-xs text-center">
|
||||||
{item.card.object}
|
{item.card.object}
|
||||||
</div>
|
</div>
|
||||||
<div className="text-white/70 text-[9px] text-center">
|
<div className="text-white/70 text-xs text-center">
|
||||||
{item.card.countryProduction}
|
{item.card.countryProduction}
|
||||||
</div>
|
</div>
|
||||||
{item.card.sizes && item.card.sizes[0] && (
|
{item.card.sizes && item.card.sizes[0] && (
|
||||||
<div className="text-white/70 text-[9px] text-center">
|
<div className="text-white/70 text-xs text-center">
|
||||||
{item.card.sizes[0].techSize}
|
{item.card.sizes[0].techSize}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -1143,8 +1179,8 @@ export function DirectSupplyCreation({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Блок 3: Заказать */}
|
{/* Блок 3: Заказать */}
|
||||||
<div className="bg-white/10 rounded-lg p-2 flex flex-col justify-center">
|
<div className="bg-white/10 rounded-lg p-2 flex flex-col justify-center h-20">
|
||||||
<div className="text-white/60 text-[10px] mb-1 text-center">
|
<div className="text-white/60 text-xs mb-2 text-center">
|
||||||
Количество
|
Количество
|
||||||
</div>
|
</div>
|
||||||
<Input
|
<Input
|
||||||
@ -1157,14 +1193,14 @@ export function DirectSupplyCreation({
|
|||||||
parseInt(e.target.value) || 0
|
parseInt(e.target.value) || 0
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
className="bg-purple-500/20 border-purple-400/30 text-white text-center h-7 text-xs font-bold"
|
className="bg-purple-500/20 border-purple-400/30 text-white text-center h-8 text-sm font-bold"
|
||||||
min="1"
|
min="1"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Блок 4: Цена */}
|
{/* Блок 4: Цена */}
|
||||||
<div className="bg-white/10 rounded-lg p-2 flex flex-col justify-center">
|
<div className="bg-white/10 rounded-lg p-2 flex flex-col justify-center h-20">
|
||||||
<div className="text-white/60 text-[10px] mb-1 text-center">
|
<div className="text-white/60 text-xs mb-1 text-center">
|
||||||
За единицу
|
За единицу
|
||||||
</div>
|
</div>
|
||||||
<Input
|
<Input
|
||||||
@ -1180,22 +1216,22 @@ export function DirectSupplyCreation({
|
|||||||
className="bg-white/20 border-white/20 text-white text-center h-7 text-xs"
|
className="bg-white/20 border-white/20 text-white text-center h-7 text-xs"
|
||||||
placeholder="₽"
|
placeholder="₽"
|
||||||
/>
|
/>
|
||||||
<div className="text-white/80 text-[9px] font-medium text-center mt-1">
|
<div className="text-white/80 text-xs font-medium text-center mt-1">
|
||||||
{formatCurrency(item.totalPrice).replace(" ₽", "₽")}
|
{formatCurrency(item.totalPrice).replace(" ₽", "₽")}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Блок 5: Услуги фулфилмента */}
|
{/* Блок 5: Услуги фулфилмента */}
|
||||||
<div className="bg-white/10 rounded-lg p-2 flex flex-col justify-center">
|
<div className="bg-white/10 rounded-lg p-2 flex flex-col justify-center h-20">
|
||||||
<div className="space-y-1 max-h-16 overflow-y-auto">
|
<div className="space-y-2 max-h-16 overflow-y-auto">
|
||||||
{selectedFulfillmentOrg &&
|
{selectedFulfillmentOrg &&
|
||||||
organizationServices[selectedFulfillmentOrg] ? (
|
organizationServices[selectedFulfillmentOrg] ? (
|
||||||
organizationServices[selectedFulfillmentOrg]
|
organizationServices[selectedFulfillmentOrg]
|
||||||
.slice(0, 2)
|
.slice(0, 4)
|
||||||
.map((service) => (
|
.map((service) => (
|
||||||
<label
|
<label
|
||||||
key={service.id}
|
key={service.id}
|
||||||
className="flex items-center space-x-1 cursor-pointer"
|
className="flex items-center space-x-2 cursor-pointer"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
@ -1214,15 +1250,15 @@ export function DirectSupplyCreation({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
className="w-2 h-2"
|
className="w-3 h-3"
|
||||||
/>
|
/>
|
||||||
<span className="text-white text-[9px]">
|
<span className="text-white text-xs">
|
||||||
{service.name.substring(0, 8)}...
|
{service.name.substring(0, 8)}...
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<span className="text-white/60 text-[9px] text-center">
|
<span className="text-white/60 text-xs text-center">
|
||||||
Выберите фулфилмент
|
Выберите фулфилмент
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
@ -1230,14 +1266,14 @@ export function DirectSupplyCreation({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Блок 6: Поставщик */}
|
{/* Блок 6: Поставщик */}
|
||||||
<div className="bg-white/10 rounded-lg p-2 flex flex-col justify-center">
|
<div className="bg-white/10 rounded-lg p-2 flex flex-col justify-center space-y-2 h-20">
|
||||||
<Select
|
<Select
|
||||||
value={item.supplierId}
|
value={item.supplierId}
|
||||||
onValueChange={(value) =>
|
onValueChange={(value) =>
|
||||||
updateSupplyItem(item.card.nmID, "supplierId", value)
|
updateSupplyItem(item.card.nmID, "supplierId", value)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<SelectTrigger className="bg-white/20 border-white/20 text-white h-7 text-[10px]">
|
<SelectTrigger className="bg-white/20 border-white/20 text-white h-7 text-xs">
|
||||||
<SelectValue placeholder="Выбрать" />
|
<SelectValue placeholder="Выбрать" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
@ -1248,19 +1284,49 @@ export function DirectSupplyCreation({
|
|||||||
))}
|
))}
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
|
|
||||||
|
{/* Информация о выбранном поставщике */}
|
||||||
|
{item.supplierId &&
|
||||||
|
suppliers.find((s) => s.id === item.supplierId) && (
|
||||||
|
<div className="text-xs text-white/60 space-y-1">
|
||||||
|
<div className="truncate">
|
||||||
|
{
|
||||||
|
suppliers.find((s) => s.id === item.supplierId)
|
||||||
|
?.contactName
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div className="truncate">
|
||||||
|
{
|
||||||
|
suppliers.find((s) => s.id === item.supplierId)
|
||||||
|
?.phone
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Кнопка добавления поставщика */}
|
||||||
|
<Button
|
||||||
|
onClick={() => setShowSupplierModal(true)}
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
className="bg-white/5 border-white/20 text-white hover:bg-white/10 h-6 px-2 text-xs w-full"
|
||||||
|
>
|
||||||
|
<Plus className="h-3 w-3 mr-1" />
|
||||||
|
Добавить
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Блок 7: Расходники фулфилмента */}
|
{/* Блок 7: Расходники фф */}
|
||||||
<div className="bg-white/10 rounded-lg p-2 flex flex-col justify-center">
|
<div className="bg-white/10 rounded-lg p-2 flex flex-col justify-center h-20">
|
||||||
<div className="space-y-1 max-h-16 overflow-y-auto">
|
<div className="space-y-2 max-h-16 overflow-y-auto">
|
||||||
{selectedFulfillmentOrg &&
|
{selectedFulfillmentOrg &&
|
||||||
organizationSupplies[selectedFulfillmentOrg] ? (
|
organizationSupplies[selectedFulfillmentOrg] ? (
|
||||||
organizationSupplies[selectedFulfillmentOrg]
|
organizationSupplies[selectedFulfillmentOrg]
|
||||||
.slice(0, 2)
|
.slice(0, 4)
|
||||||
.map((supply) => (
|
.map((supply) => (
|
||||||
<label
|
<label
|
||||||
key={supply.id}
|
key={supply.id}
|
||||||
className="flex items-center space-x-1 cursor-pointer"
|
className="flex items-center space-x-2 cursor-pointer"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
@ -1279,15 +1345,15 @@ export function DirectSupplyCreation({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
className="w-2 h-2"
|
className="w-3 h-3"
|
||||||
/>
|
/>
|
||||||
<span className="text-white text-[9px]">
|
<span className="text-white text-xs">
|
||||||
{supply.name.substring(0, 6)}...
|
{supply.name.substring(0, 6)}...
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<span className="text-white/60 text-[9px] text-center">
|
<span className="text-white/60 text-xs text-center">
|
||||||
Выберите фулфилмент
|
Выберите фулфилмент
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
@ -1295,23 +1361,19 @@ export function DirectSupplyCreation({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Блок 8: Расходники селлера */}
|
{/* Блок 8: Расходники селлера */}
|
||||||
<div className="bg-white/10 rounded-lg p-2 flex flex-col justify-center">
|
<div className="bg-white/10 rounded-lg p-2 flex flex-col justify-center h-20">
|
||||||
<div className="space-y-1">
|
<div className="space-y-2">
|
||||||
<label className="flex items-center space-x-1 cursor-pointer">
|
<label className="flex items-center space-x-2 cursor-pointer">
|
||||||
<input type="checkbox" className="w-2 h-2" />
|
<input type="checkbox" className="w-3 h-3" />
|
||||||
<span className="text-white text-[9px]">
|
<span className="text-white text-xs">Упаковка</span>
|
||||||
Упаковка
|
|
||||||
</span>
|
|
||||||
</label>
|
</label>
|
||||||
<label className="flex items-center space-x-1 cursor-pointer">
|
<label className="flex items-center space-x-2 cursor-pointer">
|
||||||
<input type="checkbox" className="w-2 h-2" />
|
<input type="checkbox" className="w-3 h-3" />
|
||||||
<span className="text-white text-[9px]">
|
<span className="text-white text-xs">Этикетки</span>
|
||||||
Этикетки
|
|
||||||
</span>
|
|
||||||
</label>
|
</label>
|
||||||
<label className="flex items-center space-x-1 cursor-pointer">
|
<label className="flex items-center space-x-2 cursor-pointer">
|
||||||
<input type="checkbox" className="w-2 h-2" />
|
<input type="checkbox" className="w-3 h-3" />
|
||||||
<span className="text-white text-[9px]">Пакеты</span>
|
<span className="text-white text-xs">Пакеты</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Reference in New Issue
Block a user