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,
} 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";
@ -40,14 +40,38 @@ interface NavItem {
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 }) {
const router = useNavigations();
const isActive = router.pathname === item.url;
const formattedUrl = formatUrl(item.url);
const isActive = router.pathname === formattedUrl;
return (
<SidebarMenuItem className={isActive ? "active text-primary" : ""}>
<SidebarMenuButton asChild>
<a href={item.url}>
<SidebarMenuItem>
<SidebarMenuButton
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>
</a>
</SidebarMenuButton>
@ -57,15 +81,25 @@ function SubSubItemComponent({ item }: { item: SubSubItem }) {
function SubItemComponent({ item }: { item: SubItem }) {
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;
if (!hasSubSubItems) {
return (
<SidebarMenuItem className={isActive ? "active text-primary" : ""}>
<SidebarMenuButton asChild>
<a href={item.url}>
{item.icon && <item.icon />}
<SidebarMenuItem>
<SidebarMenuButton
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>
</a>
</SidebarMenuButton>
@ -75,12 +109,22 @@ function SubItemComponent({ item }: { item: SubItem }) {
return (
<Collapsible asChild className="group/collapsible">
<SidebarMenuItem className={isActive ? "active text-primary" : ""}>
<SidebarMenuItem>
<CollapsibleTrigger asChild>
<SidebarMenuButton>
{item.icon && <item.icon />}
<span>{item.title}</span>
<ChevronRight className="ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" />
<SidebarMenuButton
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>
<ChevronRight
className={`ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90 ${isActive ? "text-primary" : ""}`}
/>
</SidebarMenuButton>
</CollapsibleTrigger>
<CollapsibleContent>
@ -97,15 +141,26 @@ function SubItemComponent({ item }: { item: SubItem }) {
function RecursiveNavItem({ item, index }: { item: NavItem; index: number }) {
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;
if (!hasSubItems) {
return (
<SidebarMenuItem className={isActive ? "active text-primary" : ""}>
<SidebarMenuButton tooltip={item.title} asChild>
<a href={item.url}>
{item.icon && <item.icon />}
<SidebarMenuItem>
<SidebarMenuButton
tooltip={item.title}
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>
</a>
</SidebarMenuButton>
@ -120,13 +175,24 @@ function RecursiveNavItem({ item, index }: { item: NavItem; index: number }) {
defaultOpen={index === 1}
className="group/collapsible"
>
<SidebarMenuItem className={isActive ? "active text-primary" : ""}>
<SidebarMenuItem>
<CollapsibleTrigger asChild>
<SidebarMenuButton tooltip={item.title}>
{item.icon && <item.icon />}
<span>{item.title}</span>
<SidebarMenuButton
tooltip={item.title}
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 && (
<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>
</CollapsibleTrigger>

View File

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