/* eslint-disable no-param-reassign */ import { useState, useEffect, ReactNode, Fragment } from "react" // nextjs components import Link from "next/link" // @mui material components import Icon from "@mui/material/Icon" import Popper from "@mui/material/Popper" import Grow, { GrowProps } from "@mui/material/Grow" import Grid from "@mui/material/Grid" import Divider from "@mui/material/Divider" import MuiLink from "@mui/material/Link" import Container from "@mui/material/Container" import { Theme } from "@mui/material/styles" // ThreeD Garden components import MDBox from "~/components/mui/MDBox" import MDTypography from "~/components/mui/MDTypography" import MDButton from "~/components/mui/MDButton" // ThreeD Garden examples components import DefaultNavbarDropdown from "~/components/elements/Navbars/DefaultNavbar/DefaultNavbarDropdown" import DefaultNavbarMobile from "~/components/elements/Navbars/DefaultNavbar/DefaultNavbarMobile" // ThreeD Garden Base Styles import breakpoints from "~/themes/theme-light/base/breakpoints" // ThreeD Garden context import { useMaterialUIController } from "~/context" // Declaring props types for DefaultNavbar interface Props { routes: { [key: string]: | ReactNode | string | { [key: string]: string | any }[] }[] brand?: string transparent?: boolean light?: boolean action?: { type: "external" | "internal" route: string color: | "primary" | "secondary" | "info" | "success" | "warning" | "error" | "dark" | "light" label: string } } interface NewGrowTypes extends GrowProps { sx: any [key: string]: any } function NewGrow(props: NewGrowTypes) { return } function DefaultNavbar({ routes, brand, transparent, light, action, }: Props): JSX.Element { const [controller] = useMaterialUIController() const { darkMode } = controller const [dropdown, setDropdown] = useState("") const [dropdownEl, setDropdownEl] = useState("") const [dropdownName, setDropdownName] = useState("") const [nestedDropdown, setNestedDropdown] = useState("") const [nestedDropdownEl, setNestedDropdownEl] = useState("") const [nestedDropdownName, setNestedDropdownName] = useState("") const [arrowRef, setArrowRef] = useState(null) const [mobileNavbar, setMobileNavbar] = useState(false) const [mobileView, setMobileView] = useState(false) const openMobileNavbar = () => setMobileNavbar(!mobileNavbar) useEffect(() => { // A function that sets the display state for the DefaultNavbarMobile. function displayMobileNavbar() { if (window.innerWidth < breakpoints.values.lg) { setMobileView(true) setMobileNavbar(false) } else { setMobileView(false) setMobileNavbar(false) } } /** The event listener that's calling the displayMobileNavbar function when resizing the window. */ window.addEventListener("resize", displayMobileNavbar) // Call the displayMobileNavbar function to set the state with the initial value. displayMobileNavbar() // Remove event listener on cleanup return () => window.removeEventListener("resize", displayMobileNavbar) }, []) const renderNavbarItems = routes.map( ({ name, icon, href, route, collapse }: any) => ( { if (collapse) { setDropdown(currentTarget) setDropdownEl(currentTarget) setDropdownName(name) } }} onMouseLeave={() => collapse && setDropdown(null)} light={light} /> ) ) // Render the routes on the dropdown menu const renderRoutes = routes.map( ({ name, collapse, columns, rowsPerColumn }: any) => { let template // Render the dropdown menu that should be display as columns if (collapse && columns && name === dropdownName) { const calculateColumns = collapse.reduce( (resultArray: any, item: any, index: any) => { const chunkIndex = Math.floor(index / rowsPerColumn) if (!resultArray[chunkIndex]) { resultArray[chunkIndex] = [] } resultArray[chunkIndex].push(item) return resultArray }, [] ) template = ( {calculateColumns.map((cols: any, key: any) => { const gridKey = `grid-${key}` const dividerKey = `divider-${key}` return ( {cols.map((col: any, index: any) => ( {col.icon} {col.name} {col.collapse && col.collapse.map((item: any) => ( e.preventDefault() : item.route } target={item.href ? "_blank" : ""} rel={item.href ? "noreferrer" : "noreferrer"} minWidth="11.25rem" display="block" variant="button" color="text" textTransform="capitalize" fontWeight="regular" py={0.625} px={2} sx={({ palette: { grey, dark }, borders: { borderRadius }, }: Theme) => ({ borderRadius: borderRadius.md, cursor: "pointer", transition: "all 300ms linear", "&:hover": { backgroundColor: grey[200], color: dark.main, }, })}> {item.name} ))} ))} {key !== 0 && ( )} ) })} ) // Render the dropdown menu that should be display as list items } else if (collapse && name === dropdownName) { template = collapse.map((item: any) => { const linkComponent = { component: MuiLink, href: item.href, target: "_blank", rel: "noreferrer", } const routeComponent = { component: Link, href: item.route, } return ( ({ borderRadius: borderRadius.md, cursor: "pointer", transition: "all 300ms linear", "&:hover": { backgroundColor: grey[200], color: dark.main, "& *": { color: dark.main, }, }, })} onMouseEnter={({ currentTarget }: any) => { if (item.dropdown) { setNestedDropdown(currentTarget) setNestedDropdownEl(currentTarget) setNestedDropdownName(item.name) } }} onMouseLeave={() => { if (item.dropdown) { setNestedDropdown(null) } }}> {item.description ? ( {typeof item.icon === "string" ? ( {item.icon} ) : ( {item.icon} )} {item.name} {item.description} ) : ( {item.icon} {item.name} )} {item.collapse && ( keyboard_arrow_right )} ) }) } return template } ) // Routes dropdown menu const dropdownMenu = ( setDropdown(dropdownEl)} onMouseLeave={() => { if (!nestedDropdown) { setDropdown(null) setDropdownName("") } }}> {({ TransitionProps }) => ( white.main, }}> arrow_drop_up {renderRoutes} )} ) // Render routes that are nested inside the dropdown menu routes const renderNestedRoutes = routes.map(({ collapse, columns }: any) => collapse && !columns ? collapse.map(({ name: parentName, collapse: nestedCollapse }: any) => { let template if (parentName === nestedDropdownName) { template = nestedCollapse && nestedCollapse.map((item: any) => { const linkComponent = { component: MuiLink, href: item.href, target: "_blank", rel: "noreferrer", } const routeComponent = { component: Link, href: item.route, } return ( ({ borderRadius: borderRadius.md, cursor: "pointer", transition: "all 300ms linear", "&:hover": { backgroundColor: grey[200], color: dark.main, "& *": { color: dark.main, }, }, })}> {item.description ? ( {item.name} {item.description} ) : ( item.name )} {item.collapse && ( keyboard_arrow_right )} ) }) } return template }) : null ) // Dropdown menu for the nested dropdowns const nestedDropdownMenu = ( { setNestedDropdown(nestedDropdownEl) }} onMouseLeave={() => { setNestedDropdown(null) setNestedDropdownName("") setDropdown(null) }}> {({ TransitionProps }) => ( white.main, }}> {renderNestedRoutes} )} ) return ( ({ backgroundColor: transparent ? transparentColor.main : rgba(darkMode ? background.sidenav : white.main, 0.8), backdropFilter: transparent ? "none" : `saturate(200%) blur(30px)`, })}> {brand} {renderNavbarItems} {action && (action.type === "internal" ? ( {action.label} ) : ( {action.label} ))} {mobileView && ( )} {dropdownMenu} {nestedDropdownMenu} ) } // Declaring default props for DefaultNavbar DefaultNavbar.defaultProps = { brand: "ThreeD Garden", transparent: false, light: false, action: false, } export default DefaultNavbar