first commit
This commit is contained in:
151
src/components/ProductListCard.tsx
Normal file
151
src/components/ProductListCard.tsx
Normal file
@ -0,0 +1,151 @@
|
||||
import React, { useState } from "react";
|
||||
import { useCart } from "@/contexts/CartContext";
|
||||
|
||||
interface ProductListCardProps {
|
||||
id?: string;
|
||||
productId?: string;
|
||||
offerKey?: string;
|
||||
image: string;
|
||||
title: string;
|
||||
brand: string;
|
||||
price: string;
|
||||
oldPrice?: string;
|
||||
discount?: string;
|
||||
rating?: number;
|
||||
stock?: string;
|
||||
delivery?: string;
|
||||
address?: string;
|
||||
recommended?: boolean;
|
||||
isExternal?: boolean;
|
||||
currency?: string;
|
||||
deliveryTime?: string;
|
||||
warehouse?: string;
|
||||
supplier?: string;
|
||||
}
|
||||
|
||||
const ProductListCard: React.FC<ProductListCardProps> = ({
|
||||
id,
|
||||
productId,
|
||||
offerKey,
|
||||
image,
|
||||
title,
|
||||
brand,
|
||||
price,
|
||||
oldPrice,
|
||||
discount,
|
||||
rating = 4.8,
|
||||
stock = "444 шт",
|
||||
delivery = "Сегодня с 18:00",
|
||||
address = "Москва ЦС (Новая Рига)",
|
||||
recommended = false,
|
||||
isExternal = false,
|
||||
currency = "RUB",
|
||||
deliveryTime,
|
||||
warehouse,
|
||||
supplier,
|
||||
}) => {
|
||||
const [count, setCount] = useState(1);
|
||||
const { addItem } = useCart();
|
||||
|
||||
// Функция для парсинга цены из строки
|
||||
const parsePrice = (priceStr: string): number => {
|
||||
const cleanPrice = priceStr.replace(/[^\d.,]/g, '').replace(',', '.');
|
||||
return parseFloat(cleanPrice) || 0;
|
||||
};
|
||||
|
||||
// Функция для парсинга количества в наличии
|
||||
const parseStock = (stockStr: string): number => {
|
||||
const match = stockStr.match(/\d+/);
|
||||
return match ? parseInt(match[0]) : 0;
|
||||
};
|
||||
|
||||
const handleAddToCart = () => {
|
||||
const availableStock = parseStock(stock);
|
||||
|
||||
// Проверяем наличие
|
||||
if (count > availableStock) {
|
||||
alert(`Недостаточно товара в наличии. Доступно: ${availableStock} шт.`);
|
||||
return;
|
||||
}
|
||||
|
||||
const numericPrice = parsePrice(price);
|
||||
const numericOldPrice = oldPrice ? parsePrice(oldPrice) : undefined;
|
||||
|
||||
addItem({
|
||||
productId: productId,
|
||||
offerKey: offerKey,
|
||||
name: title,
|
||||
description: `${brand} - ${title}`,
|
||||
brand: brand,
|
||||
price: numericPrice,
|
||||
originalPrice: numericOldPrice,
|
||||
currency: currency,
|
||||
quantity: count,
|
||||
deliveryTime: deliveryTime || delivery,
|
||||
warehouse: warehouse || address,
|
||||
supplier: supplier,
|
||||
isExternal: isExternal,
|
||||
image: image,
|
||||
});
|
||||
|
||||
// Показываем уведомление о добавлении
|
||||
alert(`Товар "${title}" добавлен в корзину (${count} шт.)`);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-layout-hflex product-item-search">
|
||||
<div className="w-layout-hflex flex-block-81">
|
||||
<div className="w-layout-hflex info-block-search-copy">
|
||||
<div className="w-layout-hflex raiting">
|
||||
<img src="/images/Star-1.svg" alt="Рейтинг" className="image-8" />
|
||||
<div className="text-block-22">{rating}</div>
|
||||
</div>
|
||||
<div className="pcs-search">{stock}</div>
|
||||
<div className="pcs-search">{delivery}</div>
|
||||
</div>
|
||||
<div className="w-layout-hflex info-block-product-card-search">
|
||||
{recommended && (
|
||||
<>
|
||||
<div className="w-layout-hflex item-recommend">
|
||||
<img src="/images/ri_refund-fill.svg" alt="Рекомендуем" />
|
||||
</div>
|
||||
<div className="text-block-25">Рекомендуем</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className="price">{price}</div>
|
||||
</div>
|
||||
<div className="w-layout-hflex add-to-cart-block">
|
||||
<div className="w-layout-hflex flex-block-82">
|
||||
<div className="w-layout-hflex pcs">
|
||||
<div className="minus-plus" onClick={() => setCount(Math.max(1, count - 1))}>
|
||||
<img src="/images/minus_icon.svg" alt="-" />
|
||||
</div>
|
||||
<div className="input-pcs">
|
||||
<div className="text-block-26">{count}</div>
|
||||
</div>
|
||||
<div className="minus-plus" onClick={() => {
|
||||
const availableStock = parseStock(stock);
|
||||
if (count < availableStock) {
|
||||
setCount(count + 1);
|
||||
} else {
|
||||
alert(`Максимальное количество: ${availableStock} шт.`);
|
||||
}
|
||||
}}>
|
||||
<img src="/images/plus_icon.svg" alt="+" />
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
onClick={handleAddToCart}
|
||||
className="button-icon w-inline-block"
|
||||
style={{ background: 'none', border: 'none', cursor: 'pointer' }}
|
||||
>
|
||||
<img src="/images/cart_icon.svg" alt="В корзину" className="image-11" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProductListCard;
|
Reference in New Issue
Block a user