update 31/01
This commit is contained in:
25
package-lock.json
generated
25
package-lock.json
generated
@@ -14,6 +14,7 @@
|
|||||||
"photoswipe": "^5.4.4",
|
"photoswipe": "^5.4.4",
|
||||||
"react": "19.2.3",
|
"react": "19.2.3",
|
||||||
"react-dom": "19.2.3",
|
"react-dom": "19.2.3",
|
||||||
|
"sonner": "^2.0.7",
|
||||||
"swiper": "^12.0.3"
|
"swiper": "^12.0.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -5628,6 +5629,15 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/sonner": {
|
||||||
|
"version": "2.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/sonner/-/sonner-2.0.7.tgz",
|
||||||
|
"integrity": "sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc",
|
||||||
|
"react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/source-map-js": {
|
"node_modules/source-map-js": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||||
@@ -6346,6 +6356,21 @@
|
|||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"zod": "^3.25.0 || ^4.0.0"
|
"zod": "^3.25.0 || ^4.0.0"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-win32-x64-msvc": {
|
||||||
|
"version": "16.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.1.0.tgz",
|
||||||
|
"integrity": "sha512-Tr0j94MphimCCks+1rtYPzQFK+faJuhHWCegU9S9gDlgyOk8Y3kPmO64UcjyzZAlligeBtYZ/2bEyrKq0d2wqQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
"photoswipe": "^5.4.4",
|
"photoswipe": "^5.4.4",
|
||||||
"react": "19.2.3",
|
"react": "19.2.3",
|
||||||
"react-dom": "19.2.3",
|
"react-dom": "19.2.3",
|
||||||
|
"sonner": "^2.0.7",
|
||||||
"swiper": "^12.0.3"
|
"swiper": "^12.0.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
|
import { Toaster } from 'sonner';
|
||||||
import Header from "@/components/other/header";
|
import Header from "@/components/other/header";
|
||||||
import Footer from "@/components/other/footer";
|
import Footer from "@/components/other/footer";
|
||||||
import TooltipProvider from "@/components/providers/TooltipProvider";
|
import TooltipProvider from "@/components/providers/TooltipProvider";
|
||||||
@@ -24,8 +25,14 @@ export default function RootLayout({
|
|||||||
{children}
|
{children}
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
|
|
||||||
|
|
||||||
<Footer />
|
<Footer />
|
||||||
|
|
||||||
|
<Toaster
|
||||||
|
position="top-right"
|
||||||
|
closeButton
|
||||||
|
richColors
|
||||||
|
/>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
export default function Buttons() {
|
'use client';
|
||||||
|
import { useCart } from '@/hooks/useCart';
|
||||||
|
|
||||||
|
export default function Buttons( {item}:any ) {
|
||||||
|
const { addToCart } = useCart();
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="pd-button-group my-5 gap-2 grid grid-cols-2 text-18 font-500">
|
<div className="pd-button-group my-5 gap-2 grid grid-cols-2 text-18 font-500">
|
||||||
@@ -6,26 +10,27 @@ export default function Buttons() {
|
|||||||
type="button"
|
type="button"
|
||||||
className="col-span-2 uppercase rounded-[12px] text-white h-[52px] border border-[#FFD83E] bg-[linear-gradient(148.21deg,#FFD83E_-14.02%,#FF4E2A_70.14%)]"
|
className="col-span-2 uppercase rounded-[12px] text-white h-[52px] border border-[#FFD83E] bg-[linear-gradient(148.21deg,#FFD83E_-14.02%,#FF4E2A_70.14%)]"
|
||||||
aria-label="Mua sản phẩm"
|
aria-label="Mua sản phẩm"
|
||||||
|
onClick={() => addToCart(item, 1, '/cart')}
|
||||||
>
|
>
|
||||||
{" "}
|
Mua ngay
|
||||||
Mua ngay{" "}
|
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="col-span-1 flex items-center justify-center uppercase rounded-[12px] text-white h-[52px] border border-[#259AFF] bg-[linear-gradient(165.29deg,#259AFF_8.53%,#114CDD_93.19%)]"
|
className="col-span-1 flex items-center justify-center uppercase rounded-[12px] text-white h-[52px] border border-[#259AFF] bg-[linear-gradient(165.29deg,#259AFF_8.53%,#114CDD_93.19%)]"
|
||||||
aria-label="Mua sản phẩm"
|
aria-label="Mua sản phẩm"
|
||||||
|
onClick={() => addToCart(item)}
|
||||||
>
|
>
|
||||||
<i className="icons icon-cart !w-[22px] !h-[22px] mr-[6px]" />
|
<i className="icons icon-cart !w-[22px] !h-[22px] mr-[6px]" />
|
||||||
<span> Thêm vào giỏ </span>
|
<span> Thêm vào giỏ </span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
|
||||||
type="button"
|
<a href='https://hoanghapc.vn/huong-dan-mua-tra-gop' target='_blank'
|
||||||
className="col-span-1 flex items-center justify-center uppercase rounded-[12px] text-white h-[52px] border border-[#259AFF] bg-[linear-gradient(165.29deg,#259AFF_8.53%,#114CDD_93.19%)]"
|
className="col-span-1 flex items-center justify-center uppercase rounded-[12px] text-white h-[52px] border border-[#259AFF] bg-[linear-gradient(165.29deg,#259AFF_8.53%,#114CDD_93.19%)]"
|
||||||
aria-label="Mua sản phẩm"
|
|
||||||
>
|
>
|
||||||
<i className="icons icon-card w-[22px] h-[22px] mr-[6px]" />
|
<i className="icons icon-card w-[22px] h-[22px] mr-[6px]" />
|
||||||
<span> Mua trả góp </span>
|
<span> Mua trả góp </span>
|
||||||
</button>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,30 +1,57 @@
|
|||||||
export default function ProductDescription() {
|
'use client';
|
||||||
return (
|
import { useState, useEffect, useRef } from "react";
|
||||||
<div className="pd-box-group bg-white mb-6 p-8 pt-6 rounded-[24px]">
|
import parse from 'html-react-parser';
|
||||||
<p className="group-title border-b border-[#D0D8E3] leading-[31px] font-600 text-24 mb-4 pb-4">
|
|
||||||
Đánh giá HHPC CORE i7 14700 | 32G DDR5 | NVIDIA RTX 3060 12G{" "}
|
|
||||||
</p>
|
|
||||||
<div className="js-static-container static-container leading-[135%]">
|
|
||||||
<div className="js-static-content static-content text-16 leading-[22px] text-justify">
|
|
||||||
|
|
||||||
|
export default function ProductDescription( {name, description}:any ) {
|
||||||
|
const contentRef = useRef<HTMLDivElement>(null);
|
||||||
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
const [isOverflow, setIsOverflow] = useState(false);
|
||||||
|
const [expanded, setExpanded] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (contentRef.current) {
|
||||||
|
if (contentRef.current.scrollHeight > 700) {
|
||||||
|
setIsOverflow(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [description]);
|
||||||
|
|
||||||
|
const handleCollapse = () => {
|
||||||
|
setExpanded(false);
|
||||||
|
|
||||||
|
containerRef.current?.scrollIntoView({
|
||||||
|
behavior: 'smooth',
|
||||||
|
block: 'start',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="pd-box-group bg-white mb-6 p-8 pt-6 rounded-[24px]" ref={containerRef}>
|
||||||
|
<p className="group-title border-b border-[#D0D8E3] leading-[31px] font-600 text-24 mb-4 pb-4">
|
||||||
|
Đánh giá {name}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="js-static-container static-container leading-[135%]" ref={contentRef}>
|
||||||
|
<div className={`static-content text-16 leading-[22px] text-justify transition-all duration-300
|
||||||
|
${!expanded && isOverflow ? 'max-h-[700px] overflow-hidden' : ''}
|
||||||
|
`}>
|
||||||
|
{parse(description)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="static-btn">
|
{isOverflow && (
|
||||||
<button
|
<div className="static-btn mt-4 flex justify-center">
|
||||||
type="button"
|
{!expanded ? (
|
||||||
aria-label="Xem thêm"
|
<button onClick={() => setExpanded(true)}>
|
||||||
className="js-showmore-button"
|
|
||||||
>
|
|
||||||
Xem thêm <i className="bx bx-chevron-down" />
|
Xem thêm <i className="bx bx-chevron-down" />
|
||||||
</button>
|
</button>
|
||||||
<button
|
) : (
|
||||||
type="button"
|
<button onClick={handleCollapse}>
|
||||||
aria-label="Thu gọn"
|
|
||||||
className="js-showless-button"
|
|
||||||
>
|
|
||||||
Thu gọn <i className="bx bx-chevron-up" />
|
Thu gọn <i className="bx bx-chevron-up" />
|
||||||
</button>
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import ProductSummary from "./summary";
|
|||||||
export default async function ProductDetail({ slug }: any) {
|
export default async function ProductDetail({ slug }: any) {
|
||||||
const {
|
const {
|
||||||
productName,
|
productName,
|
||||||
|
productId,
|
||||||
review,
|
review,
|
||||||
visit,
|
visit,
|
||||||
quantity,
|
quantity,
|
||||||
@@ -21,12 +22,13 @@ export default async function ProductDetail({ slug }: any) {
|
|||||||
productImage, imageCollection,
|
productImage, imageCollection,
|
||||||
price, marketPrice, deal_list, price_off, sale_rules,
|
price, marketPrice, deal_list, price_off, sale_rules,
|
||||||
hasVAT, warranty,
|
hasVAT, warranty,
|
||||||
specialOffer
|
specialOffer,
|
||||||
|
productDescription,
|
||||||
|
productSpec
|
||||||
} = slug
|
} = slug
|
||||||
|
|
||||||
const image = {
|
const image = {
|
||||||
productImage,
|
productImage, imageCollection
|
||||||
imageCollection
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const priceData = {
|
const priceData = {
|
||||||
@@ -85,7 +87,7 @@ export default async function ProductDetail({ slug }: any) {
|
|||||||
|
|
||||||
<ProductOffer item={specialOffer}/>
|
<ProductOffer item={specialOffer}/>
|
||||||
|
|
||||||
<Buttons />
|
<Buttons item={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" />
|
||||||
@@ -101,9 +103,10 @@ 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 />
|
{ productDescription &&
|
||||||
|
<ProductDescription name={productName} description={productDescription} />
|
||||||
|
}
|
||||||
|
|
||||||
{/* Đánh giá và bình luận */}
|
|
||||||
<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 />
|
<Review />
|
||||||
|
|
||||||
@@ -112,7 +115,9 @@ export default async function ProductDetail({ slug }: any) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-right w-[440px]">
|
<div className="col-right w-[440px]">
|
||||||
<ProductSpec />
|
{productSpec &&
|
||||||
|
<ProductSpec item={productSpec} />
|
||||||
|
}
|
||||||
|
|
||||||
<Article />
|
<Article />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,349 +1,30 @@
|
|||||||
export default function ProductSpec() {
|
import parse from 'html-react-parser';
|
||||||
|
|
||||||
|
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">
|
||||||
{" "}
|
Thông số kỹ thuật
|
||||||
Thông số kỹ thuật{" "}
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div className="pd-spec-group">
|
<div className="pd-spec-group">
|
||||||
<table>
|
{parse(item)}
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>STT</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>MÃ HÀNG</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>TÊN HÀNG</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>THỜI HẠN BẢO HÀNH</strong>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>1</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>CPU</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>
|
|
||||||
<a href="https://hoanghapc.vn/cpu-intel-core-ultra-7-265k">
|
|
||||||
INTEL CORE ULTRA 7 265K UP 5.5GHz | 20 CORE | 20 THREAD
|
|
||||||
</a>
|
|
||||||
</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>36 THÁNG</strong>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>2</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>MAIN</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>
|
|
||||||
<a href="https://hoanghapc.vn/mainboard-colorful-battle-ax-z890m-plus-v20">
|
|
||||||
COLORFUL BATTLE-AX Z890M-PLUS V20 DDR5
|
|
||||||
</a>
|
|
||||||
</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>36 THÁNG</strong>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>3</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>TẢN NHIỆT</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>
|
|
||||||
<a href="https://hoanghapc.vn/tan-nhiet-cpu-id-cooling-frozn-a620-pro-se-argb">
|
|
||||||
ID-COOLING FROZN A620 PRO SE ARGB
|
|
||||||
</a>
|
|
||||||
</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>12 THÁNG</strong>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>4</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>RAM</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>
|
|
||||||
<a href="https://hoanghapc.vn/ram-ddr5-teamgroup-t-create-expert-32gb-6000mhz">
|
|
||||||
DDR5 TEAMGROUP T-CREATE EXPERT 32GB 6000MHz (2x16GB)
|
|
||||||
</a>
|
|
||||||
</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>36 THÁNG</strong>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>5</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>SSD</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>
|
|
||||||
<a href="https://hoanghapc.vn/o-cung-ssd-teamgroup-g50-1tb">
|
|
||||||
TEAMGROUP G50 1TB PCIE Gen4x4 - RW 5000MB/s
|
|
||||||
</a>
|
|
||||||
</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>60 THÁNG</strong>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>6</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<span style={{ color: "#000" }}>
|
|
||||||
<strong>VGA</strong>
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>
|
|
||||||
<a href="https://hoanghapc.vn/vga-colorful-rtx-3060-nb-duo-12g-v4-l-v">
|
|
||||||
COLORFUL RTX 3060 NB DUO 12G V4 L-V GDDR6
|
|
||||||
</a>
|
|
||||||
</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>36 THÁNG</strong>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>7</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>PSU</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>
|
|
||||||
<a href="https://hoanghapc.vn/nguon-deepcool-pl750d-750w">
|
|
||||||
DEEPCOOL PL750D 750W 80 PLUS BRONZE | ATX 3.1 | PCIE 5.1
|
|
||||||
</a>
|
|
||||||
</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>60 THÁNG</strong>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>8</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>CASE</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>
|
|
||||||
<a href="https://hoanghapc.vn/vo-case-xigmatek-gaming-x-ii-3f-3fan-rgb">
|
|
||||||
XIGMATEK GAMING X II 3F - 3FAN RGB
|
|
||||||
</a>
|
|
||||||
</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }} />
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</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"
|
||||||
style={{ display: "none" }}
|
style={{ display: "none" }}
|
||||||
>
|
>
|
||||||
<table>
|
{parse(item)}
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>STT</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>MÃ HÀNG</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>TÊN HÀNG</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>THỜI HẠN BẢO HÀNH</strong>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>1</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>CPU</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>
|
|
||||||
<a href="https://hoanghapc.vn/cpu-intel-core-ultra-7-265k">
|
|
||||||
INTEL CORE ULTRA 7 265K UP 5.5GHz | 20 CORE | 20 THREAD
|
|
||||||
</a>
|
|
||||||
</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>36 THÁNG</strong>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>2</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>MAIN</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>
|
|
||||||
<a href="https://hoanghapc.vn/mainboard-colorful-battle-ax-z890m-plus-v20">
|
|
||||||
COLORFUL BATTLE-AX Z890M-PLUS V20 DDR5
|
|
||||||
</a>
|
|
||||||
</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>36 THÁNG</strong>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>3</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>TẢN NHIỆT</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>
|
|
||||||
<a href="https://hoanghapc.vn/tan-nhiet-cpu-id-cooling-frozn-a620-pro-se-argb">
|
|
||||||
ID-COOLING FROZN A620 PRO SE ARGB
|
|
||||||
</a>
|
|
||||||
</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>12 THÁNG</strong>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>4</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>RAM</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>
|
|
||||||
<a href="https://hoanghapc.vn/ram-ddr5-teamgroup-t-create-expert-32gb-6000mhz">
|
|
||||||
DDR5 TEAMGROUP T-CREATE EXPERT 32GB 6000MHz (2x16GB)
|
|
||||||
</a>
|
|
||||||
</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>36 THÁNG</strong>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>5</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>SSD</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>
|
|
||||||
<a href="https://hoanghapc.vn/o-cung-ssd-teamgroup-g50-1tb">
|
|
||||||
TEAMGROUP G50 1TB PCIE Gen4x4 - RW 5000MB/s
|
|
||||||
</a>
|
|
||||||
</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>60 THÁNG</strong>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>6</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<span style={{ color: "#000" }}>
|
|
||||||
<strong>VGA</strong>
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>
|
|
||||||
<a href="https://hoanghapc.vn/vga-colorful-rtx-3060-nb-duo-12g-v4-l-v">
|
|
||||||
COLORFUL RTX 3060 NB DUO 12G V4 L-V GDDR6
|
|
||||||
</a>
|
|
||||||
</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>36 THÁNG</strong>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>7</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>PSU</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>
|
|
||||||
<a href="https://hoanghapc.vn/nguon-deepcool-pl750d-750w">
|
|
||||||
DEEPCOOL PL750D 750W 80 PLUS BRONZE | ATX 3.1 | PCIE 5.1
|
|
||||||
</a>
|
|
||||||
</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>60 THÁNG</strong>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>8</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>CASE</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }}>
|
|
||||||
<strong>
|
|
||||||
<a href="https://hoanghapc.vn/vo-case-xigmatek-gaming-x-ii-3f-3fan-rgb">
|
|
||||||
XIGMATEK GAMING X II 3F - 3FAN RGB
|
|
||||||
</a>
|
|
||||||
</strong>
|
|
||||||
</td>
|
|
||||||
<td style={{ textAlign: "center" }} />
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
4
src/data/productDetail/index.tsx
Normal file
4
src/data/productDetail/index.tsx
Normal file
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
import { toast } from 'sonner';
|
||||||
import { useEffect, useState, useCallback } from 'react';
|
import { useEffect, useState, useCallback } from 'react';
|
||||||
import {
|
import {
|
||||||
getCartItems,
|
getCartItems,
|
||||||
@@ -14,9 +14,12 @@ import {
|
|||||||
CART_CHANGE_EVENT,
|
CART_CHANGE_EVENT,
|
||||||
type CartItem,
|
type CartItem,
|
||||||
} from '../services/cart';
|
} from '../services/cart';
|
||||||
|
import { useRouter } from 'next/navigation';
|
||||||
|
|
||||||
|
|
||||||
export function useCart() {
|
export function useCart() {
|
||||||
const [cartItems, setCartItems] = useState<CartItem[] | null>(null);
|
const [cartItems, setCartItems] = useState<CartItem[] | null>(null);
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
// Load cart lần đầu
|
// Load cart lần đầu
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -47,9 +50,26 @@ export function useCart() {
|
|||||||
setCartItems(getCartItems());
|
setCartItems(getCartItems());
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const addToCart = useCallback((productId: number, quantity: number = 1) => {
|
const addToCart = useCallback((productId: number, quantity: number = 1, redirect = '') => {
|
||||||
const result = addProductToCart(productId, quantity);
|
const result = addProductToCart(productId, quantity);
|
||||||
|
|
||||||
|
if (result?.success) {
|
||||||
|
toast.success('Đã thêm vào giỏ hàng', {
|
||||||
|
description: result.message,
|
||||||
|
duration: 2500,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (redirect) {
|
||||||
|
router.push(redirect);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
toast.error('Thêm sản phẩm thất bại', {
|
||||||
|
description: result?.message || 'Vui lòng thử lại',
|
||||||
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// hoanghapc/src/lib/productPage.ts
|
// hoanghapc/src/lib/productPage.ts
|
||||||
import { categories } from "@/data/categories";
|
import { categories } from "@/data/categories";
|
||||||
import { productList } from "@/data/productList";
|
import { productList } from "@/data/productList";
|
||||||
|
import { productDetail } from "@/data/productDetail"
|
||||||
|
|
||||||
export type ProductResult =
|
export type ProductResult =
|
||||||
| { type: "product_category"; data: any }
|
| { type: "product_category"; data: any }
|
||||||
@@ -28,7 +29,16 @@ export function resolveProductPage(slug: string): ProductResult | null {
|
|||||||
.find((p: any) => p.productUrl === url);
|
.find((p: any) => p.productUrl === url);
|
||||||
|
|
||||||
if (product) {
|
if (product) {
|
||||||
return { type: "product_detail", data: product };
|
const data = {
|
||||||
|
...product,
|
||||||
|
productDescription : productDetail.productDescription,
|
||||||
|
productSpec : productDetail.productSpec
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: "product_detail",
|
||||||
|
data
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
Reference in New Issue
Block a user