update 2/2/2026
This commit is contained in:
@@ -41,7 +41,7 @@ export default function Banner( {id}:any ) {
|
|||||||
alt={item.name}
|
alt={item.name}
|
||||||
width={100}
|
width={100}
|
||||||
height={100}
|
height={100}
|
||||||
className="block w-full lazy rounded-[24px]"
|
className="block w-full rounded-[24px]"
|
||||||
unoptimized
|
unoptimized
|
||||||
/>
|
/>
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -1,138 +0,0 @@
|
|||||||
export default function Article() {
|
|
||||||
return (
|
|
||||||
<div className="pd-box-group bg-white mb-6 px-4 py-6 rounded-[24px]">
|
|
||||||
<p className="text-20 font-600 mb-4"> Tin tức mới nhất </p>
|
|
||||||
{/* limit: 5 */}
|
|
||||||
<div className="pd-article-holder flex flex-col gap-4">
|
|
||||||
<div className="art-item">
|
|
||||||
<a href="" className="art-img">
|
|
||||||
<img
|
|
||||||
src="https://hoanghapccdn.com/media/news/14_100__c___u_h__nh_m__y_t__nh_______h___a_theo_ng__n_s__ch.jpg"
|
|
||||||
alt=""
|
|
||||||
width={1}
|
|
||||||
height={1}
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
<div className="art-text">
|
|
||||||
<a href="" className="art-title">
|
|
||||||
<h3>
|
|
||||||
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eum
|
|
||||||
quidem asperiores provident dicta veniam deleniti eaque
|
|
||||||
repudiandae cum esse, ducimus officiis quibusdam pariatur
|
|
||||||
neque voluptates voluptas. Quisquam qui minus dolorum?
|
|
||||||
</h3>
|
|
||||||
</a>
|
|
||||||
<div className="art-summary">
|
|
||||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit,
|
|
||||||
obcaecati ducimus veritatis aliquid sunt accusamus unde nisi
|
|
||||||
nostrum fugit facere illo quos. Ad error suscipit, quidem optio
|
|
||||||
aut laudantium at!
|
|
||||||
</div>
|
|
||||||
<div className="art-time">
|
|
||||||
<i className="bx bx-calendar-alt" />
|
|
||||||
<time>23/4/2024</time>
|
|
||||||
<i className="w-[1.5px] h-[12px] bg-[#A0A5AC] mx-1" />
|
|
||||||
<span>Mai Văn Học</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="art-item">
|
|
||||||
<a href="" className="art-img">
|
|
||||||
<img
|
|
||||||
src="https://hoanghapccdn.com/media/news/14_100__c___u_h__nh_m__y_t__nh_______h___a_theo_ng__n_s__ch.jpg"
|
|
||||||
alt=""
|
|
||||||
width={1}
|
|
||||||
height={1}
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
<div className="art-text">
|
|
||||||
<a href="" className="art-title">
|
|
||||||
<h3>
|
|
||||||
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eum
|
|
||||||
quidem asperiores provident dicta veniam deleniti eaque
|
|
||||||
repudiandae cum esse, ducimus officiis quibusdam pariatur
|
|
||||||
neque voluptates voluptas. Quisquam qui minus dolorum?
|
|
||||||
</h3>
|
|
||||||
</a>
|
|
||||||
<div className="art-summary">
|
|
||||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit,
|
|
||||||
obcaecati ducimus veritatis aliquid sunt accusamus unde nisi
|
|
||||||
nostrum fugit facere illo quos. Ad error suscipit, quidem optio
|
|
||||||
aut laudantium at!
|
|
||||||
</div>
|
|
||||||
<div className="art-time">
|
|
||||||
<i className="bx bx-calendar-alt text-16 text-[#A0A5AC]" />
|
|
||||||
<time>23/4/2024</time>
|
|
||||||
<i className="w-[1.5px] h-[12px] bg-[#A0A5AC]" />
|
|
||||||
<span>Mai Văn Học</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="art-item">
|
|
||||||
<a href="" className="art-img">
|
|
||||||
<img
|
|
||||||
src="https://hoanghapccdn.com/media/news/14_100__c___u_h__nh_m__y_t__nh_______h___a_theo_ng__n_s__ch.jpg"
|
|
||||||
alt=""
|
|
||||||
width={1}
|
|
||||||
height={1}
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
<div className="art-text">
|
|
||||||
<a href="" className="art-title">
|
|
||||||
<h3>
|
|
||||||
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eum
|
|
||||||
quidem asperiores provident dicta veniam deleniti eaque
|
|
||||||
repudiandae cum esse, ducimus officiis quibusdam pariatur
|
|
||||||
neque voluptates voluptas. Quisquam qui minus dolorum?
|
|
||||||
</h3>
|
|
||||||
</a>
|
|
||||||
<div className="art-summary">
|
|
||||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit,
|
|
||||||
obcaecati ducimus veritatis aliquid sunt accusamus unde nisi
|
|
||||||
nostrum fugit facere illo quos. Ad error suscipit, quidem optio
|
|
||||||
aut laudantium at!
|
|
||||||
</div>
|
|
||||||
<div className="art-time">
|
|
||||||
<i className="bx bx-calendar-alt text-16 text-[#A0A5AC]" />
|
|
||||||
<time>23/4/2024</time>
|
|
||||||
<i className="w-[1.5px] h-[12px] bg-[#A0A5AC]" />
|
|
||||||
<span>Mai Văn Học</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="art-item">
|
|
||||||
<a href="" className="art-img">
|
|
||||||
<img
|
|
||||||
src="https://hoanghapccdn.com/media/news/14_100__c___u_h__nh_m__y_t__nh_______h___a_theo_ng__n_s__ch.jpg"
|
|
||||||
alt=""
|
|
||||||
width={1}
|
|
||||||
height={1}
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
<div className="art-text">
|
|
||||||
<a href="" className="art-title">
|
|
||||||
<h3>
|
|
||||||
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eum
|
|
||||||
quidem asperiores provident dicta veniam deleniti eaque
|
|
||||||
repudiandae cum esse, ducimus officiis quibusdam pariatur
|
|
||||||
neque voluptates voluptas. Quisquam qui minus dolorum?
|
|
||||||
</h3>
|
|
||||||
</a>
|
|
||||||
<div className="art-summary">
|
|
||||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit,
|
|
||||||
obcaecati ducimus veritatis aliquid sunt accusamus unde nisi
|
|
||||||
nostrum fugit facere illo quos. Ad error suscipit, quidem optio
|
|
||||||
aut laudantium at!
|
|
||||||
</div>
|
|
||||||
<div className="art-time">
|
|
||||||
<i className="bx bx-calendar-alt text-16 text-[#A0A5AC]" />
|
|
||||||
<time>23/4/2024</time>
|
|
||||||
<i className="w-[1.5px] h-[12px] bg-[#A0A5AC]" />
|
|
||||||
<span>Mai Văn Học</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
17
src/components/product/detail/articles/index.tsx
Normal file
17
src/components/product/detail/articles/index.tsx
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import ArticleItem from "@/components/shared/ArticleItem"
|
||||||
|
|
||||||
|
export default function Article( {item} : any ) {
|
||||||
|
return (
|
||||||
|
<div className="pd-box-group bg-white mb-6 px-4 py-6 rounded-[24px]">
|
||||||
|
<p className="text-20 font-600 mb-4"> Tin tức mới nhất </p>
|
||||||
|
|
||||||
|
<div className="pd-article-holder flex flex-col gap-4">
|
||||||
|
{
|
||||||
|
item.slice(0,5).map((item:any) =>
|
||||||
|
<ArticleItem key={item.id} item={item} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,161 +0,0 @@
|
|||||||
export default function Comment() {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<div className="flex items-center justify-between leading-8 gap-2 mb-4">
|
|
||||||
<p className="m-0 text-18 font-500"> 0 Bình luận </p>
|
|
||||||
<div className="flex flex-wrap gap-2 text-14 font-500 pd-comment-btn">
|
|
||||||
<button
|
|
||||||
className="h-8 border border-[#D1D5DB] rounded-[40px] flex items-center gap-[3px] px-8 hover:border-[#0678DB] hover:text-[#0678DB] current"
|
|
||||||
type="button"
|
|
||||||
aria-label="Đánh giá"
|
|
||||||
>
|
|
||||||
{" "}
|
|
||||||
Tất cả{" "}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className="h-8 border border-[#D1D5DB] rounded-[40px] flex items-center gap-[3px] px-4 hover:border-[#0678DB] hover:text-[#0678DB]"
|
|
||||||
type="button"
|
|
||||||
aria-label="Đánh giá"
|
|
||||||
>
|
|
||||||
{" "}
|
|
||||||
5 <i className="bxr bx-star" />{" "}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className="h-8 border border-[#D1D5DB] rounded-[40px] flex items-center gap-[3px] px-4 hover:border-[#0678DB] hover:text-[#0678DB]"
|
|
||||||
type="button"
|
|
||||||
aria-label="Đánh giá"
|
|
||||||
>
|
|
||||||
{" "}
|
|
||||||
4 <i className="bxr bx-star" />{" "}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className="h-8 border border-[#D1D5DB] rounded-[40px] flex items-center gap-[3px] px-4 hover:border-[#0678DB] hover:text-[#0678DB]"
|
|
||||||
type="button"
|
|
||||||
aria-label="Đánh giá"
|
|
||||||
>
|
|
||||||
{" "}
|
|
||||||
3 <i className="bxr bx-star" />{" "}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className="h-8 border border-[#D1D5DB] rounded-[40px] flex items-center gap-[3px] px-4 hover:border-[#0678DB] hover:text-[#0678DB]"
|
|
||||||
type="button"
|
|
||||||
aria-label="Đánh giá"
|
|
||||||
>
|
|
||||||
{" "}
|
|
||||||
2 <i className="bxr bx-star" />{" "}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className="h-8 border border-[#D1D5DB] rounded-[40px] flex items-center gap-[3px] px-4 hover:border-[#0678DB] hover:text-[#0678DB]"
|
|
||||||
type="button"
|
|
||||||
aria-label="Đánh giá"
|
|
||||||
>
|
|
||||||
{" "}
|
|
||||||
1 <i className="bxr bx-star" />{" "}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="border border-[#DDDDDD] rounded-[12px] overflow-hidden ">
|
|
||||||
<textarea
|
|
||||||
className="p-3 w-full resize-none h-[96px] outline-none border-none"
|
|
||||||
defaultValue={""}
|
|
||||||
/>
|
|
||||||
<div className="border-t border-[#DDDDDD] bg-[#F5F6F7] p-[10px_12px] text-right">
|
|
||||||
<button
|
|
||||||
className="bg-btn text-white h-10 px-9 text-18 font-500 rounded-[30px]"
|
|
||||||
type="button"
|
|
||||||
aria-label="submit"
|
|
||||||
>
|
|
||||||
{" "}
|
|
||||||
GỬI{" "}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="">
|
|
||||||
<div className="first:border-t first:mt-4 first:pt-4 border-[#D1D5DB] mb-5 flex gap-3 text-14 leading-[18px]">
|
|
||||||
<div className="w-10 h-10 rounded-full bg-[#9CA3AF] leading-10 text-center uppercase text-white font-600 overflow-hidden">
|
|
||||||
<span>p</span>
|
|
||||||
{/* <img src="images/avatar-admin.png" class="block w-full h-full"/> */}
|
|
||||||
</div>
|
|
||||||
<div className="w-[calc(100%_-_52px)]">
|
|
||||||
<div className="flex items-center gap-2 mb-1">
|
|
||||||
<b className="capitalize"> tên khách hàng </b>
|
|
||||||
<i className="bxr bxs-radio-circle text-[7px] text-[#6B7280]" />
|
|
||||||
<span className="text-[#6B7280]"> 11-11-2025, 11:11 </span>
|
|
||||||
</div>
|
|
||||||
<i className="star star-2" />
|
|
||||||
<div className="my-2">
|
|
||||||
Lorem ipsum dolor, sit amet consectetur adipisicing elit.
|
|
||||||
Fugiat magnam ipsam pariatur mollitia ratione distinctio magni
|
|
||||||
corrupti ad expedita. Natus, ullam inventore. Amet
|
|
||||||
consequuntur aspernatur deserunt accusantium, tempore
|
|
||||||
blanditiis magni!
|
|
||||||
</div>
|
|
||||||
<div className="flex gap-2 leading-[30px]">
|
|
||||||
<button
|
|
||||||
className="group flex items-center gap-[6px] border border-[#D1D5DB] px-3 rounded-[20px] hover:border-[#0678DB] hover:text-[#0678DB]"
|
|
||||||
type="button"
|
|
||||||
aria-label="actions"
|
|
||||||
>
|
|
||||||
{" "}
|
|
||||||
<i className="group-hover:text-[#0678DB] text-[#928FA8] bxr bx-heart" />{" "}
|
|
||||||
0{" "}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className="group flex items-center gap-[6px] border border-[#D1D5DB] px-3 rounded-[20px] hover:border-[#0678DB] hover:text-[#0678DB]"
|
|
||||||
type="button"
|
|
||||||
aria-label="actions"
|
|
||||||
>
|
|
||||||
{" "}
|
|
||||||
<i className="group-hover:text-[#0678DB] text-[#928FA8] bxr bx-reply-stroke" />{" "}
|
|
||||||
Trả lời{" "}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div className="bg-[#F3F4F6] rounded-[12px] overflow-hidden mt-3">
|
|
||||||
<div className="first:border-0 flex items-start gap-3 p-3 border-t border-[#D1D5DB]">
|
|
||||||
<div className="w-10 h-10 rounded-full bg-[#9CA3AF] leading-10 text-center uppercase text-white font-600 overflow-hidden">
|
|
||||||
{/* <span>p</span> */}
|
|
||||||
<img
|
|
||||||
src="images/avatar-admin.png"
|
|
||||||
className="block w-full h-full"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="w-[calc(100%_-_52px)]">
|
|
||||||
<div className="flex items-center gap-2 mb-1">
|
|
||||||
<b className="capitalize"> tên khách hàng </b>
|
|
||||||
<span className="bg-[linear-gradient(70.1deg,#75798B_62.94%,#ADB5CD_100%)] text-white px-[6px] leading-[18px] rounded-[20px] font-500 text-10">
|
|
||||||
{" "}
|
|
||||||
Quản trị viên{" "}
|
|
||||||
</span>
|
|
||||||
<i className="bxr bxs-radio-circle text-[7px] text-[#6B7280]" />
|
|
||||||
<span className="text-[#6B7280]">
|
|
||||||
{" "}
|
|
||||||
11-11-2025, 11:11{" "}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div className="my-2" style={{ whiteSpace: "pre-line" }}>
|
|
||||||
Lorem ipsum dolor, sit amet consectetur adipisicing
|
|
||||||
elit. Fugiat magnam ipsam pariatur mollitia ratione
|
|
||||||
distinctio magni corrupti ad expedita. Natus, ullam
|
|
||||||
inventore. Amet consequuntur aspernatur deserunt
|
|
||||||
accusantium, tempore blanditiis magni!{" "}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/* xem thêm */}
|
|
||||||
<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"
|
|
||||||
>
|
|
||||||
XEM THÊM{" "}
|
|
||||||
<i className="bx bx-chevron-down text-20 align-middle mt-[-3px]" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
36
src/components/product/detail/comments/CommentList.tsx
Normal file
36
src/components/product/detail/comments/CommentList.tsx
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
'use client';
|
||||||
|
import { useState } from "react";
|
||||||
|
import CommentItem from "@/components/shared/CommentItem"
|
||||||
|
|
||||||
|
const COMMENT_PER_PAGE = 5;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div>
|
||||||
|
{
|
||||||
|
commentData.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>
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
16
src/components/product/detail/comments/Form.tsx
Normal file
16
src/components/product/detail/comments/Form.tsx
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
export default function Form() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<textarea
|
||||||
|
className="p-3 w-full resize-none h-[96px] outline-none border-none"
|
||||||
|
defaultValue={""}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="border-t border-[#DDDDDD] bg-[#F5F6F7] p-[10px_12px] text-right">
|
||||||
|
<button type="button" aria-label="submit"
|
||||||
|
className="bg-btn text-white h-10 px-9 text-18 font-500 rounded-[30px]"
|
||||||
|
> GỬI </button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
40
src/components/product/detail/comments/index.tsx
Normal file
40
src/components/product/detail/comments/index.tsx
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { CommentData } from "@/data/comments";
|
||||||
|
import Form from "./Form";
|
||||||
|
import CommentList from "./CommentList";
|
||||||
|
|
||||||
|
export default function Comment() {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="flex items-center justify-between leading-8 gap-2 mb-4">
|
||||||
|
<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>
|
||||||
|
|
||||||
|
{buildButtonFilter()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="border border-[#DDDDDD] rounded-[12px] overflow-hidden js-comment-form">
|
||||||
|
<Form />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{CommentData.list.length > 0 &&
|
||||||
|
<CommentList item={CommentData.list}/>
|
||||||
|
}
|
||||||
|
</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,38 +1,34 @@
|
|||||||
import { formatPrice } from "@/lib/utils";
|
import { formatPrice } from "@/lib/utils";
|
||||||
import ProductImage from "./image";
|
import ProductImage from "./images";
|
||||||
import Static from "./static";
|
import Static from "./static";
|
||||||
import ProductDescription from "./description"
|
import ProductDescription from "./description"
|
||||||
import Comment from "./comment";
|
import Comment from "./comments";
|
||||||
import Review from "./review";
|
import Review from "./reviews";
|
||||||
import ProductSpec from "./specifications";
|
import ProductSpec from "./specifications";
|
||||||
import Article from "./article";
|
import Article from "./articles";
|
||||||
import ProductPrice from "./price";
|
import ProductPrice from "./price";
|
||||||
import ProductOffer from "./offer";
|
import ProductOffer from "./offer";
|
||||||
import Buttons from "./button";
|
import Buttons from "./buttons";
|
||||||
import ProductSummary from "./summary";
|
import ProductSummary from "./summary";
|
||||||
|
|
||||||
export default async function ProductDetail({ slug }: any) {
|
import { ReviewData } from "@/data/reviews";
|
||||||
const {
|
|
||||||
productName,
|
|
||||||
productId,
|
|
||||||
review,
|
|
||||||
visit,
|
|
||||||
quantity,
|
|
||||||
productSummary,
|
|
||||||
productImage, imageCollection,
|
|
||||||
price, marketPrice, deal_list, price_off, sale_rules,
|
|
||||||
hasVAT, warranty,
|
|
||||||
specialOffer,
|
|
||||||
productDescription,
|
|
||||||
productSpec
|
|
||||||
} = slug
|
|
||||||
|
|
||||||
const image = {
|
export default async function ProductDetail({ slug }: any) {
|
||||||
productImage, imageCollection
|
|
||||||
|
const imageList = {
|
||||||
|
productImage : slug.productImage,
|
||||||
|
imageCollection : slug.imageCollection
|
||||||
}
|
}
|
||||||
|
|
||||||
const priceData = {
|
const priceData = {
|
||||||
price, marketPrice, deal_list, price_off, sale_rules, hasVAT, warranty, quantity
|
price : slug.price,
|
||||||
|
marketPrice : slug.marketPrice,
|
||||||
|
deal_list : slug.deal_list,
|
||||||
|
price_off : slug.price_off,
|
||||||
|
sale_rules : slug.sale_rules,
|
||||||
|
hasVAT : slug.hasVAT,
|
||||||
|
warranty : slug.warranty,
|
||||||
|
quantity : slug.quantity
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(slug)
|
console.log(slug)
|
||||||
@@ -42,27 +38,27 @@ export default async function ProductDetail({ slug }: any) {
|
|||||||
<div className="product-detail-page container">
|
<div className="product-detail-page container">
|
||||||
<div className="pd-info-container static bg-white rounded-[24px] p-6 mb-6">
|
<div className="pd-info-container static bg-white rounded-[24px] p-6 mb-6">
|
||||||
<h1 className="leading-8 text-[#004BA4] text-24 mb-6 font-600">
|
<h1 className="leading-8 text-[#004BA4] text-24 mb-6 font-600">
|
||||||
{productName}
|
{slug.productName}
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<div className="gap-6 flex flex-wrap items-start leading-[18px]">
|
<div className="gap-6 flex flex-wrap items-start leading-[18px]">
|
||||||
<div className="col-left-group w-[424px] sticky top-[90px]">
|
<div className="col-left-group w-[424px] sticky top-[90px]">
|
||||||
<ProductImage data={image} />
|
<ProductImage data={imageList} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-middle-group w-[464px]">
|
<div className="col-middle-group w-[464px]">
|
||||||
|
|
||||||
<div className="pb-3 mb-3 border-b border-[#DEE4EC] flex flex-wrap items-center gap-2">
|
<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">
|
<button type="button" className="m-0 flex items-center gap-1">
|
||||||
<i className={`star star-${review.rate}`} />
|
<i className={`star star-${ReviewData.summary.avgRate}`} />
|
||||||
<span className="font-500"> ({review.total}) </span>
|
<span className="font-500"> ({ReviewData.summary.total}) </span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<i className="w-[1px] h-4 bg-[#DEE4EC]" />
|
<i className="w-[1px] h-4 bg-[#DEE4EC]" />
|
||||||
|
|
||||||
<p className="m-0">
|
<p className="m-0">
|
||||||
Lượt xem:
|
Lượt xem:
|
||||||
<span className="text-[#004BA4] font-500">{formatPrice(visit)}</span>
|
<span className="text-[#004BA4] font-500">{formatPrice(slug.visit)}</span>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<i className="w-[1px] h-4 bg-[#DEE4EC]" />
|
<i className="w-[1px] h-4 bg-[#DEE4EC]" />
|
||||||
@@ -71,7 +67,7 @@ export default async function ProductDetail({ slug }: any) {
|
|||||||
Tình trạng:
|
Tình trạng:
|
||||||
<span
|
<span
|
||||||
dangerouslySetInnerHTML={{
|
dangerouslySetInnerHTML={{
|
||||||
__html: quantity > 0
|
__html: slug.quantity > 0
|
||||||
? '<span class="font-500 text-[#00AD4F]">Còn hàng</span>'
|
? '<span class="font-500 text-[#00AD4F]">Còn hàng</span>'
|
||||||
: '<span class="font-500 red">Liên hệ</span>'
|
: '<span class="font-500 red">Liên hệ</span>'
|
||||||
}}
|
}}
|
||||||
@@ -79,15 +75,15 @@ export default async function ProductDetail({ slug }: any) {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{ productSummary &&
|
{ slug.productSummary &&
|
||||||
<ProductSummary item={productSummary} />
|
<ProductSummary item={slug.productSummary} />
|
||||||
}
|
}
|
||||||
|
|
||||||
<ProductPrice item={priceData} />
|
<ProductPrice item={priceData} />
|
||||||
|
|
||||||
<ProductOffer item={specialOffer}/>
|
<ProductOffer item={slug.specialOffer}/>
|
||||||
|
|
||||||
<Buttons item={productId} />
|
<Buttons item={slug.productId} />
|
||||||
|
|
||||||
<p className="m-0 flex items-center gap-3 text-16 leading-[22px]">
|
<p className="m-0 flex items-center gap-3 text-16 leading-[22px]">
|
||||||
<i className="icons icon-truck-2 !w-6" />
|
<i className="icons icon-truck-2 !w-6" />
|
||||||
@@ -103,23 +99,32 @@ export default async function ProductDetail({ slug }: any) {
|
|||||||
|
|
||||||
<div className="pd-content-container flex flex-wrap items-baseline gap-6">
|
<div className="pd-content-container flex flex-wrap items-baseline gap-6">
|
||||||
<div className="col-left w-[784px]">
|
<div className="col-left w-[784px]">
|
||||||
{ productDescription &&
|
{ slug.productDescription &&
|
||||||
<ProductDescription name={productName} description={productDescription} />
|
<ProductDescription
|
||||||
|
name={slug.productName}
|
||||||
|
description={slug.productDescription}
|
||||||
|
/>
|
||||||
}
|
}
|
||||||
|
|
||||||
<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]">
|
||||||
<Review />
|
<p className="leading-[31px] font-600 text-24 mb-4 pb-4">
|
||||||
|
Đánh giá và bình luận
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<Review item={ReviewData}/>
|
||||||
|
|
||||||
<Comment />
|
<Comment />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-right w-[440px]">
|
<div className="col-right w-[440px]">
|
||||||
{productSpec &&
|
{slug.productSpec &&
|
||||||
<ProductSpec item={productSpec} />
|
<ProductSpec item={slug.productSpec} />
|
||||||
}
|
}
|
||||||
|
|
||||||
<Article />
|
{ slug.related['article-article'].length > 0 &&
|
||||||
|
<Article item={ slug.related['article-article'] } />
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,227 +0,0 @@
|
|||||||
export default function Review() {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<p className="leading-[31px] font-600 text-24 mb-4 pb-4">
|
|
||||||
{" "}
|
|
||||||
Đánh giá và bình luận{" "}
|
|
||||||
</p>
|
|
||||||
{/* Rating */}
|
|
||||||
<div className="pd-rating-conatiner mb-9" id="js-pd-rating">
|
|
||||||
<div className="flex flex-wrap justify-between gap-6">
|
|
||||||
<div className="w-[200px] text-center">
|
|
||||||
<p className="font-600 text-[40px] leading-[48px] mb-2"> 0 </p>
|
|
||||||
<p className="my-2 text-[#6B7280]"> 0 lượt đánh giá </p>
|
|
||||||
<i className="star star-3" />
|
|
||||||
<button
|
|
||||||
className="rating-btn block h-10 w-full text-white text-14 font-500 rounded-[30px] bg-btn uppercase mt-3"
|
|
||||||
type="button"
|
|
||||||
aria-label="đánh giá"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="w-[calc(100%_-_224px)] text-14 font-500 leading-[18px] flex flex-col gap-4">
|
|
||||||
<div className="flex items-center justify-between gap-2 flex-wrap">
|
|
||||||
<p className="m-0 flex gap-[3px] w-[30px]">
|
|
||||||
{" "}
|
|
||||||
<span>5</span>{" "}
|
|
||||||
<i className="bx bxs-star text-[#FBBF24] text-16" />{" "}
|
|
||||||
</p>
|
|
||||||
<div className="relative bg-[#E8ECF6] overflow-hidden rounded-[30px] h-3 w-[calc(100%_-_71px)]">
|
|
||||||
<i
|
|
||||||
className="max-w-[100%] bg-[#0678DB] absolute inset-0"
|
|
||||||
style={{ width: "0%" }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<p className="m-0 text-[#6B7280] w-[25px] text-right"> 0 </p>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center justify-between gap-2 flex-wrap">
|
|
||||||
<p className="m-0 flex gap-[3px] w-[30px]">
|
|
||||||
<span>4</span>{" "}
|
|
||||||
<i className="bx bxs-star text-[#FBBF24] text-16" />
|
|
||||||
</p>
|
|
||||||
<div className="relative bg-[#E8ECF6] overflow-hidden rounded-[30px] h-3 w-[calc(100%_-_71px)]">
|
|
||||||
<i
|
|
||||||
className="max-w-[100%] bg-[#0678DB] absolute inset-0"
|
|
||||||
style={{ width: "0%" }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<p className="m-0 text-[#6B7280] w-[25px] text-right"> 0 </p>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center justify-between gap-2 flex-wrap">
|
|
||||||
<p className="m-0 flex gap-[3px] w-[30px]">
|
|
||||||
<span>3</span>{" "}
|
|
||||||
<i className="bx bxs-star text-[#FBBF24] text-16" />
|
|
||||||
</p>
|
|
||||||
<div className="relative bg-[#E8ECF6] overflow-hidden rounded-[30px] h-3 w-[calc(100%_-_71px)]">
|
|
||||||
<i
|
|
||||||
className="max-w-[100%] bg-[#0678DB] absolute inset-0"
|
|
||||||
style={{ width: "0%" }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<p className="m-0 text-[#6B7280] w-[25px] text-right"> 0 </p>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center justify-between gap-2 flex-wrap">
|
|
||||||
<p className="m-0 flex gap-[3px] w-[30px]">
|
|
||||||
<span>2</span>{" "}
|
|
||||||
<i className="bx bxs-star text-[#FBBF24] text-16" />
|
|
||||||
</p>
|
|
||||||
<div className="relative bg-[#E8ECF6] overflow-hidden rounded-[30px] h-3 w-[calc(100%_-_71px)]">
|
|
||||||
<i
|
|
||||||
className="max-w-[100%] bg-[#0678DB] absolute inset-0"
|
|
||||||
style={{ width: "0%" }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<p className="m-0 text-[#6B7280] w-[25px] text-right"> 0 </p>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center justify-between gap-2 flex-wrap">
|
|
||||||
<p className="m-0 flex gap-[3px] w-[30px]">
|
|
||||||
<span>1</span>{" "}
|
|
||||||
<i className="bx bxs-star text-[#FBBF24] text-16" />
|
|
||||||
</p>
|
|
||||||
<div className="relative bg-[#E8ECF6] overflow-hidden rounded-[30px] h-3 w-[calc(100%_-_71px)]">
|
|
||||||
<i
|
|
||||||
className="max-w-[100%] bg-[#0678DB] absolute inset-0"
|
|
||||||
style={{ width: "0%" }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<p className="m-0 text-[#6B7280] w-[25px] text-right"> 0 </p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="pd-rating-form mt-8 hidden">
|
|
||||||
<div className="flex items-center mb-4 gap-4">
|
|
||||||
<p className="m-0"> Chọn đánh giá của bạn </p>
|
|
||||||
<div className="rating-comment clearfix">
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
className="rating-input"
|
|
||||||
id="rating-input-review-0-5"
|
|
||||||
defaultValue={5}
|
|
||||||
data-title="Quá tuyệt vời"
|
|
||||||
name="user_post[rate]"
|
|
||||||
defaultChecked={true}
|
|
||||||
/>
|
|
||||||
<label
|
|
||||||
htmlFor="rating-input-review-0-5"
|
|
||||||
className="rating-star js-rating-star"
|
|
||||||
data-title="Quá tuyệt vời"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
className="rating-input"
|
|
||||||
id="rating-input-review-0-4"
|
|
||||||
defaultValue={4}
|
|
||||||
data-title="Rất tốt"
|
|
||||||
name="user_post[rate]"
|
|
||||||
/>
|
|
||||||
<label
|
|
||||||
htmlFor="rating-input-review-0-4"
|
|
||||||
className="rating-star js-rating-star"
|
|
||||||
data-title="Rất tốt"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
className="rating-input"
|
|
||||||
id="rating-input-review-0-3"
|
|
||||||
defaultValue={3}
|
|
||||||
data-title="Bình thường"
|
|
||||||
name="user_post[rate]"
|
|
||||||
/>
|
|
||||||
<label
|
|
||||||
htmlFor="rating-input-review-0-3"
|
|
||||||
className="rating-star js-rating-star"
|
|
||||||
data-title="Bình thường"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
className="rating-input"
|
|
||||||
id="rating-input-review-0-2"
|
|
||||||
defaultValue={2}
|
|
||||||
data-title="Tạm được"
|
|
||||||
name="user_post[rate]"
|
|
||||||
/>
|
|
||||||
<label
|
|
||||||
htmlFor="rating-input-review-0-2"
|
|
||||||
className="rating-star js-rating-star"
|
|
||||||
data-title="Tạm được"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
className="rating-input"
|
|
||||||
id="rating-input-review-0-1"
|
|
||||||
defaultValue={1}
|
|
||||||
data-title="Không thích"
|
|
||||||
name="user_post[rate]"
|
|
||||||
/>
|
|
||||||
<label
|
|
||||||
htmlFor="rating-input-review-0-1"
|
|
||||||
className="rating-star js-rating-star"
|
|
||||||
data-title="Không thích"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<span
|
|
||||||
id="js-star-tip"
|
|
||||||
className="star-tip bg-[#2b8ae0] text-white rounded-[3px] relative px-2 leading-[26px]"
|
|
||||||
>
|
|
||||||
{" "}
|
|
||||||
Quá tuyệt vời{" "}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div className="lg:grid grid-cols-2 gap-3">
|
|
||||||
<textarea
|
|
||||||
className="w-full block p-3 resize-none h-[100px] outline-none border border-[#DDDDDD] rounded-[12px]"
|
|
||||||
placeholder="Nhập đánh giá của bạn"
|
|
||||||
defaultValue={""}
|
|
||||||
/>
|
|
||||||
<div className="grid lg:grid-cols-2 gap-2">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
className="border border-[#DDDDDD] rounded-[8px] px-3"
|
|
||||||
placeholder="Họ tên*"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
type="tel"
|
|
||||||
className="border border-[#DDDDDD] rounded-[8px] px-3"
|
|
||||||
inputMode="numeric"
|
|
||||||
pattern="[0-9]{10,11}"
|
|
||||||
maxLength={11}
|
|
||||||
placeholder="Số điện thoại*"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
className="border border-[#DDDDDD] rounded-[8px] px-3"
|
|
||||||
placeholder="Email*"
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="bg-btn text-white rounded-[8px]"
|
|
||||||
aria-label="Đánh giá"
|
|
||||||
>
|
|
||||||
{" "}
|
|
||||||
Gửi đánh giá{" "}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<p className="red font-600"> </p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="text-14 leading-[18px] mt-4" id="">
|
|
||||||
<div className="last:border-0 border-b border-[#DDDDDD] py-5">
|
|
||||||
<div className="flex items-center gap-2 mb-2">
|
|
||||||
<b className="font-600 capitalize"> tên khách hàng </b>
|
|
||||||
<i className="bxr bxs-radio-circle text-[7px] text-[#6B7280]" />
|
|
||||||
<span className="text-[#6B7280]"> 11-11-2025, 11:11 </span>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-wrap gap-3">
|
|
||||||
<i className="star star-3 scale-[0.8] ml-[-7px]" />
|
|
||||||
<div className="w-[calc(100%-98px)]">
|
|
||||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Vel
|
|
||||||
illum deserunt similique cumque accusantium qui assumenda
|
|
||||||
quod. Saepe illum beatae aspernatur odit, voluptatum voluptate
|
|
||||||
maiores dolore expedita similique officia consequuntur?
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
101
src/components/product/detail/reviews/Form.jsx
Normal file
101
src/components/product/detail/reviews/Form.jsx
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useState, Fragment } from 'react';
|
||||||
|
|
||||||
|
export default function ReviewForm() {
|
||||||
|
const [rate, setRate] = useState(5);
|
||||||
|
const [rateTitle, setRateTitle] = useState('Quá tuyệt vời');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="flex items-center mb-4 gap-4">
|
||||||
|
<p className="m-0"> Chọn đánh giá của bạn </p>
|
||||||
|
|
||||||
|
<div className="rating-comment clearfix">
|
||||||
|
<CreateStar
|
||||||
|
rate={rate}
|
||||||
|
setRate={setRate}
|
||||||
|
setRateTitle={setRateTitle}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span className="star-tip bg-[#2b8ae0] text-white rounded-[3px] px-2 leading-[26px]">
|
||||||
|
{rateTitle}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="lg:grid grid-cols-2 gap-3">
|
||||||
|
<textarea
|
||||||
|
className="w-full block p-3 resize-none h-[100px] outline-none border border-[#DDDDDD] rounded-[12px]"
|
||||||
|
placeholder="Nhập đánh giá của bạn"
|
||||||
|
defaultValue={""}
|
||||||
|
/>
|
||||||
|
<div className="grid lg:grid-cols-2 gap-2">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="border border-[#DDDDDD] rounded-[8px] px-3"
|
||||||
|
placeholder="Họ tên*"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="tel"
|
||||||
|
className="border border-[#DDDDDD] rounded-[8px] px-3"
|
||||||
|
inputMode="numeric"
|
||||||
|
pattern="[0-9]{10,11}"
|
||||||
|
maxLength={11}
|
||||||
|
placeholder="Số điện thoại*"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="border border-[#DDDDDD] rounded-[8px] px-3"
|
||||||
|
placeholder="Email*"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="bg-btn text-white rounded-[8px]"
|
||||||
|
aria-label="Đánh giá"
|
||||||
|
>
|
||||||
|
Gửi đánh giá
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p className="red font-600"> </p>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function CreateStar({ rate, setRate, setRateTitle }) {
|
||||||
|
const stars = [
|
||||||
|
{ rate: 5, title: 'Quá tuyệt vời' },
|
||||||
|
{ rate: 4, title: 'Rất tốt' },
|
||||||
|
{ rate: 3, title: 'Bình thường' },
|
||||||
|
{ rate: 2, title: 'Tạm được' },
|
||||||
|
{ rate: 1, title: 'Không thích' },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{stars.map(({ rate: star, title }) => (
|
||||||
|
<Fragment key={star}>
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
className="rating-input"
|
||||||
|
name="user_post[rate]"
|
||||||
|
id={`rating-${star}`}
|
||||||
|
value={star}
|
||||||
|
checked={rate === star}
|
||||||
|
onChange={() => setRate(star)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<label
|
||||||
|
htmlFor={`rating-${star}`}
|
||||||
|
title={title}
|
||||||
|
className="rating-star js-rating-star"
|
||||||
|
onMouseEnter={() => setRateTitle(title)}
|
||||||
|
onClick={() => setRateTitle(title)}
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
38
src/components/product/detail/reviews/ReviewList.tsx
Normal file
38
src/components/product/detail/reviews/ReviewList.tsx
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
'use client';
|
||||||
|
import { useState } from "react";
|
||||||
|
import ReviewItem from "@/components/shared/ReviewItem";
|
||||||
|
|
||||||
|
const REVIEW_PER_PAGE = 5;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{reviewData &&
|
||||||
|
reviewData.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>
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
71
src/components/product/detail/reviews/StarPercent.tsx
Normal file
71
src/components/product/detail/reviews/StarPercent.tsx
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
export default function StarPercent({ item }: any) {
|
||||||
|
|
||||||
|
const listRate = item?.list_rate || [];
|
||||||
|
const { count, percent } = getStarPercent(listRate);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{[5, 4, 3, 2, 1].map((star) => {
|
||||||
|
const starRating = star as StarRating;
|
||||||
|
return (
|
||||||
|
<div key={star}
|
||||||
|
className="flex items-center justify-between gap-2 flex-wrap">
|
||||||
|
<p className="m-0 flex gap-[3px] w-[30px]">
|
||||||
|
|
||||||
|
<span>{star}</span>
|
||||||
|
<i className="bx bxs-star text-[#FBBF24] text-16" />
|
||||||
|
</p>
|
||||||
|
<div className="relative bg-[#E8ECF6] overflow-hidden rounded-[30px] h-3 w-[calc(100%_-_71px)]">
|
||||||
|
<i
|
||||||
|
className="max-w-[100%] bg-[#0678DB] absolute inset-0"
|
||||||
|
style={{ width: `${percent[starRating]}%` }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<p className="m-0 text-[#6B7280] w-[25px] text-right"> {count[starRating]} </p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
type StarRating = 1 | 2 | 3 | 4 | 5;
|
||||||
|
|
||||||
|
function getStarPercent(list_rate: any[] = []) {
|
||||||
|
const result: Record<StarRating, number> = {
|
||||||
|
1: 0,
|
||||||
|
2: 0,
|
||||||
|
3: 0,
|
||||||
|
4: 0,
|
||||||
|
5: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let totalCount = 0;
|
||||||
|
|
||||||
|
list_rate.forEach(item => {
|
||||||
|
totalCount += item.total;
|
||||||
|
result[item.rate as StarRating] = item.total;
|
||||||
|
});
|
||||||
|
|
||||||
|
const percent: Record<StarRating, number> = {
|
||||||
|
1: 0,
|
||||||
|
2: 0,
|
||||||
|
3: 0,
|
||||||
|
4: 0,
|
||||||
|
5: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (totalCount > 0) {
|
||||||
|
Object.keys(result).forEach(key => {
|
||||||
|
percent[key as unknown as StarRating] = Math.round(
|
||||||
|
(result[key as unknown as StarRating] / totalCount) * 100
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
count: result,
|
||||||
|
percent,
|
||||||
|
totalCount
|
||||||
|
};
|
||||||
|
}
|
||||||
45
src/components/product/detail/reviews/index.tsx
Normal file
45
src/components/product/detail/reviews/index.tsx
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
'use client';
|
||||||
|
import { useState } from "react";
|
||||||
|
import StarPercent from "./StarPercent";
|
||||||
|
import ReviewForm from "./Form"
|
||||||
|
import ReviewList from "./ReviewList";
|
||||||
|
|
||||||
|
export default function Review( {item} : any ) {
|
||||||
|
|
||||||
|
const [ show, setShow ] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className={`pd-rating-conatiner mb-9 ${show ? 'active' : ''}`} id="js-pd-rating">
|
||||||
|
<div className="flex flex-wrap justify-between gap-6">
|
||||||
|
<div className="w-[200px] text-center">
|
||||||
|
<p className="font-600 text-[40px] leading-[48px] mb-2"> {item.summary.avgRate}.0 </p>
|
||||||
|
<p className="my-2 text-[#6B7280]"> {item.summary.total} lượt đánh giá </p>
|
||||||
|
<i className={`star star-${item.summary.avgRate}`} />
|
||||||
|
|
||||||
|
<button
|
||||||
|
className="rating-btn block h-10 w-full text-white text-14 font-500 rounded-[30px] bg-btn uppercase mt-3"
|
||||||
|
type="button"
|
||||||
|
aria-label="đánh giá"
|
||||||
|
onClick={ () => setShow(show => !show) }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="w-[calc(100%_-_224px)] text-14 font-500 leading-[18px] flex flex-col gap-4">
|
||||||
|
<StarPercent item={item.summary} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="pd-rating-form mt-8 hidden">
|
||||||
|
<ReviewForm />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{item.list.length > 0 &&
|
||||||
|
<div className="text-14 leading-[18px] mt-4">
|
||||||
|
<ReviewList item={item.list}/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import parse from 'html-react-parser';
|
import parse from 'html-react-parser';
|
||||||
|
|
||||||
export default function ProductSpec( {item} : any ) {
|
export default function ProductSpec( {item} : any ) {
|
||||||
console.log(item)
|
|
||||||
return (
|
return (
|
||||||
<div className="pd-box-group bg-white mb-6 px-4 py-6 rounded-[24px]">
|
<div className="pd-box-group bg-white mb-6 px-4 py-6 rounded-[24px]">
|
||||||
<p className="group-title border-b border-[#D0D8E3] leading-[31px] font-600 text-24 mb-4 pb-4">
|
<p className="group-title border-b border-[#D0D8E3] leading-[31px] font-600 text-24 mb-4 pb-4">
|
||||||
@@ -11,14 +11,15 @@ export default function ProductSpec( {item} : any ) {
|
|||||||
<div className="pd-spec-group">
|
<div className="pd-spec-group">
|
||||||
{parse(item)}
|
{parse(item)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href="#fancybox-spec"
|
href="#fancybox-spec"
|
||||||
data-fancybox=""
|
data-fancybox=""
|
||||||
className="table m-auto mt-4 text-white leading-10 uppercase rounded-[40px] bg-btn font-500 text-16 px-6"
|
className="table m-auto mt-4 text-white leading-10 uppercase rounded-[40px] bg-btn font-500 text-16 px-6"
|
||||||
>
|
>
|
||||||
|
|
||||||
Xem tất cả thông số
|
Xem tất cả thông số
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className="pd-spec-group p-3"
|
className="pd-spec-group p-3"
|
||||||
id="fancybox-spec"
|
id="fancybox-spec"
|
||||||
|
|||||||
78
src/components/shared/CommentItem.tsx
Normal file
78
src/components/shared/CommentItem.tsx
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
'use client';
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { formatDate } from "@/lib/utils";
|
||||||
|
import parse from 'html-react-parser';
|
||||||
|
import CommentReply from "@/components/shared/CommentReply";
|
||||||
|
import Form from "../product/detail/comments/Form";
|
||||||
|
|
||||||
|
export default function CommentItem({ item }: any) {
|
||||||
|
const [activeFormId, setActiveFormId] = useState<number | null>(null);
|
||||||
|
|
||||||
|
const handleReply = () => {
|
||||||
|
setActiveFormId(prev =>
|
||||||
|
prev === item.id ? null : item.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('aaaaaaaaaa', item)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{ item.is_user_admin == 1 || item.approved == 1 &&
|
||||||
|
<div className="first:border-t first:mt-4 first:pt-4 border-[#D1D5DB] mb-5 flex gap-3 text-14 leading-[18px]">
|
||||||
|
<div className="w-10 h-10 rounded-full bg-[#9CA3AF] leading-10 text-center uppercase text-white font-600 overflow-hidden">
|
||||||
|
{ item.is_user_admin == 1
|
||||||
|
? parse(`<img src="images/avatar-admin.png" className="block w-full h-full"/>`)
|
||||||
|
: parse(`<span> ${item.user_name.substring(0,1)} </span>`)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="w-[calc(100%_-_52px)]">
|
||||||
|
<div className="flex items-center gap-2 mb-1">
|
||||||
|
<b className="capitalize"> {item.user_name.split(' -')[0]} </b>
|
||||||
|
<i className="bxr bxs-radio-circle text-[7px] text-[#6B7280]" />
|
||||||
|
<span className="text-[#6B7280]"> {formatDate(item.post_time)} </span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<i className={`star star-${item.rate}`} />
|
||||||
|
|
||||||
|
<div className="my-2"> {item.content} </div>
|
||||||
|
|
||||||
|
<div className="flex gap-2 leading-[30px]">
|
||||||
|
<button type="button" aria-label="actions"
|
||||||
|
className="group flex items-center gap-[6px] border border-[#D1D5DB] px-3 rounded-[20px] hover:border-[#0678DB] hover:text-[#0678DB]"
|
||||||
|
>
|
||||||
|
<i className="group-hover:text-[#0678DB] text-[#928FA8] bxr bx-heart" />
|
||||||
|
{item.people_like_count}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button type="button" aria-label="actions"
|
||||||
|
className="group flex items-center gap-[6px] border border-[#D1D5DB] px-3 rounded-[20px] hover:border-[#0678DB] hover:text-[#0678DB]"
|
||||||
|
onClick={handleReply}
|
||||||
|
>
|
||||||
|
<i className="group-hover:text-[#0678DB] text-[#928FA8] bxr bx-reply-stroke" />
|
||||||
|
Trả lời
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{activeFormId === item.id && (
|
||||||
|
<div className="my-2 border border-[#DDDDDD] rounded-[12px] overflow-hidden js-comment-form" id={`js-comment-form-${item.id}`}>
|
||||||
|
<Form />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
|
||||||
|
{ item.new_replies.length > 0 &&
|
||||||
|
<div className="bg-[#F3F4F6] rounded-[12px] overflow-hidden mt-3">
|
||||||
|
{
|
||||||
|
item.new_replies.map( (reply:any) =>
|
||||||
|
<CommentReply item={reply} key={reply.id} />)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
28
src/components/shared/CommentReply.tsx
Normal file
28
src/components/shared/CommentReply.tsx
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import { formatDate } from "@/lib/utils";
|
||||||
|
import parse from 'html-react-parser';
|
||||||
|
|
||||||
|
export default function CommentReply({ item }: any) {
|
||||||
|
return (
|
||||||
|
<div className="first:border-0 flex items-start gap-3 p-3 border-t border-[#D1D5DB]">
|
||||||
|
<div className="w-10 h-10 rounded-full bg-[#9CA3AF] leading-10 text-center uppercase text-white font-600 overflow-hidden">
|
||||||
|
{ item.is_user_admin == 1
|
||||||
|
? parse(`<img src="images/avatar-admin.png" className="block w-full h-full"/>`)
|
||||||
|
: parse(`<span> ${item.user_name.substring(0,1)} </span>`)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="w-[calc(100%_-_52px)]">
|
||||||
|
<div className="flex items-center gap-2 mb-1">
|
||||||
|
{ item.is_user_admin == 1
|
||||||
|
? parse(`<span className="bg-[linear-gradient(70.1deg,#75798B_62.94%,#ADB5CD_100%)] text-white px-[6px] leading-[18px] rounded-[20px] font-500 text-10">Quản trị viên</span>`)
|
||||||
|
: parse(`<b className="capitalize"> ${item.user_name.split(' -')[0]} </b>`)
|
||||||
|
}
|
||||||
|
<i className="bxr bxs-radio-circle text-[7px] text-[#6B7280]" />
|
||||||
|
<span className="text-[#6B7280]"> {formatDate(item.post_time)} </span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="my-2" style={{ whiteSpace: "pre-line" }}> {item.content} </div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
21
src/components/shared/ReviewItem.tsx
Normal file
21
src/components/shared/ReviewItem.tsx
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { formatDate } from "@/lib/utils";
|
||||||
|
|
||||||
|
export default function ReviewItem({ item }: any) {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="last:border-0 border-b border-[#DDDDDD] py-5">
|
||||||
|
<div className="flex items-center gap-2 mb-2">
|
||||||
|
<b className="font-600 capitalize">
|
||||||
|
{item.user_name.split(' -')[0]}
|
||||||
|
</b>
|
||||||
|
<i className="bxr bxs-radio-circle text-[7px] text-[#6B7280]" />
|
||||||
|
<span className="text-[#6B7280]"> {formatDate(item.post_time)} </span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-wrap gap-3">
|
||||||
|
<i className={`star star-${item.rate} scale-[0.8] ml-[-7px]`} />
|
||||||
|
<div className="w-[calc(100%-98px)]"> {item.content} </div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
219
src/data/comments/index.tsx
Normal file
219
src/data/comments/index.tsx
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
export const CommentData = {
|
||||||
|
"summary": {
|
||||||
|
"list_rate": [],
|
||||||
|
"avgRate": 0,
|
||||||
|
"total": 0,
|
||||||
|
},
|
||||||
|
"list": [
|
||||||
|
{
|
||||||
|
"id": "10187",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "5631",
|
||||||
|
"people_like_count": "2",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "Test - S\u0110T: 0988776521",
|
||||||
|
"rate": "5",
|
||||||
|
"title": "VGA ASUS ROG ASTRAL LC GEFORCE RTX 5090 32GB GDDR7 OC EDITION (512-bit, HDMI+DP, 1x16-pin)",
|
||||||
|
"content": "sp t\u1ed1t ....................................",
|
||||||
|
"files": [],
|
||||||
|
"approved": "1",
|
||||||
|
"post_time": "1767776160",
|
||||||
|
"counter": 1,
|
||||||
|
"new_replies": [
|
||||||
|
{
|
||||||
|
"id": "10186",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "2106",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "1",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "Admin",
|
||||||
|
"rate": "5",
|
||||||
|
"title": "\u1ed4 c\u1ee9ng SSD Samsung PM9A1 512GB M.2 NVMe PCIe Gen 4 x4 (\u0110\u1ecdc 6900MB\/s - Ghi 5000MB\/s)",
|
||||||
|
"content": "SSD Samsung PM9A1 512GB c\u00f2n kh\u00f4ng \u1ea1, cho em xin gi\u00e1 v\u1edbi \u1ea1.",
|
||||||
|
"files": [],
|
||||||
|
"approved": "0",
|
||||||
|
"post_time": "1767666181",
|
||||||
|
"counter": 2,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "10185",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "6669",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "VU THANH CHUNG - S\u0110T: 0975064835",
|
||||||
|
"rate": "5",
|
||||||
|
"title": "HHPC CORE i7 14700KF | 64GB | NVIDIA RTX 5070 Ti 16G",
|
||||||
|
"content": "Qu\u00e1 l\u00e0 r\u1ebb",
|
||||||
|
"files": [],
|
||||||
|
"approved": "0",
|
||||||
|
"post_time": "1766984906",
|
||||||
|
"counter": 3,
|
||||||
|
"new_replies": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "10186",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "2106",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "1",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "Quang Phuc",
|
||||||
|
"rate": "5",
|
||||||
|
"title": "\u1ed4 c\u1ee9ng SSD Samsung PM9A1 512GB M.2 NVMe PCIe Gen 4 x4 (\u0110\u1ecdc 6900MB\/s - Ghi 5000MB\/s)",
|
||||||
|
"content": "SSD Samsung PM9A1 512GB c\u00f2n kh\u00f4ng \u1ea1, cho em xin gi\u00e1 v\u1edbi \u1ea1.",
|
||||||
|
"files": [],
|
||||||
|
"approved": "1",
|
||||||
|
"post_time": "1767666181",
|
||||||
|
"counter": 2,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "10185",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "6669",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "VU THANH CHUNG - S\u0110T: 0975064835",
|
||||||
|
"rate": "5",
|
||||||
|
"title": "HHPC CORE i7 14700KF | 64GB | NVIDIA RTX 5070 Ti 16G",
|
||||||
|
"content": "Qu\u00e1 l\u00e0 r\u1ebb",
|
||||||
|
"files": [],
|
||||||
|
"approved": "1",
|
||||||
|
"post_time": "1766984906",
|
||||||
|
"counter": 3,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "10184",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "5053",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "L\u00ea Tr\u01b0\u01a1ng - S\u0110T: 0865660958",
|
||||||
|
"rate": "5",
|
||||||
|
"title": "HH SERVER - DUAL XEON 2696 V4 | 128GB | NVIDIA RTX 3060 12G",
|
||||||
|
"content": "Video To Future mong mu\u1ed1n h\u1ee3p t\u00e1c v\u1edbi qu\u00fd doanhh nghi\u1ec7p \u0111\u1ec3 ph\u00e2n ph\u1ed1i ph\u1ea7n m\u1ec1m g\u1eedi nh\u1eefng kho\u1ea3nh kh\u1eafc \u0111\u1eb9p v\u00e0 y\u00eau th\u01b0\u01a1ng \u0111\u1ebfn t\u01b0\u01a1ng lai. M\u00ecnh mu\u1ed1n xin s\u1ed1 fone c\u1ee7a ph\u00f2ng kinh doanh \u0111\u1ec3 g\u1eb7p tr\u1ef1c ti\u1ebfp trao \u0111\u1ed5i. Tr\u00e2n tr\u1ecdng c\u1ea3m \u01a1n!\n",
|
||||||
|
"files": [],
|
||||||
|
"approved": "1",
|
||||||
|
"post_time": "1765177283",
|
||||||
|
"counter": 4,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "10183",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "6500",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "Phan Phu - S\u0110T: 0816550160",
|
||||||
|
"rate": "5",
|
||||||
|
"title": "HH SERVER - DUAL XEON E5 2676 V3 | 64G | NVIDIA GT 730 2GB - H\u00e0ng l\u01b0\u1edbt",
|
||||||
|
"content": "B\u1ed9 n\u00e0y b\u00e1n nguy\u00ean v\u1eady hay c\u00f3 \u0111\u1ed5i case kh\u00e1c \u0111\u01b0\u1ee3c kh\u00f4ng \u1ea1. \u1ede c\u1ea7n th\u01a1 giao h\u00e0ng m\u1ea5y ng\u00e0y v\u1eady b\u1ea1n",
|
||||||
|
"files": [],
|
||||||
|
"approved": "1",
|
||||||
|
"post_time": "1764308881",
|
||||||
|
"counter": 5,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "10182",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "917",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "L\u00ea Th\u01b0\u1edbng - S\u0110T: 0349711051",
|
||||||
|
"rate": "5",
|
||||||
|
"title": "B\u1ed9 Ph\u00e1t Wifi ASUS RT-AC68U (Chu\u1ea9n Doanh Nghi\u1ec7p)",
|
||||||
|
"content": "Wifi r\u1ea5t kh\u1ecfe, ph\u00e1t xa, 40 ng\u01b0\u1eddi d\u00f9ng c\u00f9ng l\u00fac v\u1eabn ok.",
|
||||||
|
"files": [],
|
||||||
|
"approved": "0",
|
||||||
|
"post_time": "1763457018",
|
||||||
|
"counter": 6,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8768",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "6669",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "VU THANH CHUNG - S\u0110T: 0988358888",
|
||||||
|
"rate": "5",
|
||||||
|
"title": "HHPC CORE i7 14700KF | 64GB | NVIDIA RTX 5070 Ti 16G",
|
||||||
|
"content": "Qu\u00e1 l\u00e0 r\u1ebb lu\u00f4n ",
|
||||||
|
"files": [],
|
||||||
|
"approved": "0",
|
||||||
|
"post_time": "1766984975",
|
||||||
|
"counter": 1,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8767",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "5981",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "NMinh - S\u1ed1 \u0111t : 0367357631",
|
||||||
|
"rate": "5",
|
||||||
|
"title": "\u0110\u00e1nh gi\u00e1 s\u1ea3n ph\u1ea9m VGA SAPPHIRE PULSE AMD RADEON RX 7800 XT 16GB GDDR6 (256-bit, HDMI+DP, 2x 8-pin)",
|
||||||
|
"content": "Ch\u1ea1y \u00eam",
|
||||||
|
"files": [],
|
||||||
|
"approved": "1",
|
||||||
|
"post_time": "1761374084",
|
||||||
|
"counter": 2,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8762",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "6434",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "Hurasoft \u0110\u1ee9c - S\u0110T: 0987876213",
|
||||||
|
"rate": "4",
|
||||||
|
"title": "HuraSoft - S\u1ea3n ph\u1ea9m test (Kh\u00f4ng x\u00f3a)",
|
||||||
|
"content": "account test rating",
|
||||||
|
"files": [],
|
||||||
|
"approved": "1",
|
||||||
|
"post_time": "1761027763",
|
||||||
|
"counter": 3,
|
||||||
|
"new_replies": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
416
src/data/reviews/index.tsx
Normal file
416
src/data/reviews/index.tsx
Normal file
@@ -0,0 +1,416 @@
|
|||||||
|
export const ReviewData = {
|
||||||
|
"summary": {
|
||||||
|
"list_rate": [
|
||||||
|
{
|
||||||
|
"rate": 4,
|
||||||
|
"total": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rate": 2,
|
||||||
|
"total": 1
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"rate": 3,
|
||||||
|
"total": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"avgRate": 3,
|
||||||
|
"total": 20,
|
||||||
|
},
|
||||||
|
"list": [
|
||||||
|
{
|
||||||
|
"id": "8768",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "6669",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "VU THANH CHUNG - S\u0110T: 0988358888",
|
||||||
|
"rate": "5",
|
||||||
|
"title": "HHPC CORE i7 14700KF | 64GB | NVIDIA RTX 5070 Ti 16G",
|
||||||
|
"content": "Qu\u00e1 l\u00e0 r\u1ebb lu\u00f4n ",
|
||||||
|
"files": [],
|
||||||
|
"approved": "0",
|
||||||
|
"post_time": "1766984975",
|
||||||
|
"counter": 1,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8767",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "5981",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "NMinh - S\u1ed1 \u0111t : 0367357631",
|
||||||
|
"rate": "5",
|
||||||
|
"title": "\u0110\u00e1nh gi\u00e1 s\u1ea3n ph\u1ea9m VGA SAPPHIRE PULSE AMD RADEON RX 7800 XT 16GB GDDR6 (256-bit, HDMI+DP, 2x 8-pin)",
|
||||||
|
"content": "Ch\u1ea1y \u00eam",
|
||||||
|
"files": [],
|
||||||
|
"approved": "0",
|
||||||
|
"post_time": "1761374084",
|
||||||
|
"counter": 2,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8762",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "6434",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "Hurasoft \u0110\u1ee9c - S\u0110T: 0987876213",
|
||||||
|
"rate": "4",
|
||||||
|
"title": "HuraSoft - S\u1ea3n ph\u1ea9m test (Kh\u00f4ng x\u00f3a)",
|
||||||
|
"content": "account test rating",
|
||||||
|
"files": [],
|
||||||
|
"approved": "1",
|
||||||
|
"post_time": "1761027763",
|
||||||
|
"counter": 3,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8761",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "6434",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "1",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "Hurasoft \u0110\u1ee9c",
|
||||||
|
"rate": "3",
|
||||||
|
"title": "HuraSoft - S\u1ea3n ph\u1ea9m test (Kh\u00f4ng x\u00f3a)",
|
||||||
|
"content": "test form",
|
||||||
|
"files": [],
|
||||||
|
"approved": "1",
|
||||||
|
"post_time": "1760337751",
|
||||||
|
"counter": 4,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8760",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "6434",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "1",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "hura test - S\u0110T: 0987654321",
|
||||||
|
"rate": "2",
|
||||||
|
"title": "HuraSoft - S\u1ea3n ph\u1ea9m test (Kh\u00f4ng x\u00f3a)",
|
||||||
|
"content": "test review 2025 ",
|
||||||
|
"files": [],
|
||||||
|
"approved": "1",
|
||||||
|
"post_time": "1760330892",
|
||||||
|
"counter": 5,
|
||||||
|
"new_replies": [
|
||||||
|
{
|
||||||
|
"id": 742,
|
||||||
|
"comment_id": 8760,
|
||||||
|
"user_avatar": "0",
|
||||||
|
"user_name": "Hurasoft \u0110\u1ee9c",
|
||||||
|
"is_user_admin": 1,
|
||||||
|
"people_like_count": 0,
|
||||||
|
"approved": 1,
|
||||||
|
"people_dislike_count": 0,
|
||||||
|
"content": "admin test",
|
||||||
|
"post_time": 1760331038
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8757",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "6270",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "Ch\u1ecbu - S\u1ed1 \u0111t : 0938553437",
|
||||||
|
"rate": "5",
|
||||||
|
"title": "\u0110\u00e1nh gi\u00e1 s\u1ea3n ph\u1ea9m Fan Xigmatek Infinity Pro 2 RGB Reverse",
|
||||||
|
"content": "5 sao",
|
||||||
|
"files": [],
|
||||||
|
"approved": "0",
|
||||||
|
"post_time": "1759639059",
|
||||||
|
"counter": 6,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8756",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "4751",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "\u0110\u1ea1i Nguy\u1ec5n - S\u1ed1 \u0111t : 0866657510",
|
||||||
|
"rate": "1",
|
||||||
|
"title": "\u0110\u00e1nh gi\u00e1 s\u1ea3n ph\u1ea9m \u1ed4 c\u1ee9ng SSD SK Hynix PC801 1TB NVMe PCIe Gen4.0 - RW 7000MB\/s",
|
||||||
|
"content": "con n\u00e0y c\u00e0i win ch\u1ea1y 6 th\u00e1ng th\u00ec t\u1ed1c v\u1ec1 2000",
|
||||||
|
"files": [],
|
||||||
|
"approved": "0",
|
||||||
|
"post_time": "1757729354",
|
||||||
|
"counter": 7,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8755",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "4620",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "Thien Than - S\u1ed1 \u0111t : 0355001407",
|
||||||
|
"rate": "5",
|
||||||
|
"title": "\u0110\u00e1nh gi\u00e1 s\u1ea3n ph\u1ea9m Ngu\u1ed3n MSI MAG A850GL PCIE5 ATX 3.0 850W (80 Plus Gold\/ Full Modular)",
|
||||||
|
"content": "Ngu\u1ed3n qu\u00e1 \u0111\u00e1ng ti\u1ec1n trong ph\u00e2n kh\u00fac \u0111\u1ea7y \u0111\u1ee7 c\u1ed5ng k\u1ebft n\u1ed1i c\u1ea7n cho linh ki\u1ec7n hi\u1ec7n nay",
|
||||||
|
"files": [],
|
||||||
|
"approved": "0",
|
||||||
|
"post_time": "1755744191",
|
||||||
|
"counter": 8,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8754",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "5356",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "Huy \u0110inh - S\u1ed1 \u0111t : 0966930673",
|
||||||
|
"rate": "5",
|
||||||
|
"title": "\u0110\u00e1nh gi\u00e1 s\u1ea3n ph\u1ea9m Mainboard MSI MAG X870 TOMAHAWK WIFI (AMD X870, Socket AM5, ATX, 4 khe RAM DDR5)",
|
||||||
|
"content": "Msi si\u00eau \u0111\u1ec9nh",
|
||||||
|
"files": [],
|
||||||
|
"approved": "0",
|
||||||
|
"post_time": "1754999244",
|
||||||
|
"counter": 9,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8753",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "5475",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "Xxxxx - S\u1ed1 \u0111t : 0987767896",
|
||||||
|
"rate": "5",
|
||||||
|
"title": "\u0110\u00e1nh gi\u00e1 s\u1ea3n ph\u1ea9m HHPC ULTRA 7 265K | 32GB DDR5 | NVIDIA RTX 3060 12GB",
|
||||||
|
"content": "Xxxxxxx",
|
||||||
|
"files": [],
|
||||||
|
"approved": "0",
|
||||||
|
"post_time": "1753883033",
|
||||||
|
"counter": 10,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8752",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "5562",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "kghasnh \u00e1d - S\u1ed1 \u0111t : 0936542873",
|
||||||
|
"rate": "1",
|
||||||
|
"title": "\u0110\u00e1nh gi\u00e1 s\u1ea3n ph\u1ea9m HHPC ALPHARD M CORE i5 14600KF | 32G | NVIDIA RTX 4070 12G",
|
||||||
|
"content": "K\u00c9M! qu\u00e1 k\u00e9mmmmmmmmmmmmmmmmmmmmmmmm",
|
||||||
|
"files": [],
|
||||||
|
"approved": "0",
|
||||||
|
"post_time": "1752472074",
|
||||||
|
"counter": 11,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8751",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "1356",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "Tr\u1ecdng Ngh\u0129a - S\u1ed1 \u0111t : 0963544681",
|
||||||
|
"rate": "1",
|
||||||
|
"title": "\u0110\u00e1nh gi\u00e1 s\u1ea3n ph\u1ea9m Ngu\u1ed3n Super Flower Leadex Platinum 2000W (80 Plus Platinum\/Full Modular)",
|
||||||
|
"content": "https:\/\/hoanghapc.vn\/nguon-may-tinh-super-flower-leadex-platinum-2000w-sale\n\n10.990.000 \u0111 } 5.990.000 \u0111",
|
||||||
|
"files": [],
|
||||||
|
"approved": "0",
|
||||||
|
"post_time": "1749750914",
|
||||||
|
"counter": 12,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8750",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "4670",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "\u0110inh L\u1ed9c - S\u1ed1 \u0111t : 0835110115",
|
||||||
|
"rate": "5",
|
||||||
|
"title": "\u0110\u00e1nh gi\u00e1 s\u1ea3n ph\u1ea9m RAM DDR5 CORSAIR VENGEANCE RGB 64GB 6400MHz (2x32GB) C32 BLACK",
|
||||||
|
"content": "Xem l\u1ea1i c\u00e1ch b\u00e1n h\u00e0ng",
|
||||||
|
"files": [],
|
||||||
|
"approved": "0",
|
||||||
|
"post_time": "1747476672",
|
||||||
|
"counter": 13,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8749",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "4670",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "\u0110inh L\u1ed9c - S\u1ed1 \u0111t : 0835110115",
|
||||||
|
"rate": "1",
|
||||||
|
"title": "\u0110\u00e1nh gi\u00e1 s\u1ea3n ph\u1ea9m RAM DDR5 CORSAIR VENGEANCE RGB 64GB 6400MHz (2x32GB) C32 BLACK",
|
||||||
|
"content": "B\u00e1n h\u00e0ng th\u00ec treo \u0111\u1ea7u d\u00ea b\u00e1n th\u1ecbt ch\u00f3, b\u00e1n h\u00e0ng kh\u00f4ng \u0111\u00fang h\u00e0ng, mua c\u00e1i n\u00e0y giao c\u00e1i kia, qu\u1ea3n l\u00fd b\u00e1n h\u00e0ng b\u00e0n thua nh\u00e2n vi\u00ean, xem l\u1ea1i c\u00e1i qu\u1ea3n l\u00fd c\u1ee7a m\u00ecnh \\. B\u00ecnh",
|
||||||
|
"files": [],
|
||||||
|
"approved": "0",
|
||||||
|
"post_time": "1747476567",
|
||||||
|
"counter": 14,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8748",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "5355",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "Thinh - S\u1ed1 \u0111t : 0964373778",
|
||||||
|
"rate": "5",
|
||||||
|
"title": "\u0110\u00e1nh gi\u00e1 s\u1ea3n ph\u1ea9m Mainboard MSI MPG X870E CARBON WIFI (AMD X870E, Socket AM5, ATX, 4 khe RAM DDR5)",
|
||||||
|
"content": "Thi\u1ebft k\u1ebf \u0111\u1eb9p, RGB tr\u00ean VRM v\u00e0 SSD slot b\u1eaft m\u1eaft. VRM cung c\u1ea5p \u0111i\u1ec7n kh\u1ee7ng. T\u00ednh n\u0103ng tooless khi c\u00e0i \u0111\u1eb7t SSD v\u00e0 card \u0111\u1ed3 h\u1ecda r\u1ea5t ti\u1ec7n l\u1ee3i. Back IO c\u00f3 r\u1ea5t nhi\u1ec1u c\u1ed5ng k\u1ebft n\u1ed1i. Bios \u0111\u01b0\u1ee3c thi\u1ebft k\u1ebf l\u1ea1i r\u1ea5t \u0111\u1eb9p v\u00e0 thu\u1eadn l\u1ee3i cho ng\u01b0\u1eddi d\u00f9ng. T\u00f3m l\u1ea1i l\u00e0 1 chi\u1ebfc x870E r\u1ea5t \u0111\u00e1ng \u0111\u1ec3 mua trong t\u1ea7m gi\u00e1.",
|
||||||
|
"files": [],
|
||||||
|
"approved": "0",
|
||||||
|
"post_time": "1747296869",
|
||||||
|
"counter": 15,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8747",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "4514",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "H\u00e0ng \u0110\u1ec3u - S\u1ed1 \u0111t : 0987654321",
|
||||||
|
"rate": "1",
|
||||||
|
"title": "\u0110\u00e1nh gi\u00e1 s\u1ea3n ph\u1ea9m AI-Deep Learning THREADRIPPER PRO 5975WX | 256GB | Dual RTX 4090 24G",
|
||||||
|
"content": "Pc \u0110\u1ec3u ",
|
||||||
|
"files": [],
|
||||||
|
"approved": "0",
|
||||||
|
"post_time": "1746253902",
|
||||||
|
"counter": 16,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8746",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "4620",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "Danh Th\u00e0nh - S\u1ed1 \u0111t : 0933444745",
|
||||||
|
"rate": "5",
|
||||||
|
"title": "\u0110\u00e1nh gi\u00e1 s\u1ea3n ph\u1ea9m Ngu\u1ed3n MSI MAG A850GL PCIE5 ATX 3.0 850W (80 Plus Gold\/ Full Modular)",
|
||||||
|
"content": "Ngu\u1ed3n t\u1ed1t nh\u1ea5t trong t\u1ea7m gi\u00e1 3tr",
|
||||||
|
"files": [],
|
||||||
|
"approved": "0",
|
||||||
|
"post_time": "1743072855",
|
||||||
|
"counter": 17,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8745",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "4771",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "Nguy\u1ec5n V\u0103n Th\u1ecbnh - S\u1ed1 \u0111t : 0862130910",
|
||||||
|
"rate": "1",
|
||||||
|
"title": "\u0110\u00e1nh gi\u00e1 s\u1ea3n ph\u1ea9m HHPC CORE i9 14900K | 64G DDR5 | NVIDIA RTX 4090 24G",
|
||||||
|
"content": "Kh\u00f4ng c\u1ea7n",
|
||||||
|
"files": [],
|
||||||
|
"approved": "0",
|
||||||
|
"post_time": "1740978395",
|
||||||
|
"counter": 18,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8744",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "5377",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "b\u1ea3o trung - S\u1ed1 \u0111t : 0326059410",
|
||||||
|
"rate": "5",
|
||||||
|
"title": "\u0110\u00e1nh gi\u00e1 s\u1ea3n ph\u1ea9m Mainboard MSI MAG Z890 TOMAHAWK WIFI (Intel Z890, Socket 1851, ATX, 4 khe RAM DDR5)",
|
||||||
|
"content": "S\u1ea3n ph\u1ea9m tuy\u1ec7t v\u1eddi c\u00e2n t\u1ed1t core ultra 9",
|
||||||
|
"files": [],
|
||||||
|
"approved": "0",
|
||||||
|
"post_time": "1740898627",
|
||||||
|
"counter": 19,
|
||||||
|
"new_replies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8743",
|
||||||
|
"item_type": "product",
|
||||||
|
"item_id": "5421",
|
||||||
|
"people_like_count": "0",
|
||||||
|
"people_dislike_count": "0",
|
||||||
|
"reply_count": "0",
|
||||||
|
"is_user_admin": "0",
|
||||||
|
"user_avatar": "",
|
||||||
|
"user_name": "Thi\u00ean Long - S\u1ed1 \u0111t : 0931287086",
|
||||||
|
"rate": "5",
|
||||||
|
"title": "\u0110\u00e1nh gi\u00e1 s\u1ea3n ph\u1ea9m HHPC RYZEN 9 9950X | 64G DDR5 | NVIDIA RTX 4070 Ti SUPER 16G",
|
||||||
|
"content": "C\u1ea5u h\u00ecnh \u0111\u00e1ng \u0111\u1ea7u t\u01b0 cho nh\u1eefng ai c\u1ea7n m\u1ed9t c\u1ed7 m\u00e1y m\u1ea1nh m\u1ebd \u0111\u1ec3 l\u00e0m vi\u1ec7c.",
|
||||||
|
"files": [],
|
||||||
|
"approved": "0",
|
||||||
|
"post_time": "1738828475",
|
||||||
|
"counter": 20,
|
||||||
|
"new_replies": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -32,7 +32,8 @@ export function resolveProductPage(slug: string): ProductResult | null {
|
|||||||
const data = {
|
const data = {
|
||||||
...product,
|
...product,
|
||||||
productDescription : productDetail.productDescription,
|
productDescription : productDetail.productDescription,
|
||||||
productSpec : productDetail.productSpec
|
productSpec : productDetail.productSpec,
|
||||||
|
related : productDetail.related
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -71,6 +71,18 @@ export function formatArticleTime(article_time: string) {
|
|||||||
return `${day}/${month}/${year}`;
|
return `${day}/${month}/${year}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function formatDate(a:any){
|
||||||
|
let dateObj = new Date(parseInt(a)*1000);
|
||||||
|
|
||||||
|
let year = dateObj.getFullYear();
|
||||||
|
let month = ((dateObj.getMonth()+1) <= 9) ? '0' + (dateObj.getMonth()+1) : dateObj.getMonth()+1;
|
||||||
|
let date = (dateObj.getDate() < 10) ? '0' + dateObj.getDate() : dateObj.getDate();
|
||||||
|
let hour = (dateObj.getHours() < 10) ? '0' + dateObj.getHours() : dateObj.getHours();
|
||||||
|
let min = (dateObj.getMinutes() < 10) ? '0' + dateObj.getMinutes() : dateObj.getMinutes();
|
||||||
|
let time = `${date}/${month}/${year}, ${hour}:${min}`;
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
export function normalizeKey(str: string) {
|
export function normalizeKey(str: string) {
|
||||||
return str
|
return str
|
||||||
|
|||||||
Reference in New Issue
Block a user