This commit is contained in:
2025-12-25 19:03:33 +07:00
24 changed files with 3440 additions and 2578 deletions

View File

@@ -0,0 +1,46 @@
'use client';
import Link from 'next/link';
import { FaHouse, FaAngleRight } from 'react-icons/fa6';
interface BreadcrumbItem {
name: string | undefined;
url: string | undefined;
}
export const Breadcrumb = ({ items }: { items: BreadcrumbItem[] }) => {
return (
<nav className="box-breadcrumb-global mb-4 text-sm text-gray-600">
<ol itemScope itemType="http://schema.org/BreadcrumbList" className="flex gap-2">
<li
itemProp="itemListElement"
itemScope
itemType="http://schema.org/ListItem"
className="flex items-center gap-2"
>
<Link href="/" itemProp="item">
<span itemProp="name" className="flex items-center gap-2">
<span style={{ fontSize: 0 }}>Trang chủ</span> <FaHouse className="text-gray-700" />
</span>
</Link>{' '}
<FaAngleRight className="text-gray-700" />
<meta itemProp="position" content="1" />
</li>
{items.map((item, idx) => (
<li
key={idx}
itemProp="itemListElement"
itemScope
itemType="http://schema.org/ListItem"
className="flex items-center"
>
<Link href={item.url ?? '/'} itemProp="item">
<span itemProp="name">{item?.name}</span>
</Link>
<meta itemProp="position" content={(idx + 1).toString()} />
{idx < items.length - 1 && <span className="mx-1">/</span>}
</li>
))}
</ol>
</nav>
);
};

View File

@@ -4,7 +4,7 @@ import Link from 'next/link';
import { FaCaretDown } from 'react-icons/fa';
import { Swiper, SwiperSlide } from 'swiper/react';
import { Autoplay, Navigation, Pagination } from 'swiper/modules';
import ItemProduct from './ItemProduct';
import ItemProduct from '@/components/common/ItemProduct';
import { InfoCategory } from '@/types';

View File

