fix dupicate nav routes

This commit is contained in:
vergiLgood1 2025-03-06 15:02:34 +07:00
parent bc03c18a05
commit 45daf059d3
2 changed files with 112 additions and 46 deletions

View File

@ -16,7 +16,7 @@ import {
SidebarMenuSub, SidebarMenuSub,
} from "@/app/_components/ui/sidebar"; } from "@/app/_components/ui/sidebar";
import * as TablerIcons from "@tabler/icons-react"; import type * as TablerIcons from "@tabler/icons-react";
import { useNavigations } from "@/app/_hooks/use-navigations"; import { useNavigations } from "@/app/_hooks/use-navigations";
@ -40,14 +40,38 @@ interface NavItem {
subItems?: SubItem[]; subItems?: SubItem[];
} }
// Helper function to ensure URLs are properly formatted
function formatUrl(url: string): string {
// If URL starts with a slash, it's already absolute
if (url.startsWith("/")) {
return url;
}
// Otherwise, ensure it's properly formatted relative to root
// Remove any potential duplicated '/dashboard' prefixes
if (url.startsWith("dashboard/")) {
return "/" + url;
}
return "/" + url;
}
function SubSubItemComponent({ item }: { item: SubSubItem }) { function SubSubItemComponent({ item }: { item: SubSubItem }) {
const router = useNavigations(); const router = useNavigations();
const isActive = router.pathname === item.url; const formattedUrl = formatUrl(item.url);
const isActive = router.pathname === formattedUrl;
return ( return (
<SidebarMenuItem className={isActive ? "active text-primary" : ""}> <SidebarMenuItem>
<SidebarMenuButton asChild> <SidebarMenuButton
<a href={item.url}> asChild
className={
isActive
? "font-medium bg-primary/10 before:absolute before:left-0 before:top-1/2 before:-translate-y-1/2 before:bg-primary"
: ""
}
>
<a href={formattedUrl} className={isActive ? "text-primary" : ""}>
<span>{item.title}</span> <span>{item.title}</span>
</a> </a>
</SidebarMenuButton> </SidebarMenuButton>
@ -57,15 +81,25 @@ function SubSubItemComponent({ item }: { item: SubSubItem }) {
function SubItemComponent({ item }: { item: SubItem }) { function SubItemComponent({ item }: { item: SubItem }) {
const router = useNavigations(); const router = useNavigations();
const isActive = router.pathname === item.url; const formattedUrl = formatUrl(item.url);
const isActive = router.pathname === formattedUrl;
const hasSubSubItems = item.subSubItems && item.subSubItems.length > 0; const hasSubSubItems = item.subSubItems && item.subSubItems.length > 0;
if (!hasSubSubItems) { if (!hasSubSubItems) {
return ( return (
<SidebarMenuItem className={isActive ? "active text-primary" : ""}> <SidebarMenuItem>
<SidebarMenuButton asChild> <SidebarMenuButton
<a href={item.url}> asChild
{item.icon && <item.icon />} className={
isActive
? "font-medium bg-primary/10 before:absolute before:left-0 before:top-1/2 before:-translate-y-1/2 before:bg-primary"
: ""
}
>
<a href={formattedUrl} className={isActive ? "text-primary" : ""}>
{item.icon && (
<item.icon className={isActive ? "text-primary" : ""} />
)}
<span>{item.title}</span> <span>{item.title}</span>
</a> </a>
</SidebarMenuButton> </SidebarMenuButton>
@ -75,12 +109,22 @@ function SubItemComponent({ item }: { item: SubItem }) {
return ( return (
<Collapsible asChild className="group/collapsible"> <Collapsible asChild className="group/collapsible">
<SidebarMenuItem className={isActive ? "active text-primary" : ""}> <SidebarMenuItem>
<CollapsibleTrigger asChild> <CollapsibleTrigger asChild>
<SidebarMenuButton> <SidebarMenuButton
{item.icon && <item.icon />} className={
<span>{item.title}</span> isActive
<ChevronRight className="ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" /> ? "font-medium bg-primary/10 before:absolute before:left-0 before:top-1/2 before:-translate-y-1/2 before:bg-primary"
: ""
}
>
{item.icon && (
<item.icon className={isActive ? "text-primary" : ""} />
)}
<span className={isActive ? "text-primary" : ""}>{item.title}</span>
<ChevronRight
className={`ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90 ${isActive ? "text-primary" : ""}`}
/>
</SidebarMenuButton> </SidebarMenuButton>
</CollapsibleTrigger> </CollapsibleTrigger>
<CollapsibleContent> <CollapsibleContent>
@ -97,15 +141,26 @@ function SubItemComponent({ item }: { item: SubItem }) {
function RecursiveNavItem({ item, index }: { item: NavItem; index: number }) { function RecursiveNavItem({ item, index }: { item: NavItem; index: number }) {
const router = useNavigations(); const router = useNavigations();
const isActive = router.pathname === item.url; const formattedUrl = formatUrl(item.url);
const isActive = router.pathname === formattedUrl;
const hasSubItems = item.subItems && item.subItems.length > 0; const hasSubItems = item.subItems && item.subItems.length > 0;
if (!hasSubItems) { if (!hasSubItems) {
return ( return (
<SidebarMenuItem className={isActive ? "active text-primary" : ""}> <SidebarMenuItem>
<SidebarMenuButton tooltip={item.title} asChild> <SidebarMenuButton
<a href={item.url}> tooltip={item.title}
{item.icon && <item.icon />} asChild
className={
isActive
? "font-medium bg-primary/10 before:absolute before:left-0 before:top-1/2 before:-translate-y-1/2 before:bg-primary"
: ""
}
>
<a href={formattedUrl} className={isActive ? "text-primary" : ""}>
{item.icon && (
<item.icon className={isActive ? "text-primary" : ""} />
)}
<span>{item.title}</span> <span>{item.title}</span>
</a> </a>
</SidebarMenuButton> </SidebarMenuButton>
@ -120,13 +175,24 @@ function RecursiveNavItem({ item, index }: { item: NavItem; index: number }) {
defaultOpen={index === 1} defaultOpen={index === 1}
className="group/collapsible" className="group/collapsible"
> >
<SidebarMenuItem className={isActive ? "active text-primary" : ""}> <SidebarMenuItem>
<CollapsibleTrigger asChild> <CollapsibleTrigger asChild>
<SidebarMenuButton tooltip={item.title}> <SidebarMenuButton
{item.icon && <item.icon />} tooltip={item.title}
<span>{item.title}</span> className={
isActive
? "font-medium bg-primary/10 before:absolute before:left-0 before:top-1/2 before:-translate-y-1/2 before:bg-primary"
: ""
}
>
{item.icon && (
<item.icon className={isActive ? "text-primary" : ""} />
)}
<span className={isActive ? "text-primary" : ""}>{item.title}</span>
{hasSubItems && ( {hasSubItems && (
<ChevronRight className="ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" /> <ChevronRight
className={`ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90 ${isActive ? "text-primary" : ""}`}
/>
)} )}
</SidebarMenuButton> </SidebarMenuButton>
</CollapsibleTrigger> </CollapsibleTrigger>

View File

@ -75,7 +75,7 @@ export const navData = {
navMain: [ navMain: [
{ {
title: "Dashboard", title: "Dashboard",
url: "dashboard", url: "/dashboard",
slug: "dashboard", slug: "dashboard",
orderSeq: 1, orderSeq: 1,
icon: IconApps, icon: IconApps,
@ -84,7 +84,7 @@ export const navData = {
}, },
{ {
title: "User Management", title: "User Management",
url: "dashboard/user-management", url: "/dashboard/user-management",
slug: "user-management", slug: "user-management",
orderSeq: 2, orderSeq: 2,
icon: IconUsers, icon: IconUsers,
@ -92,7 +92,7 @@ export const navData = {
}, },
{ {
title: "Crime Management", title: "Crime Management",
url: "/crime-management", url: "/dashboard/crime-management",
slug: "crime-management", slug: "crime-management",
orderSeq: 3, orderSeq: 3,
icon: IconGavel, icon: IconGavel,
@ -108,7 +108,7 @@ export const navData = {
}, },
{ {
title: "Crime Categories", title: "Crime Categories",
url: "/crime-management/crime-categories", url: "/dashboard/crime-management/crime-categories",
slug: "crime-categories", slug: "crime-categories",
icon: IconSlice, icon: IconSlice,
orderSeq: 2, orderSeq: 2,
@ -116,7 +116,7 @@ export const navData = {
}, },
{ {
title: "Cases", title: "Cases",
url: "/crime-management/crime-cases", url: "/dashboard/crime-management/crime-cases",
slug: "crime-cases", slug: "crime-cases",
icon: IconAlertTriangle, icon: IconAlertTriangle,
orderSeq: 3, orderSeq: 3,
@ -124,7 +124,7 @@ export const navData = {
subSubItems: [ subSubItems: [
{ {
title: "New Case", title: "New Case",
url: "/crime-management/crime-cases/case-new", url: "/dashboard/crime-management/crime-cases/case-new",
slug: "new-case", slug: "new-case",
icon: IconAlertTriangle, icon: IconAlertTriangle,
orderSeq: 1, orderSeq: 1,
@ -132,7 +132,7 @@ export const navData = {
}, },
{ {
title: "Active Cases", title: "Active Cases",
url: "/crime-management/crime-cases/case-active", url: "/dashboard/crime-management/crime-cases/case-active",
slug: "active-cases", slug: "active-cases",
icon: IconAlertTriangle, icon: IconAlertTriangle,
orderSeq: 2, orderSeq: 2,
@ -140,7 +140,7 @@ export const navData = {
}, },
{ {
title: "Resolved Cases", title: "Resolved Cases",
url: "/crime-management/crime-cases/case-closed", url: "/dashboard/crime-management/crime-cases/case-closed",
slug: "resolved-cases", slug: "resolved-cases",
icon: IconAlertTriangle, icon: IconAlertTriangle,
orderSeq: 3, orderSeq: 3,
@ -152,7 +152,7 @@ export const navData = {
}, },
{ {
title: "Geographic Data", title: "Geographic Data",
url: "/geographic-data", url: "/dashboard/geographic-data",
slug: "geographic-data", slug: "geographic-data",
orderSeq: 4, orderSeq: 4,
icon: IconWorld, icon: IconWorld,
@ -160,7 +160,7 @@ export const navData = {
subItems: [ subItems: [
{ {
title: "Locations", title: "Locations",
url: "/geographic-data/locations", url: "/dashboard/geographic-data/locations",
slug: "locations", slug: "locations",
icon: IconMapPin, icon: IconMapPin,
orderSeq: 1, orderSeq: 1,
@ -168,7 +168,7 @@ export const navData = {
subSubItems: [ subSubItems: [
{ {
title: "Cities", title: "Cities",
url: "/geographic-data/cities", url: "/dashboard/geographic-data/cities",
slug: "cities", slug: "cities",
icon: IconMap, icon: IconMap,
orderSeq: 1, orderSeq: 1,
@ -176,7 +176,7 @@ export const navData = {
}, },
{ {
title: "Districts", title: "Districts",
url: "/geographic-data/districts", url: "/dashboard/geographic-data/districts",
slug: "districts", slug: "districts",
icon: IconMap, icon: IconMap,
orderSeq: 2, orderSeq: 2,
@ -186,7 +186,7 @@ export const navData = {
}, },
{ {
title: "Geographic Info", title: "Geographic Info",
url: "/geographic-data/geographic-info", url: "/dashboard/geographic-data/geographic-info",
slug: "geographic-info", slug: "geographic-info",
icon: IconLayersDifference, icon: IconLayersDifference,
orderSeq: 3, orderSeq: 3,
@ -196,7 +196,7 @@ export const navData = {
}, },
{ {
title: "Demographics", title: "Demographics",
url: "/demographics", url: "/dashboard/demographics",
slug: "demographics", slug: "demographics",
orderSeq: 5, orderSeq: 5,
icon: IconFriends, icon: IconFriends,
@ -204,7 +204,7 @@ export const navData = {
subItems: [ subItems: [
{ {
title: "Demographics Data", title: "Demographics Data",
url: "/demographics/demographics-data", url: "/dashboard/demographics/demographics-data",
slug: "demographics-data", slug: "demographics-data",
icon: IconDna2, icon: IconDna2,
orderSeq: 1, orderSeq: 1,
@ -232,7 +232,7 @@ export const navData = {
// }, // },
{ {
title: "Settings", title: "Settings",
url: "/settings", url: "/dashboard/settings",
slug: "settings", slug: "settings",
orderSeq: 6, orderSeq: 6,
icon: IconSettings, icon: IconSettings,
@ -240,7 +240,7 @@ export const navData = {
subItems: [ subItems: [
{ {
title: "Navigation", title: "Navigation",
url: "/settings/navigation", url: "/dashboard/settings/navigation",
slug: "navigation", slug: "navigation",
icon: IconNavigation, icon: IconNavigation,
orderSeq: 1, orderSeq: 1,
@ -248,7 +248,7 @@ export const navData = {
subSubItems: [ subSubItems: [
{ {
title: "Nav Items", title: "Nav Items",
url: "/settings/navigation/nav-items", url: "/dashboard/settings/navigation/nav-items",
slug: "nav-items", slug: "nav-items",
icon: IconMenu2, icon: IconMenu2,
orderSeq: 1, orderSeq: 1,
@ -256,7 +256,7 @@ export const navData = {
subSubItems: [ subSubItems: [
{ {
title: "Nav Sub Items", title: "Nav Sub Items",
url: "/settings/navigation/nav-sub-items", url: "/dashboard/settings/navigation/nav-sub-items",
slug: "nav-sub-items", slug: "nav-sub-items",
icon: IconMenu2, icon: IconMenu2,
orderSeq: 1, orderSeq: 1,
@ -272,12 +272,12 @@ export const navData = {
reports: [ reports: [
{ {
name: "Crime Reports", name: "Crime Reports",
url: "#", url: "/dashboard/reports/crime-reports",
icon: IconFrame, icon: IconFrame,
}, },
{ {
name: "Demographics Reports", name: "Demographics Reports",
url: "#", url: "/dashboard/reports/demographics-reports",
icon: IconChartPie, icon: IconChartPie,
}, },
], ],