diff --git a/app/client/components/LoggedIn.js b/app/client/components/LoggedIn.js
new file mode 100644
index 00000000..50521d5f
--- /dev/null
+++ b/app/client/components/LoggedIn.js
@@ -0,0 +1,11 @@
+import React, { Component } from 'react';
+
+export default class LoggedIn extends Component {
+ render() {
+ return (
+
+
Logged in as {this.props.user.username}
+
+ );
+ }
+}
diff --git a/app/client/components/Login.js b/app/client/components/Login.js
index 7385a496..b2e373ff 100644
--- a/app/client/components/Login.js
+++ b/app/client/components/Login.js
@@ -1,11 +1,17 @@
-import React from 'react';
+import React, { Component, PropTypes } from 'react';
+
+export default class Login extends Component {
+ static propTypes = {
+ onLogin: PropTypes.func.isRequired
+ };
-export default class App extends React.Component {
handleLogin() {
const { onLogin } = this.props;
const username = this.refs.username.value;
onLogin({ username, loggedIn: true });
+
+ this.props.router.push('/loggedin');
}
render() {
diff --git a/app/client/containers/App.js b/app/client/containers/App.js
index b99cbfe3..2b45c8ed 100644
--- a/app/client/containers/App.js
+++ b/app/client/containers/App.js
@@ -1,19 +1,15 @@
-import React from 'react';
-import { bindActionCreators } from 'redux';
-import { connect } from 'react-redux';
-import userActions from '../actions/user';
-import Login from '../components/Login';
+import React, { Component, PropTypes } from 'react';
-@connect((state) => state)
-export default class App extends React.Component {
- render() {
- const { user, dispatch } = this.props;
- const boundUserActions = bindActionCreators(userActions, dispatch);
+export default class App extends Component {
+ static propTypes = {
+ children: PropTypes.element.isRequired
+ };
+ render() {
return (
- !user.loggedIn ?
- :
- Hi { user.username }!
+
+ {this.props.children}
+
);
}
}
diff --git a/app/client/containers/LoggedInPage.js b/app/client/containers/LoggedInPage.js
new file mode 100644
index 00000000..636d9130
--- /dev/null
+++ b/app/client/containers/LoggedInPage.js
@@ -0,0 +1,12 @@
+import { connect } from 'react-redux';
+import LoggedIn from '../components/LoggedIn';
+
+const mapStateToProps = (state) => {
+ return state;
+};
+
+const mapDispatchToProps = (dispatch) => { // eslint-disable-line no-unused-vars
+ return {};
+};
+
+export default connect(mapStateToProps, mapDispatchToProps)(LoggedIn);
diff --git a/app/client/containers/LoginPage.js b/app/client/containers/LoginPage.js
new file mode 100644
index 00000000..1eb28d33
--- /dev/null
+++ b/app/client/containers/LoginPage.js
@@ -0,0 +1,17 @@
+import { connect } from 'react-redux';
+import { bindActionCreators } from 'redux';
+import Login from '../components/Login';
+import userActions from '../actions/user';
+
+const mapStateToProps = (state) => {
+ return state;
+};
+
+const mapDispatchToProps = (dispatch) => {
+ const user = bindActionCreators(userActions, dispatch);
+ return {
+ onLogin: user.login
+ };
+};
+
+export default connect(mapStateToProps, mapDispatchToProps)(Login);
diff --git a/app/client/main.js b/app/client/main.js
index 3e8748c3..101014e9 100644
--- a/app/client/main.js
+++ b/app/client/main.js
@@ -1,18 +1,20 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
-import App from './containers/App';
-import configureStore from './store/default';
+import { Router, hashHistory } from 'react-router';
+import { syncHistoryWithStore } from 'react-router-redux';
+import routes from './routes';
+import configureStore from './store';
const initialState = {};
const store = configureStore(initialState);
+const routerHistory = syncHistoryWithStore(hashHistory, store);
+
const rootElement = document.querySelector(document.currentScript.getAttribute('data-container'));
ReactDOM.render(
-
+
,
rootElement
);
diff --git a/app/client/routes.js b/app/client/routes.js
new file mode 100644
index 00000000..c44e9a68
--- /dev/null
+++ b/app/client/routes.js
@@ -0,0 +1,13 @@
+import React from 'react';
+import { Route, IndexRoute } from 'react-router';
+
+import App from './containers/App';
+import LoginPage from './containers/LoginPage';
+import LoggedInPage from './containers/LoggedInPage';
+
+export default (
+
+
+
+
+);
diff --git a/app/client/store/default.js b/app/client/store.js
similarity index 50%
rename from app/client/store/default.js
rename to app/client/store.js
index 0c5e2702..35065063 100644
--- a/app/client/store/default.js
+++ b/app/client/store.js
@@ -1,18 +1,25 @@
import { createStore, applyMiddleware, combineReducers, compose } from 'redux';
+import { hashHistory } from 'react-router';
+import { routerMiddleware, routerReducer as routing, push } from 'react-router-redux';
+import persistState from 'redux-localstorage';
import thunk from 'redux-thunk';
-import user from '../reducers/user';
-import userActions from '../actions/user';
+import user from './reducers/user';
+import userActions from './actions/user';
+
+const router = routerMiddleware(hashHistory);
const actionCreators = {
- ...userActions
+ ...userActions,
+ push
};
const reducers = {
- user
+ user,
+ routing
};
-const middlewares = [thunk];
+const middlewares = [ thunk, router ];
const composeEnhancers = (() => {
const compose_ = window && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__;
@@ -22,9 +29,9 @@ const composeEnhancers = (() => {
return compose;
})();
-const enhancer = composeEnhancers(applyMiddleware(...middlewares));
-const rootReducer = combineReducers(reducers);
-
export default function configureStore(initialState) {
+ const enhancer = composeEnhancers(applyMiddleware(...middlewares), persistState());
+ const rootReducer = combineReducers(reducers);
+
return createStore(rootReducer, initialState, enhancer);
}
diff --git a/package.json b/package.json
index 7249e87f..d5ffe9d1 100644
--- a/package.json
+++ b/package.json
@@ -11,8 +11,11 @@
"react": "^15.4.2",
"react-dom": "^15.4.2",
"react-redux": "^5.0.2",
+ "react-router": "^3.0.2",
+ "react-router-redux": "^4.0.7",
"redux": "^3.0.0",
"redux-actions": "^1.2.1",
+ "redux-localstorage": "^0.4.1",
"redux-thunk": "^2.2.0"
},
"devDependencies": {