update 03/02
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
'use client';
|
||||
|
||||
export default function ScrollToReviewButton({
|
||||
avgRate,
|
||||
total
|
||||
}) {
|
||||
const HEADER_HEIGHT = 120;
|
||||
|
||||
const goToReview = () => {
|
||||
const el = document.querySelector('.pd-comment-container');
|
||||
if (!el) return;
|
||||
|
||||
const top =
|
||||
el.getBoundingClientRect().top + window.scrollY - HEADER_HEIGHT;
|
||||
|
||||
window.scrollTo({ top, behavior: 'smooth' });
|
||||
};
|
||||
|
||||
return (
|
||||
<button type="button" className="m-0 flex items-center gap-1"
|
||||
onClick={goToReview}
|
||||
>
|
||||
<i className={`star star-${avgRate}`} />
|
||||
<span className="font-500"> ({total}) </span>
|
||||
</button>
|
||||
)
|
||||
}
|
||||
@@ -1,35 +1,22 @@
|
||||
'use client';
|
||||
import { useState } from "react";
|
||||
import CommentItem from "@/components/shared/CommentItem"
|
||||
|
||||
const COMMENT_PER_PAGE = 5;
|
||||
'use client';
|
||||
import { useShowMore } from "@/hooks/useShowMore"
|
||||
import CommentItem from "@/components/shared/CommentItem"
|
||||
import ShowMoreButton from "@/components/shared/ButtonShowMore"
|
||||
|
||||
export default function CommentList( {item}:any ) {
|
||||
const total = item?.length;
|
||||
|
||||
const [page, setPage] = useState(1);
|
||||
const displayCount = page * COMMENT_PER_PAGE;
|
||||
const hasMore = displayCount < total;
|
||||
const commentData = item.slice(0, displayCount);
|
||||
const { displayData, hasMore, loadMore } = useShowMore(item, 5);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
{
|
||||
commentData.map( (comment:any) => <CommentItem item={comment} key={comment.id} />)
|
||||
}
|
||||
{displayData.map((comment: any) => (
|
||||
<CommentItem item={comment} key={comment.id} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
{hasMore &&
|
||||
<div className="text-center mt-4">
|
||||
<button type="button" aria-label="Xem thêm"
|
||||
className="border border-[#0678DB] text-[#0678DB] rounded-[30px] h-10 px-6 hover:bg-[#0678DB] hover:text-white"
|
||||
onClick={()=> setPage(prev => prev+1) }
|
||||
>
|
||||
XEM THÊM
|
||||
<i className="bx bx-chevron-down text-20 align-middle mt-[-3px]" />
|
||||
</button>
|
||||
</div>
|
||||
{hasMore &&
|
||||
<ShowMoreButton onClick={loadMore}/>
|
||||
}
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
'use client';
|
||||
import { useState, useMemo } from "react";
|
||||
|
||||
import { CommentData } from "@/data/comments";
|
||||
import Form from "./Form";
|
||||
import CommentList from "./CommentList";
|
||||
|
||||
export default function Comment() {
|
||||
const [star, setStar] = useState<number | null>(null);
|
||||
|
||||
const filteredComments = useMemo(() => {
|
||||
if (star === null) return CommentData.list;
|
||||
return CommentData.list.filter(item => Number(item.rate) === star);
|
||||
}, [star]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -10,31 +19,35 @@ export default function Comment() {
|
||||
<p className="m-0 text-18 font-500"> {CommentData.list.length} Bình luận </p>
|
||||
|
||||
<div className="flex flex-wrap gap-2 text-14 font-500 pd-comment-btn">
|
||||
<button type="button" aria-label="Đánh giá"
|
||||
className="h-8 border border-[#D1D5DB] rounded-[40px] flex items-center gap-[3px] px-8 hover:border-[#0678DB] hover:text-[#0678DB] current"
|
||||
> Tất cả </button>
|
||||
<button type="button"
|
||||
className={`h-8 border rounded-[40px] px-8
|
||||
${star === null ? 'border-[#0678DB] text-[#0678DB]' : 'border-[#D1D5DB]'}`}
|
||||
onClick={() => setStar(null)}
|
||||
>
|
||||
Tất cả
|
||||
</button>
|
||||
|
||||
{buildButtonFilter()}
|
||||
{[5,4,3,2,1].map(s => (
|
||||
<button type="button"
|
||||
key={s}
|
||||
className={`h-8 border rounded-[40px] px-4 flex items-center gap-[3px]
|
||||
${star === s ? 'border-[#0678DB] text-[#0678DB]' : 'border-[#D1D5DB]'}`}
|
||||
onClick={() => setStar(s)}
|
||||
>
|
||||
{s} <i className="bxr bx-star" />
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div className="border border-[#DDDDDD] rounded-[12px] overflow-hidden js-comment-form">
|
||||
<Form />
|
||||
</div>
|
||||
|
||||
{CommentData.list.length > 0 &&
|
||||
<CommentList item={CommentData.list}/>
|
||||
}
|
||||
{filteredComments.length > 0 && (
|
||||
<CommentList item={filteredComments} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function buildButtonFilter(){
|
||||
const star = [5,4,3,2,1]
|
||||
|
||||
return star.map(item => (
|
||||
<button type="button" aria-label="Đánh giá" key={item}
|
||||
className="h-8 border border-[#D1D5DB] rounded-[40px] flex items-center gap-[3px] px-4 hover:border-[#0678DB] hover:text-[#0678DB]"
|
||||
> {item} <i className="bxr bx-star" /> </button>
|
||||
))
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import parse from 'html-react-parser';
|
||||
import { formatPrice } from "@/lib/utils";
|
||||
import ProductImage from "./images";
|
||||
import Static from "./static";
|
||||
@@ -10,6 +11,8 @@ import ProductPrice from "./price";
|
||||
import ProductOffer from "./offer";
|
||||
import Buttons from "./buttons";
|
||||
import ProductSummary from "./summary";
|
||||
import ScrollToReviewButton from "./buttons/ScrollToReviewButton";
|
||||
import ProductTab from "./products";
|
||||
|
||||
import { ReviewData } from "@/data/reviews";
|
||||
|
||||
@@ -31,8 +34,6 @@ export default async function ProductDetail({ slug }: any) {
|
||||
quantity : slug.quantity
|
||||
}
|
||||
|
||||
console.log(slug)
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="product-detail-page container">
|
||||
@@ -48,30 +49,27 @@ export default async function ProductDetail({ slug }: any) {
|
||||
|
||||
<div className="col-middle-group w-[464px]">
|
||||
|
||||
<div className="pb-3 mb-3 border-b border-[#DEE4EC] flex flex-wrap items-center gap-2">
|
||||
<button type="button" className="m-0 flex items-center gap-1">
|
||||
<i className={`star star-${ReviewData.summary.avgRate}`} />
|
||||
<span className="font-500"> ({ReviewData.summary.total}) </span>
|
||||
</button>
|
||||
<div className="pb-3 mb-3 border-b border-[#DEE4EC] flex flex-wrap items-center gap-2">
|
||||
<ScrollToReviewButton
|
||||
avgRate={ReviewData.summary.avgRate}
|
||||
total={ReviewData.summary.total}
|
||||
/>
|
||||
|
||||
<i className="w-[1px] h-4 bg-[#DEE4EC]" />
|
||||
|
||||
<p className="m-0">
|
||||
Lượt xem:
|
||||
<span className="text-[#004BA4] font-500">{formatPrice(slug.visit)}</span>
|
||||
<span className="text-[#004BA4] font-500">{formatPrice(slug.visit) }</span>
|
||||
</p>
|
||||
|
||||
<i className="w-[1px] h-4 bg-[#DEE4EC]" />
|
||||
|
||||
<p className="m-0">
|
||||
Tình trạng:
|
||||
<span
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: slug.quantity > 0
|
||||
? '<span class="font-500 text-[#00AD4F]">Còn hàng</span>'
|
||||
: '<span class="font-500 red">Liên hệ</span>'
|
||||
}}
|
||||
/>
|
||||
{ slug.quantity > 0
|
||||
? parse('<span class="font-500 text-[#00AD4F]">Còn hàng</span>')
|
||||
: parse('<span class="font-500 red">Liên hệ</span>')
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -106,7 +104,7 @@ export default async function ProductDetail({ slug }: any) {
|
||||
/>
|
||||
}
|
||||
|
||||
<div className="pd-comment-container bg-white mb-6 p-8 pt-6 rounded-[24px] text-16 leading-[22px]">
|
||||
<div className="pd-comment-container bg-white mb-6 p-8 pt-6 rounded-[24px] text-16 leading-[22px]" id="js-comment-container">
|
||||
<p className="leading-[31px] font-600 text-24 mb-4 pb-4">
|
||||
Đánh giá và bình luận
|
||||
</p>
|
||||
@@ -129,727 +127,7 @@ export default async function ProductDetail({ slug }: any) {
|
||||
</div>
|
||||
|
||||
{/* Sản phẩm tương tự + Sản phẩm đã xem */}
|
||||
<div className="pd-product-container bg-white px-6 py-8 rounded-[24px]">
|
||||
<div className="pd-tab-group relative flex mb-8 border-b border-[#DEE4EC] font-600 text-24 gap-10 leading-[31px] pb-5">
|
||||
<button type="button" aria-label="tab" className="js-pd-tab">
|
||||
Sản phẩm tương tự
|
||||
</button>
|
||||
|
||||
<button type="button" aria-label="tab" className="js-pd-tab">
|
||||
Sản phẩm đã xem
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="relative z-[1] bg-white relative min-h-[300px] js-product-holder">
|
||||
<div className="swiper overflow-hidden">
|
||||
<div className="swiper-wrapper">
|
||||
<div className="swiper-slide">
|
||||
<div className="p-item">
|
||||
<a href="" className="p-img">
|
||||
<img
|
||||
src="images/product-1.jpg"
|
||||
alt=""
|
||||
width={250}
|
||||
height={250}
|
||||
/>
|
||||
</a>
|
||||
<div className="p-text">
|
||||
<div className="p-price-group">
|
||||
<del>52.000.000 đ</del>
|
||||
<span className="p-discount">-10%</span>
|
||||
<p className="p-price">22.000.000 đ</p>
|
||||
</div>
|
||||
<a href="" className="p-name">
|
||||
<h3>
|
||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit.
|
||||
Suscipit quos obcaecati totam, atque vel
|
||||
</h3>
|
||||
</a>
|
||||
<div className="p-btn-group flex items-center justify-between text-16 font-500 leading-[23px]">
|
||||
<div>
|
||||
<p className="m-0 text-[#00AD4F] flex items-center gap-1">
|
||||
<i className="bx bx-check-circle text-18 w-[18px]" />
|
||||
<span>Sẵn hàng</span>
|
||||
</p>
|
||||
<p className="m-0 text-[#E16B10] flex items-center gap-1">
|
||||
<i className="bx bx-gift text-18 w-[18px]" />
|
||||
<span>Quà tặng</span>
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className="p-btn bx bx-plus bg-btn text-white rounded-full w-9 h-9 text-20"
|
||||
aria-label="Mua"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-tooltip hidden">
|
||||
<div className="bg-white rounded-[20px] overflow-hidden border-2 border-[#EAECF0] shadow-[0px_6px_8px_-2px_#10182814]">
|
||||
<p className="tooltip-name px-5 py-4 text-white font-600 text-16 leading-[21px] bg-[linear-gradient(180.3deg,#259AFF_-18.56%,_#114CDD_100.92%)] m-0">
|
||||
[Tặng bàn phím] HHPC ULTRA 7 265K | 32GB DDR5 | NVIDIA RTX
|
||||
3060 12GB
|
||||
</p>
|
||||
<div className="p-4 tooltip-content">
|
||||
<div className="last:border-0 last:p-0 last:m-0 text-16 border-b border-[#DEE4EC] mb-4 pb-4">
|
||||
<p className="m-0 flex items-center flex-wrap gap-1">
|
||||
<b className="font-600">Giá bán:</b>
|
||||
<b className="font-600 text-[#FF4E2A] text-18">
|
||||
48.990.000 đ
|
||||
</b>
|
||||
<del className="text-[#A0A5AC] font-300">
|
||||
52.000.000 đ
|
||||
</del>
|
||||
<span className="bg-[#FA354A] text-white text-11 px-[6px] leading-[18px] rounded-[20px]">
|
||||
-6%
|
||||
</span>
|
||||
</p>
|
||||
<p className="m-0">
|
||||
<b className="font-600">Bảo hành:</b>
|
||||
<span>Theo từng linh kiện</span>
|
||||
</p>
|
||||
</div>
|
||||
<div className="last:mb-0 mb-6 px-1">
|
||||
<p className="text-16 font-600 flex items-center leading-6 mb-2">
|
||||
<i className="icons icon-screen" />
|
||||
<span>Thông số sản phẩm</span>
|
||||
</p>
|
||||
<div className="tooltip-spec">
|
||||
<div className="item">
|
||||
CPU: INTEL CORE i5 13400F up 4.6GHz | 10 CORE | 16
|
||||
THREAD
|
||||
</div>
|
||||
<div className="item">
|
||||
RAM: DDR4 16GB (1x16G) 3200 MHz
|
||||
</div>
|
||||
<div className="item">
|
||||
VGA: NVIDIA RTX 3060 12GB GDDR6
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="rounded-[12px] bg-[linear-gradient(182.15deg,#FFA480_-18.44%,#EB0C23_60.76%)] p-1 pt-2">
|
||||
<p className="px-2 text-16 font-600 flex items-center leading-5 mb-2 text-white">
|
||||
<i className="icons icon-gift" />
|
||||
<span>Khuyến mại hấp dẫn</span>
|
||||
</p>
|
||||
<div className="tooltip-offer rounded-[8px] bg-[#FEF2F2] px-2 py-4">
|
||||
<div className="item">
|
||||
<p>
|
||||
<span style={{ color: "red", fontSize: "12pt" }}>
|
||||
<strong>
|
||||
⭐ Bảo Hành Tại Nơi Sử Dụng (Áp Dụng Nội Thành
|
||||
Hà Nội và Hồ Chí Minh)
|
||||
</strong>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div className="item">
|
||||
<p>
|
||||
<span style={{ color: "red", fontSize: "12pt" }}>
|
||||
<strong>
|
||||
⭐ Bảo Hành Siêu Tốc 1 Đổi 1 Trong 24h
|
||||
</strong>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div className="item">
|
||||
<p>
|
||||
<span style={{ color: "red", fontSize: "12pt" }}>
|
||||
<strong>
|
||||
⭐ Miễn Phí 100% Vận Chuyển Toàn Quốc
|
||||
</strong>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="swiper-slide">
|
||||
<div className="p-item">
|
||||
<a href="" className="p-img">
|
||||
<img
|
||||
src="images/product-2.jpg"
|
||||
alt=""
|
||||
width={250}
|
||||
height={250}
|
||||
/>
|
||||
</a>
|
||||
<div className="p-text">
|
||||
<div className="p-price-group">
|
||||
<p className="p-price">22.000.000 đ</p>
|
||||
</div>
|
||||
<a href="" className="p-name">
|
||||
<h3>
|
||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit.
|
||||
Suscipit quos obcaecati totam, atque vel
|
||||
</h3>
|
||||
</a>
|
||||
<div className="p-btn-group flex items-center justify-between text-16 font-500 leading-[23px]">
|
||||
<div>
|
||||
<p className="m-0 red flex items-center gap-1">
|
||||
<i className="bx bxs-phone text-18 w-[18px]" />
|
||||
<span>Liên hệ</span>
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className="p-btn bx bx-plus bg-btn text-white rounded-full w-9 h-9 text-20"
|
||||
aria-label="Mua"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-tooltip hidden">
|
||||
<div className="bg-white rounded-[20px] overflow-hidden border-2 border-[#EAECF0] shadow-[0px_6px_8px_-2px_#10182814]">
|
||||
<p className="tooltip-name px-5 py-4 text-white font-600 text-16 leading-[21px] bg-[linear-gradient(180.3deg,#259AFF_-18.56%,_#114CDD_100.92%)] m-0">
|
||||
[Tặng bàn phím] HHPC ULTRA 7 265K | 32GB DDR5 | NVIDIA RTX
|
||||
3060 12GB
|
||||
</p>
|
||||
<div className="p-4 tooltip-content">
|
||||
<div className="last:border-0 last:p-0 last:m-0 text-16 border-b border-[#DEE4EC] mb-4 pb-4">
|
||||
<p className="m-0 flex items-center flex-wrap gap-1">
|
||||
<b className="font-600">Giá bán:</b>
|
||||
<b className="font-600 text-[#FF4E2A] text-18">
|
||||
48.990.000 đ
|
||||
</b>
|
||||
<del className="text-[#A0A5AC] font-300">
|
||||
52.000.000 đ
|
||||
</del>
|
||||
<span className="bg-[#FA354A] text-white text-11 px-[6px] leading-[18px] rounded-[20px]">
|
||||
-6%
|
||||
</span>
|
||||
</p>
|
||||
<p className="m-0">
|
||||
<b className="font-600">Bảo hành:</b>
|
||||
<span>Theo từng linh kiện</span>
|
||||
</p>
|
||||
</div>
|
||||
<div className="last:mb-0 mb-6 px-1">
|
||||
<p className="text-16 font-600 flex items-center leading-6 mb-2">
|
||||
<i className="icons icon-screen" />
|
||||
<span>Thông số sản phẩm</span>
|
||||
</p>
|
||||
<div className="tooltip-spec">
|
||||
<div className="item">
|
||||
CPU: INTEL CORE i5 13400F up 4.6GHz | 10 CORE | 16
|
||||
THREAD
|
||||
</div>
|
||||
<div className="item">
|
||||
RAM: DDR4 16GB (1x16G) 3200 MHz
|
||||
</div>
|
||||
<div className="item">
|
||||
VGA: NVIDIA RTX 3060 12GB GDDR6
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="swiper-slide">
|
||||
<div className="p-item">
|
||||
<a href="" className="p-img">
|
||||
<img
|
||||
src="images/product-3.jpg"
|
||||
alt=""
|
||||
width={250}
|
||||
height={250}
|
||||
/>
|
||||
</a>
|
||||
<div className="p-text">
|
||||
<div className="p-price-group">
|
||||
<del>52.000.000 đ</del>
|
||||
<span className="p-discount">-10%</span>
|
||||
<p className="p-price">22.000.000 đ</p>
|
||||
</div>
|
||||
<a href="" className="p-name">
|
||||
<h3>
|
||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit.
|
||||
Suscipit quos obcaecati totam, atque vel
|
||||
</h3>
|
||||
</a>
|
||||
<div className="p-btn-group flex items-center justify-between text-16 font-500 leading-[23px]">
|
||||
<div>
|
||||
<p className="m-0 red flex items-center gap-1">
|
||||
<i className="bx bxs-phone text-18 w-[18px]" />
|
||||
<span>Liên hệ</span>
|
||||
</p>
|
||||
<p className="m-0 text-[#E16B10] flex items-center gap-1">
|
||||
<i className="bx bx-gift text-18 w-[18px]" />
|
||||
<span>Quà tặng</span>
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className="p-btn bx bx-plus bg-btn text-white rounded-full w-9 h-9 text-20"
|
||||
aria-label="Mua"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-tooltip hidden">
|
||||
<div className="bg-white rounded-[20px] overflow-hidden border-2 border-[#EAECF0] shadow-[0px_6px_8px_-2px_#10182814]">
|
||||
<p className="tooltip-name px-5 py-4 text-white font-600 text-16 leading-[21px] bg-[linear-gradient(180.3deg,#259AFF_-18.56%,_#114CDD_100.92%)] m-0">
|
||||
[Tặng bàn phím] HHPC ULTRA 7 265K | 32GB DDR5 | NVIDIA RTX
|
||||
3060 12GB
|
||||
</p>
|
||||
<div className="p-4 tooltip-content">
|
||||
<div className="last:border-0 last:p-0 last:m-0 text-16 border-b border-[#DEE4EC] mb-4 pb-4">
|
||||
<p className="m-0 flex items-center flex-wrap gap-1">
|
||||
<b className="font-600">Giá bán:</b>
|
||||
<b className="font-600 text-[#FF4E2A] text-18">
|
||||
48.990.000 đ
|
||||
</b>
|
||||
<del className="text-[#A0A5AC] font-300">
|
||||
52.000.000 đ
|
||||
</del>
|
||||
<span className="bg-[#FA354A] text-white text-11 px-[6px] leading-[18px] rounded-[20px]">
|
||||
-6%
|
||||
</span>
|
||||
</p>
|
||||
<p className="m-0">
|
||||
<b className="font-600">Bảo hành:</b>
|
||||
<span>Theo từng linh kiện</span>
|
||||
</p>
|
||||
</div>
|
||||
<div className="last:mb-0 mb-6 px-1">
|
||||
<p className="text-16 font-600 flex items-center leading-6 mb-2">
|
||||
<i className="icons icon-screen" />
|
||||
<span>Thông số sản phẩm</span>
|
||||
</p>
|
||||
<div className="tooltip-spec">
|
||||
<div className="item">
|
||||
CPU: INTEL CORE i5 13400F up 4.6GHz | 10 CORE | 16
|
||||
THREAD
|
||||
</div>
|
||||
<div className="item">
|
||||
RAM: DDR4 16GB (1x16G) 3200 MHz
|
||||
</div>
|
||||
<div className="item">
|
||||
VGA: NVIDIA RTX 3060 12GB GDDR6
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="rounded-[12px] bg-[linear-gradient(182.15deg,#FFA480_-18.44%,#EB0C23_60.76%)] p-1 pt-2">
|
||||
<p className="px-2 text-16 font-600 flex items-center leading-5 mb-2 text-white">
|
||||
<i className="icons icon-gift" />
|
||||
<span>Khuyến mại hấp dẫn</span>
|
||||
</p>
|
||||
<div className="tooltip-offer rounded-[8px] bg-[#FEF2F2] px-2 py-4">
|
||||
<div className="item">
|
||||
<p>
|
||||
<span style={{ color: "red", fontSize: "12pt" }}>
|
||||
<strong>
|
||||
⭐ Bảo Hành Tại Nơi Sử Dụng (Áp Dụng Nội Thành
|
||||
Hà Nội và Hồ Chí Minh)
|
||||
</strong>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div className="item">
|
||||
<p>
|
||||
<span style={{ color: "red", fontSize: "12pt" }}>
|
||||
<strong>
|
||||
⭐ Bảo Hành Siêu Tốc 1 Đổi 1 Trong 24h
|
||||
</strong>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div className="item">
|
||||
<p>
|
||||
<span style={{ color: "red", fontSize: "12pt" }}>
|
||||
<strong>
|
||||
⭐ Miễn Phí 100% Vận Chuyển Toàn Quốc
|
||||
</strong>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="swiper-slide">
|
||||
<div className="p-item">
|
||||
<a href="" className="p-img">
|
||||
<img
|
||||
src="images/product-4.jpg"
|
||||
alt=""
|
||||
width={250}
|
||||
height={250}
|
||||
/>
|
||||
</a>
|
||||
<div className="p-text">
|
||||
<div className="p-price-group">
|
||||
<del>52.000.000 đ</del>
|
||||
<span className="p-discount">-10%</span>
|
||||
<p className="p-price">22.000.000 đ</p>
|
||||
</div>
|
||||
<a href="" className="p-name">
|
||||
<h3>
|
||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit.
|
||||
Suscipit quos obcaecati totam, atque vel
|
||||
</h3>
|
||||
</a>
|
||||
<div className="p-btn-group flex items-center justify-between text-16 font-500 leading-[23px]">
|
||||
<div>
|
||||
<p className="m-0 text-[#00AD4F] flex items-center gap-1">
|
||||
<i className="bx bx-check-circle text-18 w-[18px]" />
|
||||
<span>Sẵn hàng</span>
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className="p-btn bx bx-plus bg-btn text-white rounded-full w-9 h-9 text-20"
|
||||
aria-label="Mua"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-tooltip hidden">
|
||||
<div className="bg-white rounded-[20px] overflow-hidden border-2 border-[#EAECF0] shadow-[0px_6px_8px_-2px_#10182814]">
|
||||
<p className="tooltip-name px-5 py-4 text-white font-600 text-16 leading-[21px] bg-[linear-gradient(180.3deg,#259AFF_-18.56%,_#114CDD_100.92%)] m-0">
|
||||
[Tặng bàn phím] HHPC ULTRA 7 265K | 32GB DDR5 | NVIDIA RTX
|
||||
3060 12GB
|
||||
</p>
|
||||
<div className="p-4 tooltip-content">
|
||||
<div className="last:border-0 last:p-0 last:m-0 text-16 border-b border-[#DEE4EC] mb-4 pb-4">
|
||||
<p className="m-0 flex items-center flex-wrap gap-1">
|
||||
<b className="font-600">Giá bán:</b>
|
||||
<b className="font-600 text-[#FF4E2A] text-18">
|
||||
48.990.000 đ
|
||||
</b>
|
||||
<del className="text-[#A0A5AC] font-300">
|
||||
52.000.000 đ
|
||||
</del>
|
||||
<span className="bg-[#FA354A] text-white text-11 px-[6px] leading-[18px] rounded-[20px]">
|
||||
-6%
|
||||
</span>
|
||||
</p>
|
||||
<p className="m-0">
|
||||
<b className="font-600">Bảo hành:</b>
|
||||
<span>Theo từng linh kiện</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="swiper-slide">
|
||||
<div className="p-item">
|
||||
<a href="" className="p-img">
|
||||
<img
|
||||
src="images/product-5.jpg"
|
||||
alt=""
|
||||
width={250}
|
||||
height={250}
|
||||
/>
|
||||
</a>
|
||||
<div className="p-text">
|
||||
<div className="p-price-group">
|
||||
<p className="p-price">22.000.000 đ</p>
|
||||
</div>
|
||||
<a href="" className="p-name">
|
||||
<h3>
|
||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit.
|
||||
Suscipit quos obcaecati totam, atque vel
|
||||
</h3>
|
||||
</a>
|
||||
<div className="p-btn-group flex items-center justify-between text-16 font-500 leading-[23px]">
|
||||
<div>
|
||||
<p className="m-0 text-[#00AD4F] flex items-center gap-1">
|
||||
<i className="bx bx-check-circle text-18 w-[18px]" />
|
||||
<span>Sẵn hàng</span>
|
||||
</p>
|
||||
<p />
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className="p-btn bx bx-plus bg-btn text-white rounded-full w-9 h-9 text-20"
|
||||
aria-label="Mua"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-tooltip hidden">
|
||||
<div className="bg-white rounded-[20px] overflow-hidden border-2 border-[#EAECF0] shadow-[0px_6px_8px_-2px_#10182814]">
|
||||
<p className="tooltip-name px-5 py-4 text-white font-600 text-16 leading-[21px] bg-[linear-gradient(180.3deg,#259AFF_-18.56%,_#114CDD_100.92%)] m-0">
|
||||
[Tặng bàn phím] HHPC ULTRA 7 265K | 32GB DDR5 | NVIDIA RTX
|
||||
3060 12GB
|
||||
</p>
|
||||
<div className="p-4 tooltip-content">
|
||||
<div className="last:border-0 last:p-0 last:m-0 text-16 border-b border-[#DEE4EC] mb-4 pb-4">
|
||||
<p className="m-0 flex items-center flex-wrap gap-1">
|
||||
<b className="font-600">Giá bán:</b>
|
||||
<b className="font-600 text-[#FF4E2A] text-18">
|
||||
48.990.000 đ
|
||||
</b>
|
||||
</p>
|
||||
<p className="m-0">
|
||||
<b className="font-600">Bảo hành:</b>
|
||||
<span>Theo từng linh kiện</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="swiper-slide">
|
||||
<div className="p-item">
|
||||
<a href="" className="p-img">
|
||||
<img
|
||||
src="images/product-7.jpg"
|
||||
alt=""
|
||||
width={250}
|
||||
height={250}
|
||||
/>
|
||||
</a>
|
||||
<div className="p-text">
|
||||
<div className="p-price-group">
|
||||
<del>52.000.000 đ</del>
|
||||
<span className="p-discount">-10%</span>
|
||||
<p className="p-price">22.000.000 đ</p>
|
||||
</div>
|
||||
<a href="" className="p-name">
|
||||
<h3>
|
||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit.
|
||||
Suscipit quos obcaecati totam, atque vel
|
||||
</h3>
|
||||
</a>
|
||||
<div className="p-btn-group flex items-center justify-between text-16 font-500 leading-[23px]">
|
||||
<div>
|
||||
<p className="m-0 red flex items-center gap-1">
|
||||
<i className="bx bxs-phone text-18 w-[18px]" />
|
||||
<span>Liên hệ</span>
|
||||
</p>
|
||||
<p className="m-0 text-[#E16B10] flex items-center gap-1">
|
||||
<i className="bx bx-gift text-18 w-[18px]" />
|
||||
<span>Quà tặng</span>
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className="p-btn bx bx-plus bg-btn text-white rounded-full w-9 h-9 text-20"
|
||||
aria-label="Mua"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-tooltip hidden">
|
||||
<div className="bg-white rounded-[20px] overflow-hidden border-2 border-[#EAECF0] shadow-[0px_6px_8px_-2px_#10182814]">
|
||||
<p className="tooltip-name px-5 py-4 text-white font-600 text-16 leading-[21px] bg-[linear-gradient(180.3deg,#259AFF_-18.56%,_#114CDD_100.92%)] m-0">
|
||||
[Tặng bàn phím] HHPC ULTRA 7 265K | 32GB DDR5 | NVIDIA RTX
|
||||
3060 12GB
|
||||
</p>
|
||||
<div className="p-4 tooltip-content">
|
||||
<div className="last:border-0 last:p-0 last:m-0 text-16 border-b border-[#DEE4EC] mb-4 pb-4">
|
||||
<p className="m-0 flex items-center flex-wrap gap-1">
|
||||
<b className="font-600">Giá bán:</b>
|
||||
<b className="font-600 text-[#FF4E2A] text-18">
|
||||
48.990.000 đ
|
||||
</b>
|
||||
<del className="text-[#A0A5AC] font-300">
|
||||
52.000.000 đ
|
||||
</del>
|
||||
<span className="bg-[#FA354A] text-white text-11 px-[6px] leading-[18px] rounded-[20px]">
|
||||
-6%
|
||||
</span>
|
||||
</p>
|
||||
<p className="m-0">
|
||||
<b className="font-600">Bảo hành:</b>
|
||||
<span>Theo từng linh kiện</span>
|
||||
</p>
|
||||
</div>
|
||||
<div className="last:mb-0 mb-6 px-1">
|
||||
<p className="text-16 font-600 flex items-center leading-6 mb-2">
|
||||
<i className="icons icon-screen" />
|
||||
<span>Thông số sản phẩm</span>
|
||||
</p>
|
||||
<div className="tooltip-spec">
|
||||
<div className="item">
|
||||
CPU: INTEL CORE i5 13400F up 4.6GHz | 10 CORE | 16
|
||||
THREAD
|
||||
</div>
|
||||
<div className="item">
|
||||
RAM: DDR4 16GB (1x16G) 3200 MHz
|
||||
</div>
|
||||
<div className="item">
|
||||
VGA: NVIDIA RTX 3060 12GB GDDR6
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="rounded-[12px] bg-[linear-gradient(182.15deg,#FFA480_-18.44%,#EB0C23_60.76%)] p-1 pt-2">
|
||||
<p className="px-2 text-16 font-600 flex items-center leading-5 mb-2 text-white">
|
||||
<i className="icons icon-gift" />
|
||||
<span>Khuyến mại hấp dẫn</span>
|
||||
</p>
|
||||
<div className="tooltip-offer rounded-[8px] bg-[#FEF2F2] px-2 py-4">
|
||||
<div className="item">
|
||||
<p>
|
||||
<span style={{ color: "red", fontSize: "12pt" }}>
|
||||
<strong>
|
||||
⭐ Bảo Hành Tại Nơi Sử Dụng (Áp Dụng Nội Thành
|
||||
Hà Nội và Hồ Chí Minh)
|
||||
</strong>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div className="item">
|
||||
<p>
|
||||
<span style={{ color: "red", fontSize: "12pt" }}>
|
||||
<strong>
|
||||
⭐ Bảo Hành Siêu Tốc 1 Đổi 1 Trong 24h
|
||||
</strong>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div className="item">
|
||||
<p>
|
||||
<span style={{ color: "red", fontSize: "12pt" }}>
|
||||
<strong>
|
||||
⭐ Miễn Phí 100% Vận Chuyển Toàn Quốc
|
||||
</strong>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="swiper-slide">
|
||||
<div className="p-item">
|
||||
<a href="" className="p-img">
|
||||
<img
|
||||
src="images/product-6.jpg"
|
||||
alt=""
|
||||
width={250}
|
||||
height={250}
|
||||
/>
|
||||
</a>
|
||||
<div className="p-text">
|
||||
<div className="p-price-group">
|
||||
<del>52.000.000 đ</del>
|
||||
<span className="p-discount">-10%</span>
|
||||
<p className="p-price">22.000.000 đ</p>
|
||||
</div>
|
||||
<a href="" className="p-name">
|
||||
<h3>
|
||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit.
|
||||
Suscipit quos obcaecati totam, atque vel
|
||||
</h3>
|
||||
</a>
|
||||
<div className="p-btn-group flex items-center justify-between text-16 font-500 leading-[23px]">
|
||||
<div>
|
||||
<p className="m-0 text-[#00AD4F] flex items-center gap-1">
|
||||
<i className="bx bx-check-circle text-18 w-[18px]" />
|
||||
<span>Sẵn hàng</span>
|
||||
</p>
|
||||
<p className="m-0 text-[#E16B10] flex items-center gap-1">
|
||||
<i className="bx bx-gift text-18 w-[18px]" />
|
||||
<span>Quà tặng</span>
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className="p-btn bx bx-plus bg-btn text-white rounded-full w-9 h-9 text-20"
|
||||
aria-label="Mua"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-tooltip hidden">
|
||||
<div className="bg-white rounded-[20px] overflow-hidden border-2 border-[#EAECF0] shadow-[0px_6px_8px_-2px_#10182814]">
|
||||
<p className="tooltip-name px-5 py-4 text-white font-600 text-16 leading-[21px] bg-[linear-gradient(180.3deg,#259AFF_-18.56%,_#114CDD_100.92%)] m-0">
|
||||
[Tặng bàn phím] HHPC ULTRA 7 265K | 32GB DDR5 | NVIDIA RTX
|
||||
3060 12GB
|
||||
</p>
|
||||
<div className="p-4 tooltip-content">
|
||||
<div className="last:border-0 last:p-0 last:m-0 text-16 border-b border-[#DEE4EC] mb-4 pb-4">
|
||||
<p className="m-0 flex items-center flex-wrap gap-1">
|
||||
<b className="font-600">Giá bán:</b>
|
||||
<b className="font-600 text-[#FF4E2A] text-18">
|
||||
48.990.000 đ
|
||||
</b>
|
||||
<del className="text-[#A0A5AC] font-300">
|
||||
52.000.000 đ
|
||||
</del>
|
||||
<span className="bg-[#FA354A] text-white text-11 px-[6px] leading-[18px] rounded-[20px]">
|
||||
-6%
|
||||
</span>
|
||||
</p>
|
||||
<p className="m-0">
|
||||
<b className="font-600">Bảo hành:</b>
|
||||
<span>Theo từng linh kiện</span>
|
||||
</p>
|
||||
</div>
|
||||
<div className="last:mb-0 mb-6 px-1">
|
||||
<p className="text-16 font-600 flex items-center leading-6 mb-2">
|
||||
<i className="icons icon-screen" />
|
||||
<span>Thông số sản phẩm</span>
|
||||
</p>
|
||||
<div className="tooltip-spec">
|
||||
<div className="item">
|
||||
CPU: INTEL CORE i5 13400F up 4.6GHz | 10 CORE | 16
|
||||
THREAD
|
||||
</div>
|
||||
<div className="item">
|
||||
RAM: DDR4 16GB (1x16G) 3200 MHz
|
||||
</div>
|
||||
<div className="item">
|
||||
VGA: NVIDIA RTX 3060 12GB GDDR6
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="rounded-[12px] bg-[linear-gradient(182.15deg,#FFA480_-18.44%,#EB0C23_60.76%)] p-1 pt-2">
|
||||
<p className="px-2 text-16 font-600 flex items-center leading-5 mb-2 text-white">
|
||||
<i className="icons icon-gift" />
|
||||
<span>Khuyến mại hấp dẫn</span>
|
||||
</p>
|
||||
<div className="tooltip-offer rounded-[8px] bg-[#FEF2F2] px-2 py-4">
|
||||
<div className="item">
|
||||
<p>
|
||||
<span style={{ color: "red", fontSize: "12pt" }}>
|
||||
<strong>
|
||||
⭐ Bảo Hành Tại Nơi Sử Dụng (Áp Dụng Nội Thành
|
||||
Hà Nội và Hồ Chí Minh)
|
||||
</strong>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div className="item">
|
||||
<p>
|
||||
<span style={{ color: "red", fontSize: "12pt" }}>
|
||||
<strong>
|
||||
⭐ Bảo Hành Siêu Tốc 1 Đổi 1 Trong 24h
|
||||
</strong>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div className="item">
|
||||
<p>
|
||||
<span style={{ color: "red", fontSize: "12pt" }}>
|
||||
<strong>
|
||||
⭐ Miễn Phí 100% Vận Chuyển Toàn Quốc
|
||||
</strong>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ProductTab item={slug.related} />
|
||||
</div>
|
||||
|
||||
</>
|
||||
|
||||
@@ -4,7 +4,7 @@ import parse from 'html-react-parser';
|
||||
export default function ProductOffer({ item }: any) {
|
||||
return (
|
||||
<>
|
||||
{item.all.length > 0 &&
|
||||
{item.specialOffer.all.length > 0 &&
|
||||
<div className="pd-offer-group mb-4 bg-[linear-gradient(182.15deg,#FFA480_-18.44%,#EB0C23_60.76%)] p-1 pt-2 rounded-[8px]">
|
||||
<div className="group-title font-600 text-white flex items-center leading-[22px] mb-2 px-2 text-16">
|
||||
<i className="icons icon-gift mr-2 animation-tada -mt-1" />
|
||||
@@ -12,7 +12,7 @@ export default function ProductOffer({ item }: any) {
|
||||
</div>
|
||||
|
||||
<div className="rounded-[8px] bg-[#FEF2F2] px-2 py-4">
|
||||
{parse(formatTextList(item.all[0].title))}
|
||||
{parse(formatTextList(item.specialOffer.all[0].title))}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
79
src/components/product/detail/products/index.tsx
Normal file
79
src/components/product/detail/products/index.tsx
Normal file
@@ -0,0 +1,79 @@
|
||||
'use client';
|
||||
import { useEffect, useState, useMemo } from "react";
|
||||
import { Swiper, SwiperSlide } from 'swiper/react';
|
||||
import { Navigation, Pagination, Autoplay } from 'swiper/modules';
|
||||
import { ProductHistory } from "@/data/productHistory";
|
||||
import ProductItem from "@/components/shared/ProductItem"
|
||||
|
||||
export default function ProductTab({ item }: any) {
|
||||
const RelatedData = item.product || [];
|
||||
const HistoryData = ProductHistory.list || [];
|
||||
|
||||
const [active, setActive] = useState<number>(1);
|
||||
useEffect(() => {
|
||||
if (RelatedData.length > 0) {
|
||||
setActive(1);
|
||||
} else if (HistoryData.length > 0) {
|
||||
setActive(2);
|
||||
} else {
|
||||
setActive(0);
|
||||
}
|
||||
}, [RelatedData, HistoryData]);
|
||||
|
||||
const products = useMemo(() => {
|
||||
if (active === 1) return RelatedData;
|
||||
if (active === 2) return HistoryData;
|
||||
return [];
|
||||
}, [active, RelatedData, HistoryData]);
|
||||
|
||||
if (active > 0) {
|
||||
return (
|
||||
<div className="pd-product-container bg-white px-6 py-8 rounded-[24px]">
|
||||
<div className="pd-tab-group relative flex mb-8 border-b border-[#DEE4EC] font-600 text-24 gap-10 leading-[31px] pb-5">
|
||||
{RelatedData.length > 0 &&
|
||||
<button type="button" aria-label="tab"
|
||||
className={active === 1 ? 'current' : ''}
|
||||
onClick={() => setActive(1)}
|
||||
> Sản phẩm tương tự </button>
|
||||
}
|
||||
|
||||
{HistoryData.length > 0 &&
|
||||
<button type="button" aria-label="tab"
|
||||
className={active === 2 ? 'current' : ''}
|
||||
onClick={() => setActive(2)}
|
||||
> Sản phẩm đã xem </button>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div className="relative z-[1] bg-white relative min-h-[300px] js-product-holder">
|
||||
<Swiper
|
||||
key={active}
|
||||
modules={[Navigation, Pagination, Autoplay]}
|
||||
spaceBetween={24}
|
||||
slidesPerView={5}
|
||||
loop={products.length > 5 ? true : false}
|
||||
autoplay={{
|
||||
delay: 3000,
|
||||
disableOnInteraction: false,
|
||||
}}
|
||||
navigation={{
|
||||
prevEl: '.custom-nav .swiper-button-prev',
|
||||
nextEl: '.custom-nav .swiper-button-next',
|
||||
}}
|
||||
breakpoints={{
|
||||
1600: {
|
||||
slidesPerView: 6,
|
||||
},
|
||||
}}
|
||||
>
|
||||
{products.map((item: any) =>
|
||||
<SwiperSlide key={item.id}>
|
||||
<ProductItem item={item} />
|
||||
</SwiperSlide>
|
||||
)}
|
||||
</Swiper>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,38 +1,21 @@
|
||||
'use client';
|
||||
import { useState } from "react";
|
||||
import { useShowMore } from "@/hooks/useShowMore"
|
||||
import ReviewItem from "@/components/shared/ReviewItem";
|
||||
|
||||
const REVIEW_PER_PAGE = 5;
|
||||
import ShowMoreButton from "@/components/shared/ButtonShowMore"
|
||||
|
||||
export default function ReviewList({ item }: any) {
|
||||
const total = item?.length;
|
||||
|
||||
const [page, setPage] = useState(1);
|
||||
const displayCount = page * REVIEW_PER_PAGE;
|
||||
const hasMore = displayCount < total;
|
||||
const reviewData = item.slice(0, displayCount);
|
||||
|
||||
|
||||
const { displayData, hasMore, loadMore } = useShowMore(item, 5);
|
||||
|
||||
return (
|
||||
<>
|
||||
{reviewData &&
|
||||
reviewData.map((item:any) =>
|
||||
<ReviewItem key={item.id} item={item} />
|
||||
)
|
||||
}
|
||||
{ displayData.map((item:any) =>
|
||||
<ReviewItem key={item.id} item={item} />
|
||||
)}
|
||||
|
||||
{ hasMore &&
|
||||
<div className="text-center mt-4">
|
||||
<button
|
||||
type="button"
|
||||
className="border border-[#0678DB] text-[#0678DB] rounded-[30px] h-10 px-6 hover:bg-[#0678DB] hover:text-white"
|
||||
aria-label="Xem thêm"
|
||||
onClick={() => setPage(prev => prev + 1)}
|
||||
>
|
||||
XEM THÊM
|
||||
<i className="bx bx-chevron-down text-20 align-middle mt-[-3px]" />
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
{ hasMore &&
|
||||
<ShowMoreButton onClick={loadMore} />
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user