Compare commits

..

3 Commits

3 changed files with 167 additions and 10 deletions

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

View File

@@ -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>
);

View File

@@ -22,7 +22,8 @@
"@/*": ["./src/*"],
"@components/*": ["./src/components/*"],
"@types/*": ["./src/types/*"],
"@styles/*": ["./src/styles/*"]
"@styles/*": ["./src/styles/*"],
"@Common/*": ["./src/components/Common/*"]
}
},
"include": [