Skip to content

Commit

Permalink
refactored Nav avoiding repetition, routes defined in NavConfig
Browse files Browse the repository at this point in the history
  • Loading branch information
dwarfered committed Jan 18, 2025
1 parent c21fd98 commit bb0f5aa
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 175 deletions.
50 changes: 50 additions & 0 deletions components/NavButton.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<Button
shape="square"
appearance="subtle"
icon={
isActive && showActiveIcon ? (
<DividerTallFilled style={{ transform: "scaleX(2)" }} />
) : undefined
}
onClick={() => router.push(route)}
style={{
width: "100%",
justifyContent: "flex-start",
display: "flex",
...(isActive ? activeStyle : {}),
}}
>
{icon}
<Body1 style={{ marginLeft: icon ? 8 : 0 }}>{label}</Body1>
</Button>
);
}
57 changes: 57 additions & 0 deletions components/NavConfig.tsx
Original file line number Diff line number Diff line change
@@ -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: <HomeRegular />,
showActiveIcon: false,
},
{
label: "App Registrations",
route: "/app-registrations",
icon: <IconAppRegistrations />,
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: <IconEnterpriseApps />,
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,
},
],
},
];
223 changes: 48 additions & 175 deletions components/NavMenu.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<Toolbar aria-label="with Separeted Groups">
<Toolbar aria-label="Navigation Menu">
<ToolbarGroup role="presentation" style={{ width: "100%" }}>
<Button
onClick={() => {
router.push("/");
}}
shape="square"
appearance="subtle"
icon={<HomeRegular />}
style={{
width: "100%",
justifyContent: "flex-start", // This aligns the button content to the left
display: "flex", // Ensures flexbox layout for content alignment,
...(pathname === "/" ? activeStyle : {}),
}}
>
<Body1Strong> Home</Body1Strong>
</Button>
<Divider />
{navConfig.map((item, index) => {
if (item.children && item.children.length > 0) {
return (
<Accordion key={index} defaultOpenItems="1">
<AccordionItem value="1">
<AccordionHeader
icon={{
as: "div",
children: item.icon,
}}
expandIconPosition="end"
>
<Body1Strong>{item.label}</Body1Strong>
</AccordionHeader>
<AccordionPanel>
{item.children.map((child, childIndex) => (
<NavButton
key={childIndex}
label={child.label}
route={child.route}
showActiveIcon={child.showActiveIcon}
/>
))}
</AccordionPanel>
</AccordionItem>
</Accordion>
);
}

{/* <AuthenticatedTemplate> */}
<Accordion defaultOpenItems="1">
<AccordionItem value="1">
<AccordionHeader
icon={<IconAppRegistrations />}
expandIconPosition="end"
>
<Body1Strong>App Registrations</Body1Strong>
</AccordionHeader>
<AccordionPanel>
<Button
icon={
pathname === "/app-registrations/analytics" ? (
<DividerTallFilled
style={{
transform: "scaleX(2)",
}}
/>
) : undefined
}
onClick={() =>
router.push("/app-registrations/analytics")
}
shape="square"
appearance="subtle"
style={{
width: "100%",
justifyContent: "flex-start",
display: "flex",
...(pathname === "/app-registrations/analytics"
? activeStyle
: {}),
}}
>
<Body1>Analytics</Body1>
</Button>
<Button
icon={
pathname === "/app-registrations/certificates-and-secrets" ? (
<DividerTallFilled
style={{
transform: "scaleX(2)",
}}
/>
) : 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
: {}),
}}
>
<Body1>Certificates & secrets</Body1>
</Button>
</AccordionPanel>
</AccordionItem>
</Accordion>
{/* </AuthenticatedTemplate> */}
<Accordion defaultOpenItems="1">
<AccordionItem value="1">
<AccordionHeader
icon={<IconEnterpriseApps />}
expandIconPosition="end"
>
<Body1Strong>Enterprise Applications</Body1Strong>
</AccordionHeader>
<AccordionPanel>
<Button
icon={
pathname ===
"/enterprise-applications/app-role-permissions" ? (
<DividerTallFilled
style={{
transform: "scaleX(2)",
}}
/>
) : 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
: {}),
}}
>
<Body1>App role permissions</Body1>
</Button>
<Button
icon={
pathname ===
"/enterprise-applications/saml-certificate-expiry-status" ? (
<DividerTallFilled
style={{
transform: "scaleX(2)",
}}
/>
) : 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
: {}),
}}
>
<Body1>SAML certificate status</Body1>
</Button>
</AccordionPanel>
</AccordionItem>
</Accordion>
return (
<div key={index}>
<NavButton
label={item.label}
route={item.route}
icon={item.icon}
showActiveIcon={item.showActiveIcon}
/>
{index < navConfig.length - 1 && <Divider />}
</div>
);
})}
</ToolbarGroup>
<ToolbarGroup role="presentation"></ToolbarGroup>
</Toolbar>
);
}

0 comments on commit bb0f5aa

Please sign in to comment.