11import { ChevronLeft , Menu } from "@mui/icons-material" ;
22import {
3+ Backdrop ,
34 Box ,
5+ Chip ,
46 CssBaseline ,
57 Divider ,
68 IconButton ,
@@ -21,16 +23,23 @@ import { Outlet, useNavigate } from "react-router-dom";
2123
2224import { MiniVariantAppBar , MiniVariantDrawer } from "./sidebar" ;
2325
24- export type RouteDef = {
25- icon : typeof SvgIcon ;
26- title : string ;
27- app : string ;
28- resource : string ;
29- route ?: string ; // If specified, this will be used as the route instead of the default one
30- isAdminPage ?: boolean ;
31- hideOnSidebar ?: boolean ;
32- placeOnBottom ?: boolean ;
33- } ;
26+ export type RouteDef =
27+ | {
28+ type : "routeDefinition" ;
29+ key : string ; // Unique key for the route
30+ icon : typeof SvgIcon ;
31+ title : string ;
32+ app : string ;
33+ resource : string ;
34+ route ?: string ; // If specified, this will be used as the route instead of the default one
35+ hideOnSidebar ?: boolean ;
36+ placeOnBottom ?: boolean ;
37+ }
38+ | {
39+ type : "separator" ;
40+ key : string ; // Unique key for the route
41+ title : string ;
42+ } ;
3443
3544type LayoutState = {
3645 showDrawer : boolean ;
@@ -64,35 +73,61 @@ export const Layout: React.FC<{ routes: RouteDef[] }> = ({ routes }) => {
6473 const toggleDrawer = ( ) =>
6574 dispatch ( ( ps ) => ( { ...ps , showDrawer : ! ps . showDrawer } ) ) ;
6675
67- const SidebarItem : React . FC < { routeInfo : RouteDef } > = ( { routeInfo } ) => (
68- < ListItem
69- key = { `${ routeInfo . app } -${ routeInfo . resource } ` }
70- sx = { routeInfo . placeOnBottom ? { marginTop : "auto" } : { } }
71- disablePadding
72- >
73- < ListItemButton
74- sx = { {
75- minHeight : 48 ,
76- px : 2.5 ,
77- justifyContent : state . showDrawer ? "initial" : "center" ,
78- } }
79- onClick = { ( ) =>
80- navigate ( routeInfo . route || `/${ routeInfo . app } /${ routeInfo . resource } ` )
81- }
76+ const SidebarItem : React . FC < { routeInfo : RouteDef } > = ( { routeInfo } ) =>
77+ routeInfo . type === "separator" ? (
78+ < ListItem key = { routeInfo . title } disablePadding sx = { { minHeight : 48 } } >
79+ { state . showDrawer ? (
80+ < ListItemButton disabled >
81+ < ListItemText primary = { routeInfo . title } />
82+ </ ListItemButton >
83+ ) : (
84+ < Stack
85+ alignItems = "center"
86+ sx = { ( t ) => ( {
87+ width : t . spacing ( 7 ) ,
88+ [ t . breakpoints . up ( "sm" ) ] : { width : t . spacing ( 8 ) } ,
89+ } ) }
90+ >
91+ < Chip
92+ label = { routeInfo . title }
93+ variant = "outlined"
94+ size = "small"
95+ sx = { { flexGrow : 0 } }
96+ />
97+ </ Stack >
98+ ) }
99+ </ ListItem >
100+ ) : (
101+ < ListItem
102+ key = { `${ routeInfo . app } -${ routeInfo . resource } ` }
103+ sx = { routeInfo . placeOnBottom ? { marginTop : "auto" } : { } }
104+ disablePadding
82105 >
83- < ListItemIcon
106+ < ListItemButton
84107 sx = { {
85- minWidth : 0 ,
86- justifyContent : "center" ,
87- mr : state . showDrawer ? 3 : "auto " ,
108+ minHeight : 48 ,
109+ px : 2.5 ,
110+ justifyContent : state . showDrawer ? "initial" : "center " ,
88111 } }
112+ onClick = { ( ) =>
113+ navigate (
114+ routeInfo . route || `/${ routeInfo . app } /${ routeInfo . resource } `
115+ )
116+ }
89117 >
90- < routeInfo . icon />
91- </ ListItemIcon >
92- { state . showDrawer && < ListItemText primary = { routeInfo . title } /> }
93- </ ListItemButton >
94- </ ListItem >
95- ) ;
118+ < ListItemIcon
119+ sx = { {
120+ minWidth : 0 ,
121+ justifyContent : "center" ,
122+ mr : state . showDrawer ? 3 : "auto" ,
123+ } }
124+ >
125+ < routeInfo . icon />
126+ </ ListItemIcon >
127+ { state . showDrawer && < ListItemText primary = { routeInfo . title } /> }
128+ </ ListItemButton >
129+ </ ListItem >
130+ ) ;
96131
97132 const menuButtonStyle : ( t : Theme ) => React . CSSProperties = ( t ) => ( {
98133 width : `calc(${ t . spacing ( 7 ) } + 1px)` ,
@@ -151,9 +186,9 @@ export const Layout: React.FC<{ routes: RouteDef[] }> = ({ routes }) => {
151186 < Divider />
152187 < Stack sx = { { height : "100%" } } >
153188 { routes
154- . filter ( ( r ) => ! r . hideOnSidebar )
189+ . filter ( ( r ) => r . type === "separator" || ! r . hideOnSidebar )
155190 . map ( ( r ) => (
156- < SidebarItem key = { ` ${ r . app } - ${ r . resource } ` } routeInfo = { r } />
191+ < SidebarItem key = { r . key } routeInfo = { r } />
157192 ) ) }
158193 </ Stack >
159194 </ MiniVariantDrawer >
@@ -163,6 +198,7 @@ export const Layout: React.FC<{ routes: RouteDef[] }> = ({ routes }) => {
163198 < Outlet />
164199 </ PageInnerContainer >
165200 </ PageOuterContainer >
201+ < Backdrop open = { state . showDrawer } onClick = { toggleDrawer } />
166202 </ Box >
167203 </ Box >
168204 ) ;
0 commit comments