update 31/01

This commit is contained in:
2026-01-31 12:00:43 +07:00
parent eb44cc2575
commit 12509e3a7b
11 changed files with 6705 additions and 6920 deletions

12719
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -15,6 +15,7 @@
"photoswipe": "^5.4.4",
"react": "19.2.3",
"react-dom": "19.2.3",
"sonner": "^2.0.7",
"swiper": "^12.0.3"
},
"devDependencies": {

View File

@@ -1,5 +1,6 @@
import type { Metadata } from "next";
import type { ReactNode } from 'react';
import { Toaster } from 'sonner';
import Header from "@/components/other/header";
import Footer from "@/components/other/footer";
import TooltipProvider from "@/components/providers/TooltipProvider";
@@ -19,13 +20,19 @@ export default function RootLayout({
<html lang="vi">
<body>
<Header />
<TooltipProvider>
{children}
</TooltipProvider>
<Footer />
<Footer />
<Toaster
position="top-right"
closeButton
richColors
/>
</body>
</html>
);

View File

@@ -1,209 +1,209 @@
export default function Home() {
return(
return (
<div className="cart-page container">
<div className="text-center px-3">
<div className="mb-4">
<img src="images/cart-empty.png" className="block m-auto" />
</div>
<p className="mt-10 mb-6 text-20 font-600">
{" "}
Không sản phẩm nào trong giỏ hàng của bạn !
</p>
<a
href="/"
className="inline-flex items-center bg-btn text-white leading-[52px] font-500 text-18 rounded-[50px] px-6"
>
{" "}
VỀ TRANG CHỦ <i className="bx bx-arrow-up-right-stroke text-30" />{" "}
</a>
</div>
<h1 className="text-[#004BA4] leading-10 text-[32px] font-600 mb-6">
{" "}
Giỏ hàng của tôi{" "}
</h1>
<div className="lg:flex flex-wrap items-start justify-between gap-6">
<div className="col-left w-[calc(100%-464px)]">
<div className="hidden lg:flex flex-wrap items-center justify-between gap-4 bg-white rounded-[12px] mb-3 py-3 px-4 lg:text-[16px] font-500 leading-10">
<p className="m-0 text-16 lg:text-[18px]"> 5 sản phẩm </p>
<button
type="button"
className="h-10 border border-[#0678DB] bg-white rounded-[40px] text-[#0678DB] px-6 transition-all duration-100 hover:bg-[#0678DB] hover:text-white"
aria-label="Xóa sản phẩm"
>
{" "}
LÀM TRỐNG GIỎ HÀNG{" "}
</button>
</div>
<div className="bg-white rounded-[16px] lg:rounded-[12px] mb-3 p-4">
<div className="cart-item mb-5 last:mb-0">
<a href="" className="item-img">
{" "}
<img src="images/product-5.jpg" />{" "}
</a>
<div className="item-text">
<div className="item-name">
<a
href=""
className="table uppercase font-500 lg:text-[16px] text-12"
>
HHPC ULTRA 7 265K | 32GB DDR5 | NVIDIA RTX 3060 12GB
</a>
<div className="group mt-2 table">
<p className="m-0 text-[#0678DB] font-500 cursor-pointer">
<span> Chi tiết khuyến mại </span>
<i className="bx bx-chevron-down text-[#A0A5AC] text-16 align-middle transition-all group-hover:rotate-[-180deg]" />
</p>
<div className="item-offer group-hover:opacity-100 group-hover:z-[5] group-hover:visible">
<div className="item">
<p>
<span style={{ fontSize: "12pt", color: "#ff0000" }}>
<strong> Tặng Balo Laptop Hoàng PC</strong>
</span>
</p>
</div>
<div className="item">
<p>
<span style={{ fontSize: "12pt", color: "#ff0000" }}>
<strong> Tặng Chuột không dây</strong>
</span>
</p>
</div>
<div className="item">
<p>
<span style={{ fontSize: "12pt", color: "#ff0000" }}>
<strong> Tặng Bàn di chuột</strong>
</span>
</p>
</div>
<div className="text-center px-3">
<div className="mb-4">
<img src="images/cart-empty.png" className="block m-auto" />
</div>
</div>
<p className="mt-10 mb-6 text-20 font-600">
{" "}
Không sản phẩm nào trong giỏ hàng của bạn !
</p>
<a
href="/"
className="inline-flex items-center bg-btn text-white leading-[52px] font-500 text-18 rounded-[50px] px-6"
>
{" "}
VỀ TRANG CHỦ <i className="bx bx-arrow-up-right-stroke text-30" />{" "}
</a>
</div>
<div className="item-quantiy">
<button
type="button"
className="js-quantity-change bx bx-minus"
/>
<input
type="number"
defaultValue={1}
min={1}
data-stock={998}
pattern="[0-9]*"
inputMode="numeric"
className="js-buy-quantity js-quantity-change text-center"
/>
<button type="button" className="js-quantity-change bx bx-plus" />
</div>
<div className="item-price text-right lg:text-left">
<p className="text-[#FF4E2A] font-bold mb-0 lg:mb-1 lg:text-[16px] lg:leading-5 text-13 leading-4">
<h1 className="text-[#004BA4] leading-10 text-[32px] font-600 mb-6">
{" "}
42.000.000 đ{" "}
</p>
<del className="block text-[#A0A5AC] lg:text-[13px] lg:leading-4 text-10 leading-3">
{" "}
52.000.000 đ{" "}
</del>
Giỏ hàng của tôi{" "}
</h1>
<div className="lg:flex flex-wrap items-start justify-between gap-6">
<div className="col-left w-[calc(100%-464px)]">
<div className="hidden lg:flex flex-wrap items-center justify-between gap-4 bg-white rounded-[12px] mb-3 py-3 px-4 lg:text-[16px] font-500 leading-10">
<p className="m-0 text-16 lg:text-[18px]"> 5 sản phẩm </p>
<button
type="button"
className="h-10 border border-[#0678DB] bg-white rounded-[40px] text-[#0678DB] px-6 transition-all duration-100 hover:bg-[#0678DB] hover:text-white"
aria-label="Xóa sản phẩm"
>
{" "}
LÀM TRỐNG GIỎ HÀNG{" "}
</button>
</div>
<div className="bg-white rounded-[16px] lg:rounded-[12px] mb-3 p-4">
<div className="cart-item mb-5 last:mb-0">
<a href="" className="item-img">
{" "}
<img src="images/product-5.jpg" />{" "}
</a>
<div className="item-text">
<div className="item-name">
<a
href=""
className="table uppercase font-500 lg:text-[16px] text-12"
>
HHPC ULTRA 7 265K | 32GB DDR5 | NVIDIA RTX 3060 12GB
</a>
<div className="group mt-2 table">
<p className="m-0 text-[#0678DB] font-500 cursor-pointer">
<span> Chi tiết khuyến mại </span>
<i className="bx bx-chevron-down text-[#A0A5AC] text-16 align-middle transition-all group-hover:rotate-[-180deg]" />
</p>
<div className="item-offer group-hover:opacity-100 group-hover:z-[5] group-hover:visible">
<div className="item">
<p>
<span style={{ fontSize: "12pt", color: "#ff0000" }}>
<strong> Tặng Balo Laptop Hoàng PC</strong>
</span>
</p>
</div>
<div className="item">
<p>
<span style={{ fontSize: "12pt", color: "#ff0000" }}>
<strong> Tặng Chuột không dây</strong>
</span>
</p>
</div>
<div className="item">
<p>
<span style={{ fontSize: "12pt", color: "#ff0000" }}>
<strong> Tặng Bàn di chuột</strong>
</span>
</p>
</div>
</div>
</div>
</div>
<div className="item-quantiy">
<button
type="button"
className="js-quantity-change bx bx-minus"
/>
<input
type="number"
defaultValue={1}
min={1}
data-stock={998}
pattern="[0-9]*"
inputMode="numeric"
className="js-buy-quantity js-quantity-change text-center"
/>
<button type="button" className="js-quantity-change bx bx-plus" />
</div>
<div className="item-price text-right lg:text-left">
<p className="text-[#FF4E2A] font-bold mb-0 lg:mb-1 lg:text-[16px] lg:leading-5 text-13 leading-4">
{" "}
42.000.000 đ{" "}
</p>
<del className="block text-[#A0A5AC] lg:text-[13px] lg:leading-4 text-10 leading-3">
{" "}
52.000.000 đ{" "}
</del>
</div>
<button
type="button"
className="item-delete bx bx-trash w-8 h-8 lg:w-10 lg:h-10 rounded-full border border-[#E7D9D9] bg-[#F8F3F3] text-[#BE1F2D] text-16 lg:text-[20px] hover:text-white hover:bg-[#BE1F2D] hover:border-transparent"
/>
</div>
</div>
</div>
<div className="bg-white p-4 lg:pt-5 rounded-[16px] lg:rounded-[12px]">
<p className="font-600 text-16 lg:text-[18px] mb-2 lg:mb-4 leading-5 lg:leading-6">
{" "}
Thông tin đơn hàng{" "}
</p>
<div className="flex items-center justify-between gap-3 border-b border-[#D2DAE3] border-dashed pb-4 mb-3 lg:mb-5 leading-5 lg:leading-6 lg:text-[16px]">
<p className="m-0"> Tổng tiền </p>
<p className="m-0 font-500 text-15 lg:text-[18px]"> 50.000.000 đ </p>
</div>
<div className="flex items-center justify-between gap-3 leading-5 lg:leading-6">
<p className="m-0 flex items-center gap-2">
<i className="bx bxs-credit-card-alt text-20 text-[#B5BAC1]" />
<span> Tổng thanh toán </span>
</p>
<p className="m-0 text-16 text-[#FF4E2A] font-bold lg:text-[20px]">
{" "}
41.450.000 <u>đ</u>{" "}
</p>
</div>
</div>
</div>
<form className="col-right w-[440px] bg-white rounded-[16px] px-5 py-6 sticky top-[90px] z-[1] shadow-[0px_4px_20px_0px_#0615070D] lg:shadow-[none]">
<p className="font-600 text-18 text-[#004BA4] leading-6 mb-1">
{" "}
Thông tin nhận hàng{" "}
</p>
<div className="leading-[18px] text-[#474747] mb-4">
Đ tiếp tục đt hàng, quý khách xin vui lòng
<button
type="button"
aria-label="Đăng nhập"
className="font-500 text-[#0678DB]"
>
{" "}
đăng nhập{" "}
</button>
hoặc nhập thông tin bên dưới. vấn viên sẽ liên hệ theo thông tin bạn
cung cấp đ xác nhận, không mua không sao
</div>
<div>
<input
type="text"
id=""
className="block w-full h-[50px] mb-4 border border-transparent rounded-[12px] bg-[#F3F3F3] px-4"
placeholder="Họ và tên"
/>
<input
type="tel"
id=""
className="block w-full h-[50px] mb-4 border border-transparent rounded-[12px] bg-[#F3F3F3] px-4"
inputMode="numeric"
pattern="[0-9]{10,11}"
maxLength={11}
placeholder="Số điện thoại"
/>
<input
type="email"
id=""
className="block w-full h-[50px] mb-4 border border-transparent rounded-[12px] bg-[#F3F3F3] px-4"
maxLength={254}
placeholder="Nhập email"
/>
<input
type="text"
id=""
className="block w-full h-[50px] mb-2 border border-transparent rounded-[12px] bg-[#F3F3F3] px-4"
placeholder="Địa chỉ nhận hàng"
/>
<p className="text-[#757575] mb-4">
{" "}
<i className="bx bx-info-circle text-16 text-[#0678DB] mr-1 align-text-top" />{" "}
<span> Nhập Số nhà, Đưng, Phường/, Quận, Tỉnh </span>{" "}
</p>
<textarea
id=""
className="block w-full h-[112px] mb-4 border border-transparent rounded-[12px] bg-[#F3F3F3] px-4 pt-[12px] resize-none outline-none"
placeholder="Ghi chú"
defaultValue={""}
/>
</div>
<div className="red font-600 my-4"> </div>
<div className="mt-5">
<button
type="submit"
className="block w-full bg-btn text-white h-[52px] rounded-[50px] font-500 text-18"
>
{" "}
ĐT HÀNG{" "}
</button>
</div>
</form>
</div>
<button
type="button"
className="item-delete bx bx-trash w-8 h-8 lg:w-10 lg:h-10 rounded-full border border-[#E7D9D9] bg-[#F8F3F3] text-[#BE1F2D] text-16 lg:text-[20px] hover:text-white hover:bg-[#BE1F2D] hover:border-transparent"
/>
</div>
</div>
</div>
<div className="bg-white p-4 lg:pt-5 rounded-[16px] lg:rounded-[12px]">
<p className="font-600 text-16 lg:text-[18px] mb-2 lg:mb-4 leading-5 lg:leading-6">
{" "}
Thông tin đơn hàng{" "}
</p>
<div className="flex items-center justify-between gap-3 border-b border-[#D2DAE3] border-dashed pb-4 mb-3 lg:mb-5 leading-5 lg:leading-6 lg:text-[16px]">
<p className="m-0"> Tổng tiền </p>
<p className="m-0 font-500 text-15 lg:text-[18px]"> 50.000.000 đ </p>
</div>
<div className="flex items-center justify-between gap-3 leading-5 lg:leading-6">
<p className="m-0 flex items-center gap-2">
<i className="bx bxs-credit-card-alt text-20 text-[#B5BAC1]" />
<span> Tổng thanh toán </span>
</p>
<p className="m-0 text-16 text-[#FF4E2A] font-bold lg:text-[20px]">
{" "}
41.450.000 <u>đ</u>{" "}
</p>
</div>
</div>
</div>
<form className="col-right w-[440px] bg-white rounded-[16px] px-5 py-6 sticky top-[90px] z-[1] shadow-[0px_4px_20px_0px_#0615070D] lg:shadow-[none]">
<p className="font-600 text-18 text-[#004BA4] leading-6 mb-1">
{" "}
Thông tin nhận hàng{" "}
</p>
<div className="leading-[18px] text-[#474747] mb-4">
Đ tiếp tục đt hàng, quý khách xin vui lòng
<button
type="button"
aria-label="Đăng nhập"
className="font-500 text-[#0678DB]"
>
{" "}
đăng nhập{" "}
</button>
hoặc nhập thông tin bên dưới. vấn viên sẽ liên hệ theo thông tin bạn
cung cấp đ xác nhận, không mua không sao
</div>
<div>
<input
type="text"
id=""
className="block w-full h-[50px] mb-4 border border-transparent rounded-[12px] bg-[#F3F3F3] px-4"
placeholder="Họ và tên"
/>
<input
type="tel"
id=""
className="block w-full h-[50px] mb-4 border border-transparent rounded-[12px] bg-[#F3F3F3] px-4"
inputMode="numeric"
pattern="[0-9]{10,11}"
maxLength={11}
placeholder="Số điện thoại"
/>
<input
type="email"
id=""
className="block w-full h-[50px] mb-4 border border-transparent rounded-[12px] bg-[#F3F3F3] px-4"
maxLength={254}
placeholder="Nhập email"
/>
<input
type="text"
id=""
className="block w-full h-[50px] mb-2 border border-transparent rounded-[12px] bg-[#F3F3F3] px-4"
placeholder="Địa chỉ nhận hàng"
/>
<p className="text-[#757575] mb-4">
{" "}
<i className="bx bx-info-circle text-16 text-[#0678DB] mr-1 align-text-top" />{" "}
<span> Nhập Số nhà, Đưng, Phường/, Quận, Tỉnh </span>{" "}
</p>
<textarea
id=""
className="block w-full h-[112px] mb-4 border border-transparent rounded-[12px] bg-[#F3F3F3] px-4 pt-[12px] resize-none outline-none"
placeholder="Ghi chú"
defaultValue={""}
/>
</div>
<div className="red font-600 my-4"> </div>
<div className="mt-5">
<button
type="submit"
className="block w-full bg-btn text-white h-[52px] rounded-[50px] font-500 text-18"
>
{" "}
ĐT HÀNG{" "}
</button>
</div>
</form>
</div>
</div>
)

View File

@@ -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 (
<>
<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"
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"
onClick={() => addToCart(item, 1, '/cart')}
>
{" "}
Mua ngay{" "}
Mua ngay
</button>
<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%)]"
aria-label="Mua sản phẩm"
onClick={() => addToCart(item)}
>
<i className="icons icon-cart !w-[22px] !h-[22px] mr-[6px]" />
<span> Thêm vào giỏ </span>
</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%)]"
aria-label="Mua sản phẩm"
>
<i className="icons icon-card w-[22px] h-[22px] mr-[6px]" />
<span> Mua trả góp </span>
</button>
</a>
</div>
</>
)

