Files
parsshop/components/productcard.tsx
2026-03-27 22:48:14 +03:30

140 lines
5.9 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 { Phone, Plus, ShoppingCart, Minus, Trash2 } from "lucide-react";
import Image from "next/image";
import Link from 'next/link';
import { useCart, Product } from "./context/cartcontext";
interface ProductCardProps {
product: Product;
}
export default function ProductCard({ product }: ProductCardProps) {
const { addToCart, decreaseQuantity, cart } = useCart();
// پیدا کردن محصول در سبد خرید
const cartItem = cart.find(item => item.id === product.id);
const quantity = cartItem ? cartItem.quantity : 0;
const generateSlug = (text: string) => {
if (!text) return "";
return text
.trim()
.replace(/[\s\u200c]+/g, '-')
.replace(/[^\w\u0600-\u06FF0-9\-]/g, '')
.replace(/\-\-+/g, '-');
};
const slug = generateSlug(product.title);
const handleIncrease = (e: React.MouseEvent) => {
e.preventDefault();
e.stopPropagation();
addToCart(product);
};
const handleDecrease = (e: React.MouseEvent) => {
e.preventDefault();
e.stopPropagation();
decreaseQuantity(product.id);
};
// پاکسازی قیمت از ویرگول و تبدیل به عدد برای نمایش صحیح
const formattedPrice = product.price
? Number(product.price.toString().replace(/,/g, '')).toLocaleString('fa-IR')
: null;
return (
<Link href={`/products/${product.id}/${slug}`} scroll={true} className="bg-white gap-1 flex flex-col justify-between border border-gray-200 rounded-xl shadow-sm p-4 transition-all hover:shadow-md">
<div className="relative flex justify-center mb-4">
<span
className={`absolute top-0 right-0 font-semibold text-[0.6em] px-2 py-1 rounded-2xl ${product.stock ? "bg-[#00c9512e] text-[#035702] border border-[#03570263] " : "bg-[#f92a3521] text-[#cf0000] border border-[#cf000047]"}`}
>
{product.stock ? "موجود" : "ناموجود"}
</span>
<Image
src={product.image}
width={150}
height={150}
alt={product.title}
/>
</div>
<p className="text-[#808080] text-sm">{product.brand}</p>
<h3 className="text-sm font-semibold">{product.title}</h3>
<div className="text-xs text-gray-500 mt-2">
<div className="flex border-b border-[#dfdfdf] mb-2 pb-2 justify-between">
<p>قطر داخلی (L):</p>
<p dir="ltr" className="font-semibold text-black">{product.l}</p>
</div>
<div className="flex justify-between">
<p>قطر خارجی (D):</p>
<p dir="ltr" className="font-semibold text-black">{product.d}</p>
</div>
</div>
{/* بخش قیمت و دکمه خرید */}
{product.price ? (
<div className="flex justify-between mt-3 items-center min-h-[32px]">
<span className="text-[0.85em] font-bold text-gray-800">
{formattedPrice} تومان
</span>
{/* بررسی موجودی برای نمایش دکمه سبد خرید */}
{product.stock ? (
quantity > 0 ? (
<div
className="flex items-center gap-3 bg-white border border-gray-200 rounded-lg py-1 px-2 shadow-sm"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
}}
>
<button
onClick={handleIncrease}
className="text-gray-500 hover:text-green-600 transition-colors"
>
<Plus size={16} />
</button>
<span className="text-xs font-bold text-gray-800 w-3 text-center">
{quantity}
</span>
<button
onClick={handleDecrease}
className="text-gray-500 hover:text-red-500 transition-colors"
>
{quantity === 1 ? <Trash2 size={16} /> : <Minus size={16} />}
</button>
</div>
) : (
<button
onClick={handleIncrease}
className="rounded-lg border border-[#e6e6e6] bg-gray-50 flex items-center p-2 text-gray-600 hover:bg-gray-200 transition-colors"
title="افزودن به سبد خرید"
>
<ShoppingCart size={16} />
</button>
)
) : (
// جایگزین دکمه خرید وقتی محصول ناموجود است
<span className="text-[10px] text-red-500 font-medium bg-red-50 px-2 py-1 rounded-md">
عدم موجودی
</span>
)}
</div>
) : (
<span className="flex justify-between mt-3 text-[0.85em] font-bold items-center gap-1 min-h-[32px] text-gray-700">
استعلام
<Phone className="mb-1" size={13} />
</span>
)}
</Link>
);
}