update
This commit is contained in:
112
src/components/other/Header/HeaderBottom/HeaderBottomRight.tsx
Normal file
112
src/components/other/Header/HeaderBottom/HeaderBottomRight.tsx
Normal file
@@ -0,0 +1,112 @@
|
||||
'use client';
|
||||
import React from 'react';
|
||||
import { menuData } from '../menuData'; // Đảm bảo file này export menuData
|
||||
import Link from 'next/link';
|
||||
import { FaCaretDown } from 'react-icons/fa';
|
||||
|
||||
const HeaderBottomRight: React.FC = () => {
|
||||
// 1. Lọc các ID danh mục hiển thị trên Header (Cấp 1)
|
||||
const allowedIds = ['407', '408', '3300', '281', '3431', '410', '3403'];
|
||||
|
||||
// 2. Hàm lấy Icon và Title dựa theo ID
|
||||
const getCategoryInfo = (id: string) => {
|
||||
switch (id) {
|
||||
case '407':
|
||||
return { icon: 'sprite-laptop', title: 'Laptop' };
|
||||
case '408':
|
||||
return { icon: 'sprite-PC', title: 'PC' };
|
||||
case '3300':
|
||||
return { icon: 'sprite-PC', title: 'PC AI' };
|
||||
case '281':
|
||||
return { icon: 'sprite-manhinh', title: 'Màn hình' };
|
||||
case '3431':
|
||||
return { icon: 'sprite-linhkien', title: 'Linh kiện PC' };
|
||||
case '410':
|
||||
return { icon: 'sprite-phimchuot', title: 'Phím chuột ghế gear' };
|
||||
case '3403':
|
||||
return { icon: 'sprite-thietbi', title: 'Thiết bị văn phòng' };
|
||||
default:
|
||||
return { icon: '', title: '' };
|
||||
}
|
||||
};
|
||||
|
||||
// Lấy danh sách all_category từ menuData[0]
|
||||
const allCategories = menuData[0]?.product?.all_category || [];
|
||||
|
||||
return (
|
||||
<>
|
||||
{allCategories.map((item) => {
|
||||
if (!allowedIds.includes(item.id)) return null;
|
||||
|
||||
const info = getCategoryInfo(item.id);
|
||||
|
||||
return (
|
||||
<li key={item.id} className="item-category-header" data-id={item.id}>
|
||||
<Link href={item.id === '408' ? '#' : item.url} className="flex items-center gap-2">
|
||||
<i className={`sprite-more ${info.icon}`}></i>
|
||||
<span className="title-header-bottom">{info.title}</span>
|
||||
<FaCaretDown size="16" className="text-white" />
|
||||
</Link>
|
||||
|
||||
<div className="list-category-child flex justify-between">
|
||||
<div className="box-left">
|
||||
<ul className="grid grid-cols-4 gap-5">
|
||||
{item.isParent === '1' && (
|
||||
<>
|
||||
{item.id === '408'
|
||||
? allCategories
|
||||
.filter((c) => ['408', '3201', '1829', '3300', '3691'].includes(c.id))
|
||||
.map((child1) => (
|
||||
<li key={child1.id} className="sub-menu">
|
||||
<Link href={child1.url} className="child-lv2 block font-bold">
|
||||
{child1.title}
|
||||
</Link>
|
||||
{child1.isParent === '1' && (
|
||||
<div className="list-child-lv3 mt-10 flex flex-col">
|
||||
{child1.children?.map((child2) => (
|
||||
<Link key={child2.id} href={child2.url} className="child-lv3">
|
||||
{child2.title}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</li>
|
||||
))
|
||||
: item.children?.map((_item_child) => (
|
||||
<li key={_item_child.id} className="sub-menu">
|
||||
<Link href={_item_child.url} className="child-lv2 block font-bold">
|
||||
{_item_child.title}
|
||||
</Link>
|
||||
{_item_child.isParent === '1' && (
|
||||
<div className="list-child-lv3 mt-10 flex flex-col">
|
||||
{_item_child.children?.map((_item_childtwo) => (
|
||||
<Link
|
||||
key={_item_childtwo.id}
|
||||
href={_item_childtwo.url}
|
||||
className="child-lv3"
|
||||
>
|
||||
{_item_childtwo.title}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className={`box-right flex-1 product-category-${item.id}`}>
|
||||
<p className="title font-bold">Bán chạy nhất</p>
|
||||
<div className="list-product-bestsale" id={`product-category-${item.id}`}></div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default HeaderBottomRight;
|
||||
68
src/components/other/Header/HeaderBottom/index.tsx
Normal file
68
src/components/other/Header/HeaderBottom/index.tsx
Normal file
@@ -0,0 +1,68 @@
|
||||
'use client';
|
||||
import React, { useState } from 'react';
|
||||
import { FaBars } from 'react-icons/fa';
|
||||
import { menuData } from '../menuData';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
import HeaderBottomRight from './HeaderBottomRight';
|
||||
|
||||
const HeaderBottom: React.FC = () => {
|
||||
return (
|
||||
<>
|
||||
<div className="header-bottom">
|
||||
<div className="container flex">
|
||||
<div className="global-menu-container">
|
||||
<div className="group-title flex items-center justify-center gap-2">
|
||||
<FaBars size="16" /> <span className="text-[13px]">Danh mục sản phẩm</span>
|
||||
</div>
|
||||
|
||||
<div className="global-menu-holder">
|
||||
{menuData[0].product.all_category.map((item) => (
|
||||
<div key={item.id} className="item">
|
||||
<Link href={item.url} className="cat-1">
|
||||
<Image
|
||||
src={item.thumnail}
|
||||
className="lazy icon-menu entered"
|
||||
alt={item.title}
|
||||
width="1"
|
||||
height="1"
|
||||
/>
|
||||
<span className="cat-title line-clamp-1">{item.title}</span>
|
||||
</Link>
|
||||
|
||||
{/* Cấp 2 & Cấp 3 */}
|
||||
{item.children && item.children.length > 0 && (
|
||||
<div className="sub-menu-list">
|
||||
{item.children.map((_children2) => (
|
||||
<div className="sub-cat-2" key={_children2.id}>
|
||||
<Link href={_children2.url} className="cat-2">
|
||||
{_children2.title}
|
||||
</Link>
|
||||
{/* Cấp 3 */}
|
||||
{_children2.children && _children2.children.length > 0 && (
|
||||
<>
|
||||
{_children2.children.map((_children3) => (
|
||||
<Link key={_children3.id} href={_children3.url}>
|
||||
{_children3.title}
|
||||
</Link>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<ul className="list-category-header relative flex w-[calc(100%_-220px)] items-center justify-between gap-5">
|
||||
<HeaderBottomRight />
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default HeaderBottom;
|
||||
132
src/components/other/Header/HeaderMid/index.tsx
Normal file
132
src/components/other/Header/HeaderMid/index.tsx
Normal file
@@ -0,0 +1,132 @@
|
||||
'use client';
|
||||
import React, { useState } from 'react';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
import { FaMapMarkerAlt, FaBars } from 'react-icons/fa';
|
||||
import BoxShowroom from '@components/common/BoxShowroom';
|
||||
|
||||
const HeaderMid: React.FC = () => {
|
||||
const PopupAddress = () => {
|
||||
const modal = document.getElementById('boxShowroom') as HTMLDialogElement;
|
||||
modal?.showModal();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="header-middle">
|
||||
<div className="container flex items-center justify-between">
|
||||
<div className="header-middle-left flex items-center">
|
||||
<Link href="/">
|
||||
<Image
|
||||
src="https://nguyencongpc.vn/media/lib/18-02-2025/logowhite-dfvefb.png"
|
||||
width="170"
|
||||
height="38"
|
||||
alt="logo"
|
||||
className="logo-header"
|
||||
/>
|
||||
</Link>
|
||||
<button className="icon-showroom flex items-center justify-center" onClick={PopupAddress}>
|
||||
<FaMapMarkerAlt size={16} />
|
||||
</button>
|
||||
</div>
|
||||
<div className="header-middle-right flex items-center">
|
||||
<div className="header-menu-category">
|
||||
<div className="box-title flex items-center justify-center gap-8">
|
||||
<FaBars size={16} />
|
||||
<p className="title-menu font-weight-500">Danh mục sản phẩm</p>
|
||||
</div>
|
||||
<div className="cau-noi"></div>
|
||||
</div>
|
||||
<div className="header-search-group">
|
||||
<form method="get" action="/tim" name="searchForm">
|
||||
<div className="box-search-input">
|
||||
<input
|
||||
type="text"
|
||||
id="js-search-box"
|
||||
name="q"
|
||||
className="form-group-input"
|
||||
placeholder="Bạn cần tìm gì?"
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
id="js-search-button"
|
||||
aria-label="submit-search"
|
||||
className="search-btn-header"
|
||||
>
|
||||
<i className="sprite sprite-search-header icon-search"></i>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div className="search-results">
|
||||
<div className="search-results-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="box-tabs-header flex items-center">
|
||||
<Link href="/buildpc" className="item-tab-header flex-column flex items-center gap-4">
|
||||
<p className="icon-item-tab flex items-center justify-center">
|
||||
<i className="sprite sprite-buildpc-header"></i>
|
||||
</p>
|
||||
<span className="font-500">Xây dựng cấu hình</span>
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
href="javascript:void(0)"
|
||||
className="item-tab-header flex-column flex items-center gap-4"
|
||||
>
|
||||
<p className="icon-item-tab flex items-center justify-center">
|
||||
<i className="sprite sprite-lienhe-header"></i>
|
||||
</p>
|
||||
<span className="font-500">Khách hàng liên hệ</span>
|
||||
</Link>
|
||||
|
||||
<Link href="/tin-tuc" className="item-tab-header flex-column flex items-center gap-4">
|
||||
<p className="icon-item-tab flex items-center justify-center">
|
||||
<i className="sprite sprite-article-header"></i>
|
||||
</p>
|
||||
<span className="font-weight-500">Tin tức công nghệ</span>
|
||||
</Link>
|
||||
|
||||
<div id="js-header-cart" className="position-relative">
|
||||
<Link href="/cart" className="item-tab-header flex-column flex items-center gap-4">
|
||||
<p className="icon-item-tab icon-cart-header flex items-center justify-center">
|
||||
<i className="sprite sprite-cart-header"></i>
|
||||
<u className="cart-count header-features-cart-amount">1</u>
|
||||
</p>
|
||||
<span className="font-weight-500">Giỏ hàng</span>
|
||||
</Link>
|
||||
<div className="cau-noi"></div>
|
||||
<div className="cart-ttip" id="js-cart-tooltip">
|
||||
<div className="cart-ttip-item-container"></div>
|
||||
<div className="cart-ttip-price justify-content-end flex items-center gap-6">
|
||||
<p>Tổng tiền hàng</p>
|
||||
<p id="js-header-cart-quantity" className="font-weight-500"></p>
|
||||
<p id="js-header-cart-total-price" className="font-weight-700"></p>
|
||||
</div>
|
||||
<Link
|
||||
href="/cart"
|
||||
className="cart-ttip-price-button flex items-center justify-center"
|
||||
>
|
||||
<p className="font-weight-700">THANH TOÁN NGAY </p>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Link
|
||||
href="/taikhoan"
|
||||
className="user-header item-tab-header flex-column flex items-center gap-4"
|
||||
>
|
||||
<p className="icon-item-tab flex items-center justify-center">
|
||||
<i className="sprite sprite-account-header"></i>
|
||||
</p>
|
||||
<span className="font-weight-500">Tài khoản</span>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<BoxShowroom />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default HeaderMid;
|
||||
63
src/components/other/Header/HeaderTop/index.tsx
Normal file
63
src/components/other/Header/HeaderTop/index.tsx
Normal file
@@ -0,0 +1,63 @@
|
||||
'use client';
|
||||
import React from 'react';
|
||||
import { Swiper, SwiperSlide } from 'swiper/react';
|
||||
import { Autoplay, Navigation, Pagination } from 'swiper/modules';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
|
||||
// Định nghĩa kiểu dữ liệu cho mỗi Banner
|
||||
interface BannerItem {
|
||||
id: number;
|
||||
link: string;
|
||||
imageSrc: string;
|
||||
altText: string;
|
||||
}
|
||||
|
||||
// Dữ liệu mẫu (Bạn có thể fetch từ API)
|
||||
const BANNER_DATA: BannerItem[] = [
|
||||
{
|
||||
id: 429,
|
||||
link: '/ad.php?id=429',
|
||||
imageSrc: 'https://nguyencongpc.vn/media/banner/01_Decc0f3e158e61fabaf09a74d48e1c357bd.webp',
|
||||
altText: 'banner 1',
|
||||
},
|
||||
{
|
||||
id: 392,
|
||||
link: '/ad.php?id=392',
|
||||
imageSrc: 'https://nguyencongpc.vn/media/banner/01_Dec383fdcbc6361363bd6d14f05d2c88ee2.webp',
|
||||
altText: 'banner 2',
|
||||
},
|
||||
];
|
||||
|
||||
const HeaderSlider: React.FC = () => {
|
||||
return (
|
||||
<div className="header-top">
|
||||
<Swiper
|
||||
modules={[Autoplay, Navigation, Pagination]}
|
||||
spaceBetween={12}
|
||||
slidesPerView={1}
|
||||
loop={true}
|
||||
className="mySwiper"
|
||||
>
|
||||
{BANNER_DATA.map((banner) => (
|
||||
<SwiperSlide key={banner.id}>
|
||||
<div className="item">
|
||||
<Link href={banner.link} className="item-banner boder-radius-10">
|
||||
<Image
|
||||
src={banner.imageSrc}
|
||||
width={1909}
|
||||
height={57}
|
||||
alt={banner.altText}
|
||||
priority={true}
|
||||
className="h-auto w-full object-cover"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
</SwiperSlide>
|
||||
))}
|
||||
</Swiper>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default HeaderSlider;
|
||||
15
src/components/other/Header/index.tsx
Normal file
15
src/components/other/Header/index.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import HeaderSlider from './HeaderTop';
|
||||
import HeaderMid from './HeaderMid';
|
||||
import HeaderBottom from './HeaderBottom';
|
||||
|
||||
const Header: React.FC = () => {
|
||||
return (
|
||||
<div className="header">
|
||||
<HeaderSlider />
|
||||
<HeaderMid />
|
||||
<HeaderBottom />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Header;
|
||||
5383
src/components/other/Header/menuData.ts
Normal file
5383
src/components/other/Header/menuData.ts
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user