@@ -2,13 +2,15 @@ import { Route, Switch } from "react-router-dom";
2
2
import { default as AntdLayout } from "antd/es/layout" ;
3
3
import { AppHeader } from "pages/common/header" ;
4
4
import * as React from "react" ;
5
- import { ReactElement } from "react" ;
5
+ import { ReactElement , useState , useEffect } from "react" ;
6
6
import { HelpDropdown } from "pages/common/help" ;
7
7
import MainContent from "components/layout/MainContent" ;
8
8
import SideBar from "components/layout/SideBar" ;
9
9
import { CNMainContent , CNSidebar } from "constants/styleSelectors" ;
10
10
import { SideBarSection , SideBarSectionProps } from "./SideBarSection" ;
11
11
import styled from "styled-components" ;
12
+ import { MenuOutlined } from "@ant-design/icons" ;
13
+ import { Drawer , Button } from "antd" ;
12
14
13
15
type LayoutProps = {
14
16
sections : SideBarSectionProps [ ] ;
@@ -29,9 +31,53 @@ const SideBarV2 = styled(SideBar)`
29
31
}
30
32
` ;
31
33
34
+ const MobileMenuButton = styled ( Button ) `
35
+ display: none;
36
+ position: fixed;
37
+ top: 75px;
38
+ right: 22px;
39
+ z-index: 1000;
40
+
41
+ @media screen and (max-width: 720px) {
42
+ display: block;
43
+ }
44
+ ` ;
45
+
46
+ const DrawerContentWrapper = styled . div `
47
+ height: 100%;
48
+ display: flex;
49
+ flex-direction: column;
50
+ ` ;
51
+
32
52
export function Layout ( props : LayoutProps ) {
53
+
54
+ const [ drawerVisible , setDrawerVisible ] = useState ( false ) ;
55
+ const [ isMobile , setIsMobile ] = useState ( false ) ;
56
+
57
+ const toggleDrawer = ( ) => {
58
+ setDrawerVisible ( ! drawerVisible ) ;
59
+ } ;
60
+
61
+ const handleMenuClick = ( ) => {
62
+ setDrawerVisible ( false ) ; // Close the drawer
63
+ } ;
64
+
65
+ useEffect ( ( ) => {
66
+ const handleResize = ( ) => setIsMobile ( window . innerWidth <= 720 ) ;
67
+ handleResize ( ) ; // Check on initial render
68
+ window . addEventListener ( "resize" , handleResize ) ;
69
+ return ( ) => window . removeEventListener ( "resize" , handleResize ) ;
70
+ } , [ ] ) ;
71
+
72
+ const mobileSections = props . sections . map ( ( section ) => ( {
73
+ ...section ,
74
+ items : section . items . filter ( ( item ) => item . mobileVisible !== false ) , // Filter mobile-visible items
75
+ } ) ) ;
76
+
77
+ const desktopSections = props . sections ;
78
+
33
79
const routes : ReactElement [ ] = [ ] ;
34
- props . sections . forEach ( ( section ) => {
80
+ desktopSections . forEach ( ( section ) => {
35
81
section . items . forEach ( ( item ) => {
36
82
routes . push (
37
83
< Route
@@ -48,18 +94,57 @@ export function Layout(props: LayoutProps) {
48
94
< AntdLayout style = { { height : "100%" } } >
49
95
< AppHeader />
50
96
< HelpDropdown />
97
+
98
+ { /* Mobile Hamburger Button */ }
99
+ { isMobile && (
100
+ < MobileMenuButton
101
+ type = "primary"
102
+ shape = "circle"
103
+ icon = { < MenuOutlined /> }
104
+ onClick = { toggleDrawer }
105
+ />
106
+ ) }
107
+
108
+ { /* Drawer for Mobile Sidebar */ }
109
+ < Drawer
110
+ width = { "240px" }
111
+ placement = "right"
112
+ closable = { true }
113
+ onClose = { toggleDrawer }
114
+ visible = { drawerVisible }
115
+ bodyStyle = { { padding : "0px" } }
116
+ destroyOnClose // Ensure drawer content is removed when closed
117
+ >
118
+ < DrawerContentWrapper >
119
+ < SideBarV2 className = { CNSidebar } >
120
+ { mobileSections
121
+ . filter ( ( section ) => section . items . length > 0 )
122
+ . map ( ( section , index ) => (
123
+ < SideBarSection
124
+ key = { index }
125
+ { ...section }
126
+ onItemClick = { handleMenuClick } // Pass handler to close the drawer
127
+ />
128
+ ) ) }
129
+ </ SideBarV2 >
130
+ </ DrawerContentWrapper >
131
+ </ Drawer >
132
+
133
+ { /* Desktop Layout */ }
51
134
< AntdLayout >
52
- < SideBarV2 className = { CNSidebar } >
53
- { props . sections
54
- . filter ( ( section ) => section . items . length > 0 )
55
- . map ( ( section , index ) => (
56
- < SideBarSection key = { index } { ...section } />
57
- ) ) }
58
- </ SideBarV2 >
135
+ { ! isMobile && (
136
+ < SideBarV2 className = { `${ CNSidebar } desktop-only` } >
137
+ { desktopSections
138
+ . filter ( ( section ) => section . items . length > 0 )
139
+ . map ( ( section , index ) => (
140
+ < SideBarSection key = { index } { ...section } />
141
+ ) ) }
142
+ </ SideBarV2 >
143
+ ) }
59
144
< MainContent className = { CNMainContent } >
60
- < Switch > { routes } </ Switch >
145
+ < Switch > { routes } </ Switch >
61
146
</ MainContent >
62
147
</ AntdLayout >
63
148
</ AntdLayout >
64
149
) ;
65
- }
150
+ }
0 commit comments