Something went wrong on our end
-
Manoa Harinjo authoredManoa Harinjo authored
Menu.tsx 8.07 KiB
import React from "react"
import { graphql, useStaticQuery } from "gatsby"
import { useLocation } from "@reach/router"
import { twMerge } from "tailwind-merge"
import { ChevronRightIcon, ChevronDownIcon } from "@heroicons/react/solid"
import { Link, isBrowser } from "@onegeo-suite/gatsby-theme-onegeo"
import { UserMenu } from "@onegeo-suite/gatsby-plugin-auth"
interface Imenu {
className?: string
name: string
userMenu?: boolean
options: any
}
const Menu = (props: Imenu) => {
const { className, name, userMenu = false } = props
const location = useLocation()
const data = useStaticQuery(graphql`
fragment MenuItem on DirectusData_menus {
sort
name
type
url
page {
slug
}
options
}
fragment MenusRecursive on DirectusData_menus {
children(filter: { status: { _eq: "published" } }, sort: "sort") {
...MenuItem
children(
filter: { status: { _eq: "published" } }
sort: "sort"
) {
...MenuItem
children(
filter: { status: { _eq: "published" } }
sort: "sort"
) {
...MenuItem
}
}
}
}
query Menus {
directus {
menus(
filter: {
status: { _eq: "published" }
parent_id: { id: { _null: true } }
}
sort: "sort"
) {
sort
name
options
...MenusRecursive
}
}
}
`)
const menuContent = data.directus.menus
const menuSelected = menuContent.find(
(menu: any) => name?.toLowerCase() === menu.name?.toLowerCase()
)
// const options = props.options ?? (menuSelected?.options || {})
const options = menuSelected?.options || {}
const oClass = options.class || {}
const oItem = oClass.items || {}
const oSubitem = oClass.subitems || {}
const menu = menuSelected?.children || []
const goto = (item) => {
if (!item) return ""
if (item?.type === "none") return ""
if (item?.type === "page") {
const slug = item?.page?.slug || ""
if (slug.at(0) === "/") return slug
return "/" + slug
}
return item?.url || ""
}
const isActive = (item) => {
// Get last part of item url without '/'
const url =
goto(item)
.split("/")
.filter((entry) => entry !== "")
.at(-1) || ""
// console.log("isActive url", goto(item), "(", url, ")")
// manage default style at build time and style at run time
const pathname = isBrowser
? window.location.pathname
: location.pathname
// Get last part of location pathname without '/'
const path =
pathname
.split("/")
.slice(2) // remove first empty entry & pathPrefix
.filter((entry) => entry !== "")
.at(-1) || ""
// console.log("isActive path", pathname, "(", path, ")")
return url === path
}
const subitems = (item: any) => {
return (
<ul
className={twMerge(
"bg-base-100 z-50 p-2 shadow-md",
oSubitem.main
)}
>
{item.children.map((itemChild: any, idx: number) => {
return (
<li
key={"M_" + name + "_L2_" + idx}
className={twMerge("", oSubitem.item)}
>
<Link
to={goto(itemChild)}
target="_blank"
className={twMerge("", oSubitem.link)}
>
<span className={twMerge("", oSubitem.name)}>
{itemChild.name}
</span>
</Link>
</li>
)
})}
</ul>
)
}
const items = (item: any) => {
return (
<ul
className={twMerge(
"menu rounded-box bg-base-100 z-50 min-w-[12rem] p-2 shadow-md",
oItem.main
)}
>
{item.children.map((itemChild: any, idx: number) => {
return (
<li
key={"M_" + name + "_L1_" + idx}
className={twMerge("", oItem.item)}
>
<Link
to={goto(itemChild)}
target="_blank"
className={twMerge("", oItem.link)}
>
<span className={twMerge("grow", oItem.name)}>
{itemChild.name}
</span>
{itemChild?.children.length > 0 && (
<ChevronRightIcon
className={twMerge(
"h-5 w-5",
oItem.icon
)}
/>
)}
</Link>
{itemChild?.children?.length > 0 &&
subitems(itemChild)}
</li>
)
})}
</ul>
)
}
return (
<ul className={twMerge(className, oClass.main)}>
{menu?.map((item: any, key: number) => {
const isItemActive = isActive(item)
return (
<li
key={"M_" + name + "_L0_" + key}
className={twMerge("", oClass.item)}
>
<Link
to={goto(item)}
target="_blank"
className={twMerge(
"",
oClass.link,
item.options?.link
)}
>
{/* TODO: option to change active bordered / color / bg */}
<span
className={twMerge(
//"border-b-4 border-transparent",
oClass.name,
item.options?.name,
isItemActive
? //border-primary
twMerge(
"text-primary font-semibold",
oClass.active
)
: ""
)}
>
{item.name}
</span>
{item.children?.length > 0 && (
<ChevronDownIcon
className={twMerge("h-5 w-5", oClass.icon)}
/>
)}
</Link>
{item.children?.length > 0 && items(item)}
</li>
)
})}
{userMenu ? <UserMenu /> : null}
</ul>
)
}
export default Menu