Compare commits
3 Commits
fd9b5a3819
...
a3ac2e27d6
| Author | SHA1 | Date | |
|---|---|---|---|
| a3ac2e27d6 | |||
| a6549f46d5 | |||
| 9adb0f7918 |
163
src/components/common/product/DealProductItem.tsx
Normal file
163
src/components/common/product/DealProductItem.tsx
Normal file
@@ -0,0 +1,163 @@
|
||||
import React from 'react';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
import { TypeListProductDeal } from '@types/TypeListProductDeal';
|
||||
|
||||
const formatCurrency = (price: number | string) => {
|
||||
return Number(price).toLocaleString('vi-VN');
|
||||
};
|
||||
|
||||
const DealProductItem = ({ item }: { item: TypeListProductDeal }) => {
|
||||
const product = item.product_info;
|
||||
const quantityLeft = item.quantity - item.sale_quantity;
|
||||
|
||||
return (
|
||||
<div
|
||||
className="product-item"
|
||||
data-id={product.id}
|
||||
data-time={item.deal_time_left}
|
||||
data-type={product.sale_rules.type}
|
||||
>
|
||||
<Link href={product.productUrl || '#'} className="product-image relative">
|
||||
<Image
|
||||
src={product.productImage?.large || '/static/assets/nguyencong_2023/images/not-image.png'}
|
||||
width={164}
|
||||
height={164}
|
||||
alt={product.productName}
|
||||
className="lazy"
|
||||
unoptimized // Thêm nếu dùng ảnh từ domain bên ngoài chưa config
|
||||
/>
|
||||
|
||||
<span className="p-type-holder">
|
||||
{product.productType?.isHot === 1 && <i className="p-icon-type p-icon-hot"></i>}
|
||||
{product.productType?.isNew === 1 && <i className="p-icon-type p-icon-new"></i>}
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
<div className="product-info">
|
||||
<Link href={product.productUrl || '#'}>
|
||||
<h3 className="product-title line-clamp-3">{product.productName}</h3>
|
||||
</Link>
|
||||
|
||||
<div className="product-martket-main flex items-center">
|
||||
{product.marketPrice > 0 ? (
|
||||
<>
|
||||
<p className="product-market-price">{product.marketPrice.toLocaleString()} ₫</p>
|
||||
<div className="product-percent-price">-{parseInt(product.price_off || '0')}%</div>
|
||||
</>
|
||||
) : product.sale_rules?.type === 'deal' ? (
|
||||
<>
|
||||
<p className="product-market-price">
|
||||
{product.sale_rules.normal_price.toLocaleString()} ₫
|
||||
</p>
|
||||
<div className="product-percent-price">0%</div>
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
<div className="product-price-main font-semibold">
|
||||
{Number(item.price) > 0 ? `${formatCurrency(item.price)}đ` : 'Liên hệ'}
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="p-quantity-sale"
|
||||
data-quantity-left={quantityLeft}
|
||||
data-quantity-sale-total={item.quantity}
|
||||
>
|
||||
<i className="sprite sprite-fire-deal"></i>
|
||||
<div className="bg-gradient"></div>
|
||||
<p className="js-line-deal-left"></p>
|
||||
<span>
|
||||
Còn {quantityLeft}/ {item.quantity} sản phẩm
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{product.specialOffer?.all?.length > 0 ? (
|
||||
<div
|
||||
className="product-offer line-clamp-2"
|
||||
dangerouslySetInnerHTML={{ __html: product.specialOffer.all[0].title }}
|
||||
/>
|
||||
) : (
|
||||
<div className="product-offer line-clamp-2"></div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* TOOLTIP */}
|
||||
<div className="tooltip p-tooltip tippy-box">
|
||||
<div className="tooltip-name">{product.productName}</div>
|
||||
<div className="tooltip-descreption">
|
||||
<div className="tooltip-descreption-price">
|
||||
{product.marketPrice > 0 ? (
|
||||
<p>Giá niêm yết</p>
|
||||
) : (
|
||||
product.sale_rules?.type === 'deal' && <p>Giá gốc</p>
|
||||
)}
|
||||
<p>Giá bán</p>
|
||||
{product.warranty !== '' && <p>Bảo hành</p>}
|
||||
<p>Tình trạng</p>
|
||||
</div>
|
||||
|
||||
<div className="tooltip-descreption-info">
|
||||
{product.marketPrice > 0 ? (
|
||||
<div className="d-flex align-items-center">
|
||||
<p className="card-price-origin color-black" style={{ position: 'relative' }}>
|
||||
{product.marketPrice.toLocaleString()}₫
|
||||
<span className="card-price-origin-line-through"></span>
|
||||
</p>
|
||||
<span className="color-red" style={{ marginLeft: '4px' }}>
|
||||
-{product.price_off}%
|
||||
</span>
|
||||
</div>
|
||||
) : product.sale_rules?.type === 'deal' ? (
|
||||
<div className="d-flex align-items-center">
|
||||
<p className="card-price-origin color-black" style={{ position: 'relative' }}>
|
||||
{product.sale_rules.normal_price.toLocaleString()} ₫
|
||||
<span className="card-price-origin-line-through"></span>
|
||||
</p>
|
||||
<span className="color-red" style={{ marginLeft: '4px' }}>
|
||||
-
|
||||
{Math.floor(
|
||||
100 -
|
||||
(Number(product.sale_rules.price) / product.sale_rules.normal_price) * 100,
|
||||
)}
|
||||
%
|
||||
</span>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<p>{Number(product.price) > 0 ? `${formatCurrency(product.price)}đ` : 'Liên hệ'}</p>
|
||||
<p className="color-primary">{product.warranty}</p>
|
||||
<p className="color-secondary">{quantityLeft > 0 ? 'Còn DEAL' : 'Hết DEAL'}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{product.productSummary && (
|
||||
<>
|
||||
<div className="tooltip-input">
|
||||
<i className="fa-solid fa-database icon-database"></i>
|
||||
<span>Thông số sản phẩm</span>
|
||||
</div>
|
||||
<div className="tooltip-list">
|
||||
<span dangerouslySetInnerHTML={{ __html: product.productSummary }} />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{product.specialOffer?.all?.length > 0 && (
|
||||
<div className="box-tooltip-gift">
|
||||
<div className="tooltip-input tooltip-gift">
|
||||
<p className="icon-gift">
|
||||
<i className="fa-solid fa-gift"></i> Khuyến mãi
|
||||
</p>
|
||||
</div>
|
||||
<div className="tooltip-list tooltip-list-gift">
|
||||
<ul dangerouslySetInnerHTML={{ __html: product.specialOffer.all[0].title }} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DealProductItem;
|
||||
@@ -3,9 +3,8 @@ import React from 'react';
|
||||
import { Swiper, SwiperSlide } from 'swiper/react';
|
||||
import { Autoplay, Navigation, Pagination } from 'swiper/modules';
|
||||
import { FaCaretRight } from 'react-icons/fa';
|
||||
|
||||
import CounDown from './CounDown';
|
||||
import ProductItem from './ProductItem';
|
||||
import { productDealData } from './productDealData';
|
||||
|
||||
const BoxProductDeal: React.FC = () => {
|
||||
return (
|
||||
@@ -30,13 +29,7 @@ const BoxProductDeal: React.FC = () => {
|
||||
slidesPerView={6}
|
||||
loop={true}
|
||||
navigation={true}
|
||||
>
|
||||
{productDealData.map((item, index) => (
|
||||
<SwiperSlide key={index}>
|
||||
<ProductItem item={item} />
|
||||
</SwiperSlide>
|
||||
))}
|
||||
</Swiper>
|
||||
></Swiper>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
"@/*": ["./src/*"],
|
||||
"@components/*": ["./src/components/*"],
|
||||
"@types/*": ["./src/types/*"],
|
||||
"@styles/*": ["./src/styles/*"]
|
||||
"@styles/*": ["./src/styles/*"],
|
||||
"@Common/*": ["./src/components/Common/*"]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
|
||||
Reference in New Issue
Block a user