import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Typography"; import classes from "./classes.module.scss"; import { useRouter } from "next/router"; import React, { useCallback, useEffect } from "react"; import useHoverable from "@Front/Hooks/useHoverable"; import classNames from "classnames"; import { IAppRule } from "@Front/Api/Entities/rule"; import { ChevronDownIcon } from "@heroicons/react/24/outline"; import useOpenable from "@Front/Hooks/useOpenable"; type IProps = { item: IItem; }; type IItemBase = { text: string; icon?: JSX.Element; hasSeparator?: boolean; color?: ETypoColor; onClose?: () => void; }; type IItemWithLink = IItemBase & { link: string; rules?: IAppRule[]; routesActive?: string[]; onClick?: never; dropdown?: never; target?: "_blank"; }; type IItemWithOnClick = IItemBase & { onClick: () => void; link?: never; rules?: never; routesActive?: never; dropdown?: never; target?: never; }; type IItemWithDropdown = IItemBase & { dropdown: { items: IItem[]; }; routesActive?: never; link?: never; rules?: never; onClick?: never; target?: never; }; export type IItem = IItemWithLink | IItemWithOnClick | IItemWithDropdown; export default function MenuItem(props: IProps) { const { item } = props; const router = useRouter(); const { pathname } = router; const [isActive, setIsActive] = React.useState(item.link === pathname); const { isOpen, toggle, open } = useOpenable(); const handleClickElement = useCallback( (e: React.MouseEvent) => { item.onClose?.(); const link = e.currentTarget.getAttribute("data-link"); if (item.target === "_blank") window.open(item.link, "_blank"); if (link) router.push(link); if (item.onClick) item.onClick(); }, [item, router], ); const { handleMouseEnter, handleMouseLeave, isHovered } = useHoverable(); const getColor = useCallback(() => { if (isActive) return ETypoColor.CONTRAST_ACTIVED; if (isHovered && item.color !== ETypoColor.ERROR_WEAK_CONTRAST) return ETypoColor.CONTRAST_HOVERED; if (item.color) return item.color; if (isHovered) return ETypoColor.CONTRAST_DEFAULT; return ETypoColor.CONTRAST_DEFAULT; }, [isActive, isHovered, item.color]); useEffect(() => { if (item.link === pathname) setIsActive(true); if (item.routesActive) { for (const routeActive of item.routesActive) { if (isActive) break; if (pathname.includes(routeActive)) setIsActive(true); } } if (item.dropdown) { for (const subItem of item.dropdown.items) { if (isActive) break; if (subItem.link === pathname) { !isOpen && open(); setIsActive(true); } if (subItem.routesActive) { for (const routeActive of subItem.routesActive) { if (isActive) break; if (pathname.includes(routeActive)) { !isOpen && open(); setIsActive(true); } } } } } }, [isActive, isOpen, item.dropdown, item.link, item.routesActive, open, pathname]); return (
{item.icon && React.cloneElement(item.icon, { color: `var(${getColor()})` })} {item.text} {item.dropdown && React.cloneElement(, { color: `var(${getColor()})`, })}
{item.dropdown && (
{item.dropdown.items.map((subItem, index) => ( ))}
)} {item.hasSeparator &&
}
); }