1
- import { FC , useEffect , useState } from 'react'
1
+ import { FC , ReactNode , useEffect , useState } from 'react'
2
2
import { useSelector , useDispatch } from 'react-redux'
3
3
import { useLocation , useNavigate } from 'react-router-dom'
4
4
import { Box } from '@mui/material'
@@ -9,58 +9,83 @@ import { getMe } from 'store/slice/User/UserActions'
9
9
import Header from './Header'
10
10
import LeftMenu from './LeftMenu'
11
11
import { IS_STANDALONE } from 'const/Mode'
12
+ import Loading from 'components/common/Loading'
13
+ import { APP_BAR_HEIGHT } from 'const/Layout'
12
14
13
- const ignorePaths = [ '/login' , '/account-delete' , '/reset-password' ]
14
- const loginPaths = [ '/login' , '/reset-password' ]
15
+ const authRequiredPathRegex = / ^ \/ c o n s o l e \/ ? .* /
15
16
16
- const Layout : FC = ( { children } ) => {
17
+ const Layout = ( { children } : { children ?: ReactNode } ) => {
17
18
const user = useSelector ( selectCurrentUser )
18
19
const location = useLocation ( )
19
- const [ open , setOpen ] = useState ( false )
20
20
const navigate = useNavigate ( )
21
21
const dispatch = useDispatch ( )
22
22
23
- const handleDrawerOpen = ( ) => {
24
- setOpen ( true )
25
- }
26
-
27
- const handleDrawerClose = ( ) => {
28
- setOpen ( false )
29
- }
23
+ const [ loading , setLoadingAuth ] = useState (
24
+ ! IS_STANDALONE && authRequiredPathRegex . test ( location . pathname ) ,
25
+ )
30
26
31
27
useEffect ( ( ) => {
32
- ! IS_STANDALONE && checkAuth ( )
28
+ ! IS_STANDALONE &&
29
+ authRequiredPathRegex . test ( location . pathname ) &&
30
+ checkAuth ( )
33
31
// eslint-disable-next-line react-hooks/exhaustive-deps
34
32
} , [ location . pathname , user ] )
35
33
36
34
const checkAuth = async ( ) => {
37
- if ( user ) return
35
+ if ( user ) {
36
+ if ( loading ) setLoadingAuth ( false )
37
+ return
38
+ }
38
39
const token = getToken ( )
39
- const isPageLogin = loginPaths . includes ( window . location . pathname )
40
+ const isLogin = location . pathname === '/login'
40
41
41
42
try {
42
43
if ( token ) {
43
- dispatch ( getMe ( ) )
44
- if ( isPageLogin ) navigate ( '/' )
44
+ await dispatch ( getMe ( ) )
45
+ if ( isLogin ) navigate ( '/console ' )
45
46
return
46
- } else if ( ! isPageLogin ) throw new Error ( 'fail auth' )
47
+ } else if ( ! isLogin ) throw new Error ( 'fail auth' )
47
48
} catch {
48
- navigate ( '/login' )
49
+ navigate ( '/login' , { replace : true } )
50
+ } finally {
51
+ if ( loading ) setLoadingAuth ( false )
49
52
}
50
53
}
51
54
55
+ if ( loading ) return < Loading />
56
+
57
+ return IS_STANDALONE || authRequiredPathRegex . test ( location . pathname ) ? (
58
+ < AuthedLayout > { children } </ AuthedLayout >
59
+ ) : (
60
+ < UnauthedLayout > { children } </ UnauthedLayout >
61
+ )
62
+ }
63
+
64
+ const AuthedLayout : FC = ( { children } ) => {
65
+ const [ open , setOpen ] = useState ( false )
66
+ const handleDrawerOpen = ( ) => {
67
+ setOpen ( true )
68
+ }
69
+
70
+ const handleDrawerClose = ( ) => {
71
+ setOpen ( false )
72
+ }
73
+ return (
74
+ < LayoutWrapper >
75
+ < Header handleDrawerOpen = { handleDrawerOpen } />
76
+ < ContentBodyWrapper >
77
+ < LeftMenu open = { open } handleDrawerClose = { handleDrawerClose } />
78
+ < ChildrenWrapper > { children } </ ChildrenWrapper >
79
+ </ ContentBodyWrapper >
80
+ </ LayoutWrapper >
81
+ )
82
+ }
83
+
84
+ const UnauthedLayout : FC = ( { children } ) => {
52
85
return (
53
86
< LayoutWrapper >
54
- { ignorePaths . includes ( location . pathname ) ? null : (
55
- < Header handleDrawerOpen = { handleDrawerOpen } />
56
- ) }
57
87
< ContentBodyWrapper >
58
- { ignorePaths . includes ( location . pathname ) ? null : (
59
- < LeftMenu open = { open } handleDrawerClose = { handleDrawerClose } />
60
- ) }
61
- < ChildrenWrapper open = { open } >
62
- { children }
63
- </ ChildrenWrapper >
88
+ < ChildrenWrapper > { children } </ ChildrenWrapper >
64
89
</ ContentBodyWrapper >
65
90
</ LayoutWrapper >
66
91
)
@@ -74,28 +99,21 @@ const LayoutWrapper = styled(Box)({
74
99
const ContentBodyWrapper = styled ( Box ) ( ( ) => ( {
75
100
backgroundColor : '#ffffff' ,
76
101
display : 'flex' ,
77
- paddingTop : 48 ,
78
- height : ' calc(100% - 48px)' ,
102
+ paddingTop : APP_BAR_HEIGHT ,
103
+ height : ` calc(100% - ${ APP_BAR_HEIGHT } px)` ,
79
104
paddingRight : 10 ,
80
- overflow : 'hidden ' ,
105
+ overflow : 'auto ' ,
81
106
} ) )
82
107
83
- const ChildrenWrapper = styled ( 'main' , { shouldForwardProp : ( prop ) => prop !== 'open' } ) < {
84
- open ?: boolean ;
85
- } > ( ( { theme, open } ) => ( {
108
+ const ChildrenWrapper = styled ( 'main' , {
109
+ shouldForwardProp : ( prop ) => prop !== 'open' ,
110
+ } ) < { } > ( ( { theme } ) => ( {
86
111
flexGrow : 1 ,
87
112
padding : theme . spacing ( 3 ) ,
88
113
transition : theme . transitions . create ( 'margin' , {
89
114
easing : theme . transitions . easing . sharp ,
90
115
duration : theme . transitions . duration . leavingScreen ,
91
116
} ) ,
92
- ...( open && {
93
- transition : theme . transitions . create ( 'margin' , {
94
- easing : theme . transitions . easing . easeOut ,
95
- duration : theme . transitions . duration . enteringScreen ,
96
- } ) ,
97
- marginLeft : 0 ,
98
- } ) ,
99
- } ) ) ;
117
+ } ) )
100
118
101
119
export default Layout
0 commit comments