Skip to content

Commit a7e16fa

Browse files
committed
Refactor navigation links: Introduce getNavItemLink utility function for consistent link handling across components. Update AppHeader, Breadcrumbs, NavFooter, NavMain, and Layout components to utilize the new function. Add LinkableItemType interface to improve type safety for navigation items.
1 parent 7ca7060 commit a7e16fa

File tree

8 files changed

+35
-14
lines changed

8 files changed

+35
-14
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ yarn-error.log
2222
/.nova
2323
/.vscode
2424
/.zed
25+
.qodo

resources/js/components/AppHeader.vue

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import type { BreadcrumbItem, NavItem } from '@/types';
2020
import { Link, usePage } from '@inertiajs/vue3';
2121
import { BookOpen, Folder, LayoutGrid, Menu, Search } from 'lucide-vue-next';
2222
import { computed } from 'vue';
23+
import { getNavItemLink } from '@/lib/utils';
2324
2425
interface Props {
2526
breadcrumbs?: BreadcrumbItem[];
@@ -82,9 +83,9 @@ const rightNavItems: NavItem[] = [
8283
<Link
8384
v-for="item in mainNavItems"
8485
:key="item.title"
85-
:href="item.href"
86+
:href="getNavItemLink(item)"
8687
class="flex items-center gap-x-3 rounded-lg px-3 py-2 text-sm font-medium hover:bg-accent"
87-
:class="activeItemStyles(item.href)"
88+
:class="activeItemStyles(getNavItemLink(item))"
8889
>
8990
<component v-if="item.icon" :is="item.icon" class="h-5 w-5" />
9091
{{ item.title }}
@@ -94,7 +95,7 @@ const rightNavItems: NavItem[] = [
9495
<a
9596
v-for="item in rightNavItems"
9697
:key="item.title"
97-
:href="item.href"
98+
:href="getNavItemLink(item)"
9899
target="_blank"
99100
rel="noopener noreferrer"
100101
class="flex items-center space-x-2 text-sm font-medium"
@@ -117,16 +118,16 @@ const rightNavItems: NavItem[] = [
117118
<NavigationMenu class="ml-10 flex h-full items-stretch">
118119
<NavigationMenuList class="flex h-full items-stretch space-x-2">
119120
<NavigationMenuItem v-for="(item, index) in mainNavItems" :key="index" class="relative flex h-full items-center">
120-
<Link :href="item.href">
121+
<Link :href="getNavItemLink(item)">
121122
<NavigationMenuLink
122-
:class="[navigationMenuTriggerStyle(), activeItemStyles(item.href), 'h-9 cursor-pointer px-3']"
123+
:class="[navigationMenuTriggerStyle(), activeItemStyles(getNavItemLink(item)), 'h-9 cursor-pointer px-3']"
123124
>
124125
<component v-if="item.icon" :is="item.icon" class="mr-2 h-4 w-4" />
125126
{{ item.title }}
126127
</NavigationMenuLink>
127128
</Link>
128129
<div
129-
v-if="isCurrentRoute(item.href)"
130+
v-if="isCurrentRoute(getNavItemLink(item))"
130131
class="absolute bottom-0 left-0 h-0.5 w-full translate-y-px bg-black dark:bg-white"
131132
></div>
132133
</NavigationMenuItem>
@@ -146,7 +147,7 @@ const rightNavItems: NavItem[] = [
146147
<Tooltip>
147148
<TooltipTrigger>
148149
<Button variant="ghost" size="icon" as-child class="group h-9 w-9 cursor-pointer">
149-
<a :href="item.href" target="_blank" rel="noopener noreferrer">
150+
<a :href="getNavItemLink(item)" target="_blank" rel="noopener noreferrer">
150151
<span class="sr-only">{{ item.title }}</span>
151152
<component :is="item.icon" class="size-5 opacity-80 group-hover:opacity-100" />
152153
</a>

resources/js/components/Breadcrumbs.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<script setup lang="ts">
22
import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from '@/components/ui/breadcrumb';
33
import { Link } from '@inertiajs/vue3';
4+
import { getNavItemLink } from '@/lib/utils';
45
56
interface BreadcrumbItem {
67
title: string;
@@ -22,7 +23,7 @@ defineProps<{
2223
</template>
2324
<template v-else>
2425
<BreadcrumbLink as-child>
25-
<Link :href="item.href ?? '#'">{{ item.title }}</Link>
26+
<Link :href="getNavItemLink(item) ?? '#'">{{ item.title }}</Link>
2627
</BreadcrumbLink>
2728
</template>
2829
</BreadcrumbItem>

resources/js/components/NavFooter.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<script setup lang="ts">
22
import { SidebarGroup, SidebarGroupContent, SidebarMenu, SidebarMenuButton, SidebarMenuItem } from '@/components/ui/sidebar';
33
import { type NavItem } from '@/types';
4+
import { getNavItemLink } from '@/lib/utils';
45
56
interface Props {
67
items: NavItem[];
@@ -16,7 +17,7 @@ defineProps<Props>();
1617
<SidebarMenu>
1718
<SidebarMenuItem v-for="item in items" :key="item.title">
1819
<SidebarMenuButton class="text-neutral-600 hover:text-neutral-800 dark:text-neutral-300 dark:hover:text-neutral-100" as-child>
19-
<a :href="item.href" target="_blank" rel="noopener noreferrer">
20+
<a :href="getNavItemLink(item)" target="_blank" rel="noopener noreferrer">
2021
<component :is="item.icon" />
2122
<span>{{ item.title }}</span>
2223
</a>

resources/js/components/NavMain.vue

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarMenuButton, SidebarMenuItem } from '@/components/ui/sidebar';
33
import { type NavItem, type SharedData } from '@/types';
44
import { Link, usePage } from '@inertiajs/vue3';
5+
import { getNavItemLink } from '@/lib/utils';
56
67
defineProps<{
78
items: NavItem[];
@@ -15,11 +16,11 @@ const page = usePage<SharedData>();
1516
<SidebarGroupLabel>Platform</SidebarGroupLabel>
1617
<SidebarMenu>
1718
<SidebarMenuItem v-for="item in items" :key="item.title">
18-
<SidebarMenuButton
19-
as-child :is-active="item.href === page.url"
19+
<SidebarMenuButton
20+
as-child :is-active="getNavItemLink(item) === page.url"
2021
:tooltip="item.title"
2122
>
22-
<Link :href="item.href">
23+
<Link :href="getNavItemLink(item)">
2324
<component :is="item.icon" />
2425
<span>{{ item.title }}</span>
2526
</Link>

resources/js/layouts/settings/Layout.vue

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Button } from '@/components/ui/button';
44
import { Separator } from '@/components/ui/separator';
55
import { type NavItem } from '@/types';
66
import { Link, usePage } from '@inertiajs/vue3';
7+
import { getNavItemLink } from '@/lib/utils';
78
89
const sidebarNavItems: NavItem[] = [
910
{
@@ -36,10 +37,10 @@ const currentPath = page.props.ziggy?.location ? new URL(page.props.ziggy.locati
3637
v-for="item in sidebarNavItems"
3738
:key="item.href"
3839
variant="ghost"
39-
:class="['w-full justify-start', { 'bg-muted': currentPath === item.href }]"
40+
:class="['w-full justify-start', { 'bg-muted': currentPath === getNavItemLink(item) }]"
4041
as-child
4142
>
42-
<Link :href="item.href">
43+
<Link :href="getNavItemLink(item)">
4344
{{ item.title }}
4445
</Link>
4546
</Button>

resources/js/lib/utils.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1+
import { LinkableItemType } from '@/types';
12
import { clsx, type ClassValue } from 'clsx';
23
import { twMerge } from 'tailwind-merge';
34

45
export function cn(...inputs: ClassValue[]) {
56
return twMerge(clsx(inputs));
67
}
8+
9+
export function getNavItemLink(item:LinkableItemType,defaultValue:string = '#') : string{
10+
if(!item.href ) return defaultValue;
11+
return item.type === 'route' ? route(item.href):item.href;
12+
}

resources/js/types/index.d.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,23 @@ export interface Auth {
66
user: User;
77
}
88

9+
export interface ILinkableItem{
10+
href?: string;
11+
type?:'href' | 'route';
12+
}
13+
14+
export type LinkableItemType = ILinkableItem
15+
916
export interface BreadcrumbItem {
1017
title: string;
1118
href: string;
19+
type?:'href' | 'route';
1220
}
1321

1422
export interface NavItem {
1523
title: string;
1624
href: string;
25+
type?:'href' | 'route';
1726
icon?: LucideIcon;
1827
isActive?: boolean;
1928
}

0 commit comments

Comments
 (0)