diff --git a/src/modules/dashboard/components/SidebarChildMenu.tsx b/src/modules/dashboard/components/SidebarChildMenu.tsx index 5f2f53d..f43b8dc 100644 --- a/src/modules/dashboard/components/SidebarChildMenu.tsx +++ b/src/modules/dashboard/components/SidebarChildMenu.tsx @@ -4,9 +4,11 @@ import { Text } from "@mantine/core"; import classNames from "./styles/sidebarChildMenu.module.css"; import SidebarMenu from "../types/SidebarMenu"; +import dashboardConfig from "../dashboard.config"; interface Props { item: NonNullable[number]; + active: boolean; } /** @@ -26,7 +28,8 @@ export default function ChildMenu(props: Props) { component="a" className={classNames.link} - href={`/dashboard${linkPath}`} + href={`${dashboardConfig.baseRoute}${linkPath}`} + fw={props.active ? "bold" : "normal"} > {props.item.label} diff --git a/src/modules/dashboard/components/SidebarMenuItem.tsx b/src/modules/dashboard/components/SidebarMenuItem.tsx index 7d0cecc..bc92762 100644 --- a/src/modules/dashboard/components/SidebarMenuItem.tsx +++ b/src/modules/dashboard/components/SidebarMenuItem.tsx @@ -1,4 +1,4 @@ -import React, { ReactNode, useState } from "react"; +import React, { useState } from "react"; import { Box, @@ -6,7 +6,9 @@ import { Group, ThemeIcon, UnstyledButton, + alpha, rem, + useMantineTheme, } from "@mantine/core"; import { TbChevronRight } from "react-icons/tb"; import * as TbIcons from "react-icons/tb"; @@ -14,6 +16,9 @@ import * as TbIcons from "react-icons/tb"; import ChildMenu from "./SidebarChildMenu"; import classNames from "./styles/sidebarMenuItem.module.css"; import SidebarMenu from "../types/SidebarMenu"; +import dashboardConfig from "../dashboard.config"; +import { usePathname } from "next/navigation"; +import areURLsSame from "@/utils/areUrlSame"; interface Props { menu: SidebarMenu; @@ -30,7 +35,11 @@ interface Props { export default function MenuItem({ menu }: Props) { const hasChildren = Array.isArray(menu.children); - const [opened, setOpened] = useState(false); + const pathname = usePathname() + + const theme = useMantineTheme(); + + const [opened, setOpened] = useState(menu.children?.some(child => areURLsSame(`${dashboardConfig.baseRoute}${child.link}`, pathname)) ?? false); const toggleOpenMenu = () => { setOpened((prev) => !prev); @@ -38,20 +47,23 @@ export default function MenuItem({ menu }: Props) { // Mapping children menu items if available const subItems = (hasChildren ? menu.children! : []).map((child, index) => ( - + )); const Icons = TbIcons as any; const Icon = typeof menu.icon === "string" ? Icons[menu.icon] : menu.icon; - // const a = typeof menu.icon === "string" + + const isActive = areURLsSame(`${dashboardConfig.baseRoute}${menu.link}`, pathname) return ( <> {/* Main Menu Item */} - onClick={toggleOpenMenu} className={classNames.control} + href={menu.link ? dashboardConfig.baseRoute + menu.link : ""} + component={menu.link ? "a" : "button"} > {/* Icon and Label */} @@ -60,7 +72,7 @@ export default function MenuItem({ menu }: Props) { - {menu.label} + {menu.label} {/* Chevron Icon for collapsible items */} diff --git a/src/modules/dashboard/data/sidebarMenus.ts b/src/modules/dashboard/data/sidebarMenus.ts index 9697f76..998a6c2 100644 --- a/src/modules/dashboard/data/sidebarMenus.ts +++ b/src/modules/dashboard/data/sidebarMenus.ts @@ -5,6 +5,7 @@ const sidebarMenus: SidebarMenu[] = [ label: "Dashboard", icon: "TbLayoutDashboard", allowedPermissions: ["*"], + link: "/", }, { label: "Users", diff --git a/src/modules/dashboard/types/SidebarMenu.d.ts b/src/modules/dashboard/types/SidebarMenu.d.ts index b41742f..77716e7 100644 --- a/src/modules/dashboard/types/SidebarMenu.d.ts +++ b/src/modules/dashboard/types/SidebarMenu.d.ts @@ -7,10 +7,11 @@ export default interface SidebarMenu { children?: { label: string; link: string; - allowedPermissions?: PermissionCode[], - allowedRoles?: RoleCode[], + allowedPermissions?: PermissionCode[]; + allowedRoles?: RoleCode[]; }[]; + link?: string; color?: ThemeIconProps["color"]; - allowedPermissions?: PermissionCode[], - allowedRoles?: RoleCode[] -} \ No newline at end of file + allowedPermissions?: PermissionCode[]; + allowedRoles?: RoleCode[]; +} diff --git a/src/utils/areUrlSame.ts b/src/utils/areUrlSame.ts new file mode 100644 index 0000000..0c8c74b --- /dev/null +++ b/src/utils/areUrlSame.ts @@ -0,0 +1,13 @@ +function areURLsSame(url1: string, url2: string): boolean { + const normalizeUrl = (url: string) => { + // Remove query parameters + url = url.split("?")[0]; + // Ensure there is no trailing slash + url = url.endsWith("/") ? url.slice(0, -1) : url; + return url.toLowerCase(); + }; + + return normalizeUrl(url1) === normalizeUrl(url2); +} + +export default areURLsSame;