@@ -1,757 +0,0 @@
import { BannerType } from '@/types/';
export const bannerData: BannerType = [
{
footer: {
banner_feedback: [
{
id: '196',
display:
"<a href=\"\/ad.php?id=196\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/14_Feb499f6fcf67f5520d1a7eb5c2e316d7ca.jpg\" width='790' height='400' alt=\"\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/14_Feb499f6fcf67f5520d1a7eb5c2e316d7ca.jpg',
desUrl: '\/ad.php?id=196',
title: '',
width: 790,
height: 400,
fileType: '',
summary: '',
},
{
id: '188',
display:
"<a href=\"\/ad.php?id=188\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/13_Febfe8f184d41a91df0d0f4fe433afb4a30.jpg\" width='790' height='400' alt=\"\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/13_Febfe8f184d41a91df0d0f4fe433afb4a30.jpg',
desUrl: '\/ad.php?id=188',
title: '',
width: 790,
height: 400,
fileType: '',
summary: '',
},
{
id: '189',
display:
"<a href=\"\/ad.php?id=189\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/13_Feb231f8f3ef1ee2d9605570a98f8b9d853.jpg\" width='790' height='400' alt=\"\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/13_Feb231f8f3ef1ee2d9605570a98f8b9d853.jpg',
desUrl: '\/ad.php?id=189',
title: '',
width: 790,
height: 400,
fileType: '',
summary: '',
},
{
id: '190',
display:
'<img border=0 src="https://nguyencongpc.vn\/media\/banner\/13_Feb815db13ba0e07cce7e5dbc99c3211970.jpg" width=\'790\' height=\'400\' alt=""\/>',
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/13_Feb815db13ba0e07cce7e5dbc99c3211970.jpg',
desUrl: '\/ad.php?id=190',
title: '',
width: 790,
height: 400,
fileType: '',
summary: '',
},
{
id: '191',
display:
"<a href=\"\/ad.php?id=191\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/13_Febbfe1281e7c753c3c0b844d2bacf7a3bd.jpg\" width='790' height='400' alt=\"\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/13_Febbfe1281e7c753c3c0b844d2bacf7a3bd.jpg',
desUrl: '\/ad.php?id=191',
title: '',
width: 790,
height: 400,
fileType: '',
summary: '',
},
{
id: '192',
display:
'<img border=0 src="https://nguyencongpc.vn\/media\/banner\/13_Feb7ac521b18c28f89be733d85f4e7ea2c0.jpg" width=\'790\' height=\'400\' alt=""\/>',
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/13_Feb7ac521b18c28f89be733d85f4e7ea2c0.jpg',
desUrl: '\/ad.php?id=192',
title: '',
width: 790,
height: 400,
fileType: '',
summary: '',
},
{
id: '193',
display:
"<a href=\"\/ad.php?id=193\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/13_Feb4a9811eda56defbf8b032a1429876515.jpg\" width='790' height='400' alt=\"\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/13_Feb4a9811eda56defbf8b032a1429876515.jpg',
desUrl: '\/ad.php?id=193',
title: '',
width: 790,
height: 400,
fileType: '',
summary: '',
},
],
banner_column_right: [
{
id: '285',
display:
"<a href=\"\/ad.php?id=285\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/29_Nov87b09c002980d1cbc1ba4f911dcf34fc.webp\" width='600' height='1812' alt=\"\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/29_Nov87b09c002980d1cbc1ba4f911dcf34fc.webp',
desUrl: '\/ad.php?id=285',
title: '',
width: 600,
height: 1812,
fileType: '',
summary: '',
},
],
banner_column_left: [
{
id: '286',
display:
"<a href=\"\/ad.php?id=286\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/01_Dec18c0af23ff50e3acf958695c258d4f6e.webp\" width='600' height='1812' alt=\"\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/01_Dec18c0af23ff50e3acf958695c258d4f6e.webp',
desUrl: '\/ad.php?id=286',
title: '',
width: 600,
height: 1812,
fileType: '',
summary: '',
},
],
},
header: {
banner_buildpc: [
{
id: '406',
display:
"<a href=\"\/ad.php?id=406\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/11_Novf4f82c644b6ea5fbeb0ef6fc5ceb9c08.jpg\" width='2360' height='316' alt=\"\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/11_Novf4f82c644b6ea5fbeb0ef6fc5ceb9c08.jpg',
desUrl: '\/ad.php?id=406',
title: '',
width: 2360,
height: 316,
fileType: '1',
summary: '',
},
{
id: '490',
display:
'<img border=0 src="https://nguyencongpc.vn\/media\/banner\/02_Decf1b77a9ec940fcf31fa7359fe29e35f1.webp" width=\'1200\' height=\'161\' alt=""\/>',
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/02_Decf1b77a9ec940fcf31fa7359fe29e35f1.webp',
desUrl: '\/ad.php?id=490',
title: '',
width: 1200,
height: 161,
fileType: '',
summary: '',
},
{
id: '489',
display:
'<img border=0 src="https://nguyencongpc.vn\/media\/banner\/02_Dec65c8fe933bee00be5c1c70f1f3f46085.webp" width=\'1200\' height=\'161\' alt=""\/>',
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/02_Dec65c8fe933bee00be5c1c70f1f3f46085.webp',
desUrl: '\/ad.php?id=489',
title: '',
width: 1200,
height: 161,
fileType: '',
summary: '',
},
],
banner_header_top_mb_2023: [
{
id: '393',
display:
"<a href=\"\/ad.php?id=393\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/01_Deca35f147ff1e98fd991ac841136f42d66.webp\" width='695' height='67' alt=\"\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/01_Deca35f147ff1e98fd991ac841136f42d66.webp',
desUrl: '\/ad.php?id=393',
title: '',
width: 695,
height: 67,
fileType: '',
summary: '',
},
{
id: '459',
display:
"<a href=\"\/ad.php?id=459\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/01_Dec515584a8a6e976d27def69db45dbb176.webp\" width='695' height='67' alt=\"Banner tuy\u1ec3n d\u1ee5ng\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/01_Dec515584a8a6e976d27def69db45dbb176.webp',
desUrl: '\/ad.php?id=459',
title: 'Banner tuy\u1ec3n d\u1ee5ng',
width: 695,
height: 67,
fileType: '',
summary: '',
},
],
banner_header_top: [
{
id: '429',
display:
"<a href=\"\/ad.php?id=429\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/01_Decc0f3e158e61fabaf09a74d48e1c357bd.webp\" width='1909' height='57' alt=\"\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/01_Decc0f3e158e61fabaf09a74d48e1c357bd.webp',
desUrl: '\/ad.php?id=429',
title: '',
width: 1909,
height: 57,
fileType: '',
summary: '',
},
{
id: '392',
display:
"<a href=\"\/ad.php?id=392\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/01_Dec383fdcbc6361363bd6d14f05d2c88ee2.webp\" width='1909' height='57' alt=\"\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/01_Dec383fdcbc6361363bd6d14f05d2c88ee2.webp',
desUrl: '\/ad.php?id=392',
title: '',
width: 1909,
height: 57,
fileType: '',
summary: '',
},
],
banner_page_deal_2023: [
{
id: '299',
display:
'<img border=0 src="https://nguyencongpc.vn\/media\/banner\/16_Jan0020c1620255554792b53307703d1377.jpg" width=\'1500\' height=\'415\' alt=""\/>',
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/16_Jan0020c1620255554792b53307703d1377.jpg',
desUrl: '\/ad.php?id=299',
title: '',
width: 1500,
height: 415,
fileType: 'banner',
summary: '',
},
],
banner_column_left: [
{
id: '283',
display:
'<img border=0 src="https://nguyencongpc.vn\/media\/banner\/11_Aug8d0ed894020346db278b6035ca259ac3.png" width=\'103\' height=\'309\' alt=""\/>',
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/11_Aug8d0ed894020346db278b6035ca259ac3.png',
desUrl: '\/ad.php?id=283',
title: '',
width: 103,
height: 309,
fileType: '',
summary: '',
},
],
banner_column_right: [
{
id: '284',
display:
'<img border=0 src="https://nguyencongpc.vn\/media\/banner\/11_Augc702ee207c9927f84d0b6b8fb3551c45.png" width=\'103\' height=\'309\' alt=""\/>',
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/11_Augc702ee207c9927f84d0b6b8fb3551c45.png',
desUrl: '\/ad.php?id=284',
title: '',
width: 103,
height: 309,
fileType: '',
summary: '',
},
],
},
homepage: {
slider_home: [
{
id: '279',
display:
"<a href=\"\/ad.php?id=279\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/24_Augc1567e876be9163f19bc323a79c73808.jpg\" width='851' height='512' alt=\"\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/24_Augc1567e876be9163f19bc323a79c73808.jpg',
desUrl: '\/ad.php?id=279',
title: '',
width: 851,
height: 512,
fileType: 'banner',
summary: '',
},
{
id: '260',
display:
"<a href=\"\/ad.php?id=260\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/05_Jun639c4383913d27dcba82037f811c2fc8.avif\" width='851' height='512' alt=\"m\u00e0n h\u00ecnh gi\u00e1 c\u1ef1c t\u1ed1t\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/05_Jun639c4383913d27dcba82037f811c2fc8.avif',
desUrl: '\/ad.php?id=260',
title: 'm\u00e0n h\u00ecnh gi\u00e1 c\u1ef1c t\u1ed1t',
width: 851,
height: 512,
fileType: 'banner',
summary: '',
},
{
id: '253',
display:
"<a href=\"\/ad.php?id=253\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/05_Jun53d07914e5c6b10cb6c90ab6d0764a48.avif\" width='851' height='512' alt=\"mua tai nghe t\u1eb7ng qu\u00e0 si\u00eau hot c\u00f9ng asus\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/05_Jun53d07914e5c6b10cb6c90ab6d0764a48.avif',
desUrl: '\/ad.php?id=253',
title: 'mua tai nghe t\u1eb7ng qu\u00e0 si\u00eau hot c\u00f9ng asus',
width: 851,
height: 512,
fileType: 'banner',
summary: '',
},
{
id: '251',
display:
"<a href=\"\/ad.php?id=251\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/05_Jun420b2ba2878f28d1111a1770cfb6abfc.avif\" width='851' height='512' alt=\"laptop gigabyte si\u00eau \u01b0u \u0111\u00e3i\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/05_Jun420b2ba2878f28d1111a1770cfb6abfc.avif',
desUrl: '\/ad.php?id=251',
title: 'laptop gigabyte si\u00eau \u01b0u \u0111\u00e3i',
width: 851,
height: 512,
fileType: 'banner',
summary: '',
},
{
id: '224',
display:
"<a href=\"\/ad.php?id=224\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/05_Jun36c372c6e8f32efb5b72783f23feb186.avif\" width='851' height='512' alt=\"NCPC AMD\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/05_Jun36c372c6e8f32efb5b72783f23feb186.avif',
desUrl: '\/ad.php?id=224',
title: 'NCPC AMD',
width: 851,
height: 512,
fileType: 'banner',
summary: '',
},
{
id: '171',
display:
"<a href=\"\/ad.php?id=171\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/11_Julbe8ebc111daa95ecfb856db2bbc0f6ca.jpg\" width='851' height='512' alt=\"sale cpu gi\u00e1 s\u1eadp s\u00e0n\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/11_Julbe8ebc111daa95ecfb856db2bbc0f6ca.jpg',
desUrl: '\/ad.php?id=171',
title: 'sale cpu gi\u00e1 s\u1eadp s\u00e0n',
width: 851,
height: 512,
fileType: '',
summary: '',
},
],
banner_under_slider_trangchu: [
{
id: '491',
display:
'<img border=0 src="https://nguyencongpc.vn\/media\/banner\/11_Dece4857620cf7d184a9d3936fe4eecdc36.jpg" width=\'1188\' height=\'322\' alt=""\/>',
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/11_Dece4857620cf7d184a9d3936fe4eecdc36.jpg',
desUrl: '\/ad.php?id=491',
title: '',
width: 1188,
height: 322,
fileType: '1',
summary: '',
},
{
id: '492',
display:
"<a href=\"\/ad.php?id=492\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/12_Deca20095da1a168b02a30025be35d237b9.webp\" width='1188' height='322' alt=\"\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/12_Deca20095da1a168b02a30025be35d237b9.webp',
desUrl: '\/ad.php?id=492',
title: '',
width: 1188,
height: 322,
fileType: 'banner',
summary: '',
},
{
id: '394',
display:
"<a href=\"\/ad.php?id=394\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/02_Decc36a9d8d65ea1c144035372aed745741.webp\" width='1188' height='322' alt=\"\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/02_Decc36a9d8d65ea1c144035372aed745741.webp',
desUrl: '\/ad.php?id=394',
title: '',
width: 1188,
height: 322,
fileType: '',
summary: '',
},
{
id: '465',
display:
"<a href=\"\/ad.php?id=465\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/02_Dec011428052819ba7366c840251d137c3b.webp\" width='594' height='161' alt=\"Banner build PC\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/02_Dec011428052819ba7366c840251d137c3b.webp',
desUrl: '\/ad.php?id=465',
title: 'Banner build PC',
width: 594,
height: 161,
fileType: '',
summary: '',
},
{
id: '481',
display:
"<a href=\"\/ad.php?id=481\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/10_Sep8385f8a9ebfdbe7b458305ff37501d34.jpg\" width='594' height='161' alt=\"\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/10_Sep8385f8a9ebfdbe7b458305ff37501d34.jpg',
desUrl: '\/ad.php?id=481',
title: '',
width: 594,
height: 161,
fileType: 'banner',
summary: '',
},
{
id: '461',
display:
"<a href=\"\/ad.php?id=461\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/05_Juna4d65cc940a1d9c49f480f7a9f657d08.jpg\" width='594' height='161' alt=\"PC-V\u0103n-Ph\u00f2ng\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/05_Juna4d65cc940a1d9c49f480f7a9f657d08.jpg',
desUrl: '\/ad.php?id=461',
title: 'PC-V\u0103n-Ph\u00f2ng',
width: 594,
height: 161,
fileType: '',
summary: '',
},
{
id: '483',
display:
"<a href=\"\/ad.php?id=483\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/10_Oct22fa126f13f9570bea797e94cbf56a97.jpg\" width='2368' height='640' alt=\"\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/10_Oct22fa126f13f9570bea797e94cbf56a97.jpg',
desUrl: '\/ad.php?id=483',
title: '',
width: 2368,
height: 640,
fileType: '1',
summary: '',
},
{
id: '484',
display:
"<a href=\"\/ad.php?id=484\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/10_Dec28dc7805471758017b6d35df068f8cb2.webp\" width='1000' height='271' alt=\"\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/10_Dec28dc7805471758017b6d35df068f8cb2.webp',
desUrl: '\/ad.php?id=484',
title: '',
width: 1000,
height: 271,
fileType: 'banner',
summary: '',
},
{
id: '486',
display:
'<img border=0 src="https://nguyencongpc.vn\/media\/banner\/14_Novec0d3a223da7bc911d7f552ec03b5d41.jpg" width=\'1000\' height=\'271\' alt=""\/>',
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/14_Novec0d3a223da7bc911d7f552ec03b5d41.jpg',
desUrl: '\/ad.php?id=486',
title: '',
width: 1000,
height: 271,
fileType: '1',
summary: '',
},
{
id: '494',
display:
'<img border=0 src="https://nguyencongpc.vn\/media\/banner\/16_Decac1ad4e087162c861dd29e24a52b16b5.webp" width=\'1188\' height=\'322\' alt=""\/>',
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/16_Decac1ad4e087162c861dd29e24a52b16b5.webp',
desUrl: '\/ad.php?id=494',
title: '',
width: 1188,
height: 322,
fileType: '1',
summary: '',
},
],
banner_slider_mobile_2023: [
{
id: '358',
display:
"<a href=\"\/ad.php?id=358\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/08_Dec42942cfd2c8d57ce55e7f436291cff20.jpg\" width='1538' height='744' alt=\"\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/08_Dec42942cfd2c8d57ce55e7f436291cff20.jpg',
desUrl: '\/ad.php?id=358',
title: '',
width: 1538,
height: 744,
fileType: '',
summary: '',
},
],
banner_product_category: [
{
id: '297',
display:
"<a href=\"\/ad.php?id=297\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/01_Jul6c180927820e683f758cb146a18e89d8.jpg\" width='1201' height='161' alt=\"277\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/01_Jul6c180927820e683f758cb146a18e89d8.jpg',
desUrl: '\/ad.php?id=297',
title: '277',
width: 1201,
height: 161,
fileType: 'banner',
summary: '',
},
],
banner_slider_homepage_main: [
{
id: '291',
display:
"<a href=\"\/ad.php?id=291\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/08_Dec46cb8ed4b30c59ee06a4010d1491caf3.webp\" width='1500' height='426' alt=\"\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/08_Dec46cb8ed4b30c59ee06a4010d1491caf3.webp',
desUrl: '\/ad.php?id=291',
title: '',
width: 1500,
height: 426,
fileType: '',
summary: '',
},
],
banner_underslider_trangchu_mobile: [
{
id: '493',
display:
"<a href=\"\/ad.php?id=493\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/12_Dec960e661cc3007d40210dc449562e8cb4.webp\" width='1538' height='448' alt=\"\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/12_Dec960e661cc3007d40210dc449562e8cb4.webp',
desUrl: '\/ad.php?id=493',
title: '',
width: 1538,
height: 448,
fileType: 'banner',
summary: '',
},
{
id: '400',
display:
"<a href=\"\/ad.php?id=400\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/02_Dece61807a2c9c98fbf6df2b30f5dbe5c9a.jpg\" width='1538' height='448' alt=\"\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/02_Dece61807a2c9c98fbf6df2b30f5dbe5c9a.jpg',
desUrl: '\/ad.php?id=400',
title: '',
width: 1538,
height: 448,
fileType: '1',
summary: '',
},
{
id: '466',
display:
"<a href=\"\/ad.php?id=466\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/14_Nov5f56ffcefe6a47200d17733246d3ab04.webp\" width='769' height='224' alt=\"\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/14_Nov5f56ffcefe6a47200d17733246d3ab04.webp',
desUrl: '\/ad.php?id=466',
title: '',
width: 769,
height: 224,
fileType: '',
summary: '',
},
{
id: '397',
display:
"<a href=\"\/ad.php?id=397\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/02_Dec2587b97c4cb08c46d195bacf675fa933.webp\" width='1538' height='448' alt=\"\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/02_Dec2587b97c4cb08c46d195bacf675fa933.webp',
desUrl: '\/ad.php?id=397',
title: '',
width: 1538,
height: 448,
fileType: '',
summary: '',
},
{
id: '395',
display:
"<a href=\"\/ad.php?id=395\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/02_Dec9a01020b2317cb3ba49586af6c9f7005.webp\" width='1538' height='448' alt=\"\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/02_Dec9a01020b2317cb3ba49586af6c9f7005.webp',
desUrl: '\/ad.php?id=395',
title: '',
width: 1538,
height: 448,
fileType: '',
summary: '',
},
{
id: '462',
display:
"<a href=\"\/ad.php?id=462\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/05_Junab6cdd7abf3dc9d00c4e5615caf68ae9.jpg\" width='769' height='224' alt=\"PCVP-mobile\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/05_Junab6cdd7abf3dc9d00c4e5615caf68ae9.jpg',
desUrl: '\/ad.php?id=462',
title: 'PCVP-mobile',
width: 769,
height: 224,
fileType: '',
summary: '',
},
],
banner_bot_home: [
{
id: '74',
display:
"<a href=\"\/ad.php?id=74\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/02_Auge40067f94bca8b5dcbc47a28e5d75e0e.jpg\" width='421' height='250' alt=\"D\u1ecbch v\u1ee5 b\u1ea3o h\u00e0nh m\u00e1y t\u00ednh si\u00eau t\u1ed1c\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/02_Auge40067f94bca8b5dcbc47a28e5d75e0e.jpg',
desUrl: '\/ad.php?id=74',
title: 'D\u1ecbch v\u1ee5 b\u1ea3o h\u00e0nh m\u00e1y t\u00ednh si\u00eau t\u1ed1c',
width: 421,
height: 250,
fileType: 'banner',
summary:
'D\u1ecbch v\u1ee5 b\u1ea3o h\u00e0nh si\u00eau t\u1ed1c 1 \u0111\u1ed5i 1: V\u1edbi c\u00e1c s\u1ea3n ph\u1ea9m \u0111\u01b0\u1ee3c ph\u00e2n ph\u1ed1i b\u1edfi Nguy\u1ec5n C\u00f4ng PC s\u1ebd \u0111\u01b0\u1ee3c cam k\u1ebft 1 ...',
},
{
id: '73',
display:
"<a href=\"\/ad.php?id=73\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/02_Aug55a6088409dc421d3390179a7712c5cd.jpg\" width='421' height='250' alt=\"H\u1ed7 tr\u1ee3 tr\u1ea3 g\u00f3p\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/02_Aug55a6088409dc421d3390179a7712c5cd.jpg',
desUrl: '\/ad.php?id=73',
title: 'H\u1ed7 tr\u1ee3 tr\u1ea3 g\u00f3p',
width: 421,
height: 250,
fileType: 'banner',
summary:
'M\u00e1y t\u00ednh Nguy\u1ec5n C\u00f4ng s\u1ebd h\u1ed7 tr\u1ee3 mua tr\u1ea3 g\u00f3p online v\u1edbi nh\u1eefng kh\u00e1ch h\u00e0ng s\u1edf h\u1eefu th\u1ebb ghi n\u1ee3 n\u1ed9i \u0111\u1ecba (VISA\/MASTER\/JCB) \u0111\u01b0\u1ee3c ph\u00e1t h\u00e0nh b\u1edfi m\u1ed9t trong c\u00e1c ng\u00e2n h\u00e0ng Citibank, ...',
},
{
id: '127',
display:
"<a href=\"\/ad.php?id=127\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/02_Aug9c6a33a9de23f9ee17a345a30b989d60.jpg\" width='421' height='250' alt=\"Ch\u01b0\u01a1ng tr\u00ecnh sale cpu\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/02_Aug9c6a33a9de23f9ee17a345a30b989d60.jpg',
desUrl: '\/ad.php?id=127',
title: 'Ch\u01b0\u01a1ng tr\u00ecnh sale cpu',
width: 421,
height: 250,
fileType: '',
summary: '',
},
{
id: '140',
display:
"<a href=\"\/ad.php?id=140\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/02_Augbf48ab9cd4431c53d804405df0685f03.jpg\" width='421' height='250' alt=\"m\u00e0n h\u00ecnh ch\u00ednh h\u00e3ng\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/02_Augbf48ab9cd4431c53d804405df0685f03.jpg',
desUrl: '\/ad.php?id=140',
title: 'm\u00e0n h\u00ecnh ch\u00ednh h\u00e3ng',
width: 421,
height: 250,
fileType: '',
summary: '',
},
],
banner_mid_home: [
{
id: '86',
display:
"<a href=\"\/ad.php?id=86\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/02_Augfcc9fb432f0f13cca14b830b8c0f3a7b.jpg\" width='421' height='250' alt=\"Laptop gaming mu\u00f4n v\u00e0n gi\u00e1 s\u1ed1c\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/02_Augfcc9fb432f0f13cca14b830b8c0f3a7b.jpg',
desUrl: '\/ad.php?id=86',
title: 'Laptop gaming mu\u00f4n v\u00e0n gi\u00e1 s\u1ed1c',
width: 421,
height: 250,
fileType: 'banner',
summary:
'Mua laptop gaming ch\u00ednh h\u00e3ng, gi\u00e1 r\u1ebb t\u1eeb c\u00e1c th\u01b0\u01a1ng hi\u1ec7u n\u1ed5i ti\u1ebfng nh\u01b0: Acer, Asus, HP, MSI, Dell, Lenovo, \u0111\u1ed5i m\u1edbi trong v\u00f2ng 7 ng\u00e0y - Mi\u1ec5n ph\u00ed n\u00e2ng c\u1ea5p RAM ...',
},
{
id: '85',
display:
"<a href=\"\/ad.php?id=85\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/02_Auge66ba57e695249705f3e4fb06a97cf81.jpg\" width='421' height='250' alt=\"Laptop v\u0103n ph\u00f2ng\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/02_Auge66ba57e695249705f3e4fb06a97cf81.jpg',
desUrl: '\/ad.php?id=85',
title: 'Laptop v\u0103n ph\u00f2ng',
width: 421,
height: 250,
fileType: '',
summary:
'Laptop v\u0103n ph\u00f2ng Acer, Asus, HP, MSI ch\u00ednh h\u00e3ng gi\u00e1 r\u1ebb. Mua online t\u1ea1i NGUYENCONG giao h\u00e0ng to\u00e0n qu\u1ed1c - H\u1ed7 tr\u1ee3 tr\u1ea3 g\u00f3p 0%. Xem ngay!',
},
{
id: '128',
display:
"<a href=\"\/ad.php?id=128\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/02_Aug199ab2453bb196abad65eee2dcb86c89.jpg\" width='421' height='250' alt=\"build pc\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/02_Aug199ab2453bb196abad65eee2dcb86c89.jpg',
desUrl: '\/ad.php?id=128',
title: 'build pc',
width: 421,
height: 250,
fileType: 'banner',
summary: '',
},
],
banner_right_home: [
{
id: '2',
display:
'<img border=0 src="https://nguyencongpc.vn\/media\/banner\/22_Oct35b55e8600025c38ca65ddd9aec06e74.jpg" width=\'421\' height=\'250\' alt="Video"\/>',
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/22_Oct35b55e8600025c38ca65ddd9aec06e74.jpg',
desUrl: '\/ad.php?id=2',
title: 'Video',
width: 421,
height: 250,
fileType: 'banner',
summary: 'E80Xj9oD2Yo',
},
{
id: '216',
display:
"<a href=\"\/ad.php?id=216\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/02_Augf62bb067892116a818d10e4edd030b7b.jpg\" width='421' height='250' alt=\"thu m\u00e1y t\u00ednh c\u0169 \u0111\u1ed5i m\u1edbi m\u00e1y t\u00ednh m\u1edbi\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/02_Augf62bb067892116a818d10e4edd030b7b.jpg',
desUrl: '\/ad.php?id=216',
title:
'thu m\u00e1y t\u00ednh c\u0169 \u0111\u1ed5i m\u1edbi m\u00e1y t\u00ednh m\u1edbi',
width: 421,
height: 250,
fileType: '',
summary: '',
},
],
banner_collection_pc: [
{
id: '433',
display:
"<a href=\"\/ad.php?id=433\" target='_blank' rel='nofollow'>\r\n<img border=0 src=\"https://nguyencongpc.vn\/media\/banner\/10_Junbf5b7840a8b53bc96c3e785d54580559.webp\" width='500' height='500' alt=\"\"\/><\/a>",
fileUrl:
'https://nguyencongpc.vn\/media\/banner\/10_Junbf5b7840a8b53bc96c3e785d54580559.webp',
desUrl: '\/ad.php?id=433',
title: '',
width: 500,
height: 500,
fileType: '',
summary: '',
},
],
},
},
];

