update 14/01

This commit is contained in:
2026-01-14 17:31:59 +07:00
parent 229bdbde54
commit f5de4a5313
36 changed files with 14527 additions and 2423 deletions

View File

@@ -1,7 +1,16 @@
import type { NextConfig } from "next"; import type { NextConfig } from "next";
const nextConfig: NextConfig = { const nextConfig: NextConfig = {
/* config options here */ images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'hoanghapccdn.com',
pathname: '/media/**',
},
],
},
}; };
export default nextConfig; export default nextConfig;

View File

@@ -2,11 +2,11 @@
import { notFound } from "next/navigation"; import { notFound } from "next/navigation";
import { findBySlug } from "@/lib/slug/slugMap"; import { findBySlug } from "@/lib/slug/slugMap";
import ProductCategory from "@/components/product/Category"; import ProductCategory from "@/components/product/category";
import ProductDetail from "@/components/product/ProductDetail"; import ProductDetail from "@/components/product/detail";
import ArticleCategory from "@/components/article/Category"; import ArticleCategory from "@/components/article/category";
import ArticleDetail from "@/components/article/ArticleDetail"; import ArticleDetail from "@/components/article/detail";
import ArticleHome from "@/components/article/Home"; import ArticleHome from "@/components/article/home";
export default async function SlugPage({ export default async function SlugPage({
params, params,

View File

@@ -1,5 +1,5 @@
import CartHome from "@/components/cart/Home"; import CartHome from "@/components/cart/home";
export default function Home() { export default function Home() {
return ( return (

View File

@@ -1,7 +1,7 @@
import type { Metadata } from "next"; import type { Metadata } from "next";
import type { ReactNode } from 'react'; import type { ReactNode } from 'react';
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 '../styles/globals.css'; import '../styles/globals.css';
export const metadata: Metadata = { export const metadata: Metadata = {

View File

@@ -1,5 +1,5 @@
import SendResult from "@/components/cart/Send"; import SendResult from "@/components/cart/send";
export default function SendCartPage() { export default function SendCartPage() {
return ( return (

View File

@@ -1,5 +1,5 @@
import ArticleHome from "@/components/article/Home"; import ArticleHome from "@/components/article/home";
export default function Home() { export default function Home() {
return ( return (

View File

@@ -1,16 +1,32 @@
import { categories } from "@/data/categories";
export default function FeaturedProductCategories() { export default function FeaturedProductCategories() {
const {all_category} = categories.product;
return ( return (
<>
{all_category &&
<div className="home-categories-container bg-white rounded-[24px] my-10 p-6 pb-8"> <div className="home-categories-container bg-white rounded-[24px] my-10 p-6 pb-8">
<h2 className="group-title font-600 text-[28px] text-[#004BA4] mb-5 leading-9"> Danh mục nổi bật </h2> <h2 className="group-title font-600 text-[28px] text-[#004BA4] mb-5 leading-9"> Danh mục nổi bật </h2>
<div className="grid grid-cols-10 gap-6"> <div className="grid grid-cols-10 gap-6">
<a href="" className="item"> {all_category
<i className="image lazy" style={{ backgroundImage: 'url(images/global/cat-3.png)' }}></i> .filter( (item:any) => item.is_featured === 1 )
<span className="block"> PC Thiết Kế Đ Họa </span> .map( (item:any) =>
</a> <a href={item.url} className="item" key={item.id}>
<i className="image lazy"
style={{ backgroundImage: `url(${item.thumnail})` }}
></i>
<a href="" className="item"><i className="image lazy" style={{ backgroundImage: 'url(images/global/cat-1.png)' }}></i><span className="block">PC Thiết</span></a><a href="" className="item"><i className="image lazy" style={{ backgroundImage: 'url(images/global/cat-2.png)' }}></i><span className="block">PC Thiết Kế Đ Họa</span></a><a href="" className="item"><i className="image lazy" style={{ backgroundImage: 'url(images/global/cat-4.png)' }}></i><span className="block">PC Thiết Kế Đ Họa</span></a><a href="" className="item"><i className="image lazy" style={{ backgroundImage: 'url(images/global/cat-5.png)' }}></i><span className="block">PC Thiết Kế Đ Họa</span></a><a href="" className="item"><i className="image lazy" style={{ backgroundImage: 'url(images/global/cat-7.png)' }}></i><span className="block">PC Thiết Kế Đ Họa</span></a><a href="" className="item"><i className="image lazy" style={{ backgroundImage: 'url(images/global/cat-8.png)' }}></i><span className="block">PC Thiết Kế Đ Họa</span></a><a href="" className="item"><i className="image lazy" style={{ backgroundImage: 'url(images/global/cat-9.png)' }}></i><span className="block">PC Thiết Kế Đ Họa</span></a><a href="" className="item"><i className="image lazy" style={{ backgroundImage: 'url(images/global/cat-11.png)' }}></i><span className="block">PC Thiết Kế Đ Họa</span></a><a href="" className="item"><i className="image lazy" style={{ backgroundImage: 'url(images/global/cat-12.png)' }}></i><span className="block">PC Thiết Kế Đ Họa</span></a><a href="" className="item"><i className="image lazy" style={{ backgroundImage: 'url(images/global/cat-13.png)' }}></i><span className="block">PC Thiết Kế Đ Họa</span></a> <span className="block">
</div> {item.title}
</div> </span>
</a>
)
}
</div>
</div>
}
</>
) )
} }

View File

@@ -1,16 +1,22 @@
'use client'; 'use client';
import { Swiper, SwiperSlide } from 'swiper/react'; import { Swiper, SwiperSlide } from 'swiper/react';
import { Navigation, Pagination, Autoplay } from 'swiper/modules'; import { Navigation, Pagination, Autoplay } from 'swiper/modules';
import { dealList } from "@/data/deals"
import DealItem from "@/components/shared/DealItem"
export default function Collection() {
const data = dealList.filter(item => item.total > 0) ?? [];
export default function Deal() {
return ( return (
<div className="home-deal-container my-[3rem]"> data.map( (item:any) => (
<div className="home-deal-container my-[3rem]" key={item.collection_info.id}>
<div className="deal-container p-4 pt-6 rounded-[12px]" style={{ backgroundImage: 'url(images/bg-deal-home.png)' }}> <div className="deal-container p-4 pt-6 rounded-[12px]" style={{ backgroundImage: 'url(images/bg-deal-home.png)' }}>
<div className="group-title flex items-center justify-between mb-6 text-white relative z-[1]"> <div className="group-title flex items-center justify-between mb-6 text-white relative z-[1]">
<div className="flex items-center flex items-center"> <div className="flex items-center flex items-center">
<div className="flex items-center"> <div className="flex items-center">
<i className="icon-bolt lazy mr-2" style={{ backgroundImage: 'url(images/icon-bolt.png)' }}></i> <i className="icon-bolt lazy mr-2" style={{ backgroundImage: 'url(images/icon-bolt.png)' }}></i>
<p className="m-0 mr-5 font-600 text-[32px]"> Cấu hình Flash Sale </p> <p className="m-0 mr-5 font-600 text-[32px]"> {item.collection_info.title} </p>
</div> </div>
<div className="deal-time-holder"> <div className="deal-time-holder">
@@ -18,7 +24,7 @@ export default function Deal() {
</div> </div>
</div> </div>
<a href="/deal" className="text-16 font-600"> Xem tất cả <i className="bx bx-chevron-right align-middle ml-[-2px] mt-[-1px]"></i> </a> <a href='/deal' className="text-16 font-600"> Xem tất cả <i className="bx bx-chevron-right align-middle ml-[-2px] mt-[-1px]"></i> </a>
</div> </div>
<div className="group relative z-[1] bg-white rounded-[12px] relative min-h-[450px] px-4 pt-6 pb-8"> <div className="group relative z-[1] bg-white rounded-[12px] relative min-h-[450px] px-4 pt-6 pb-8">
@@ -46,43 +52,16 @@ export default function Deal() {
}, },
}} }}
> >
<SwiperSlide> { item.list.map( (deal:any) =>
<div className="deal-item"> <SwiperSlide key={deal.id}>
<a href="" className="deal-img"> <DealItem item={deal} />
<img src="images/product-1.jpg" alt="" width="1" height="1" className="fit-img"/>
</a>
<div className="deal-text">
<a href="" className="deal-name"> Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptatum eveniet reprehenderit, in maiores quaerat soluta mollitia </a>
<div className="deal-price-holder">
<div>
<p className="deal-price"> 48.990.000 đ </p>
<del> 52.000.000 đ </del>
<span className="deal-discount"> -6% </span>
</div>
<button type="button" className="deal-btn bx bx-plus" aria-label="Mua"></button>
</div>
<div className="deal-count">
<i className="deal-line" style={{ width: '30%' }}></i>
<span> Còn: 3/5 sản phẩm </span>
</div>
<div className="deal-offer">
<span className="text-[#BE1F2D]"> Quà tặng: </span>
Màn hình Coolest Maste chuột không dây Logitech
</div>
</div>
</div>
</SwiperSlide> </SwiperSlide>
)}
<SwiperSlide><div className="deal-item"><a href="" className="deal-img"><img src="images/product-2.jpg" alt="" width="1" height="1" className="fit-img" /></a><div className="deal-text"><a href="" className="deal-name">Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptatum eveniet reprehenderit, in maiores quaerat soluta mollitia</a><div className="deal-price-holder"><div><p className="deal-price">48.990.000 đ</p><del>52.000.000 đ</del><span className="deal-discount">-6%</span></div><button type="button" className="deal-btn bx bx-plus" aria-label="Mua"></button></div><div className="deal-count"><i className="deal-line" style={{ width: '0%' }}></i><span>Còn: 3/5 sản phẩm</span></div><div className="deal-offer"></div></div></div></SwiperSlide> <SwiperSlide><div className="deal-item"><a href="" className="deal-img"><img src="images/product-3.jpg" alt="" width="1" height="1" className="fit-img" /></a><div className="deal-text"><a href="" className="deal-name">Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptatum eveniet reprehenderit, in maiores quaerat soluta mollitia</a><div className="deal-price-holder"><div><p className="deal-price">48.990.000 đ</p><del>52.000.000 đ</del><span className="deal-discount">-6%</span></div><button type="button" className="deal-btn bx bx-plus" aria-label="Mua"></button></div><div className="deal-count"><i className="deal-line" style={{ width: '70%' }}></i><span>Còn: 3/5 sản phẩm</span></div><div className="deal-offer"><span className="text-[#BE1F2D]">Quà tặng:</span>Màn hình Coolest Maste chuột không dây Logitech</div></div></div></SwiperSlide> <SwiperSlide><div className="deal-item"><a href="" className="deal-img"><img src="images/product-4.jpg" alt="" width="1" height="1" className="fit-img" /></a><div className="deal-text"><a href="" className="deal-name">Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptatum eveniet reprehenderit, in maiores quaerat soluta mollitia</a><div className="deal-price-holder"><div><p className="deal-price">48.990.000 đ</p><del>52.000.000 đ</del><span className="deal-discount">-6%</span></div><button type="button" className="deal-btn bx bx-plus" aria-label="Mua"></button></div><div className="deal-count"><i className="deal-line" style={{ width: '90%' }}></i><span>Còn: 3/5 sản phẩm</span></div><div className="deal-offer"><span className="text-[#BE1F2D]">Quà tặng:</span>Màn hình Coolest Maste chuột không dây Logitech</div></div></div></SwiperSlide> <SwiperSlide><div className="deal-item"><a href="" className="deal-img"><img src="images/product-5.jpg" alt="" width="1" height="1" className="fit-img" /></a><div className="deal-text"><a href="" className="deal-name">Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptatum eveniet reprehenderit, in maiores quaerat soluta mollitia</a><div className="deal-price-holder"><div><p className="deal-price">48.990.000 đ</p><del>52.000.000 đ</del><span className="deal-discount">-6%</span></div><button type="button" className="deal-btn bx bx-plus" aria-label="Mua"></button></div><div className="deal-count"><i className="deal-line" style={{ width: '90%' }}></i><span>Còn: 3/5 sản phẩm</span></div><div className="deal-offer"><span className="text-[#BE1F2D]">Quà tặng:</span>Màn hình Coolest Maste</div></div></div></SwiperSlide> <SwiperSlide><div className="deal-item"><a href="" className="deal-img"><img src="images/product-6.jpg" alt="" width="1" height="1" className="fit-img" /></a><div className="deal-text"><a href="" className="deal-name">Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptatum eveniet reprehenderit, in maiores quaerat soluta mollitia</a><div className="deal-price-holder"><div><p className="deal-price">48.990.000 đ</p><del>52.000.000 đ</del><span className="deal-discount">-6%</span></div><button type="button" className="deal-btn bx bx-plus" aria-label="Mua"></button></div><div className="deal-count"><i className="deal-line" style={{ width: '90%' }}></i><span>Còn: 3/5 sản phẩm</span></div><div className="deal-offer"></div></div></div></SwiperSlide>
</Swiper> </Swiper>
</div> </div>
</div> </div>
</div> </div>
))
) )
} }

View File

@@ -0,0 +1,18 @@
import ImageItem from '@/components/shared/ImageItem';
type Props = {
data?: any[];
className?: string;
};
export default function BannerList({ data = [], className = '' }: Props) {
if (!data.length) return null;
return (
<div className={className}>
{data.map((item) => (
<ImageItem key={item.id} item={item} />
))}
</div>
);
}

View File

@@ -1,8 +1,16 @@
'use client'; 'use client';
import { Swiper, SwiperSlide } from 'swiper/react'; import { Swiper, SwiperSlide } from 'swiper/react';
import { Navigation, Pagination, Autoplay } from 'swiper/modules'; import { Navigation, Pagination, Autoplay } from 'swiper/modules';
import { banner } from '@/data/banner'
import ImageItem from '@/components/shared/ImageItem';
import ImageList from './ImageList';
export default function Slider() { export default function Slider() {
const bannerSlider = banner.homepage['2022_home_slider'] ?? [];
const bannerRight = banner.homepage['2022_home_right_slider'] ?? [];
const bannerUnder = banner.homepage['2022_home_under_slider'] ?? [];
const underSlider = banner.homepage['2022_4_under_slider'] ?? [];
return( return(
<div className="home-banner-container mb-10 min-h-[845px]"> <div className="home-banner-container mb-10 min-h-[845px]">
<div className="banner-slider gap-4 grid grid-cols-3 w-[932px] m-[auto_0_auto_auto]"> <div className="banner-slider gap-4 grid grid-cols-3 w-[932px] m-[auto_0_auto_auto]">
@@ -19,29 +27,14 @@ export default function Slider() {
}} }}
pagination={{ clickable: true }} pagination={{ clickable: true }}
> >
<SwiperSlide> {
<a href=""> bannerSlider.map((item:any) =>
<img src="/images/homepage/home-slide.png" alt="" width={100} height={100} className="block w-full lazy"/> <SwiperSlide key={item.id}>
</a> <ImageItem item={item} />
</SwiperSlide> </SwiperSlide>
)
}
<SwiperSlide>
<a href="">
<img src="https://placehold.co/792x543/EEE/31343C" alt="" width="" height="" className="block w-full lazy"/>
</a>
</SwiperSlide>
<SwiperSlide>
<a href="">
<img src="https://placehold.co/792x543/EEE/31343C" alt="" width="" height="" className="block w-full lazy"/>
</a>
</SwiperSlide>
<SwiperSlide>
<a href="">
<img src="https://placehold.co/792x543/EEE/31343C" alt="" width="" height="" className="block w-full lazy"/>
</a>
</SwiperSlide>
</Swiper> </Swiper>
<div className="custom-nav hidden"> <div className="custom-nav hidden">
@@ -58,34 +51,22 @@ export default function Slider() {
</div> </div>
</div> </div>
<div className="home-banner-right col-span-1"> <ImageList
<a href="" className="last:mb-0 mb-4"> data={bannerRight}
<img src="images/homepage/right-1.png" alt="" width="" height="" className="block w-full lazy"/> className="home-banner-right col-span-1"
</a> />
<a href="" className="last:mb-0 mb-4"> <ImageList
<img src="images/homepage/right-2.png" alt="" width="" height="" className="block w-full lazy"/> data={bannerUnder}
</a> className="grid grid-cols-3 gap-4 col-span-3"
/>
</div> </div>
<div className="home-banner-right grid grid-cols-3 gap-4 col-span-3">
<a href="">
<img src="images/homepage/under-slide-1.png" alt="" width="" height="" className="block w-full lazy"/>
</a>
<a href=""> <img src="images/homepage/under-slide-2.png" alt="" width="" height="" className="block w-full lazy"/> </a> <a href=""> <img src="images/homepage/under-slide-3.png" alt="" width="" height="" className="block w-full lazy"/> </a> <ImageList
</div> data={underSlider}
</div> className="grid grid-cols-4 gap-4 mt-4"
/>
<div className="grid grid-cols-4 gap-4 mt-4">
<a href="">
<img src="images/homepage/under-1.png" alt="" width="" height="" className="block w-full lazy"/>
</a>
<a href=""> <img src="images/homepage/under-2.png" alt="" width="" height="" className="block w-full lazy"/> </a>
<a href=""> <img src="images/homepage/under-3.png" alt="" width="" height="" className="block w-full lazy"/> </a>
<a href=""> <img src="images/homepage/under-4.png" alt="" width="" height="" className="block w-full lazy"/> </a>
</div>
</div> </div>
) )
} }

View File

@@ -1,10 +1,11 @@
import Slider from "./Slider"; import Slider from "./slider";
import Deal from "./Deal"; import Deal from "./deal";
import FeaturedProductCategories from "./Category"; import FeaturedProductCategories from "./category";
import ProductCategories from "./Product"; import ProductCategories from "./product";
import Article from "./Article"; import Article from "./article";
export default function HomePage() {
export default function Home() {
return( return(
<div className="home-page !-mt-5 pt-6"> <div className="home-page !-mt-5 pt-6">
<div className="container"> <div className="container">

View File

@@ -1,21 +1,64 @@
import Link from "next/link"; import Link from "next/link";
import { useCart } from "@/hooks/useCart";
import { getAllProducts, formatPrice } from "@/lib/utils"
export default function Cart() { export default function Cart() {
const { cartCount, cartIds, loading } = useCart();
const allProducts = getAllProducts();
const productsInCart = allProducts.filter(p => cartIds.includes(p.id) );
console.log(productsInCart);
return ( return (
<> <>
<div className="header-cart-item" id="js-header-cart"> <div className="header-cart-item" id="js-header-cart">
<Link href="/cart" rel="nofollow" className="flex items-center"> <Link href="/cart" rel="nofollow" className="flex items-center">
<i className="icon-cart relative mr-[10px]"> <i className="icon-cart relative mr-[10px]">
<b className="js-cart-count cart-count">0</b> <b className="js-cart-count cart-count">{cartCount}</b>
</i> </i>
<span className="text"> Giỏ <br />Hàng </span> <span className="text"> Giỏ <br />Hàng </span>
</Link> </Link>
<div className="header-cart-hover" id="js-header-cart-holder"> {productsInCart.length > 0 &&
<div className="cart-items-holder"><div className="cart-item"><a href="/o-cung-di-dong-ssd-transcend-esd310-1tb" className="cart-img"><img src="https://mygear.io.vn/media/product/75-6728-transcend-esd310-theme.jpg"/></a><div className="cart-text"><a href="/o-cung-di-dong-ssd-transcend-esd310-1tb" className="d-block font-700" style={{ marginBottom: '5px' }}> Cứng Di Đng SSD Transcend ESD310 1TB</a><p className="font-300" style={{ margin: '5px 0' }}> Màu sắc : <b>Màu Đen</b></p><p className="m-0 d-flex justify-content-between"><b>x2</b><b className="red">4.580.000 đ</b></p></div></div><div className="cart-item"><a href="/msi-pro-b860-p-wifi" className="cart-img"><img src="https://mygear.io.vn/media/product/75-7042-pro-b860-p-wifi-1.jpg"/></a><div className="cart-text"><a href="/msi-pro-b860-p-wifi" className="d-block font-700" style={{ marginBottom: '5px' }}>Mainboard MSI PRO B860-P WIFI DDR5</a><p className="m-0 d-flex justify-content-between"><b>x1</b><b className="red">6.190.000 đ</b></p></div></div></div><div className="cart-price-hover"><p className="grey m-0 text-right"> Tổng tiền hàng (<span className="red"><span className="js-cart-count">3</span> sản phẩm</span>): <span className="red text-18 font-600" style={{ verticalAlign: 'top' }}> 10.770.000đ </span></p><a href="/cart" className="d-block text-center text-white btn-goCart"> THANH TOÁN NGAY </a></div> <div className="header-cart-hover">
<div className="cart-items-holder">
{productsInCart.map((item:any) =>
<div className="cart-item" key={item.id}>
<Link href={item.productUrl} className="cart-img">
<img src={item.productImage.small} alt="image" width={100} height={100} />
</Link>
<div className="cart-text">
<Link href={item.productUrl} className="d-block font-700" style={{ marginBottom: "5px" }}>
{item.productName}
</Link>
<p className="m-0 d-flex justify-content-between">
<b>x1</b>
<b className="red">
{item.price > 0 ? formatPrice(item.price) +'đ' : 'Liên hệ'}
</b>
</p>
</div> </div>
</div> </div>
)}
<p className="text-center underline font-600 red" style={{ margin: '0', padding: "10px" }}> 1 số sp không trong DB tĩnh </p>
</div>
<div className="cart-price-hover">
<p className="grey m-0 text-right">
Tổng tiền hàng
(<span className="red"><span className="js-cart-count">{cartCount}</span> sản phẩm</span>):
<span className="red text-18 font-600" style={{ verticalAlign: "top" }}> 10.770.000đ </span>
</p>
<Link href="/cart" className="d-block text-center text-white btn-goCart"> THANH TOÁN NGAY </Link>
</div>
</div>
}
</div>
</> </>
) )
} }

File diff suppressed because one or more lines are too long

View File

@@ -5,7 +5,7 @@ import useFancybox from '@/lib/useFancyBox';
import Link from 'next/link'; import Link from 'next/link';
import Logo from "./Logo"; import Logo from "./Logo";
import Menu from "./Menu"; import Menu from "@/components/other/menu";
import Search from "./Search"; import Search from "./Search";
import Cart from "./Cart"; import Cart from "./Cart";
import Account from "./Account"; import Account from "./Account";
@@ -41,17 +41,18 @@ export default function Header() {
<div className="header-middle-group w-[583px] flex items-center justify-between gap-2"> <div className="header-middle-group w-[583px] flex items-center justify-between gap-2">
<Menu /> <Menu />
<Search /> <Search />
</div> </div>
<div className="header-right-group relative flex items-center justify-between gap-4 w-[420px] text-white leading-[18px] font-500"> <div className="header-right-group relative flex items-center justify-between gap-4 w-[420px] text-white leading-[18px] font-500">
<a href="#fancybox-headphone" <Link href="#fancybox-headphone"
data-fancybox="fancybox-hotline" data-fancybox="fancybox-hotline"
className="flex items-center gap-2" className="flex items-center gap-2"
> >
<i className="icons icon-headphone"></i> <i className="icons icon-headphone"></i>
<span className="text"> Hotline<br/> Mua Hàng </span> <span className="text"> Hotline<br/> Mua Hàng </span>
</a> </Link>
<Link href="/he-thong-cua-hang" className="flex items-center gap-2"> <Link href="/he-thong-cua-hang" className="flex items-center gap-2">
<i className="icons icon-showroom"></i> <i className="icons icon-showroom"></i>
@@ -92,14 +93,13 @@ export default function Header() {
<span> Bảo Hành Tận Nhà </span> <span> Bảo Hành Tận Nhà </span>
</Link> </Link>
<a <Link href="#fancybox-feedback"
href="#fancybox-feedback"
data-fancybox="fancybox-feedback" data-fancybox="fancybox-feedback"
className="flex items-center gap-2 hover:text-[#0678DB]" className="flex items-center gap-2 hover:text-[#0678DB]"
> >
<i className="icons icon-feedback"></i> <i className="icons icon-feedback"></i>
<span> Feedback </span> <span> Feedback </span>
</a> </Link>
</div> </div>
</div> </div>
</div> </div>

File diff suppressed because one or more lines are too long

View File

@@ -1,10 +1,10 @@
import ProductFilter from "./Filter"; import ProductFilter from "./filter";
import Static from "./Static"; import Static from "./static";
import FAQ from "./FAQ"; import FAQ from "./faq";
import Banner from "./Banner"; import Banner from "./banner";
import SortByCollection from "./Sort"; import SortByCollection from "./sort";
import ProductList from "./Product"; import ProductList from "./productList";
import Paging from "./Paging"; import Paging from "./paging";
export default function ProductCategory({ slug }: { slug: string }) { export default function ProductCategory({ slug }: { slug: string }) {

View File

@@ -0,0 +1,80 @@
'use client';
import Link from "next/link";
import { formatPrice } from "@/lib/utils";
import { useDealItem } from "@/hooks/useDealItem"
import { useCart } from '@/hooks/useCart';
export default function DealItem( {item} : any) {
const deal = useDealItem(item);
if (!deal) return null;
const { addToCart, isInCart } = useCart();
const {
productInfo,
price,
marketPrice,
discount,
remain,
saleRemainPercent,
specialOffer,
} = deal;
const discountView = discount > 0 ? (<>
<del>{formatPrice(marketPrice)} đ</del>
<span className="deal-discount">-{discount}%</span>
</>
) : null;
return (
<div className="deal-item">
<Link href={ productInfo.productUrl } className="deal-img">
<img
src={ productInfo.productImage.large }
alt={ productInfo.productName }
width={200}
height={200}
className="fit-img"
/>
</Link>
<div className="deal-text">
<Link href={ productInfo.productUrl } className="deal-name">
{ productInfo.productName }
</Link>
<div className="deal-price-holder">
<div>
<p className="deal-price"> {formatPrice(price)} đ </p>
{discountView}
</div>
<button className="deal-btn bx bx-plus" type="button" aria-label="Mua"
onClick={() => addToCart(productInfo.id)}
disabled={isInCart(productInfo.id)}
></button>
</div>
<div className="deal-count">
<i className="deal-line" style={{ width: saleRemainPercent + '%' }}></i>
<span> Còn:
{remain}/{item.quantity}
sản phẩm
</span>
</div>
{specialOffer && (
<div className="deal-offer">
<span className="text-[#BE1F2D]">Quà tặng: </span>
<div
dangerouslySetInnerHTML={{ __html: specialOffer }}
/>
</div>
)}
</div>
</div>
)
}

View File

@@ -1,27 +0,0 @@
'use client';
import React from 'react';
type Props = {
target: string;
group?: string;
children: React.ReactNode;
className?: string;
};
export default function FancyboxTrigger({
target,
group = 'default',
children,
className
}: Props) {
return (
<a
href={target}
data-fancybox={group}
className={className}
>
{children}
</a>
);
}

View File

@@ -0,0 +1,18 @@
'use client';
import Image from 'next/image';
import Link from 'next/link';
export default function ImageComponent({item}:any){
return(
<Link href={item.desUrl}>
<Image
src={item.fileUrl}
alt={item.name}
width={100}
height={100}
className="block w-full"
unoptimized
/>
</Link>
)
}

View File

1271
src/data/articles/index.tsx Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
export const banner = { export const banner = {
header : { "header" : {
"2024_global_banner_two_sides": [ "2024_global_banner_two_sides": [
{ {
"id": "553", "id": "553",
@@ -85,9 +85,9 @@ export const banner = {
] ]
}, },
footer : {}, "footer" : {},
homepage : { "homepage" : {
"2022_home_slider": [ "2022_home_slider": [
{ {
"id": "578", "id": "578",
@@ -677,7 +677,7 @@ export const banner = {
}, },
product_list : { "product_list" : {
"2025_hompage_banner_product_category": [ "2025_hompage_banner_product_category": [
{ {
"id": "574", "id": "574",

829
src/data/deals/index.tsx Normal file
View File

@@ -0,0 +1,829 @@
export const dealList = [
{
"total": 26,
"collection_info": {
"id": 1,
"title": "C\u1ea5u h\u00ecnh Flash Sale",
"summary": "Mi\u00eau t\u1ea3 nh\u00f3m deal 1",
},
"list": [
{
"id": "342",
"title": "HHPC CORE i7 14700KF | 64GB | NVIDIA RTX 5070 Ti 16G",
"price": 51750000,
"quantity": "10",
"min_purchase": "1",
"max_purchase": "10",
"to_time": "02-02-2026, 8:30 am",
"is_featured": "0",
"last_update": "1767576809",
"sale_order": "0",
"deal_time_happen": 796220,
"deal_time_left": 1624780,
"sale_quantity": "0",
"request_path": "\/deal\/342",
"is_start": 1,
"is_end": 0,
"is_active": "1",
"product_info": {
"id": 6669,
"productName": "HHPC CORE i7 14700KF | 64GB | NVIDIA RTX 5070 Ti 16G",
"productSKU": "0",
"price": 52790000,
"proThum": "6669_pc_anubis_14700kf_sale_4.jpg",
"specialOffer": {
"other": [
{
"id": 0,
"title": "<p>\u2b50\u00a0<span style=\"font-size: medium;\"><strong><span style=\"color: #ff0000;\">Gi\u00e1 khuy\u1ebfn m\u00e3i CPU Ryzen 7 9800X3D ch\u1ec9 c\u00f2n<\/span><\/strong><\/span><span style=\"font-size: medium;\"><strong><span style=\"color: #ff0000;\">\u00a0<\/span><span style=\"color: #008000; font-size: x-large;\">10.990.000\u0111<\/span>\u00a0<span style=\"color: #ff0000;\">\u00e1p d\u1ee5ng khi build PC t\u1ea1i Ho\u00e0ng H\u00e0 PC<\/span><\/strong><\/span><\/p>\r\n<p><span style=\"font-size: 12pt;\">\u2b50 Gi\u00e1\u00a0CPU Ryzen 7 9800X3D khi mua k\u00e8m main\u00a0B650 tr\u1edf l\u00ean l\u00e0:\u00a0<span style=\"font-size: 18pt;\"><strong>12.290.000\u0111<\/strong><\/span><\/span><\/p>\r\n<p><span style=\"font-size: 12pt;\">\u2b50 Gi\u00e1 b\u00e1n l\u1ebb\u00a0CPU Ryzen 7 9800X3D l\u00e0:\u00a0<strong><span style=\"font-size: 18pt;\">13.290.000\u0111<\/span><\/strong><\/span><\/p>\r\n<p><span style=\"font-size: 12pt;\">\u2b50 L\u01afU \u00dd: Ch\u01b0\u01a1ng tr\u00ecnh kh\u00f4ng \u00e1p d\u1ee5ng c\u1ed9ng d\u1ed3n v\u1edbi c\u00e1c ch\u01b0\u01a1ng tr\u00ecnh kh\u00e1c<\/span><\/p>\r\n<p><span style=\"font-size: 12pt;\">\u2b50 Ch\u01b0\u01a1ng tr\u00ecnh \u00e1p d\u1ee5ng v\u1edbi kh\u00e1ch h\u00e0ng Build PC c\u00f3 \u0111\u1ee7 th\u00eam 7 linh ki\u1ec7n sau:\u00a0<span style=\"font-size: 12pt;\">VGA,T\u1ea2N NHI\u1ec6T, MAIN, RAM, SSD, NGU\u1ed2N , V\u1ece CASE<\/span><\/span><\/p>",
"type": "",
"thumbnail": "",
"cash_value": 0,
"quantity": 1,
"from_time": "",
"to_time": "",
"url": "",
"description": "",
"status": 1
}
],
"all": [
{
"id": 0,
"title": "<p>\u2b50\u00a0<span style=\"font-size: medium;\"><strong><span style=\"color: #ff0000;\">Gi\u00e1 khuy\u1ebfn m\u00e3i CPU Ryzen 7 9800X3D ch\u1ec9 c\u00f2n<\/span><\/strong><\/span><span style=\"font-size: medium;\"><strong><span style=\"color: #ff0000;\">\u00a0<\/span><span style=\"color: #008000; font-size: x-large;\">10.990.000\u0111<\/span>\u00a0<span style=\"color: #ff0000;\">\u00e1p d\u1ee5ng khi build PC t\u1ea1i Ho\u00e0ng H\u00e0 PC<\/span><\/strong><\/span><\/p>\r\n<p><span style=\"font-size: 12pt;\">\u2b50 Gi\u00e1\u00a0CPU Ryzen 7 9800X3D khi mua k\u00e8m main\u00a0B650 tr\u1edf l\u00ean l\u00e0:\u00a0<span style=\"font-size: 18pt;\"><strong>12.290.000\u0111<\/strong><\/span><\/span><\/p>\r\n<p><span style=\"font-size: 12pt;\">\u2b50 Gi\u00e1 b\u00e1n l\u1ebb\u00a0CPU Ryzen 7 9800X3D l\u00e0:\u00a0<strong><span style=\"font-size: 18pt;\">13.290.000\u0111<\/span><\/strong><\/span><\/p>\r\n<p><span style=\"font-size: 12pt;\">\u2b50 L\u01afU \u00dd: Ch\u01b0\u01a1ng tr\u00ecnh kh\u00f4ng \u00e1p d\u1ee5ng c\u1ed9ng d\u1ed3n v\u1edbi c\u00e1c ch\u01b0\u01a1ng tr\u00ecnh kh\u00e1c<\/span><\/p>\r\n<p><span style=\"font-size: 12pt;\">\u2b50 Ch\u01b0\u01a1ng tr\u00ecnh \u00e1p d\u1ee5ng v\u1edbi kh\u00e1ch h\u00e0ng Build PC c\u00f3 \u0111\u1ee7 th\u00eam 7 linh ki\u1ec7n sau:\u00a0<span style=\"font-size: 12pt;\">VGA,T\u1ea2N NHI\u1ec6T, MAIN, RAM, SSD, NGU\u1ed2N , V\u1ece CASE<\/span><\/span><\/p>",
"type": "",
"thumbnail": "",
"cash_value": 0,
"quantity": 1,
"from_time": "",
"to_time": "",
"url": "",
"description": "",
"status": 1
}
]
},
"productUrl": "\/hhpc-core-i7-14700kf-64gb-rtx-5070-ti-16g",
"productImage": {
"small": "https:\/\/hoanghapccdn.com\/media\/product\/75_6669_pc_anubis_14700kf_sale_4.jpg",
"large": "https:\/\/hoanghapccdn.com\/media\/product\/250_6669_pc_anubis_14700kf_sale_4.jpg",
"original": "https:\/\/hoanghapccdn.com\/media\/product\/6669_pc_anubis_14700kf_sale_4.jpg"
},
"specialOfferGroup": []
}
},
{
"id": "341",
"title": "HHPC CORE i7 14700KF | 64GB | NVIDIA RTX 5070 12G",
"price": 43800000,
"quantity": "10",
"min_purchase": "1",
"max_purchase": "10",
"to_time": "02-02-2026, 8:30 am",
"is_featured": "0",
"last_update": "1767576805",
"sale_order": "0",
"deal_time_happen": 796220,
"deal_time_left": 1624780,
"sale_quantity": "0",
"request_path": "\/deal\/341",
"is_start": 1,
"is_end": 0,
"is_active": "1",
"product_info": {
"id": 6668,
"productName": "HHPC CORE i7 14700KF | 64GB | NVIDIA RTX 5070 12G",
"productSKU": "0",
"price": 44690000,
"proThum": "6668_pc_anubis_14700kf_sale_3.jpg",
"specialOffer": {
"other": [
{
"id": 0,
"title": "<p>\u2b50\u00a0<span style=\"font-size: medium;\"><strong><span style=\"color: #ff0000;\">Gi\u00e1 khuy\u1ebfn m\u00e3i CPU Ryzen 7 9800X3D ch\u1ec9 c\u00f2n<\/span><\/strong><\/span><span style=\"font-size: medium;\"><strong><span style=\"color: #ff0000;\">\u00a0<\/span><span style=\"color: #008000; font-size: x-large;\">10.990.000\u0111<\/span>\u00a0<span style=\"color: #ff0000;\">\u00e1p d\u1ee5ng khi build PC t\u1ea1i Ho\u00e0ng H\u00e0 PC<\/span><\/strong><\/span><\/p>\r\n<p><span style=\"font-size: 12pt;\">\u2b50 Gi\u00e1\u00a0CPU Ryzen 7 9800X3D khi mua k\u00e8m main\u00a0B650 tr\u1edf l\u00ean l\u00e0:\u00a0<span style=\"font-size: 18pt;\"><strong>12.290.000\u0111<\/strong><\/span><\/span><\/p>\r\n<p><span style=\"font-size: 12pt;\">\u2b50 Gi\u00e1 b\u00e1n l\u1ebb\u00a0CPU Ryzen 7 9800X3D l\u00e0:\u00a0<strong><span style=\"font-size: 18pt;\">13.290.000\u0111<\/span><\/strong><\/span><\/p>\r\n<p><span style=\"font-size: 12pt;\">\u2b50 L\u01afU \u00dd: Ch\u01b0\u01a1ng tr\u00ecnh kh\u00f4ng \u00e1p d\u1ee5ng c\u1ed9ng d\u1ed3n v\u1edbi c\u00e1c ch\u01b0\u01a1ng tr\u00ecnh kh\u00e1c<\/span><\/p>\r\n<p><span style=\"font-size: 12pt;\">\u2b50 Ch\u01b0\u01a1ng tr\u00ecnh \u00e1p d\u1ee5ng v\u1edbi kh\u00e1ch h\u00e0ng Build PC c\u00f3 \u0111\u1ee7 th\u00eam 7 linh ki\u1ec7n sau:\u00a0<span style=\"font-size: 12pt;\">VGA,T\u1ea2N NHI\u1ec6T, MAIN, RAM, SSD, NGU\u1ed2N , V\u1ece CASE<\/span><\/span><\/p>",
"type": "",
"thumbnail": "",
"cash_value": 0,
"quantity": 1,
"from_time": "",
"to_time": "",
"url": "",
"description": "",
"status": 1
}
],
"all": [
{
"id": 0,
"title": "<p>\u2b50\u00a0<span style=\"font-size: medium;\"><strong><span style=\"color: #ff0000;\">Gi\u00e1 khuy\u1ebfn m\u00e3i CPU Ryzen 7 9800X3D ch\u1ec9 c\u00f2n<\/span><\/strong><\/span><span style=\"font-size: medium;\"><strong><span style=\"color: #ff0000;\">\u00a0<\/span><span style=\"color: #008000; font-size: x-large;\">10.990.000\u0111<\/span>\u00a0<span style=\"color: #ff0000;\">\u00e1p d\u1ee5ng khi build PC t\u1ea1i Ho\u00e0ng H\u00e0 PC<\/span><\/strong><\/span><\/p>\r\n<p><span style=\"font-size: 12pt;\">\u2b50 Gi\u00e1\u00a0CPU Ryzen 7 9800X3D khi mua k\u00e8m main\u00a0B650 tr\u1edf l\u00ean l\u00e0:\u00a0<span style=\"font-size: 18pt;\"><strong>12.290.000\u0111<\/strong><\/span><\/span><\/p>\r\n<p><span style=\"font-size: 12pt;\">\u2b50 Gi\u00e1 b\u00e1n l\u1ebb\u00a0CPU Ryzen 7 9800X3D l\u00e0:\u00a0<strong><span style=\"font-size: 18pt;\">13.290.000\u0111<\/span><\/strong><\/span><\/p>\r\n<p><span style=\"font-size: 12pt;\">\u2b50 L\u01afU \u00dd: Ch\u01b0\u01a1ng tr\u00ecnh kh\u00f4ng \u00e1p d\u1ee5ng c\u1ed9ng d\u1ed3n v\u1edbi c\u00e1c ch\u01b0\u01a1ng tr\u00ecnh kh\u00e1c<\/span><\/p>\r\n<p><span style=\"font-size: 12pt;\">\u2b50 Ch\u01b0\u01a1ng tr\u00ecnh \u00e1p d\u1ee5ng v\u1edbi kh\u00e1ch h\u00e0ng Build PC c\u00f3 \u0111\u1ee7 th\u00eam 7 linh ki\u1ec7n sau:\u00a0<span style=\"font-size: 12pt;\">VGA,T\u1ea2N NHI\u1ec6T, MAIN, RAM, SSD, NGU\u1ed2N , V\u1ece CASE<\/span><\/span><\/p>",
"type": "",
"thumbnail": "",
"cash_value": 0,
"quantity": 1,
"from_time": "",
"to_time": "",
"url": "",
"description": "",
"status": 1
}
]
},
"productUrl": "\/hhpc-core-i7-14700kf-64gb-rtx-5070-12g",
"productImage": {
"small": "https:\/\/hoanghapccdn.com\/media\/product\/75_6668_pc_anubis_14700kf_sale_3.jpg",
"large": "https:\/\/hoanghapccdn.com\/media\/product\/250_6668_pc_anubis_14700kf_sale_3.jpg",
"original": "https:\/\/hoanghapccdn.com\/media\/product\/6668_pc_anubis_14700kf_sale_3.jpg"
},
"specialOfferGroup": []
}
},
{
"id": "340",
"title": "HHPC CORE i7 14700KF | 64GB | NVIDIA RTX 5060 Ti 16G",
"price": 41100000,
"quantity": "10",
"min_purchase": "1",
"max_purchase": "10",
"to_time": "02-02-2026, 8:30 am",
"is_featured": "0",
"last_update": "1767576799",
"sale_order": "0",
"deal_time_happen": 796220,
"deal_time_left": 1624780,
"sale_quantity": "0",
"request_path": "\/deal\/340",
"is_start": 1,
"is_end": 0,
"is_active": "1",
"product_info": {
"id": 6667,
"productName": "HHPC CORE i7 14700KF | 64GB | NVIDIA RTX 5060 Ti 16G",
"productSKU": "0",
"price": 41890000,
"proThum": "6667_pc_anubis_5060ti_sale.jpg",
"specialOffer": {
"all": []
},
"productUrl": "\/hhpc-core-i7-14700kf-64gb-rtx-5060-ti-16g",
"productImage": {
"small": "https:\/\/hoanghapccdn.com\/media\/product\/75_6667_pc_anubis_5060ti_sale.jpg",
"large": "https:\/\/hoanghapccdn.com\/media\/product\/250_6667_pc_anubis_5060ti_sale.jpg",
"original": "https:\/\/hoanghapccdn.com\/media\/product\/6667_pc_anubis_5060ti_sale.jpg"
},
"specialOfferGroup": []
}
},
{
"id": "330",
"title": "HHPC RYZEN 7 9800X3D | 32G DDR5 | RX 7800 XT 16G",
"price": 41550000,
"quantity": "10",
"min_purchase": "1",
"max_purchase": "10",
"to_time": "02-02-2026, 8:30 am",
"is_featured": "0",
"last_update": "1767576954",
"sale_order": "0",
"deal_time_happen": 796220,
"deal_time_left": 1624780,
"sale_quantity": "0",
"request_path": "\/deal\/330",
"is_start": 1,
"is_end": 0,
"is_active": "1",
"product_info": {
"id": 6246,
"productName": "HHPC RYZEN 7 9800X3D | 32G DDR5 | RX 7800 XT 16G",
"productSKU": "0",
"price": 42380000,
"proThum": "6246_pc_mag_forge_120a_airflow.jpg",
"specialOffer": {
"all": []
},
"productUrl": "\/hhpc-ryzen-7-9800x3d-32g-ddr5-rx-7800-xt-16g",
"productImage": {
"small": "https:\/\/hoanghapccdn.com\/media\/product\/75_6246_pc_mag_forge_120a_airflow.jpg",
"large": "https:\/\/hoanghapccdn.com\/media\/product\/250_6246_pc_mag_forge_120a_airflow.jpg",
"original": "https:\/\/hoanghapccdn.com\/media\/product\/6246_pc_mag_forge_120a_airflow.jpg"
},
"specialOfferGroup": []
}
},
{
"id": "329",
"title": "HHPC RYZEN 7 9800X3D | 32G DDR5 | NVIDIA RTX 5060 8G",
"price": 42050000,
"quantity": "10",
"min_purchase": "1",
"max_purchase": "10",
"to_time": "02-02-2026, 8:30 am",
"is_featured": "0",
"last_update": "1767576950",
"sale_order": "0",
"deal_time_happen": 796220,
"deal_time_left": 1624780,
"sale_quantity": "0",
"request_path": "\/deal\/329",
"is_start": 1,
"is_end": 0,
"is_active": "1",
"product_info": {
"id": 6130,
"productName": "HHPC RYZEN 7 9800X3D | 32G DDR5 | NVIDIA RTX 5060 8G",
"productSKU": "0",
"price": 42880000,
"proThum": "6130_pc_endura_d5_sale_ha1.jpg",
"specialOffer": {
"all": []
},
"productUrl": "\/hhpc-ryzen-7-9800x3d-32g-d5-rtx-5060-8g",
"productImage": {
"small": "https:\/\/hoanghapccdn.com\/media\/product\/75_6130_pc_endura_d5_sale_ha1.jpg",
"large": "https:\/\/hoanghapccdn.com\/media\/product\/250_6130_pc_endura_d5_sale_ha1.jpg",
"original": "https:\/\/hoanghapccdn.com\/media\/product\/6130_pc_endura_d5_sale_ha1.jpg"
},
"specialOfferGroup": []
}
},
{
"id": "328",
"title": "HHPC RYZEN 7 9800X3D | 32G DDR5 | NVIDIA RTX 5090 32G",
"price": 132550000,
"quantity": "10",
"min_purchase": "1",
"max_purchase": "10",
"to_time": "02-02-2026, 8:30 am",
"is_featured": "0",
"last_update": "1767576946",
"sale_order": "0",
"deal_time_happen": 796220,
"deal_time_left": 1624780,
"sale_quantity": "0",
"request_path": "\/deal\/328",
"is_start": 1,
"is_end": 0,
"is_active": "1",
"product_info": {
"id": 6111,
"productName": "HHPC RYZEN 7 9800X3D | 32G DDR5 | NVIDIA RTX 5090 32G",
"productSKU": "0",
"price": 135230000,
"proThum": "6111_pc_endura_d5_sale_ha2.jpg",
"specialOffer": {
"all": []
},
"productUrl": "\/hhpc-ryzen-7-9800x3d-32g-d5-rtx-5090-32g",
"productImage": {
"small": "https:\/\/hoanghapccdn.com\/media\/product\/75_6111_pc_endura_d5_sale_ha2.jpg",
"large": "https:\/\/hoanghapccdn.com\/media\/product\/250_6111_pc_endura_d5_sale_ha2.jpg",
"original": "https:\/\/hoanghapccdn.com\/media\/product\/6111_pc_endura_d5_sale_ha2.jpg"
},
"specialOfferGroup": []
}
},
{
"id": "327",
"title": "HHPC RYZEN 7 9800X3D | 32G DDR5 | NVIDIA RTX 5080 16G",
"price": 70100000,
"quantity": "10",
"min_purchase": "1",
"max_purchase": "10",
"to_time": "02-02-2026, 8:30 am",
"is_featured": "0",
"last_update": "1767577069",
"sale_order": "0",
"deal_time_happen": 796220,
"deal_time_left": 1624780,
"sale_quantity": "0",
"request_path": "\/deal\/327",
"is_start": 1,
"is_end": 0,
"is_active": "1",
"product_info": {
"id": 6110,
"productName": "HHPC RYZEN 7 9800X3D | 32G DDR5 | NVIDIA RTX 5080 16G",
"productSKU": "0",
"price": 71520000,
"proThum": "6110_pc_endura_d5_sale_ha3.jpg",
"specialOffer": {
"all": []
},
"productUrl": "\/hhpc-ryzen-7-9800x3d-32g-d5-rtx-5080-16g",
"productImage": {
"small": "https:\/\/hoanghapccdn.com\/media\/product\/75_6110_pc_endura_d5_sale_ha3.jpg",
"large": "https:\/\/hoanghapccdn.com\/media\/product\/250_6110_pc_endura_d5_sale_ha3.jpg",
"original": "https:\/\/hoanghapccdn.com\/media\/product\/6110_pc_endura_d5_sale_ha3.jpg"
},
"specialOfferGroup": []
}
},
{
"id": "326",
"title": "HHPC RYZEN 7 9800X3D | 32G DDR5 | NVIDIA RTX 5070 Ti 16G",
"price": 57850000,
"quantity": "10",
"min_purchase": "1",
"max_purchase": "10",
"to_time": "02-02-2026, 8:30 am",
"is_featured": "0",
"last_update": "1767576941",
"sale_order": "0",
"deal_time_happen": 796220,
"deal_time_left": 1624780,
"sale_quantity": "0",
"request_path": "\/deal\/326",
"is_start": 1,
"is_end": 0,
"is_active": "1",
"product_info": {
"id": 6109,
"productName": "HHPC RYZEN 7 9800X3D | 32G DDR5 | NVIDIA RTX 5070 Ti 16G",
"productSKU": "0",
"price": 59020000,
"proThum": "6109_pc_endura_d5_sale_ha1.jpg",
"specialOffer": {
"all": []
},
"productUrl": "\/hhpc-ryzen-7-9800x3d-32g-d5-rtx-5070-ti-16g",
"productImage": {
"small": "https:\/\/hoanghapccdn.com\/media\/product\/75_6109_pc_endura_d5_sale_ha1.jpg",
"large": "https:\/\/hoanghapccdn.com\/media\/product\/250_6109_pc_endura_d5_sale_ha1.jpg",
"original": "https:\/\/hoanghapccdn.com\/media\/product\/6109_pc_endura_d5_sale_ha1.jpg"
},
"specialOfferGroup": []
}
},
{
"id": "325",
"title": "HHPC RYZEN 7 9800X3D | 32G DDR5 | NVIDIA RTX 5070 12G",
"price": 49600000,
"quantity": "10",
"min_purchase": "1",
"max_purchase": "10",
"to_time": "02-02-2026, 8:30 am",
"is_featured": "0",
"last_update": "1767576936",
"sale_order": "0",
"deal_time_happen": 796220,
"deal_time_left": 1624780,
"sale_quantity": "0",
"request_path": "\/deal\/325",
"is_start": 1,
"is_end": 0,
"is_active": "1",
"product_info": {
"id": 6108,
"productName": "HHPC RYZEN 7 9800X3D | 32G DDR5 | NVIDIA RTX 5070 12G",
"productSKU": "0",
"price": 50590000,
"proThum": "6108_pc_endura_d5_sale_ha3.jpg",
"specialOffer": {
"all": []
},
"productUrl": "\/hhpc-ryzen-7-9800x3d-32g-d5-rtx-5070-12g",
"productImage": {
"small": "https:\/\/hoanghapccdn.com\/media\/product\/75_6108_pc_endura_d5_sale_ha3.jpg",
"large": "https:\/\/hoanghapccdn.com\/media\/product\/250_6108_pc_endura_d5_sale_ha3.jpg",
"original": "https:\/\/hoanghapccdn.com\/media\/product\/6108_pc_endura_d5_sale_ha3.jpg"
},
"specialOfferGroup": []
}
},
{
"id": "324",
"title": "HHPC RYZEN 7 9800X3D | 32G DDR5 | NVIDIA RTX 5060 Ti 16G",
"price": 46650000,
"quantity": "10",
"min_purchase": "1",
"max_purchase": "10",
"to_time": "02-02-2026, 8:30 am",
"is_featured": "0",
"last_update": "1767576932",
"sale_order": "0",
"deal_time_happen": 796220,
"deal_time_left": 1624780,
"sale_quantity": "0",
"request_path": "\/deal\/324",
"is_start": 1,
"is_end": 0,
"is_active": "1",
"product_info": {
"id": 6106,
"productName": "HHPC RYZEN 7 9800X3D | 32G DDR5 | NVIDIA RTX 5060 Ti 16G",
"productSKU": "0",
"price": 47590000,
"proThum": "6106_pc_endura_d5_sale_ha2.jpg",
"specialOffer": {
"all": []
},
"productUrl": "\/hhpc-ryzen-7-9800x3d-32g-d5-rtx-5060-ti-16g",
"productImage": {
"small": "https:\/\/hoanghapccdn.com\/media\/product\/75_6106_pc_endura_d5_sale_ha2.jpg",
"large": "https:\/\/hoanghapccdn.com\/media\/product\/250_6106_pc_endura_d5_sale_ha2.jpg",
"original": "https:\/\/hoanghapccdn.com\/media\/product\/6106_pc_endura_d5_sale_ha2.jpg"
},
"specialOfferGroup": []
}
}
]
},
{
"total": 34,
"collection_info": {
"id": 2,
"title": "Linh ki\u1ec7n Flash Sale",
"summary": ""
},
"list": [
{
"id": "364",
"title": "Tai nghe kh\u00f4ng d\u00e2y Corsair HS55 Wireless Core Black",
"price": "1390000",
"quantity": "10",
"min_purchase": "1",
"max_purchase": "10",
"to_time": "02-02-2026, 8:30 am",
"is_featured": "0",
"last_update": "1768017144",
"sale_order": "0",
"deal_time_happen": 364434,
"deal_time_left": 1624566,
"sale_quantity": "0",
"request_path": "\/deal\/364",
"is_start": 1,
"is_end": 0,
"is_active": "1",
"product_info": {
"id": 6569,
"productName": "Tai nghe kh\u00f4ng d\u00e2y Corsair HS55 Wireless Core Black",
"productSKU": "0",
"price": 1590000,
"proThum": "6569_hs55_wireless_core_sale.jpg",
"specialOffer": {
"other": [
{
"id": 0,
"title": "<p>\u2b50\u00a0<span style=\"font-size: medium;\"><strong><span style=\"color: #ff0000;\">Gi\u00e1 khuy\u1ebfn m\u00e3i CPU Ryzen 7 9800X3D ch\u1ec9 c\u00f2n<\/span><\/strong><\/span><span style=\"font-size: medium;\"><strong><span style=\"color: #ff0000;\">\u00a0<\/span><span style=\"color: #008000; font-size: x-large;\">10.990.000\u0111<\/span>\u00a0<span style=\"color: #ff0000;\">\u00e1p d\u1ee5ng khi build PC t\u1ea1i Ho\u00e0ng H\u00e0 PC<\/span><\/strong><\/span><\/p>\r\n<p><span style=\"font-size: 12pt;\">\u2b50 Gi\u00e1\u00a0CPU Ryzen 7 9800X3D khi mua k\u00e8m main\u00a0B650 tr\u1edf l\u00ean l\u00e0:\u00a0<span style=\"font-size: 18pt;\"><strong>12.290.000\u0111<\/strong><\/span><\/span><\/p>\r\n<p><span style=\"font-size: 12pt;\">\u2b50 Gi\u00e1 b\u00e1n l\u1ebb\u00a0CPU Ryzen 7 9800X3D l\u00e0:\u00a0<strong><span style=\"font-size: 18pt;\">13.290.000\u0111<\/span><\/strong><\/span><\/p>\r\n<p><span style=\"font-size: 12pt;\">\u2b50 L\u01afU \u00dd: Ch\u01b0\u01a1ng tr\u00ecnh kh\u00f4ng \u00e1p d\u1ee5ng c\u1ed9ng d\u1ed3n v\u1edbi c\u00e1c ch\u01b0\u01a1ng tr\u00ecnh kh\u00e1c<\/span><\/p>\r\n<p><span style=\"font-size: 12pt;\">\u2b50 Ch\u01b0\u01a1ng tr\u00ecnh \u00e1p d\u1ee5ng v\u1edbi kh\u00e1ch h\u00e0ng Build PC c\u00f3 \u0111\u1ee7 th\u00eam 7 linh ki\u1ec7n sau:\u00a0<span style=\"font-size: 12pt;\">VGA,T\u1ea2N NHI\u1ec6T, MAIN, RAM, SSD, NGU\u1ed2N , V\u1ece CASE<\/span><\/span><\/p>",
"type": "",
"thumbnail": "",
"cash_value": 0,
"quantity": 1,
"from_time": "",
"to_time": "",
"url": "",
"description": "",
"status": 1
}
],
"all": [
{
"id": 0,
"title": "<p>\u2b50\u00a0<span style=\"font-size: medium;\"><strong><span style=\"color: #ff0000;\">Gi\u00e1 khuy\u1ebfn m\u00e3i CPU Ryzen 7 9800X3D ch\u1ec9 c\u00f2n<\/span><\/strong><\/span><span style=\"font-size: medium;\"><strong><span style=\"color: #ff0000;\">\u00a0<\/span><span style=\"color: #008000; font-size: x-large;\">10.990.000\u0111<\/span>\u00a0<span style=\"color: #ff0000;\">\u00e1p d\u1ee5ng khi build PC t\u1ea1i Ho\u00e0ng H\u00e0 PC<\/span><\/strong><\/span><\/p>\r\n<p><span style=\"font-size: 12pt;\">\u2b50 Gi\u00e1\u00a0CPU Ryzen 7 9800X3D khi mua k\u00e8m main\u00a0B650 tr\u1edf l\u00ean l\u00e0:\u00a0<span style=\"font-size: 18pt;\"><strong>12.290.000\u0111<\/strong><\/span><\/span><\/p>\r\n<p><span style=\"font-size: 12pt;\">\u2b50 Gi\u00e1 b\u00e1n l\u1ebb\u00a0CPU Ryzen 7 9800X3D l\u00e0:\u00a0<strong><span style=\"font-size: 18pt;\">13.290.000\u0111<\/span><\/strong><\/span><\/p>\r\n<p><span style=\"font-size: 12pt;\">\u2b50 L\u01afU \u00dd: Ch\u01b0\u01a1ng tr\u00ecnh kh\u00f4ng \u00e1p d\u1ee5ng c\u1ed9ng d\u1ed3n v\u1edbi c\u00e1c ch\u01b0\u01a1ng tr\u00ecnh kh\u00e1c<\/span><\/p>\r\n<p><span style=\"font-size: 12pt;\">\u2b50 Ch\u01b0\u01a1ng tr\u00ecnh \u00e1p d\u1ee5ng v\u1edbi kh\u00e1ch h\u00e0ng Build PC c\u00f3 \u0111\u1ee7 th\u00eam 7 linh ki\u1ec7n sau:\u00a0<span style=\"font-size: 12pt;\">VGA,T\u1ea2N NHI\u1ec6T, MAIN, RAM, SSD, NGU\u1ed2N , V\u1ece CASE<\/span><\/span><\/p>",
"type": "",
"thumbnail": "",
"cash_value": 0,
"quantity": 1,
"from_time": "",
"to_time": "",
"url": "",
"description": "",
"status": 1
}
]
},
"productUrl": "\/tai-nghe-corsair-hs55-wireless-core-black",
"productImage": {
"small": "https:\/\/hoanghapccdn.com\/media\/product\/75_6569_hs55_wireless_core_sale.jpg",
"large": "https:\/\/hoanghapccdn.com\/media\/product\/250_6569_hs55_wireless_core_sale.jpg",
"original": "https:\/\/hoanghapccdn.com\/media\/product\/6569_hs55_wireless_core_sale.jpg"
},
"specialOfferGroup": []
}
},
{
"id": "363",
"title": "Tai nghe Corsair HS55 Surround Carbon",
"price": "1390000",
"quantity": "10",
"min_purchase": "1",
"max_purchase": "10",
"to_time": "02-02-2026, 8:30 am",
"is_featured": "0",
"last_update": "1768017107",
"sale_order": "0",
"deal_time_happen": 364434,
"deal_time_left": 1624566,
"sale_quantity": "0",
"request_path": "\/deal\/363",
"is_start": 1,
"is_end": 0,
"is_active": "1",
"product_info": {
"id": 6644,
"productName": "Tai nghe Corsair HS55 Surround Carbon",
"productSKU": "0",
"price": 1590000,
"proThum": "6644_hs55_surround_carbon_sale.jpg",
"specialOffer": {
"all": []
},
"productUrl": "\/tai-nghe-corsair-hs55-surround-carbon",
"productImage": {
"small": "https:\/\/hoanghapccdn.com\/media\/product\/75_6644_hs55_surround_carbon_sale.jpg",
"large": "https:\/\/hoanghapccdn.com\/media\/product\/250_6644_hs55_surround_carbon_sale.jpg",
"original": "https:\/\/hoanghapccdn.com\/media\/product\/6644_hs55_surround_carbon_sale.jpg"
},
"specialOfferGroup": []
}
},
{
"id": "362",
"title": "VGA GIGABYTE GEFORCE RTX 5080 WINDFORCE OC SFF 16G (GDDR7, 256-bit, HDMI +DP, 1x16-pin)",
"price": "31990000",
"quantity": "10",
"min_purchase": "1",
"max_purchase": "10",
"to_time": "02-02-2026, 8:30 am",
"is_featured": "0",
"last_update": "1767853933",
"sale_order": "1",
"deal_time_happen": 537234,
"deal_time_left": 1624566,
"sale_quantity": "1",
"request_path": "\/deal\/362",
"is_start": 1,
"is_end": 0,
"is_active": "1",
"product_info": {
"id": 5678,
"productName": "VGA GIGABYTE GEFORCE RTX 5080 WINDFORCE OC SFF 16G (GDDR7, 256-bit, HDMI +DP, 1x16-pin)",
"productSKU": "0",
"price": 34990000,
"proThum": "5678_rtx_5080_windforce_oc_sff_sale.jpg",
"specialOffer": {
"all": []
},
"productUrl": "\/vga-gigabyte-geforce-rtx-5080-windforce-oc-sff-16g",
"productImage": {
"small": "https:\/\/hoanghapccdn.com\/media\/product\/75_5678_rtx_5080_windforce_oc_sff_sale.jpg",
"large": "https:\/\/hoanghapccdn.com\/media\/product\/250_5678_rtx_5080_windforce_oc_sff_sale.jpg",
"original": "https:\/\/hoanghapccdn.com\/media\/product\/5678_rtx_5080_windforce_oc_sff_sale.jpg"
},
"specialOfferGroup": []
}
},
{
"id": "361",
"title": "B\u00e0n ph\u00edm c\u01a1 DareU EK106 PRO Black Golden Cloud switch",
"price": "1290000",
"quantity": "10",
"min_purchase": "1",
"max_purchase": "10",
"to_time": "02-02-2026, 8:30 am",
"is_featured": "0",
"last_update": "1767585250",
"sale_order": "2",
"deal_time_happen": 796434,
"deal_time_left": 1624566,
"sale_quantity": "2",
"request_path": "\/deal\/361",
"is_start": 1,
"is_end": 0,
"is_active": "1",
"product_info": {
"id": 6061,
"productName": "B\u00e0n ph\u00edm c\u01a1 DareU EK106 PRO Black Golden Cloud switch",
"productSKU": "0",
"price": 1490000,
"proThum": "6061_ek106_pro_sale.jpg",
"specialOffer": {
"all": []
},
"productUrl": "\/ban-phim-co-dareu-ek106-pro-black-golden-cloud",
"productImage": {
"small": "https:\/\/hoanghapccdn.com\/media\/product\/75_6061_ek106_pro_sale.jpg",
"large": "https:\/\/hoanghapccdn.com\/media\/product\/250_6061_ek106_pro_sale.jpg",
"original": "https:\/\/hoanghapccdn.com\/media\/product\/6061_ek106_pro_sale.jpg"
},
"specialOfferGroup": []
}
},
{
"id": "359",
"title": "Fan Asus TUF GAMING TF120 ARGB 3IN1 WHITE",
"price": "590000",
"quantity": "10",
"min_purchase": "1",
"max_purchase": "10",
"to_time": "02-02-2026, 8:30 am",
"is_featured": "0",
"last_update": "1767576873",
"sale_order": "0",
"deal_time_happen": 796434,
"deal_time_left": 1624566,
"sale_quantity": "0",
"request_path": "\/deal\/359",
"is_start": 1,
"is_end": 0,
"is_active": "1",
"product_info": {
"id": 4037,
"productName": "Fan Asus TUF GAMING TF120 ARGB 3IN1 WHITE",
"productSKU": "0",
"price": 790000,
"proThum": "4037_tf120_white_sale.jpg",
"specialOffer": {
"all": []
},
"productUrl": "\/fan-asus-tuf-gaming-tf120-argb-3in1-white",
"productImage": {
"small": "https:\/\/hoanghapccdn.com\/media\/product\/75_4037_tf120_white_sale.jpg",
"large": "https:\/\/hoanghapccdn.com\/media\/product\/250_4037_tf120_white_sale.jpg",
"original": "https:\/\/hoanghapccdn.com\/media\/product\/4037_tf120_white_sale.jpg"
},
"specialOfferGroup": []
}
},
{
"id": "358",
"title": "Fan Asus TUF GAMING TF120 ARGB 3IN1 ",
"price": "590000",
"quantity": "10",
"min_purchase": "1",
"max_purchase": "10",
"to_time": "02-02-2026, 8:30 am",
"is_featured": "0",
"last_update": "1767576869",
"sale_order": "0",
"deal_time_happen": 796434,
"deal_time_left": 1624566,
"sale_quantity": "0",
"request_path": "\/deal\/358",
"is_start": 1,
"is_end": 0,
"is_active": "1",
"product_info": {
"id": 3536,
"productName": "Fan Asus TUF GAMING TF120 ARGB 3IN1 ",
"productSKU": "0",
"price": 790000,
"proThum": "3536_tf120_sale.jpg",
"specialOffer": {
"all": []
},
"productUrl": "\/fan-asus-tuf-gaming-tf120-argb-3in1",
"productImage": {
"small": "https:\/\/hoanghapccdn.com\/media\/product\/75_3536_tf120_sale.jpg",
"large": "https:\/\/hoanghapccdn.com\/media\/product\/250_3536_tf120_sale.jpg",
"original": "https:\/\/hoanghapccdn.com\/media\/product\/3536_tf120_sale.jpg"
},
"specialOfferGroup": []
}
},
{
"id": "357",
"title": "V\u1ecf case Hyte Y60 Snow White - Mid Tower ATX",
"price": "3990000",
"quantity": "10",
"min_purchase": "1",
"max_purchase": "10",
"to_time": "02-02-2026, 8:30 am",
"is_featured": "0",
"last_update": "1767576982",
"sale_order": "0",
"deal_time_happen": 796434,
"deal_time_left": 1624566,
"sale_quantity": "0",
"request_path": "\/deal\/357",
"is_start": 1,
"is_end": 0,
"is_active": "1",
"product_info": {
"id": 4625,
"productName": "V\u1ecf case Hyte Y60 Snow White - Mid Tower ATX",
"productSKU": "0",
"price": 5190000,
"proThum": "4625_y60_white_sale.jpg",
"specialOffer": {
"all": []
},
"productUrl": "\/vo-case-hyte-y60-snow-white-mid-tower-atx",
"productImage": {
"small": "https:\/\/hoanghapccdn.com\/media\/product\/75_4625_y60_white_sale.jpg",
"large": "https:\/\/hoanghapccdn.com\/media\/product\/250_4625_y60_white_sale.jpg",
"original": "https:\/\/hoanghapccdn.com\/media\/product\/4625_y60_white_sale.jpg"
},
"specialOfferGroup": []
}
},
{
"id": "356",
"title": "V\u1ecf case Hyte Y60 Black - Mid Tower ATX",
"price": "3990000",
"quantity": "10",
"min_purchase": "1",
"max_purchase": "10",
"to_time": "02-02-2026, 8:30 am",
"is_featured": "0",
"last_update": "1767576860",
"sale_order": "0",
"deal_time_happen": 796434,
"deal_time_left": 1624566,
"sale_quantity": "0",
"request_path": "\/deal\/356",
"is_start": 1,
"is_end": 0,
"is_active": "1",
"product_info": {
"id": 4624,
"productName": "V\u1ecf case Hyte Y60 Black - Mid Tower ATX",
"productSKU": "0",
"price": 5190000,
"proThum": "4624_y60_black_sale.jpg",
"specialOffer": {
"all": []
},
"productUrl": "\/vo-case-hyte-y60-black-mid-tower-atx",
"productImage": {
"small": "https:\/\/hoanghapccdn.com\/media\/product\/75_4624_y60_black_sale.jpg",
"large": "https:\/\/hoanghapccdn.com\/media\/product\/250_4624_y60_black_sale.jpg",
"original": "https:\/\/hoanghapccdn.com\/media\/product\/4624_y60_black_sale.jpg"
},
"specialOfferGroup": []
}
},
{
"id": "352",
"title": "T\u1ea3n nhi\u1ec7t CPU Thermalright AXP-100RH",
"price": "990000",
"quantity": "10",
"min_purchase": "1",
"max_purchase": "10",
"to_time": "02-02-2026, 8:30 am",
"is_featured": "0",
"last_update": "1767576852",
"sale_order": "0",
"deal_time_happen": 796434,
"deal_time_left": 1624566,
"sale_quantity": "0",
"request_path": "\/deal\/352",
"is_start": 1,
"is_end": 0,
"is_active": "1",
"product_info": {
"id": 1985,
"productName": "T\u1ea3n nhi\u1ec7t CPU Thermalright AXP-100RH",
"productSKU": "0",
"price": 1590000,
"proThum": "1985_axp_100_rh_sale.jpg",
"specialOffer": {
"all": []
},
"productUrl": "\/tan-nhiet-thermalright-axp-100rh",
"productImage": {
"small": "https:\/\/hoanghapccdn.com\/media\/product\/75_1985_axp_100_rh_sale.jpg",
"large": "https:\/\/hoanghapccdn.com\/media\/product\/250_1985_axp_100_rh_sale.jpg",
"original": "https:\/\/hoanghapccdn.com\/media\/product\/1985_axp_100_rh_sale.jpg"
},
"specialOfferGroup": []
}
},
{
"id": "351",
"title": "T\u1ea3n nhi\u1ec7t CPU Thermalright AXP-100 C65",
"price": "1290000",
"quantity": "10",
"min_purchase": "1",
"max_purchase": "10",
"to_time": "02-02-2026, 8:30 am",
"is_featured": "0",
"last_update": "1767576848",
"sale_order": "0",
"deal_time_happen": 796434,
"deal_time_left": 1624566,
"sale_quantity": "0",
"request_path": "\/deal\/351",
"is_start": 1,
"is_end": 0,
"is_active": "1",
"product_info": {
"id": 1986,
"productName": "T\u1ea3n nhi\u1ec7t CPU Thermalright AXP-100 C65",
"productSKU": "0",
"price": 1990000,
"proThum": "1986_axp_100_c65_sale.jpg",
"specialOffer": {
"all": []
},
"productUrl": "\/thermalright-axp-100-c65",
"productImage": {
"small": "https:\/\/hoanghapccdn.com\/media\/product\/75_1986_axp_100_c65_sale.jpg",
"large": "https:\/\/hoanghapccdn.com\/media\/product\/250_1986_axp_100_c65_sale.jpg",
"original": "https:\/\/hoanghapccdn.com\/media\/product\/1986_axp_100_c65_sale.jpg"
},
"specialOfferGroup": []
}
}
],
}
]

File diff suppressed because it is too large Load Diff

11910
src/data/products/index.tsx Normal file

File diff suppressed because it is too large Load Diff

53
src/hooks/useCart.ts Normal file
View File

@@ -0,0 +1,53 @@
'use client';
import { useEffect, useState, useCallback } from 'react';
import {
getCartProductIds,
addProductToCart,
removeProductFromCart,
clearCart,
} from '../services/cart';
export function useCart() {
const [cartIds, setCartIds] = useState<number[] | null>(null);
// Load cart lần đầu
useEffect(() => {
setCartIds(getCartProductIds());
}, []);
const refresh = useCallback(() => {
setCartIds(getCartProductIds());
}, []);
const addToCart = useCallback((productId: number) => {
addProductToCart(productId);
refresh();
}, [refresh]);
const removeFromCart = useCallback((productId: number) => {
removeProductFromCart(productId);
refresh();
}, [refresh]);
const clear = useCallback(() => {
clearCart();
setCartIds([]);
}, []);
const isInCart = useCallback(
(productId: number) => cartIds?.includes(productId) ?? false,
[cartIds]
);
return {
cartIds: cartIds ?? [],
cartCount: cartIds?.length ?? 0,
loading: cartIds === null,
addToCart,
removeFromCart,
clear,
isInCart,
};
}

26
src/hooks/useDealItem.ts Normal file
View File

@@ -0,0 +1,26 @@
import { calculateDiscount } from "../lib/utils";
import type { DealItemProps } from "../types/deal"
export function useDealItem(item: DealItemProps) {
if (item.deal_time_left <= 0) return null;
const productInfo = item.product_info;
const price = Number(item.price);
const marketPrice = Number(productInfo.price);
const discount = calculateDiscount(price, marketPrice);
const remain = item.quantity - item.sale_quantity;
const saleRemainPercent = 100 - (item.sale_quantity / item.quantity) * 100;
const specialOffer = productInfo?.specialOffer?.all?.[0]?.title ?? '';
return {
productInfo,
price,
marketPrice,
discount,
remain,
saleRemainPercent,
specialOffer,
};
}

20
src/lib/utils.tsx Normal file
View File

@@ -0,0 +1,20 @@
// Add tất cả sp trong data product vào 1 mảng
import { productList } from '@/data/products';
export function getAllProducts() {
return productList.flatMap((group:any) => group.list);
}
// Format giá
export function formatPrice(amount: number) {
return amount.toLocaleString('vi-VN');
}
// Tính % giảm giá
export function calculateDiscount(
price: number,
marketPrice: number
) {
if (price <= 0 || marketPrice <= price) return 0;
return Math.ceil(((marketPrice - price) / marketPrice) * 100);
}

48
src/services/cart.ts Normal file
View File

@@ -0,0 +1,48 @@
'use client';
const CART_KEY = 'cart_product_ids';
// 1. Lấy danh sách ID
export function getCartProductIds(): number[] {
if (typeof window === 'undefined') return [];
try {
const raw = localStorage.getItem(CART_KEY);
return raw ? (JSON.parse(raw) as number[]) : [];
} catch (error) {
console.error('Invalid cart data', error);
return [];
}
}
// 2. Thêm sản phẩm
export function addProductToCart(productId: number) {
if (typeof window === 'undefined') return;
const ids = getCartProductIds();
if (ids.includes(productId)) {
console.log('Product đã tồn tại:', productId);
return;
}
ids.push(productId);
localStorage.setItem(CART_KEY, JSON.stringify(ids));
}
// 3. Xóa 1 sản phẩm
export function removeProductFromCart(productId: number) {
if (typeof window === 'undefined') return;
const ids = getCartProductIds();
const newIds = ids.filter(id => id !== productId);
localStorage.setItem(CART_KEY, JSON.stringify(newIds));
}
// 4. Xóa giỏ hàng
export function clearCart() {
if (typeof window === 'undefined') return;
localStorage.removeItem(CART_KEY);
}

View File

@@ -208,6 +208,9 @@ body{min-width:1248px;background:#E8ECF6}
.home-banner-container a{border-radius:8px;overflow:hidden;display:block;position:relative} .home-banner-container a{border-radius:8px;overflow:hidden;display:block;position:relative}
.home-banner-container a:hover::before{width:120%;background-color:rgba(255,255,255,0);z-index:2;transition:.45s ease-out} .home-banner-container a:hover::before{width:120%;background-color:rgba(255,255,255,0);z-index:2;transition:.45s ease-out}
.home-banner-container a::before{content:"";position:absolute;top:0;left:-15%;bottom:0;width:0;height:100%;background-color:rgba(255,255,255,0.5);transition:none;transform:skewX(-25deg)} .home-banner-container a::before{content:"";position:absolute;top:0;left:-15%;bottom:0;width:0;height:100%;background-color:rgba(255,255,255,0.5);transition:none;transform:skewX(-25deg)}
.home-banner-right a{margin-bottom: 16px;}
.home-banner-right a:last-child{margin-bottom: 0;}
.home-banner-left {max-height: 420px;overflow: hidden;}
.deal-container{position:relative;/*background:linear-gradient(3.56deg,#41A7FF 16.18%,#114CDD 115.33%)*/} .deal-container{position:relative;/*background:linear-gradient(3.56deg,#41A7FF 16.18%,#114CDD 115.33%)*/}
/*.deal-container::before{content:"";background:url(/images/deal-bg.png) no-repeat;z-index:1;position:absolute;top:0;right:0;height:50%;width:50%;opacity:.8;background-size:contain;background-position:bottom}*/ /*.deal-container::before{content:"";background:url(/images/deal-bg.png) no-repeat;z-index:1;position:absolute;top:0;right:0;height:50%;width:50%;opacity:.8;background-size:contain;background-position:bottom}*/
.deal-container .deal-time-holder{display:flex;align-items:center;color:#333;font-weight:700;font-size:18px;gap:24px;text-align:center} .deal-container .deal-time-holder{display:flex;align-items:center;color:#333;font-weight:700;font-size:18px;gap:24px;text-align:center}
@@ -491,6 +494,7 @@ body{min-width:1248px;background:#E8ECF6}
.footer-contact-info > p{font-size:20px;line-height:26px} .footer-contact-info > p{font-size:20px;line-height:26px}
.global-faq-container{padding-top:64px;padding-bottom:64px} .global-faq-container{padding-top:64px;padding-bottom:64px}
.home-page .banner-slider{width:1196px} .home-page .banner-slider{width:1196px}
.home-banner-left {max-height: 792px;}
.deal-container .group-title a{font-size:18px} .deal-container .group-title a{font-size:18px}
.home-categories-container .group-title{line-height:40px;font-size:32px} .home-categories-container .group-title{line-height:40px;font-size:32px}
.home-categories-container .item{padding:8px;font-size:16px;line-height:20px} .home-categories-container .item{padding:8px;font-size:16px;line-height:20px}

8
src/types/deal.ts Normal file
View File

@@ -0,0 +1,8 @@
// src/types/deal.ts
export type DealItemProps = {
deal_time_left: number;
price: number;
quantity: number;
sale_quantity: number;
product_info: any;
};