/* 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