133 lines
3.9 KiB
JavaScript
133 lines
3.9 KiB
JavaScript
import { useState } from "react";
|
|
import { ChevronDown, ChevronUp } from "lucide-react";
|
|
import { Link } from "react-router-dom";
|
|
|
|
const MobileMenu = ({ isOpen, closeMenu, navItems, megaMenu }) => {
|
|
const [openSection, setOpenSection] = useState(null);
|
|
|
|
if (!isOpen) return null;
|
|
|
|
const toggle = (key) => {
|
|
setOpenSection(openSection === key ? null : key);
|
|
};
|
|
|
|
return (
|
|
<div className="md:hidden bg-white shadow-lg border-t z-50">
|
|
<div className="px-4 py-3 space-y-2">
|
|
{/* MAIN NAV ITEMS */}
|
|
{navItems.map((item) => (
|
|
<div key={item.id}>
|
|
{/* If dropdown exists */}
|
|
{item.hasDropdown ? (
|
|
<>
|
|
<button
|
|
onClick={() => toggle(item.id)}
|
|
className="w-full flex justify-between items-center py-3 text-left font-semibold text-gray-900"
|
|
>
|
|
{item.label}
|
|
{openSection === item.id ? (
|
|
<ChevronUp size={20} />
|
|
) : (
|
|
<ChevronDown size={20} />
|
|
)}
|
|
</button>
|
|
|
|
{/* DROPDOWN MEGA MENU */}
|
|
<div
|
|
className={`transition-all overflow-hidden duration-300 ${
|
|
openSection === item.id
|
|
? "max-h-[700px] opacity-100"
|
|
: "max-h-0 opacity-0"
|
|
}`}
|
|
>
|
|
{/* MEN */}
|
|
<AccordionBlock
|
|
title="Men"
|
|
items={megaMenu.men}
|
|
closeMenu={closeMenu}
|
|
/>
|
|
|
|
{/* WOMEN */}
|
|
<AccordionBlock
|
|
title="Women"
|
|
items={megaMenu.women}
|
|
closeMenu={closeMenu}
|
|
/>
|
|
|
|
{/* KIDS */}
|
|
<AccordionBlock
|
|
title="Kids"
|
|
items={megaMenu.kids}
|
|
closeMenu={closeMenu}
|
|
/>
|
|
|
|
{/* ACCESSORIES */}
|
|
<AccordionBlock
|
|
title="Accessories"
|
|
items={megaMenu.accessories}
|
|
closeMenu={closeMenu}
|
|
/>
|
|
</div>
|
|
</>
|
|
) : (
|
|
<Link
|
|
to={item.href}
|
|
onClick={closeMenu}
|
|
className="block py-3 font-semibold text-gray-900 rounded hover:bg-gray-100"
|
|
>
|
|
{item.label}
|
|
</Link>
|
|
)}
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default MobileMenu;
|
|
|
|
/* ---------------------------------------------
|
|
Sub Menu Accordion (MEN / WOMEN / KIDS...)
|
|
---------------------------------------------- */
|
|
const AccordionBlock = ({ title, items, closeMenu }) => {
|
|
const [open, setOpen] = useState(false);
|
|
|
|
return (
|
|
<div className="border-b">
|
|
<button
|
|
onClick={() => setOpen(!open)}
|
|
className="w-full flex justify-between items-center py-2 font-medium text-gray-800"
|
|
>
|
|
{title}
|
|
{open ? <ChevronUp size={18} /> : <ChevronDown size={18} />}
|
|
</button>
|
|
|
|
<div
|
|
className={`transition-all duration-300 overflow-hidden ${
|
|
open ? "max-h-[500px] opacity-100" : "max-h-0 opacity-0"
|
|
}`}
|
|
>
|
|
{items.map((block, idx) => (
|
|
<div key={idx} className="pl-4 py-2">
|
|
<h4 className="font-semibold text-gray-700">{block.title}</h4>
|
|
|
|
<div className="mt-1 space-y-1">
|
|
{block.items.map((item, index) => (
|
|
<Link
|
|
key={index}
|
|
to={item.href}
|
|
onClick={closeMenu}
|
|
className="block text-sm text-gray-600 hover:text-rose-500"
|
|
>
|
|
{item.label}
|
|
</Link>
|
|
))}
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|