View File

@@ -4,7 +4,7 @@ import { Swiper, SwiperSlide } from 'swiper/react';
import { Autoplay, Navigation, Pagination } from 'swiper/modules';
import Image from 'next/image';
import Link from 'next/link';
import { bannerData } from './bannerData';
import { bannerData } from '@/data/banner';
const SliderHome: React.FC = () => {
// data banner slider

View File

@@ -47,7 +47,7 @@ const IconFixRight: React.FC = () => {
className="lazy"
/>
<div className="contact-info">
<b className="d-block">Chat Facebook</b>
<b className="block">Chat Facebook</b>
<span>(8h-22h30)</span>
</div>
</Link>
@@ -57,14 +57,14 @@ const IconFixRight: React.FC = () => {
className="flex items-center"
style={{
background: '#fff',
bottom: '135px',
bottom: '145px',
width: '170px',
padding: '10px',
borderRadius: '15px',
boxShadow: '0 1px 2px 1px #01010133',
color: '#007bff',
fontSize: '14px',
height: '65px',
height: '50px',
}}
>
<Image
@@ -76,7 +76,7 @@ const IconFixRight: React.FC = () => {
style={{ marginRight: '10px' }}
/>
<div className="contact-info">
<b className="d-block">Chat Zalo</b>
<b className="block">Chat Zalo</b>
<span>(8h-22h30)</span>
</div>
</Link>

View File

@@ -0,0 +1,37 @@
import { Swiper, SwiperSlide } from 'swiper/react';
import { Autoplay, Navigation, Pagination } from 'swiper/modules';
import Image from 'next/image';
import Link from 'next/link';
import { bannerData } from '@/data/banner';
const BannerCategory = () => {
const dataSlider = bannerData[0].product_list;
return (
<div className="box-banner-category">
<Swiper
modules={[Autoplay, Navigation, Pagination]}
spaceBetween={12}
slidesPerView={1}
loop={true}
>
{dataSlider?.banner_category_2023?.map((banner, index) => (
<SwiperSlide key={index}>
<Link href={banner.desUrl} className="item-banner boder-radius-10">
<Image
src={banner.fileUrl}
width={1909}
height={57}
alt={banner.title}
priority={true}
className="boder-radius-10"
/>
</Link>
</SwiperSlide>
))}
</Swiper>
</div>
);
};
export default BannerCategory;

View File

@@ -0,0 +1,67 @@
'use client';
import React from 'react';
import Link from 'next/link';
import { usePathname, useSearchParams } from 'next/navigation';
import { PriceFilter, AttributeFilterList, BrandFilter } from '@/types';
import { FaXmark } from 'react-icons/fa6';
interface Filters {
price_filter_list?: PriceFilter[];
attribute_filter_list?: AttributeFilterList[];
brand_filter_list?: BrandFilter[];
current_category?: { url: string };
}
const ActiveFilters: React.FC<{ filters: Filters }> = ({ filters }) => {
const pathname = usePathname();
const searchParams = useSearchParams();
const fullUrl = `${pathname}?${searchParams.toString()}`;
const selectedPrice = filters.price_filter_list?.filter((f) => fullUrl.includes(f.url)) ?? [];
const selectedBrand = filters.brand_filter_list?.filter((f) => fullUrl.includes(f.url)) ?? [];
const selectedAttr =
filters.attribute_filter_list?.flatMap((attr) =>
attr.value_list.filter((v) => pathname.includes(v.url)),
) ?? [];
const allSelected = [...selectedPrice, ...selectedBrand, ...selectedAttr];
const isFiltered = allSelected.length;
console.log(isFiltered);
if (isFiltered === 0) return null;
return (
<div className="info-filter-category flex gap-3">
<p className="title">Lọc theo:</p>
<div className="list-filter-category list-filter-active list-filter-last flex flex-wrap items-center gap-3">
{selectedPrice.map((item) => (
<Link key={item.url} href={item.url} className="item flex items-center gap-2 bg-white">
{item.name} <FaXmark />
</Link>
))}
{selectedBrand.map((item) => (
<Link key={item.url} href={item.url} className="item flex items-center gap-2 bg-white">
{item.name} <FaXmark />
</Link>
))}
{selectedAttr.map((val) => (
<Link key={val.url} href={val.url} className="item flex items-center gap-2 bg-white">
{val.name} <FaXmark />
</Link>
))}
{isFiltered >= 1 && (
<Link
href={filters.current_category?.url ?? '#'}
className="item delete-filter-all flex items-center gap-2 bg-white"
>
Xóa tất cả <FaXmark />
</Link>
)}
</div>
</div>
);
};
export default ActiveFilters;

View File

@@ -0,0 +1,106 @@
'use client';
import React from 'react';
import Link from 'next/link';
import { PriceFilter, AttributeFilterList, BrandFilter } from '@/types';
import { FaSortDown } from 'react-icons/fa6';
import ActiveFilters from './ActiveFilters';
interface Filters {
price_filter_list?: PriceFilter[];
attribute_filter_list?: AttributeFilterList[];
brand_filter_list?: BrandFilter[];
}
interface BoxFilterProps {
filters: Filters;
}
const BoxFilter: React.FC<BoxFilterProps> = ({ filters }) => {
const { price_filter_list, attribute_filter_list, brand_filter_list } = filters;
return (
<div className="box-filter-category boder-radius-10">
{/* khoảng giá */}
{price_filter_list && (
<div className="info-filter-category flex gap-10">
<p className="title">Khoảng giá:</p>
<div className="list-filter-category flex flex-1 flex-wrap items-center gap-2">
{price_filter_list.map((ItemPrice, index) => (
<div
key={index}
className={`item item-cetner flex gap-4 ${ItemPrice.is_selected == '1' ? 'current' : ''}`}
>
<Link href={ItemPrice.url}>{ItemPrice.name}</Link>
<a href={ItemPrice.url}>
(${ItemPrice.is_selected == '1' ? 'Xóa' : ItemPrice.count})
</a>
</div>
))}
</div>
</div>
)}
{/* chọn thiêu tiêu trí */}
{attribute_filter_list && (
<div className="info-filter-category flex gap-10">
<p className="title">Chọn theo tiêu chí:</p>
<div className="list-filter-category flex flex-1 flex-wrap items-center gap-3">
{/* thương hiệu */}
{brand_filter_list && brand_filter_list.length > 0 && (
<div className={`item ${brand_filter_list[0].is_selected === '1' ? 'current' : ''}`}>
<div className="flex items-center">
{brand_filter_list[0].is_selected === '1' ? (
<span>{brand_filter_list[0].name}</span>
) : (
<span>Thương hiệu</span>
)}
<FaSortDown size={16} style={{ marginBottom: 8 }} />
</div>
<ul>
{brand_filter_list.map((item, idx) => (
<li key={idx} className="flex items-center gap-3">
<Link href={item.url}>{item.name}</Link>
<Link href={item.url}>({item.is_selected === '1' ? 'Xóa' : item.count})</Link>
</li>
))}
</ul>
</div>
)}
{/* Attribute filter */}
{attribute_filter_list && attribute_filter_list.length > 0 && (
<>
{attribute_filter_list.map((attr, idx) => (
<div
key={idx}
className={`item ${attr.value_list[0]?.is_selected === '1' ? 'current' : ''}`}
>
<a href="javascript:void(0)" className="flex items-center">
{attr.value_list[0]?.is_selected === '1' ? (
<span>{attr.value_list[0].name}</span>
) : (
<span>{attr.name}</span>
)}
<FaSortDown size={16} style={{ marginBottom: 8 }} />
</a>
<ul>
{attr.value_list.map((val) => (
<li key={val.id} className="flex items-center gap-3">
<Link href={val.url}>{val.name}</Link>
<Link href={val.url}>{val.is_selected === '1' ? 'Xóa' : val.count}</Link>
</li>
))}
</ul>
</div>
))}
</>
)}
</div>
</div>
)}
<ActiveFilters filters={filters} />
</div>
);
};
export default BoxFilter;

View File

@@ -0,0 +1,93 @@
'use client';
import React from 'react';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { FaGrip, FaList } from 'react-icons/fa6';
interface SortItem {
key: string;
url: string;
}
interface SortProps {
sort_by_collection: SortItem[];
product_display_type?: 'grid' | 'list';
}
const BoxSort: React.FC<SortProps> = ({ sort_by_collection, product_display_type }) => {
const pathname = usePathname();
return (
<div className="box-sort-category flex items-center justify-between">
<div className="sort-option flex items-center gap-3">
{sort_by_collection
.filter((item) =>
['price-desc', 'price-asc', 'comment', 'rating', 'name'].includes(item.key),
)
.map((item) => {
let label: string | null = null;
let iconClass: string | null = null;
switch (item.key) {
case 'price-desc':
label = 'Giá giảm dần';
iconClass = 'sprite-more sprite-gia-giam-category';
break;
case 'price-asc':
label = 'Giá tăng dần';
iconClass = 'sprite-more sprite-gia-tang-cateogry';
break;
case 'comment':
label = 'Trao đổi';
iconClass = 'sprite-more sprite-trao-doi-category';
break;
case 'rating':
label = 'Đánh giá';
iconClass = 'sprite-more sprite-danh-gia-category';
break;
case 'name':
label = 'Tên A->Z';
break;
}
return (
<Link
key={item.key}
href={item.url}
className={`item flex items-center ${
pathname.includes(item.key) ? 'selected' : ''
}`}
>
{iconClass && <i className={iconClass}></i>}
<span>{label}</span>
</Link>
);
})}
</div>
<div className="sort-bar-select-category flex items-center gap-3">
<a
href="javascript:;"
className={`item-sort-bar d-flex align-items-center ${
product_display_type === 'grid' ? 'active' : ''
}`}
onClick={() => {
window.location.reload();
}}
>
<FaGrip />
</a>
<a
href="javascript:;"
className={`item-sort-bar ${product_display_type === 'list' ? 'active' : ''}`}
onClick={() => {
console.log('Set display to list');
window.location.reload();
}}
>
<FaList />
</a>
</div>
</div>
);
};
export default BoxSort;

View File

@@ -0,0 +1,30 @@
'use client';
import React from 'react';
import Link from 'next/link';
import Image from 'next/image';
import { ChildCategory } from '@/types';
interface BoxCategoryChildProps {
item: ChildCategory;
}
const ItemCategoryChild: React.FC<BoxCategoryChildProps> = ({ item }) => {
const ItemImage = item.big_image
? item.big_image
: item.thumnail
? item.thumnail
: '/static/assets/nguyencong_2023/images/favicon.png';
return (
<li>
<Link href={item.url}>
<div className="border-img lazy flex items-center justify-center">
<Image src={ItemImage} width={60} height={60} alt={item.title} />
</div>
<p className="txt font-weight-500">{item.title}</p>
</Link>
</li>
);
};
export default ItemCategoryChild;

View File

@@ -0,0 +1,124 @@
'use client';
import React from 'react';
import Link from 'next/link';
import type { CategoryData } from '@/types';
import { productCategoryData } from '@/data/product/category';
import { findCategoryBySlug } from '@/lib/category';
// box
import { Breadcrumb } from '@components/common/Breadcrumb';
import BannerCategory from './BannerCategory';
import ItemCategoryChild from './ItemCategoryChild';
import BoxFilter from './BoxFilter';
import BoxSort from './BoxSort';
import ItemProduct from '@/components/common/ItemProduct';
interface CategoryPageProps {
slug: string; // khai báo prop slug
}
const CategoryPage: React.FC<CategoryPageProps> = ({ slug }) => {
// Ép kiểu dữ liệu từ index.ts về CategoryData[] nếu cần
const categories = productCategoryData as unknown as CategoryData[];
const currentCategory = findCategoryBySlug(slug, categories);
const breadcrumbItems = currentCategory?.current_category?.path?.path?.map((p) => ({
name: p.name,
url: p.url,
})) ?? [
{ name: 'Trang chủ', url: '/' },
{ name: currentCategory?.current_category.name, url: currentCategory?.current_category.url },
];
// Trường hợp không tìm thấy danh mục
if (!currentCategory) {
return (
<div className="flex items-center justify-center bg-gradient-to-br from-blue-50 to-indigo-100 py-50">
<div className="max-w-md rounded-2xl bg-white p-8 text-center shadow-xl">
<div className="mx-auto mb-6 flex h-16 w-16 items-center justify-center rounded-full bg-blue-100">
<svg
className="h-8 w-8 text-blue-600"
fill="none"
stroke="currentColor"
strokeWidth="2"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M9.172 9.172a4 4 0 015.656 5.656M6.343 6.343a8 8 0 0111.314 11.314M12 12l.01.01"
/>
</svg>
</div>
<h1 className="text-2xl font-bold text-gray-800">Không tìm thấy danh mục</h1>
<p className="mt-3 text-gray-600">
Đưng dẫn <code className="rounded bg-gray-100 px-2 py-0.5 text-sm">{slug}</code> không
tồn tại hoặc đã bị xoá.
</p>
<Link
href="/"
className="mt-6 inline-flex items-center justify-center rounded-lg bg-blue-600 px-6 py-2.5 font-medium text-white transition hover:bg-blue-700 focus:ring-2 focus:ring-blue-400 focus:outline-none"
>
Về trang chủ
</Link>
</div>
</div>
);
}
// lấy sản phẩm
const products = Object.values(currentCategory.product_list);
return (
<div className="page-category">
<div className="container">
<Breadcrumb items={breadcrumbItems} />
<BannerCategory />
<h1 className="name-category font-bold">{currentCategory.current_category.name}</h1>
<div className="box-content-category">
<ul className="category-child boder-radius-10 flex flex-wrap justify-center">
{currentCategory.current_category.children?.map((item, index) => (
<ItemCategoryChild item={item} key={index} />
))}
</ul>
{/* filter */}
<BoxFilter filters={currentCategory} />
<div className="box-list-product-category boder-radius-10">
{/* filter sort */}
<BoxSort
sort_by_collection={currentCategory.sort_by_collection}
product_display_type="grid"
/>
</div>
{/* list product */}
<div className="list-product-category grid grid-cols-5 gap-3">
{products.map((item, index) => (
<ItemProduct key={index} item={item} />
))}
</div>
<div className="paging flex items-center justify-center">
{currentCategory.paging_collection.map((item, index) => (
<Link
key={index}
href={item.url}
className={`item ${item.is_active === '1' ? 'current' : ''}`}
>
{item.name}
</Link>
))}
</div>
</div>
</div>
</div>
);
};
export default CategoryPage;