Files
sfera-new/src/components/supplies/cart-summary.tsx

237 lines
9.1 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 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>
);
}