import { useState, useEffect, useRef } from "react";
import AppBar from "@mui/material/AppBar";
import Toolbar from "@mui/material/Toolbar";
import Button from "@mui/material/Button";
import IconButton from "@mui/material/IconButton";
import Box from "@mui/material/Box";
import Header from "../Header";
import SearchIcon from "@mui/icons-material/Search";
import LocalMallIcon from '@mui/icons-material/LocalMall';
import AccountCircleIcon from "@mui/icons-material/AccountCircle";
import logoSrc from "../../assets/images/amberlogo.png";
import { styled } from '@mui/material/styles';
import { MenuItem, Select, FormControl, Badge, Typography } from '@mui/material';
import MobileNav from "./components/MobileNav";
import SideCart from "../SideCart/SideCart";
import MenuIcon from "@mui/icons-material/Menu";
import SearchProduct from "../SearchProduct"
import CategoryIcon from '@mui/icons-material/Category';
import HomeIcon from '@mui/icons-material/Home';
import BrushIcon from '@mui/icons-material/Brush';
import LoyaltyIcon from '@mui/icons-material/Loyalty';
import Grid from '@mui/material/Grid2';
import { useSelector, useDispatch } from 'react-redux';
import { fetchProducts } from "../../redux/slices/productSlice";
import ProductService from "../../services/ProductService";
import { Swiper, SwiperSlide } from 'swiper/react';
import { Scrollbar, A11y, Navigation } from 'swiper/modules';
import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';
import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
function calculateTotalQuantity(cartItems) {
return cartItems.reduce((total, item) => total + item.quantity, 0);
}
const LanguageSelect = styled(Select)(({ theme }) => ({
backgroundColor: 'black',
color: 'white',
border: '1px solid black',
fontSize: 12,
'& .MuiSelect-icon': {
color: 'white',
},
'&:hover': {
backgroundColor: 'white',
color: 'black',
},
'& .MuiMenuItem-root': {
backgroundColor: 'black',
color: 'white',
},
'& .MuiMenuItem-root:hover': {
backgroundColor: 'white',
color: 'black',
},
}));
const LanguageSelectItem = styled(MenuItem)(() => ({
backgroundColor: 'black',
color: 'white',
'&:hover': {
backgroundColor: 'white',
color: 'black',
},
}));
const COLLECTION_PRIORITY_BY_TYPE = {
apparel: [
"EID'S TIME FOR LOVE COLLECTION",
"ND X MARII FOR AMBER",
"MIRAGE COLLECTION",
"SOMEWHERE SOMEHOW SOMEONE",
"OASIS ABAYA COLLECTION",
"RAYA ROMANTICS COLLECTION 2025",
"CASUAL WEAR",
"AINA ABDUL MERCHANDISE",
"ATMA SARI",
"FLOWER POWER",
"AMBER SCARVES FLOWER POWER SERIES",
],
};
const normalizeTitle = (value = "") => value.trim().toUpperCase();
const getProductTypeMenuLabel = (productType = "") => {
return normalizeTitle(productType) === "BEAUTY" ? "Essentials" : productType;
};
const NAV_MENU_STRUCTURE = [
{
productType: "Apparel",
label: "APPAREL",
groups: [
{
label: "Casual",
children: [
{ label: "ND X Marii for Amber", titles: ["ND X MARII FOR AMBER"] },
{ label: "Somewhere Somehow Someone", titles: ["SOMEWHERE SOMEHOW SOMEONE"] },
{ label: "Flower Power", titles: ["FLOWER POWER"] },
],
},
{
label: "Traditional",
children: [
{ label: "Eid's Time For Love", titles: ["EID'S TIME FOR LOVE"] },
{ label: "Raya Romantics", titles: ["RAYA ROMANTICS COLLECTION 2025"] },
{ label: "Atma Sari", titles: ["ATMA SARI"] },
{ label: "Oasis abaya collection", titles: ["OASIS ABAYA COLLECTION", "MIRAGE COLLECTION"] },
],
},
],
},
{
productType: "BEAUTY",
label: "Essentials",
children: [
{ label: "Cosmetics", titles: ["COSMETICS"] },
{ label: "Hand & Body Lotion", titles: ["HAND & BODY LOTION"] },
],
},
];
const sortCollectionsByPriority = (collection = [], productType = "") => {
const typeKey = (productType || "").trim().toLowerCase();
const priorityList = COLLECTION_PRIORITY_BY_TYPE[typeKey] || [];
const priorityMap = new Map(
priorityList.map((title, index) => [normalizeTitle(title), index])
);
return [...collection].sort((a, b) => {
const aTitle = normalizeTitle(a?.title || "");
const bTitle = normalizeTitle(b?.title || "");
const aPriority = priorityMap.has(aTitle)
? priorityMap.get(aTitle)
: Number.MAX_SAFE_INTEGER;
const bPriority = priorityMap.has(bTitle)
? priorityMap.get(bTitle)
: Number.MAX_SAFE_INTEGER;
if (aPriority !== bPriority) {
return aPriority - bPriority;
}
const aUpdatedAt = a?.updatedAt ? Date.parse(a.updatedAt) : 0;
const bUpdatedAt = b?.updatedAt ? Date.parse(b.updatedAt) : 0;
if (aUpdatedAt !== bUpdatedAt) {
return bUpdatedAt - aUpdatedAt;
}
return aTitle.localeCompare(bTitle);
});
};
function mapProductTypesWithCollections(products) {
// Create a Map to group collections by productType
const productTypeMap = new Map();
products.forEach(product => {
const { productType, collections } = product;
// If productType already exists, merge its collections
if (productTypeMap.has(productType)) {
const existingCollections = productTypeMap.get(productType);
const newCollections = collections.map(collection => collection);
productTypeMap.set(productType, [...new Set([...existingCollections, ...newCollections])]);
} else {
// Add a new productType with its collections
productTypeMap.set(productType, collections.map(collection => collection));
}
});
// Convert the Map into the desired array structure
return Array.from(productTypeMap, ([productType, collection]) => ({ productType, collection }));
}
function getUniqueCollections(data) {
return data.map(item => {
// Use a Map to store unique collection titles with their corresponding image
const uniqueCollectionsMap = new Map();
item.collection.forEach(({ title, image, updatedAt }) => {
if (!uniqueCollectionsMap.has(title)) {
uniqueCollectionsMap.set(title, { title, image, updatedAt });
}
});
// Convert the Map back to an array
return {
productType: item.productType,
collection: sortCollectionsByPriority(
Array.from(uniqueCollectionsMap.values()),
item.productType
)
};
});
}
const Navbar = () => {
const swiperRef = useRef(null); // Create a ref for the Swiper instance
const childTransitionTimerRef = useRef(null);
const [showHeader, setShowHeader] = useState(true);
const [showSearch, setShowSearch] = useState(false);
const [isAtTop, setIsAtTop] = useState(false);
const [isProductPage, setIsProductPage] = useState(false);
const [lastScrollPos, setLastScrollPos] = useState(0);
const [language, setLanguage] = useState('English');
const dispatch = useDispatch();
const cart = useSelector((state) => state.cart.cart)
const products = useSelector((state) => state.products.products.data)
const [cartAmount, setCartAmount] = useState(0);
const [openSideMenu, setOpenSideMenu] = useState(false);
const [openSideCart, setOpenSideCart] = useState(false);
const [navItem, setNavItem] = useState([]);
const [navItemCompanyInfo, setNavItemCompanyInfo] = useState([]);
const [activeMenu, setActiveMenu] = useState(null);
const [activeGroup, setActiveGroup] = useState(null);
const [displayCollection, setDisplayCollection] = useState({
productType: null,
list: []
})
useEffect(() => {
dispatch(fetchProducts())
if (window.location.pathname === "/") setIsAtTop(true);
const handleScroll = () => {
if (window.location.pathname === "/") setIsAtTop(window.scrollY < 20);
};
window.addEventListener("scroll", handleScroll);
// Cleanup on component unmount
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, [])
useEffect(() => {
if (!cart?.lines?.nodes) return // don't need to do anything if we have no cart data
setCartAmount(calculateTotalQuantity(cart?.lines?.nodes))
}, [cart])
useEffect(() => {
//Navbar item are based on products type, thus get all the item and then we should be good
if (products.length > 0) {
let navItemData = mapProductTypesWithCollections(products)
navItemData = getUniqueCollections(navItemData)
navItemData = navItemData.filter(({ productType }) => normalizeTitle(productType) !== "HOME")
setNavItem(navItemData)
// extra info for the navbar
setNavItemCompanyInfo([]);
/*
setNavItemCompanyInfo([{
name:"DELIVERY INFORMATION",
link:"/delivery_info"
},
{
name:"SALE TERMS & CONDITIONS",
link:"/sale_terms_and_condition"
},
{
name:"RETURNS & REFUNDS",
link:"/return_and_exchange"
},
{
name:"CONTACT US",
link:"/contact_us"
}]);
*/
}
}, [products])
const handleChange = (event) => {
setLanguage(event.target.value);
};
useEffect(() => {
const handleScroll = () => {
const currentScrollPos = window.scrollY;
if (currentScrollPos > lastScrollPos && currentScrollPos > 50) setShowHeader(false)
else setShowHeader(true)
setLastScrollPos(currentScrollPos);
};
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, [lastScrollPos]);
const renderCollectionDisplay = (colletion) => {
return (
{
sessionStorage.setItem('amber-select-collection', JSON.stringify(colletion))
sessionStorage.setItem('amber-select-product-type', displayCollection.productType)
window.location.href = `/products`;
}}
>
{colletion?.title?.toUpperCase()}
)
}
const swipeToLeft = () => {
if (swiperRef.current) {
swiperRef.current.slidePrev(); // Move to the previous slide
}
};
const swipeToRight = () => {
if (swiperRef.current) {
swiperRef.current.slideNext(); // Move to the previous slide
}
};
const displayCollectionList = (collection = [], productType) => {
const sortedCollection = sortCollectionsByPriority(collection, productType);
setDisplayCollection([])
setTimeout(() => {
setDisplayCollection({
productType,
list: sortedCollection
})
}, 100);
}
const hideCollectionList = () => {
setDisplayCollection([])
}
const handleGroupMouseEnter = (groupLabel) => {
if (activeGroup === groupLabel) return;
if (childTransitionTimerRef.current) {
clearTimeout(childTransitionTimerRef.current);
}
setActiveGroup(null);
childTransitionTimerRef.current = setTimeout(() => {
setActiveGroup(groupLabel);
}, 40);
}
const navigateToMenuItem = (productType, item = null) => {
sessionStorage.setItem('amber-select-product-type', productType)
sessionStorage.removeItem('amber-select-collection')
sessionStorage.removeItem('amber-select-collections')
if (item) {
sessionStorage.setItem('amber-select-collection', JSON.stringify({
title: item.label,
image: null
}))
sessionStorage.setItem('amber-select-collections', JSON.stringify(item.titles || []))
}
window.location.href = `/products`;
}
return (
<>
{
hideCollectionList()
setActiveMenu(null)
setActiveGroup(null)
}}
>
{/* Conditionally render the Header */}
{showHeader && }
{/* SIDEBAR BUTTON */}
setOpenSideMenu(true)}
className="navItem"
sx={{
backgroundColor: "transparent",
color: (isAtTop) ? "white" : "black",
"&:hover": {
backgroundColor: "rgba(0, 0, 0, 0.1)",
},
}}
>
{/* Left Section: Logo */}
{/* Center Section: Nav Items */}
{NAV_MENU_STRUCTURE.map((menu) => (
{
if (childTransitionTimerRef.current) {
clearTimeout(childTransitionTimerRef.current);
}
setActiveMenu(menu.label);
setActiveGroup(null);
}}
>
{(
<>
{menu.groups ? (
<>
{menu.groups.map((group) => (
))}
{activeGroup && (
{menu.groups
.find((group) => group.label === activeGroup)
?.children.map((item) => (
))}
)}
>
) : (
{menu.children.map((item) => (
))}
)}
>
)}
))}
{/*
{navItem.map(({ productType, collection }) => ())}
{navItemCompanyInfo.map(({ name, link }) => ())}
*/}
{/* Right Section: Search and Profile */}
{/*
English
Malay
Chinese
*/}
{ setShowSearch(true) }}>
{ setOpenSideCart(true) }}
badgeContent={cartAmount} color="primary">
{/*
*/}
{/* On Hover Collection */}
0) ? "block" : "none" }}>
(swiperRef.current = swiper)}
>
{displayCollection?.list?.map((colletion) => {
return renderCollectionDisplay(colletion)
})}
{showSearch && { setShowSearch(false) }} />}
{ setOpenSideMenu(false) }} />
{ setOpenSideCart(false) }} />
>
);
};
export default Navbar;