diff --git a/components/NavButton.tsx b/components/NavButton.tsx new file mode 100644 index 0000000..3bc9dfe --- /dev/null +++ b/components/NavButton.tsx @@ -0,0 +1,50 @@ +import React from "react"; +import { Button, Body1, tokens } from "@fluentui/react-components"; +import { DividerTallFilled } from "@fluentui/react-icons"; +import { useRouter, usePathname } from "next/navigation"; + +interface NavButtonProps { + label: string; + route: string; + showActiveIcon?: boolean; + icon?: React.ReactNode; +} + +const activeStyle = { + backgroundColor: tokens.colorNeutralBackground2, + color: tokens.colorNeutralForeground2BrandSelected, +}; + +export function NavButton({ + label, + route, + icon, + showActiveIcon = false, +}: NavButtonProps) { + const router = useRouter(); + const pathname = usePathname(); + + const isActive = pathname === route; + + return ( + + ) : undefined + } + onClick={() => router.push(route)} + style={{ + width: "100%", + justifyContent: "flex-start", + display: "flex", + ...(isActive ? activeStyle : {}), + }} + > + {icon} + {label} + + ); +} \ No newline at end of file diff --git a/components/NavConfig.tsx b/components/NavConfig.tsx new file mode 100644 index 0000000..4a04f56 --- /dev/null +++ b/components/NavConfig.tsx @@ -0,0 +1,57 @@ + +import { HomeRegular } from "@fluentui/react-icons"; +import IconAppRegistrations from "./styling/icons/IconAppRegistrations"; +import IconEnterpriseApps from "./styling/icons/IconEnterpriseApps"; + +interface NavItem { + label: string; + route: string; + icon?: React.ReactNode; // Icon for the header or button + showActiveIcon?: boolean; // Whether to show the active divider icon + children?: NavItem[]; // Sub-items if this item has an accordion +} + +export const navConfig: NavItem[] = [ + { + label: "Home", + route: "/", + icon: , + showActiveIcon: false, + }, + { + label: "App Registrations", + route: "/app-registrations", + icon: , + showActiveIcon: false, + children: [ + { + label: "Analytics", + route: "/app-registrations/analytics", + showActiveIcon: true, + }, + { + label: "Certificates & secrets", + route: "/app-registrations/certificates-and-secrets", + showActiveIcon: true, + }, + ], + }, + { + label: "Enterprise Applications", + route: "/enterprise-applications", + icon: , + showActiveIcon: false, + children: [ + { + label: "App role permissions", + route: "/enterprise-applications/app-role-permissions", + showActiveIcon: true, + }, + { + label: "SAML certificate status", + route: "/enterprise-applications/saml-certificate-expiry-status", + showActiveIcon: true, + }, + ], + }, +]; \ No newline at end of file diff --git a/components/NavMenu.tsx b/components/NavMenu.tsx index 4e60b7d..baed266 100644 --- a/components/NavMenu.tsx +++ b/components/NavMenu.tsx @@ -1,190 +1,63 @@ import { + Toolbar, + ToolbarGroup, Accordion, - AccordionHeader, AccordionItem, + AccordionHeader, AccordionPanel, - Body1, - Body1Strong, - Button, Divider, - tokens, - Toolbar, - ToolbarGroup, + Body1Strong, } from "@fluentui/react-components"; -import { DividerTallFilled, HomeRegular } from "@fluentui/react-icons"; -import { usePathname, useRouter } from "next/navigation"; -import IconAppRegistrations from "./styling/icons/IconAppRegistrations"; -import IconEnterpriseApps from "./styling/icons/IconEnterpriseApps"; - -export default function NavMenu() { - const router = useRouter(); - - const pathname = usePathname(); // Get the current route - const activeStyle = { - backgroundColor: tokens.colorNeutralBackground2, - color: tokens.colorNeutralForeground2BrandSelected, - }; +import { NavButton } from "./NavButton"; +import { navConfig } from "./NavConfig"; +export default function NavMenu() { return ( - + - { - router.push("/"); - }} - shape="square" - appearance="subtle" - icon={} - style={{ - width: "100%", - justifyContent: "flex-start", // This aligns the button content to the left - display: "flex", // Ensures flexbox layout for content alignment, - ...(pathname === "/" ? activeStyle : {}), - }} - > - Home - - + {navConfig.map((item, index) => { + if (item.children && item.children.length > 0) { + return ( + + + + {item.label} + + + {item.children.map((child, childIndex) => ( + + ))} + + + + ); + } - {/* */} - - - } - expandIconPosition="end" - > - App Registrations - - - - ) : undefined - } - onClick={() => - router.push("/app-registrations/analytics") - } - shape="square" - appearance="subtle" - style={{ - width: "100%", - justifyContent: "flex-start", - display: "flex", - ...(pathname === "/app-registrations/analytics" - ? activeStyle - : {}), - }} - > - Analytics - - - ) : undefined - } - onClick={() => - router.push("/app-registrations/certificates-and-secrets") - } - shape="square" - appearance="subtle" - style={{ - width: "100%", - justifyContent: "flex-start", - display: "flex", - ...(pathname === "/app-registrations/certificates-and-secrets" - ? activeStyle - : {}), - }} - > - Certificates & secrets - - - - - {/* */} - - - } - expandIconPosition="end" - > - Enterprise Applications - - - - ) : undefined - } - onClick={() => - router.push("/enterprise-applications/app-role-permissions") - } - shape="square" - appearance="subtle" - style={{ - width: "100%", - justifyContent: "flex-start", - display: "flex", - ...(pathname === - "/enterprise-applications/app-role-permissions" - ? activeStyle - : {}), - }} - > - App role permissions - - - ) : undefined - } - onClick={() => - router.push( - "/enterprise-applications/saml-certificate-expiry-status" - ) - } - shape="square" - appearance="subtle" - style={{ - width: "100%", - justifyContent: "flex-start", - display: "flex", - ...(pathname === - "/enterprise-applications/saml-certificate-expiry-status" - ? activeStyle - : {}), - }} - > - SAML certificate status - - - - + return ( + + + {index < navConfig.length - 1 && } + + ); + })} - ); }