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": {