Skip to content

Commit fa06044

Browse files
committed
refactor(routes): use pojo route definitions
- move route definitions out of `Root` component - use pojo routes - split `authRouteResolver` into `requireAuth` and `requireUnauth` - use selector to resolve auth state
1 parent 68fca63 commit fa06044

File tree

10 files changed

+64
-57
lines changed

10 files changed

+64
-57
lines changed

src/components/app/app.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import React, { Component, PropTypes } from 'react';
22
import { connect } from 'react-redux';
33
import { createSelector } from 'reselect';
4-
import { POST_SIGN_IN_PATH, POST_SIGN_OUT_PATH } from 'src/config';
54
import { authActions, getAuth } from 'src/core/auth';
5+
import { paths } from '../routes';
66

77

88
export class App extends Component {
@@ -27,16 +27,15 @@ export class App extends Component {
2727
const { auth } = this.props;
2828

2929
if (auth.authenticated && !nextProps.auth.authenticated) {
30-
router.replace(POST_SIGN_OUT_PATH);
30+
router.replace(paths.SIGN_IN);
3131
}
3232
else if (!auth.authenticated && nextProps.auth.authenticated) {
33-
router.replace(POST_SIGN_IN_PATH);
33+
router.replace(paths.TASKS);
3434
}
3535
}
3636

3737
signOut() {
3838
this.props.signOut();
39-
window.location.replace('/');
4039
}
4140

4241
render() {

src/components/root.js

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,18 @@
11
import React, { PropTypes } from 'react';
22
import { Provider } from 'react-redux';
3-
import { Route, Router } from 'react-router';
3+
import { Router } from 'react-router';
4+
import { getRoutes } from './routes';
45

5-
// config
6-
import { SIGN_IN_PATH, TASKS_PATH } from 'src/config';
76

8-
// components
9-
import App from './app/app';
10-
import SignIn from './sign-in/sign-in';
11-
import Tasks from './tasks/tasks';
12-
13-
14-
export default function Root({history, onEnter, store}) {
7+
export default function Root({history, store}) {
158
return (
169
<Provider store={store}>
17-
<Router history={history}>
18-
<Route component={App} onEnter={onEnter} path="/">
19-
<Route component={SignIn} path={SIGN_IN_PATH} />
20-
<Route component={Tasks} path={TASKS_PATH} />
21-
</Route>
22-
</Router>
10+
<Router history={history} routes={getRoutes(store.getState)} />
2311
</Provider>
2412
);
2513
}
2614

2715
Root.propTypes = {
2816
history: PropTypes.object.isRequired,
29-
onEnter: PropTypes.func.isRequired,
3017
store: PropTypes.object.isRequired
3118
};

src/components/routes.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { isAuthenticated } from 'src/core/auth';
2+
import App from './app/app';
3+
import SignIn from './sign-in/sign-in';
4+
import Tasks from './tasks/tasks';
5+
6+
7+
export const paths = {
8+
ROOT: '/',
9+
SIGN_IN: '/sign-in',
10+
TASKS: '/'
11+
};
12+
13+
14+
const requireAuth = getState => {
15+
return (nextState, replace) => {
16+
if (!isAuthenticated(getState())) {
17+
replace(paths.SIGN_IN);
18+
}
19+
};
20+
};
21+
22+
const requireUnauth = getState => {
23+
return (nextState, replace) => {
24+
if (isAuthenticated(getState())) {
25+
replace(paths.TASKS);
26+
}
27+
};
28+
};
29+
30+
31+
export const getRoutes = getState => {
32+
return {
33+
path: paths.ROOT,
34+
component: App,
35+
childRoutes: [
36+
{
37+
indexRoute: {
38+
component: Tasks,
39+
onEnter: requireAuth(getState)
40+
}
41+
},
42+
{
43+
path: paths.SIGN_IN,
44+
component: SignIn,
45+
onEnter: requireUnauth(getState)
46+
}
47+
]
48+
};
49+
};

src/components/tasks/task-filters.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import { Link } from 'react-router';
66
export function TaskFilters({filter}) {
77
return (
88
<ul className="task-filters">
9-
<li><Link className={classNames({active: !filter})} to="/tasks">View All</Link></li>
10-
<li><Link activeClassName="active" to={{pathname: '/tasks', query: {filter: 'active'}}}>Active</Link></li>
11-
<li><Link activeClassName="active" to={{pathname: '/tasks', query: {filter: 'completed'}}}>Completed</Link></li>
9+
<li><Link className={classNames({active: !filter})} to="/">View All</Link></li>
10+
<li><Link activeClassName="active" to={{pathname: '/', query: {filter: 'active'}}}>Active</Link></li>
11+
<li><Link activeClassName="active" to={{pathname: '/', query: {filter: 'completed'}}}>Completed</Link></li>
1212
</ul>
1313
);
1414
}

src/config.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,3 @@ export const FIREBASE_CONFIG = {
44
databaseURL: 'https://todo-react-redux.firebaseio.com',
55
storageBucket: 'firebase-todo-react-redux.appspot.com'
66
};
7-
8-
9-
// Route paths
10-
export const SIGN_IN_PATH = '/sign-in';
11-
export const TASKS_PATH = '/tasks';
12-
export const POST_SIGN_IN_PATH = TASKS_PATH;
13-
export const POST_SIGN_OUT_PATH = SIGN_IN_PATH;

src/core/auth/index.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ import * as authActions from './actions';
55
export { authActions };
66
export * from './action-types';
77
export { authReducer } from './reducer';
8-
export * from './route-resolver';
9-
export { getAuth } from './selectors';
8+
export { getAuth, isAuthenticated } from './selectors';
109

1110

1211
export function initAuth(dispatch) {

src/core/auth/route-resolver.js

Lines changed: 0 additions & 16 deletions
This file was deleted.

src/core/auth/selectors.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ export function getAuth(state) {
22
return state.auth;
33
}
44

5-
export function getAuthenticated(state) {
5+
export function isAuthenticated(state) {
66
return getAuth(state).authenticated;
77
}

src/main.js

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,20 @@ import { AppContainer } from 'react-hot-loader';
66
import { browserHistory } from 'react-router';
77
import { syncHistoryWithStore } from 'react-router-redux';
88

9-
import { authRouteResolver, initAuth } from './core/auth';
9+
import { initAuth } from './core/auth';
1010
import configureStore from './core/store';
1111
import Root from './components/root';
1212

1313

1414
const store = configureStore();
1515
const syncedHistory = syncHistoryWithStore(browserHistory, store);
16-
const onEnter = authRouteResolver(store.getState);
1716
const rootElement = document.getElementById('root');
1817

1918

2019
function render(Root) {
2120
ReactDOM.render(
2221
<AppContainer>
23-
<Root
24-
history={syncedHistory}
25-
onEnter={onEnter}
26-
store={store}
27-
/>
22+
<Root history={syncedHistory} store={store} />
2823
</AppContainer>,
2924
rootElement
3025
);

src/vendor.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ import 'redux-thunk';
1515
import 'classnames';
1616
import 'firebase';
1717
import 'immutable';
18+
import 'reselect';

0 commit comments

Comments
 (0)