amati/apps/frontend/src/components/NavbarMenuItem.tsx

111 lines
2.9 KiB
TypeScript

import { useState } from "react";
import * as TbIcons from "react-icons/tb";
// import classNames from "./styles/navbarMenuItem.module.css";
// import dashboardConfig from "../dashboard.config";
// import { usePathname } from "next/navigation";
// import areURLsSame from "@/utils/areUrlSame";
import { SidebarMenu } from "backend/types";
import ChildMenu from "./NavbarChildMenu";
import { Link } from "@tanstack/react-router";
import { Button } from "@/shadcn/components/ui/button";
import { ChevronRightIcon} from "lucide-react";
import { cn } from "@/lib/utils";
interface Props {
menu: SidebarMenu;
isActive: boolean;
onClick: (link: string) => void;
}
//TODO: Make bold and collapsed when the item is active
/**
* `MenuItem` is a React functional component that displays an individual menu item.
* It can optionally include a collapsible sub-menu for items with children.
*
* @param props - The component props.
* @param props.menu - The menu item data to display.
* @returns A React element representing an individual menu item.
*/
export default function MenuItem({ menu, isActive, onClick }: Props) {
const hasChildren = Array.isArray(menu.children);
// const pathname = usePathname();
const [opened, setOpened] = useState(
// menu.children?.some((child) =>
// areURLsSame(`${dashboardConfig.baseRoute}${child.link}`, pathname)
// ) ?? false
false
);
const toggleOpenMenu = () => {
setOpened((prev) => !prev);
};
const handleClick = () => {
onClick(menu.link ?? "");
if (!hasChildren) {
toggleOpenMenu();
}
};
// Mapping children menu items if available
const subItems = (hasChildren ? menu.children! : []).map((child, index) => (
<ChildMenu key={index} item={child} active={false} />
));
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const Icons = TbIcons as any;
const Icon =
typeof menu.icon.tb === "string" ? Icons[menu.icon.tb] : menu.icon.tb;
// const isActive = areURLsSame(
// `${dashboardConfig.baseRoute}${menu.link}`,
// pathname
// );
return (
<>
{/* Main Menu Item */}
<Button
variant="ghost"
className={cn(
"w-full p-2 rounded-md justify-between focus:outline-none",
isActive ? "bg-[--primary-color] text-white" : "text-black"
)}
onClick={handleClick}
asChild
>
<Link to={menu.link ?? "#"}>
<div className="flex items-center">
{/* Icon */}
<span className="mr-3">
<Icon className="w-4 h-4" />
</span>
{/* Label */}
<span className="text-xs font-normal whitespace-normal">{menu.label}</span>
</div>
{/* Chevron Icon */}
{hasChildren && (
<ChevronRightIcon
className={`w-4 h-4 transition-transform ${
opened ? "rotate-90" : "rotate-0"
}`}
/>
)}
</Link>
</Button>
{/* Collapsible Sub-Menu */}
{hasChildren && (
<div className={cn("transition-all", opened ? "block" : "hidden")}>
{subItems}
</div>
)}
</>
);
}