fix dupicate nav routes
This commit is contained in:
parent
bc03c18a05
commit
45daf059d3
|
@ -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>
|
||||||
|
|
|
@ -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,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in New Issue