View File

@@ -1,30 +1,57 @@
export default function ProductDescription() {
'use client';
import { useState, useEffect, useRef } from "react";
import parse from 'html-react-parser';
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]">
<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á HHPC CORE i7 14700 | 32G DDR5 | NVIDIA RTX 3060 12G{" "}
Đánh giá {name}
</p>
<div className="js-static-container static-container leading-[135%]">
<div className="js-static-content static-content text-16 leading-[22px] text-justify">
<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 className="static-btn">
<button
type="button"
aria-label="Xem thêm"
className="js-showmore-button"
>
Xem thêm <i className="bx bx-chevron-down" />
</button>
<button
type="button"
aria-label="Thu gọn"
className="js-showless-button"
>
Thu gọn <i className="bx bx-chevron-up" />
</button>
</div>
{isOverflow && (
<div className="static-btn mt-4 flex justify-center">
{!expanded ? (
<button onClick={() => setExpanded(true)}>
Xem thêm <i className="bx bx-chevron-down" />
</button>
) : (
<button onClick={handleCollapse}>
Thu gọn <i className="bx bx-chevron-up" />
</button>
)}
</div>
)}
</div>
</div>
)

View File

@@ -13,7 +13,8 @@ import ProductSummary from "./summary";
export default async function ProductDetail({ slug }: any) {
const {
productName,
productName,
productId,
review,
visit,
quantity,
@@ -21,12 +22,13 @@ export default async function ProductDetail({ slug }: any) {
productImage, imageCollection,
price, marketPrice, deal_list, price_off, sale_rules,
hasVAT, warranty,
specialOffer
specialOffer,
productDescription,
productSpec
} = slug
const image = {
productImage,
imageCollection
productImage, imageCollection
}
const priceData = {
@@ -85,7 +87,7 @@ export default async function ProductDetail({ slug }: any) {
<ProductOffer item={specialOffer}/>
<Buttons />
<Buttons item={productId} />
<p className="m-0 flex items-center gap-3 text-16 leading-[22px]">
<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="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]">
<Review />
@@ -112,7 +115,9 @@ export default async function ProductDetail({ slug }: any) {
</div>
<div className="col-right w-[440px]">
<ProductSpec />
{productSpec &&
<ProductSpec item={productSpec} />
}
<Article />
</div>

View File

@@ -1,349 +1,30 @@
export default function ProductSpec() {
import parse from 'html-react-parser';
export default function ProductSpec( {item} : any ) {
console.log(item)
return (
<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">
{" "}
Thông số kỹ thuật{" "}
Thông số kỹ thuật
</p>
<div className="pd-spec-group">
<table>
<tbody>
<tr>
<td style={{ textAlign: "center" }}>
<strong>STT</strong>
</td>
<td style={{ textAlign: "center" }}>
<strong> 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>
{parse(item)}
</div>
<a
href="#fancybox-spec"
data-fancybox=""
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>
<div
className="pd-spec-group p-3"
id="fancybox-spec"
style={{ display: "none" }}
>
<table>
<tbody>
<tr>
<td style={{ textAlign: "center" }}>
<strong>STT</strong>
</td>
<td style={{ textAlign: "center" }}>
<strong> 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>
{parse(item)}
</div>
</div>
)

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
'use client';
import { toast } from 'sonner';
import { useEffect, useState, useCallback } from 'react';
import {
getCartItems,
@@ -14,9 +14,12 @@ import {
CART_CHANGE_EVENT,
type CartItem,
} from '../services/cart';
import { useRouter } from 'next/navigation';
export function useCart() {
const [cartItems, setCartItems] = useState<CartItem[] | null>(null);
const router = useRouter();
// Load cart lần đầu
useEffect(() => {
@@ -47,8 +50,25 @@ export function useCart() {
setCartItems(getCartItems());
}, []);
const addToCart = useCallback((productId: number, quantity: number = 1) => {
const result = addProductToCart(productId, quantity);
const addToCart = useCallback((productId: number, quantity: number = 1, redirect = '') => {
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;
}, []);

View File

@@ -1,6 +1,7 @@
// hoanghapc/src/lib/productPage.ts
import { categories } from "@/data/categories";
import { productList } from "@/data/productList";
import { productDetail } from "@/data/productDetail"
export type ProductResult =
| { type: "product_category"; data: any }
@@ -28,7 +29,16 @@ export function resolveProductPage(slug: string): ProductResult | null {
.find((p: any) => p.productUrl === url);
if (product) {
return { type: "product_detail", data: product };
const data = {
...product,
productDescription : productDetail.productDescription,
productSpec : productDetail.productSpec
}
return {
type: "product_detail",
data
};
}
return null;