84 lines
2.8 KiB
TypeScript
84 lines
2.8 KiB
TypeScript
|
|
import React from 'react';
|
||
|
|
import Tippy from '@tippyjs/react';
|
||
|
|
import 'tippy.js/dist/tippy.css';
|
||
|
|
import { DealType } from '@/types';
|
||
|
|
|
||
|
|
type ProductItemProps = {
|
||
|
|
item: DealType;
|
||
|
|
};
|
||
|
|
|
||
|
|
const formatCurrency = (value: number | string) => {
|
||
|
|
const num = typeof value === 'string' ? parseInt(value) : value;
|
||
|
|
return num.toLocaleString('vi-VN');
|
||
|
|
};
|
||
|
|
|
||
|
|
const ProductItem: React.FC<ProductItemProps> = ({ item }) => {
|
||
|
|
const { product_info } = item;
|
||
|
|
const offers = product_info.specialOffer?.all ?? [];
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className="product-item">
|
||
|
|
<a href={product_info.productUrl} className="product-image relative">
|
||
|
|
{product_info.productImage.large ? (
|
||
|
|
<img
|
||
|
|
src={product_info.productImage.large}
|
||
|
|
width="164"
|
||
|
|
height="164"
|
||
|
|
alt={product_info.productName}
|
||
|
|
className="lazy"
|
||
|
|
/>
|
||
|
|
) : (
|
||
|
|
<img
|
||
|
|
src="/static/assets/nguyencong_2023/images/not-image.png"
|
||
|
|
width="164"
|
||
|
|
height="164"
|
||
|
|
alt={product_info.productName}
|
||
|
|
className="lazy"
|
||
|
|
/>
|
||
|
|
)}
|
||
|
|
<span className="p-type-holder">
|
||
|
|
{product_info.productType.isHot === 1 && <i className="p-icon-type p-icon-hot"></i>}
|
||
|
|
{product_info.productType.isNew === 1 && <i className="p-icon-type p-icon-new"></i>}
|
||
|
|
</span>
|
||
|
|
</a>
|
||
|
|
<div className="product-info">
|
||
|
|
<a href={product_info.productUrl}>
|
||
|
|
<h3 className="product-title line-clamp-3">{product_info.productName}</h3>
|
||
|
|
</a>
|
||
|
|
<div className="product-martket-main flex items-center">
|
||
|
|
{product_info.marketPrice > 0 ? (
|
||
|
|
<p className="product-market-price">{product_info.marketPrice.toLocaleString()} ₫</p>
|
||
|
|
) : (
|
||
|
|
<p className="product-market-price">
|
||
|
|
{product_info.sale_rules.normal_price.toLocaleString()} ₫
|
||
|
|
</p>
|
||
|
|
)}
|
||
|
|
<div className="product-percent-price">-{product_info.price_off || 0}%</div>
|
||
|
|
</div>
|
||
|
|
<div className="product-price-main font-bold">
|
||
|
|
{item.price > '0' ? `${formatCurrency(product_info.price)}đ` : 'Liên hệ'}
|
||
|
|
</div>
|
||
|
|
<div className="p-quantity-sale">
|
||
|
|
<i className="sprite sprite-fire-deal"></i>
|
||
|
|
<div className="bg-gradient"></div>
|
||
|
|
<p className="js-line-deal-left"></p>
|
||
|
|
<span>
|
||
|
|
Còn {Number(item.quantity) - Number(item.sale_quantity)}/{Number(item.quantity)} sản
|
||
|
|
phẩm
|
||
|
|
</span>
|
||
|
|
</div>
|
||
|
|
{offers.length > 0 && (
|
||
|
|
<div
|
||
|
|
className="product-offer line-clamp-2"
|
||
|
|
dangerouslySetInnerHTML={{
|
||
|
|
__html: product_info.specialOffer!.all![0].title,
|
||
|
|
}}
|
||
|
|
/>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
};
|
||
|
|
|
||
|
|
export default ProductItem;
|