first commit

This commit is contained in:
Bivekich
2025-06-26 06:59:59 +03:00
commit d44874775c
450 changed files with 76635 additions and 0 deletions

View 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;