1
1
import React , { Component } from 'react' ;
2
2
import { HashRouter as Router } from 'react-router-dom' ;
3
+ import PropTypes from 'prop-types' ;
4
+
3
5
import { withWidth , CssBaseline , MuiThemeProvider } from '@material-ui/core' ;
4
6
5
7
import { Navigator } from './core' ;
6
8
import { ROUTES } from './config' ;
7
- import { dark as darkTheme , light as lightTheme } from './themes/backoffice' ;
8
9
import { Loading } from './views' ;
9
10
10
- class Backoffice extends Component {
11
+ class App extends Component {
11
12
state = {
12
13
loading : true ,
13
14
authenticated : false ,
14
15
nightMode : false ,
15
16
token : { } ,
16
17
user : { } ,
17
18
username : '' ,
19
+
20
+ errorResponse : { } ,
21
+ successfulResponse : { } ,
22
+ responseInterceptor : null ,
23
+ } ;
24
+
25
+ /**
26
+ * Remove the response interceptor.
27
+ *
28
+ * @param {any } interceptor
29
+ *
30
+ * @param {undefined }
31
+ */
32
+ removeResponseInterceptor = interceptor => {
33
+ axios . interceptors . response . eject ( interceptor ) ;
34
+ } ;
35
+
36
+ /**
37
+ * Record API responses & do something.
38
+ *
39
+ * @param {any } interceptor
40
+ *
41
+ * @param {undefined }
42
+ */
43
+ addResponseInterceptor = ( ) => {
44
+ const responseInterceptor = axios . interceptors . response . use (
45
+ response => {
46
+ return response ;
47
+ } ,
48
+
49
+ error => {
50
+ // In occasions of Unauthorized requests (401),
51
+ // Remove the stored tokens.
52
+ if ( error . response . status === 401 ) {
53
+ this . removeToken ( ) ;
54
+ }
55
+
56
+ return Promise . reject ( error ) ;
57
+ } ,
58
+ ) ;
59
+
60
+ this . setState ( {
61
+ responseInterceptor,
62
+ } ) ;
18
63
} ;
19
64
20
65
/**
@@ -48,8 +93,7 @@ class Backoffice extends Component {
48
93
const response = await axios . post ( '/api/v1/auth/signout' ) ;
49
94
50
95
if ( response . status === 200 ) {
51
- // remove token data stored in localStorage.
52
- await localStorage . removeItem ( 'token' ) ;
96
+ this . removeToken ( ) ;
53
97
54
98
this . setState ( {
55
99
loading : false ,
@@ -151,17 +195,19 @@ class Backoffice extends Component {
151
195
token . auth_token
152
196
} `;
153
197
154
- // Add an expired_at timestamp based in the expired_in property in the token.
155
- // A client defined expiry time makes sense here since a server time is
156
- // not what we should depend on.
157
- token . expired_at = moment ( )
158
- . add ( token . expires_in , 'seconds' )
159
- . format ( 'YYYY-MM-DD hh:mm:ss' ) ;
160
-
161
198
// Store it locally for the authentication token to persist.
162
199
window . localStorage . setItem ( 'token' , JSON . stringify ( token ) ) ;
163
200
} ;
164
201
202
+ /**
203
+ * Remove token data stored in persistent storage.
204
+ *
205
+ * @return {undefined }
206
+ */
207
+ removeToken = ( ) => {
208
+ localStorage . removeItem ( 'token' ) ;
209
+ } ;
210
+
165
211
/**
166
212
* Fetch the authenticated user.
167
213
*
@@ -188,26 +234,30 @@ class Backoffice extends Component {
188
234
} ;
189
235
190
236
async componentDidMount ( ) {
237
+ // Listen for all API responses.
238
+ this . addResponseInterceptor ( ) ;
239
+
191
240
// Setup Night Mode via Persistent Storage.
192
241
this . setNightMode ( ) ;
193
242
194
243
// Authenticate via Persistent Storage.
195
244
const token = this . token ( ) ;
196
- let expired = true ;
197
245
198
- if ( token . hasOwnProperty ( 'expired_at' ) ) {
199
- expired = moment ( token . expired_at ) . unix ( ) > moment ( ) . unix ( ) ;
246
+ if ( Object . keys ( token ) . length > 0 ) {
247
+ await this . authenticate ( JSON . stringify ( token ) ) ;
200
248
}
201
249
202
- // if (!expired) {
203
- await this . authenticate ( JSON . stringify ( token ) ) ;
204
- // }
205
-
206
250
this . setState ( { loading : false } ) ;
207
251
}
208
252
253
+ componentWillUnmount ( ) {
254
+ const { responseInterceptor } = this . state ;
255
+
256
+ this . removeResponseInterceptor ( responseInterceptor ) ;
257
+ }
258
+
209
259
render ( ) {
210
- const { width } = this . props ;
260
+ const { width, environment , darkTheme , lightTheme } = this . props ;
211
261
const { loading, nightMode } = this . state ;
212
262
213
263
return (
@@ -226,7 +276,7 @@ class Backoffice extends Component {
226
276
pageProps = { {
227
277
...this . state ,
228
278
width,
229
- environment : 'backoffice' ,
279
+ environment : environment ,
230
280
routes : ROUTES ,
231
281
handleNightmodeToggled : this
232
282
. handleNightmodeToggled ,
@@ -242,4 +292,10 @@ class Backoffice extends Component {
242
292
}
243
293
}
244
294
245
- export default withWidth ( ) ( Backoffice ) ;
295
+ App . propTypes = {
296
+ environment : PropTypes . oneOf ( [ 'backoffice' ] ) . isRequired ,
297
+ darkTheme : PropTypes . object . isRequired ,
298
+ lightTheme : PropTypes . object . isRequired ,
299
+ } ;
300
+
301
+ export default withWidth ( ) ( App ) ;
0 commit comments