11<script setup lang="ts">
2- import { Breadcrumb , BreadcrumbItem , BreadcrumbLink , BreadcrumbList , BreadcrumbPage , BreadcrumbSeparator } from ' @/components/ui/breadcrumb' ;
3- import { SidebarTrigger } from ' @/components/ui/sidebar' ;
4- import { type BreadcrumbItem as BreadcrumbItemType } from ' @/types' ;
2+ import { Link , usePage } from ' @inertiajs/vue3'
3+ import type { BreadcrumbItem } from ' @/types'
4+ import AppLogo from ' @/components/AppLogo.vue'
5+ import AppLogoIcon from ' @/components/AppLogoIcon.vue'
6+ import { Button } from " @/components/ui/button"
7+ import {
8+ NavigationMenu ,
9+ NavigationMenuItem ,
10+ NavigationMenuLink ,
11+ NavigationMenuList ,
12+ navigationMenuTriggerStyle ,
13+ } from ' @/components/ui/navigation-menu'
14+ import {
15+ DropdownMenu ,
16+ DropdownMenuContent ,
17+ DropdownMenuTrigger ,
18+ } from ' @/components/ui/dropdown-menu'
19+ import {
20+ Tooltip ,
21+ TooltipContent ,
22+ TooltipProvider ,
23+ TooltipTrigger ,
24+ } from ' @/components/ui/tooltip'
25+ import type { NavItem } from ' @/types'
26+ import {
27+ Sheet ,
28+ SheetContent ,
29+ SheetHeader ,
30+ SheetTrigger ,
31+ } from ' @/components/ui/sheet'
32+ import type { SharedData } from ' @/types'
33+ import { Avatar , AvatarFallback , AvatarImage } from ' @/components/ui/avatar'
34+ import { Menu , ChevronDown , FolderGit2 , BookOpenText , Search , LayoutGrid } from ' lucide-vue-next'
35+ import { useInitials } from ' @/composables/useInitials.ts'
36+ import { cn } from ' @/lib/utils'
37+ import UserMenuContent from ' @/components/UserMenuContent.vue'
38+ import Icon from ' @/components/Icon.vue'
539
640interface Props {
7- breadcrumbs? : BreadcrumbItemType [];
41+ breadcrumbs? : BreadcrumbItem []
842}
943
1044const props = withDefaults (defineProps <Props >(), {
11- breadcrumbs : () => [],
12- });
45+ breadcrumbs : () => []
46+ })
47+
48+ const mainNavItems: NavItem [] = [
49+ {
50+ title: ' Dashboard' ,
51+ url: ' /dashboard' ,
52+ icon: LayoutGrid ,
53+ },
54+ ]
55+
56+ const rightNavItems: NavItem [] = [
57+ {
58+ title: ' Repository' ,
59+ url: ' https://github.com/laravel/vue-starter-kit' ,
60+ icon: FolderGit2 ,
61+ },
62+ {
63+ title: ' Documentation' ,
64+ url: ' https://laravel.com/docs/starter-kits' ,
65+ icon: BookOpenText ,
66+ },
67+ ]
68+
69+ const activeItemStyles = " bg-neutral-100 text-neutral-900 dark:bg-neutral-800 dark:text-neutral-100"
70+
71+ const { auth } = usePage <SharedData >().props
72+ const getInitials = useInitials ()
1373 </script >
1474
1575<template >
16- <header
17- class =" flex h-16 shrink-0 items-center gap-2 px-4 transition-[width,height] ease-linear group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12"
18- >
19- <div class =" flex items-center gap-2" >
20- <SidebarTrigger class =" -ml-1" />
21- <template v-if =" breadcrumbs .length > 0 " >
22- <Breadcrumb >
23- <BreadcrumbList >
24- <template v-for =" (item , index ) in breadcrumbs " :key =" index " >
25- <BreadcrumbItem >
26- <template v-if =" index === breadcrumbs .length - 1 " >
27- <BreadcrumbPage >{{ item.title }}</BreadcrumbPage >
28- </template >
29- <template v-else >
30- <BreadcrumbLink :href =" item.href" >
76+ <div >
77+ <div class =" border-b border-sidebar-border/80" >
78+ <div class =" flex h-16 items-center px-4 md:max-w-7xl mx-auto" >
79+ <!-- Mobile Menu -->
80+ <div class =" lg:hidden" >
81+ <Sheet >
82+ <SheetTrigger :as-child =" true" >
83+ <Button variant =" ghost" size =" icon" class =" mr-2 w-[34px] h-[34px]" >
84+ <Menu class =" h-5 w-5" />
85+ </Button >
86+ </SheetTrigger >
87+ <SheetContent side =" left" class =" bg-neutral-50 h-full flex flex-col items-stretch w-64" >
88+ <SheetHeader class =" text-left flex justify-start" >
89+ <AppLogoIcon class =" h-6 w-6 fill-current text-black dark:text-white" />
90+ </SheetHeader >
91+ <div class =" flex flex-col h-full space-y-4 mt-6 flex-1" >
92+ <div class =" flex flex-col text-sm h-full justify-between" >
93+ <div class =" flex flex-col space-y-4" >
94+ <Link v-for =" item in mainNavItems"
95+ :key =" item.title"
96+ :href =" item.url"
97+ class =" flex items-center space-x-2 font-medium" >
98+ <Icon v-if =" item.icon" :icon-node =" item.icon" class =" h-5 w-5" />
99+ <span >{{ item.title }}</span >
100+ </Link >
101+ </div >
102+
103+ <div class =" flex flex-col space-y-4" >
104+ <a v-for =" item in rightNavItems"
105+ :key =" item.title"
106+ :href =" item.url"
107+ target =" _blank"
108+ rel =" noopener noreferrer"
109+ class =" flex items-center space-x-2 font-medium" >
110+ <Icon v-if =" item.icon" :icon-node =" item.icon" class =" h-5 w-5" />
111+ <span >{{ item.title }}</span >
112+ </a >
113+ </div >
114+ </div >
115+ </div >
116+ </SheetContent >
117+ </Sheet >
118+ </div >
119+
120+ <Link href =" /dashboard" class =" flex items-center space-x-2" >
121+ <AppLogo />
122+ </Link >
123+
124+ <!-- Desktop Navigation -->
125+ <div class =" hidden lg:flex items-center space-x-6 h-full ml-6" >
126+ <NavigationMenu class =" h-full flex items-stretch" >
127+ <NavigationMenuList class =" h-full space-x-2 flex items-stretch" >
128+ <NavigationMenuItem v-for =" (item, index) in mainNavItems"
129+ :key =" index"
130+ class =" h-full flex items-center relative" >
131+ <Link :href =" item.url" >
132+ <NavigationMenuLink :class =" [
133+ navigationMenuTriggerStyle(),
134+ activeItemStyles,
135+ 'px-3 h-9 cursor-pointer'
136+ ]" >
137+ <Icon v-if =" item.icon" :icon-node =" item.icon" class =" mr-2 h-4 w-4" />
31138 {{ item.title }}
32- </BreadcrumbLink >
33- </template >
34- </BreadcrumbItem >
35- <BreadcrumbSeparator v-if =" index !== breadcrumbs.length - 1" />
36- </template >
37- </BreadcrumbList >
38- </Breadcrumb >
39- </template >
139+ </NavigationMenuLink >
140+ </Link >
141+ <div class =" h-0.5 translate-y-px bg-black dark:bg-white w-full absolute bottom-0 left-0" ></div >
142+ </NavigationMenuItem >
143+ </NavigationMenuList >
144+ </NavigationMenu >
145+ </div >
146+
147+ <div class =" ml-auto flex items-center space-x-2" >
148+ <div class =" relative flex items-center space-x-1" >
149+ <Button variant =" ghost" size =" icon" class =" w-9 h-9 cursor-pointer" >
150+ <Search class =" h-5 w-5" />
151+ </Button >
152+ <div class =" hidden lg:flex space-x-1" >
153+ <TooltipProvider v-for =" item in rightNavItems"
154+ :key =" item.title"
155+ :delay-duration =" 0" >
156+ <Tooltip >
157+ <TooltipTrigger >
158+ <Button variant =" ghost" size =" icon" :as-child =" true" class =" w-9 h-9 cursor-pointer" >
159+ <a :href =" item.url" target =" _blank" rel =" noopener noreferrer" >
160+ <span class =" sr-only" >{{ item.title }}</span >
161+ <Icon v-if =" item.icon" :icon-node =" item.icon" class =" h-5 w-5" />
162+ </a >
163+ </Button >
164+ </TooltipTrigger >
165+ <TooltipContent >
166+ <p >{{ item.title }}</p >
167+ </TooltipContent >
168+ </Tooltip >
169+ </TooltipProvider >
170+ </div >
171+ </div >
172+ <DropdownMenu >
173+ <DropdownMenuTrigger :as-child =" true" >
174+ <Button variant =" ghost" class =" h-9 px-1.5" >
175+ <Avatar class =" h-7 w-7 overflow-hidden rounded-lg" >
176+ <AvatarImage :src =" auth.user.avatar" :alt =" auth.user.name" />
177+ <AvatarFallback class =" rounded-lg text-black dark:text-white" >
178+ {{ getInitials(auth.user.name) }}
179+ </AvatarFallback >
180+ </Avatar >
181+ <ChevronDown class =" h-4 w-4 hidden lg:block" />
182+ </Button >
183+ </DropdownMenuTrigger >
184+ <DropdownMenuContent class =" w-56" align =" end" >
185+ <UserMenuContent :user =" auth.user" />
186+ </DropdownMenuContent >
187+ </DropdownMenu >
188+ </div >
189+ </div >
190+ </div >
191+ <div v-if =" props.breadcrumbs.length > 1" class =" w-full flex border-b border-sidebar-border/70" >
192+ <div class =" flex h-12 items-center justify-start w-full px-4 md:max-w-7xl mx-auto text-neutral-500" >
193+ <Breadcrumbs :breadcrumbs =" props.breadcrumbs" />
194+ </div >
40195 </div >
41- </header >
42- </template >
196+ </div >
197+ </template >
0 commit comments