237 lines
9.1 KiB
TypeScript
237 lines
9.1 KiB
TypeScript
"use client";
|
||
|
||
import React from "react";
|
||
import { Card } from "@/components/ui/card";
|
||
import { Button } from "@/components/ui/button";
|
||
import { Badge } from "@/components/ui/badge";
|
||
import { ShoppingCart, Building2, Plus, Minus, Eye } from "lucide-react";
|
||
import { SelectedProduct } from "./types";
|
||
|
||
interface CartSummaryProps {
|
||
selectedProducts: SelectedProduct[];
|
||
onQuantityChange: (
|
||
productId: string,
|
||
supplierId: string,
|
||
quantity: number
|
||
) => void;
|
||
onRemoveProduct: (productId: string, supplierId: string) => void;
|
||
onCreateSupply: () => void;
|
||
onToggleVisibility: () => void;
|
||
formatCurrency: (amount: number) => string;
|
||
visible: boolean;
|
||
}
|
||
|
||
export function CartSummary({
|
||
selectedProducts,
|
||
onQuantityChange,
|
||
onRemoveProduct,
|
||
onCreateSupply,
|
||
onToggleVisibility,
|
||
formatCurrency,
|
||
visible,
|
||
}: CartSummaryProps) {
|
||
if (!visible || selectedProducts.length === 0) {
|
||
return null;
|
||
}
|
||
|
||
// Группируем товары по поставщикам
|
||
const groupedProducts = selectedProducts.reduce((acc, product) => {
|
||
if (!acc[product.supplierId]) {
|
||
acc[product.supplierId] = {
|
||
supplier: product.supplierName,
|
||
products: [],
|
||
};
|
||
}
|
||
acc[product.supplierId].products.push(product);
|
||
return acc;
|
||
}, {} as Record<string, { supplier: string; products: SelectedProduct[] }>);
|
||
|
||
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
|
||
);
|
||
};
|
||
|
||
return (
|
||
<Card className="bg-gradient-to-br from-purple-500/10 to-pink-500/10 backdrop-blur-xl border border-purple-500/20 mb-6 shadow-2xl">
|
||
<div className="p-4">
|
||
<div className="flex items-center justify-between mb-4">
|
||
<div className="flex items-center space-x-3">
|
||
<div className="p-2 bg-gradient-to-r from-purple-500 to-pink-500 rounded-lg">
|
||
<ShoppingCart className="h-5 w-5 text-white" />
|
||
</div>
|
||
<div>
|
||
<h3 className="text-white font-bold text-lg">Корзина</h3>
|
||
<p className="text-purple-200 text-xs">
|
||
{selectedProducts.length} товаров от{" "}
|
||
{Object.keys(groupedProducts).length} поставщиков
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<Button
|
||
variant="ghost"
|
||
size="sm"
|
||
onClick={onToggleVisibility}
|
||
className="text-white/60 hover:text-white hover:bg-white/10 rounded-xl"
|
||
>
|
||
<Eye className="h-4 w-4" />
|
||
</Button>
|
||
</div>
|
||
|
||
{/* Группировка по поставщикам */}
|
||
{Object.entries(groupedProducts).map(([supplierId, group]) => (
|
||
<div key={supplierId} className="mb-4 last:mb-0">
|
||
<div className="flex items-center mb-2 pb-1 border-b border-white/10">
|
||
<Building2 className="h-4 w-4 text-blue-400 mr-2" />
|
||
<span className="text-white font-medium">{group.supplier}</span>
|
||
<Badge className="ml-2 bg-blue-500/20 text-blue-300 border-blue-500/30 text-xs">
|
||
{group.products.length} товар(ов)
|
||
</Badge>
|
||
</div>
|
||
|
||
<div className="space-y-2">
|
||
{group.products.map((product) => {
|
||
const discountedPrice = product.discount
|
||
? product.price * (1 - product.discount / 100)
|
||
: product.price;
|
||
const totalPrice = discountedPrice * product.selectedQuantity;
|
||
|
||
return (
|
||
<div
|
||
key={`${product.supplierId}-${product.id}`}
|
||
className="flex items-center space-x-3 bg-white/5 rounded-lg p-3"
|
||
>
|
||
<img
|
||
src={product.mainImage || "/api/placeholder/50/50"}
|
||
alt={product.name}
|
||
className="w-12 h-12 rounded-lg object-cover"
|
||
/>
|
||
<div className="flex-1 min-w-0">
|
||
<h4 className="text-white font-medium text-xs mb-1 truncate">
|
||
{product.name}
|
||
</h4>
|
||
<p className="text-white/60 text-xs mb-1">
|
||
{product.article}
|
||
</p>
|
||
<div className="flex items-center space-x-2">
|
||
<div className="flex items-center space-x-1">
|
||
<Button
|
||
variant="ghost"
|
||
size="sm"
|
||
onClick={() => {
|
||
const newQuantity = Math.max(
|
||
0,
|
||
product.selectedQuantity - 1
|
||
);
|
||
if (newQuantity === 0) {
|
||
onRemoveProduct(product.id, product.supplierId);
|
||
} else {
|
||
onQuantityChange(
|
||
product.id,
|
||
product.supplierId,
|
||
newQuantity
|
||
);
|
||
}
|
||
}}
|
||
className="h-6 w-6 p-0 text-white/60 hover:text-white hover:bg-white/10"
|
||
>
|
||
<Minus className="h-3 w-3" />
|
||
</Button>
|
||
<span className="text-white text-xs w-6 text-center">
|
||
{product.selectedQuantity}
|
||
</span>
|
||
<Button
|
||
variant="ghost"
|
||
size="sm"
|
||
onClick={() => {
|
||
onQuantityChange(
|
||
product.id,
|
||
product.wholesalerId,
|
||
Math.min(
|
||
product.quantity,
|
||
product.selectedQuantity + 1
|
||
)
|
||
);
|
||
}}
|
||
disabled={
|
||
product.selectedQuantity >= product.quantity
|
||
}
|
||
className="h-6 w-6 p-0 text-white/60 hover:text-white hover:bg-white/10"
|
||
>
|
||
<Plus className="h-3 w-3" />
|
||
</Button>
|
||
</div>
|
||
<div className="text-right">
|
||
<div className="text-white font-semibold text-xs">
|
||
{formatCurrency(totalPrice)}
|
||
</div>
|
||
{product.discount && (
|
||
<div className="text-white/40 text-xs line-through">
|
||
{formatCurrency(
|
||
product.price * product.selectedQuantity
|
||
)}
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<Button
|
||
variant="ghost"
|
||
size="sm"
|
||
onClick={() =>
|
||
onRemoveProduct(product.id, product.supplierId)
|
||
}
|
||
className="text-red-400 hover:text-red-300 hover:bg-red-500/10"
|
||
>
|
||
✕
|
||
</Button>
|
||
</div>
|
||
);
|
||
})}
|
||
</div>
|
||
</div>
|
||
))}
|
||
|
||
{/* Итого */}
|
||
<div className="border-t border-white/20 pt-3 mt-4">
|
||
<div className="flex justify-between items-center">
|
||
<span className="text-white font-semibold text-sm">
|
||
Итого: {getTotalItems()} товаров
|
||
</span>
|
||
<span className="text-white font-bold text-lg">
|
||
{formatCurrency(getTotalAmount())}
|
||
</span>
|
||
</div>
|
||
<div className="flex space-x-2 mt-3">
|
||
<Button
|
||
variant="outline"
|
||
className="flex-1 border-purple-300/30 text-white hover:bg-white/10"
|
||
onClick={onToggleVisibility}
|
||
>
|
||
<Plus className="h-4 w-4 mr-2" />
|
||
Добавить еще
|
||
</Button>
|
||
<Button
|
||
className="flex-1 bg-gradient-to-r from-green-500 to-emerald-500 hover:from-green-600 hover:to-emerald-600 text-white"
|
||
onClick={onCreateSupply}
|
||
>
|
||
<ShoppingCart className="h-4 w-4 mr-2" />
|
||
Оформить поставку
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</Card>
|
||
);
|
||
}
|