1- import type { FC , ReactNode } from 'react' ;
1+ import type { FC } from 'react' ;
22import { Header } from './Header' ;
33import { Footer } from './Footer' ;
4- import { Link } from 'react-router-dom' ;
4+ import { NavLink , Outlet , useLocation , useNavigate } from 'react-router-dom' ;
55import {
66 Sidebar ,
77 SidebarContent ,
@@ -11,56 +11,134 @@ import {
1111 SidebarMenuSub ,
1212 SidebarMenuSubItem ,
1313 SidebarMenuSubButton ,
14- SidebarProvider ,
14+ SidebarGroup ,
1515} from '@oasisprotocol/ui-library/src/components/ui/sidebar' ;
16- import { AppWindow , Compass } from 'lucide-react' ;
16+ import { Compass , LayoutDashboard } from 'lucide-react' ;
17+ import { Button } from '@oasisprotocol/ui-library/src/components/ui/button' ;
18+ import { Layout } from '@oasisprotocol/ui-library/src/components/ui/layout' ;
19+ import {
20+ Breadcrumb ,
21+ BreadcrumbList ,
22+ BreadcrumbItem ,
23+ BreadcrumbLink ,
24+ BreadcrumbSeparator ,
25+ } from '@oasisprotocol/ui-library/src/components/ui/breadcrumb' ;
26+
27+ const locationListMap : Record < string , string [ ] > = {
28+ '/explore' : [ 'Explore' ] ,
29+ '/dashboard/machines' : [ 'Dashboard' , 'Machines' ] ,
30+ '/dashboard/apps' : [ 'Dashboard' , 'My Apps' ] ,
31+ '/' : [ 'Dashboard' ] ,
32+ } ;
1733
18- interface MainLayoutProps {
19- children : ReactNode ;
20- }
34+ export const MainLayout : FC = ( ) => {
35+ const navigate = useNavigate ( ) ;
36+ const location = useLocation ( ) ;
37+ const locationList = Object . entries ( locationListMap ) . find ( ( [ path ] ) =>
38+ location . pathname . toLowerCase ( ) . startsWith ( path )
39+ ) ?. [ 1 ] ;
2140
22- export const MainLayout : FC < MainLayoutProps > = ( { children } ) => {
41+ const getBreadcrumbPath = ( index : number ) => {
42+ if ( ! locationList ) return '/' ;
43+ if ( index === 0 && locationList [ 0 ] === 'Dashboard' ) {
44+ return '/dashboard' ;
45+ }
46+ return location . pathname ;
47+ } ;
2348 return (
24- < div className = "flex flex-col min-h-screen" >
25- < Header />
26- < SidebarProvider className = "min-h-fit flex-1" >
49+ < Layout
50+ headerContent = { < Header /> }
51+ headerBreadcrumbsContent = {
52+ ! ! locationList ?. length && (
53+ < Breadcrumb className = "flex px-2" >
54+ < BreadcrumbList >
55+ { locationList . flatMap ( ( loc , i ) => {
56+ const elements = [
57+ < BreadcrumbItem key = { loc + i } >
58+ < BreadcrumbLink asChild >
59+ < NavLink
60+ to = { getBreadcrumbPath ( i ) }
61+ className = "text-foreground text-sm font-normal"
62+ >
63+ { loc }
64+ </ NavLink >
65+ </ BreadcrumbLink >
66+ </ BreadcrumbItem > ,
67+ ] ;
68+
69+ if ( i + 1 < locationList . length ) {
70+ elements . push (
71+ < BreadcrumbSeparator key = { `sep-${ loc } -${ i } ` } />
72+ ) ;
73+ }
74+
75+ return elements ;
76+ } ) }
77+ </ BreadcrumbList >
78+ </ Breadcrumb >
79+ )
80+ }
81+ footerContent = { < Footer /> }
82+ sidebar = {
2783 < Sidebar collapsible = "icon" className = "border-r !static !h-full" >
28- < SidebarContent >
29- < SidebarMenu >
30- < SidebarMenuItem >
31- < SidebarMenuButton asChild tooltip = "Dashboard" >
32- < Link to = "/dashboard" >
33- < AppWindow />
34- < span > Dashboard</ span >
35- </ Link >
36- </ SidebarMenuButton >
84+ < SidebarContent className = "bg-sidebar-background" >
85+ < SidebarGroup >
86+ < SidebarMenu >
87+ < SidebarMenuItem >
88+ < SidebarMenuButton asChild >
89+ < Button
90+ onClick = { ( ) => navigate ( '/dashboard' ) }
91+ variant = "ghost"
92+ className = "w-full justify-start p-2 h-8 rounded-md cursor-pointer"
93+ >
94+ < LayoutDashboard className = "h-4 w-4 text-sidebar-foreground" />
95+ Dashboard
96+ </ Button >
97+ </ SidebarMenuButton >
98+ </ SidebarMenuItem >
3799 < SidebarMenuSub >
38100 < SidebarMenuSubItem >
39101 < SidebarMenuSubButton asChild >
40- < Link to = "/dashboard/apps" > My Apps</ Link >
102+ < Button
103+ onClick = { ( ) => navigate ( '/dashboard/apps' ) }
104+ variant = "ghost"
105+ className = "w-full justify-start p-2 h-8 rounded-md cursor-pointer"
106+ >
107+ My Apps
108+ </ Button >
41109 </ SidebarMenuSubButton >
42110 </ SidebarMenuSubItem >
43111 < SidebarMenuSubItem >
44112 < SidebarMenuSubButton asChild >
45- < Link to = "/dashboard/machines" > Machines</ Link >
113+ < Button
114+ onClick = { ( ) => navigate ( '/dashboard/machines' ) }
115+ variant = "ghost"
116+ className = "w-full justify-start p-2 h-8 rounded-md cursor-pointer"
117+ >
118+ Machines
119+ </ Button >
46120 </ SidebarMenuSubButton >
47121 </ SidebarMenuSubItem >
48122 </ SidebarMenuSub >
49- </ SidebarMenuItem >
50- < SidebarMenuItem >
51- < SidebarMenuButton asChild tooltip = "Explore" >
52- < Link to = "/explore" >
53- < Compass />
54- < span > Explore</ span >
55- </ Link >
123+ < SidebarMenuButton asChild >
124+ < Button
125+ onClick = { ( ) => navigate ( '/explore' ) }
126+ variant = "ghost"
127+ className = "w-full justify-start p-2 h-8 rounded-md cursor-pointer"
128+ >
129+ < Compass className = "h-4 w-4 text-sidebar-foreground" />
130+ Explore
131+ </ Button >
56132 </ SidebarMenuButton >
57- </ SidebarMenuItem >
58- </ SidebarMenu >
133+ </ SidebarMenu >
134+ </ SidebarGroup >
59135 </ SidebarContent >
60136 </ Sidebar >
61- < main className = "flex-1 p-5" > { children } </ main >
62- </ SidebarProvider >
63- < Footer />
64- </ div >
137+ }
138+ >
139+ < div className = "flex-1 p-5 h-5/6" >
140+ < Outlet />
141+ </ div >
142+ </ Layout >
65143 ) ;
66144} ;
0 commit comments