1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
import React from 'react';
import { Switch, Route, Redirect } from 'react-router';
import { CSSTransitionGroup } from 'react-transition-group';
import WindowChrome from './components/WindowChrome';
import LoginPage from './containers/LoginPage';
import ConnectPage from './containers/ConnectPage';
import SettingsPage from './containers/SettingsPage';
import AccountPage from './containers/AccountPage';
import SelectLocationPage from './containers/SelectLocationPage';
import { getTransitionProps } from './transitions';
/**
* Create routes
*
* @export
* @param {function} getState - function to get redux state
* @param {object} componentProps - extra props to propagate across components
* @returns {React.element}
*/
export default function makeRoutes(getState, componentProps) {
/**
* Merge props and render component
* @param {React.Component} component - component class
* @param {...} rest - props
* @private
*/
const renderMergedProps = (component, ...rest) => {
const finalProps = Object.assign({}, componentProps, ...rest);
return (
React.createElement(component, finalProps)
);
};
/**
* Renders public route
* Example: <PublicRoute path="/" component={ MyComponent } />
* @private
*/
const PublicRoute = ({ component, ...rest }) => {
return (
<Route {...rest} render={ (routeProps) => {
return renderMergedProps(component, routeProps, ...rest);
}} />
);
};
/**
* Renders protected route that requires authentication, otherwise redirects to /
* Example: <PrivateRoute path="/protected" component={ MyComponent } />
* @private
*/
const PrivateRoute = ({ component, ...rest }) => {
return (
<Route {...rest} render={ (routeProps) => {
const { account } = getState();
const isLoggedIn = account.status === 'ok';
if(isLoggedIn) {
return renderMergedProps(component, routeProps, ...rest);
} else {
return (<Redirect to={ '/' } />);
}
}} />
);
};
/**
* Renders login route that is only available to non-authenticated
* users. Otherwise this route redirects user to /connect.
* Example: <LoginRoute path="/login" component={ MyComponent } />
* @private
*/
const LoginRoute = ({ component, ...rest }) => {
return (
<Route {...rest} render={ (routeProps) => {
const { account } = getState();
const isLoggedIn = account.status === 'ok';
if(isLoggedIn) {
return (<Redirect to={ '/connect' } />);
} else {
return renderMergedProps(component, routeProps, ...rest);
}
}} />
);
};
// store previous route
let previousRoute;
return (
<Route render={({location}) => {
const toRoute = location.pathname;
const fromRoute = previousRoute;
const transitionProps = getTransitionProps(fromRoute, toRoute);
previousRoute = toRoute;
return (
<WindowChrome>
<CSSTransitionGroup component="div" className="transition-container" { ...transitionProps }>
<Switch key={ location.key } location={ location }>
<LoginRoute exact path="/" component={ LoginPage } />
<PrivateRoute exact path="/connect" component={ ConnectPage } />
<PublicRoute exact path="/settings" component={ SettingsPage } />
<PrivateRoute path="/settings/account" component={ AccountPage } />
<PrivateRoute path="/select-location" component={ SelectLocationPage } />
</Switch>
</CSSTransitionGroup>
</WindowChrome>
);
}} />
);
}
|