From 0ed8759bab4fd9f4d9d14b899cf1118ae1fc431d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Delattre?= Date: Tue, 15 Nov 2016 20:21:45 +0100 Subject: [PATCH] Add user store and login actions --- package.json | 5 +++- src/public/js/app.js | 1 + src/public/js/components/user-login.jsx | 40 +++++++++++++++++++++---- src/public/js/reducers/index.js | 4 ++- src/public/js/reducers/users.js | 20 +++++++++++++ src/public/js/store.js | 15 ++++++++-- webpack.config.babel.js | 3 ++ yarn.lock | 18 +++++++++++ 8 files changed, 97 insertions(+), 9 deletions(-) create mode 100644 src/public/js/reducers/users.js diff --git a/package.json b/package.json index 985b265..7dbba9c 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,10 @@ "react-redux": "^4.4.6", "react-router": "^3.0.0", "react-router-redux": "^4.0.7", - "redux": "^3.6.0" + "redux": "^3.6.0", + "redux-logger": "^2.7.4", + "redux-promise-middleware": "^4.1.0", + "redux-thunk": "^2.1.0" }, "devDependencies": { "axios": "^0.15.2", diff --git a/src/public/js/app.js b/src/public/js/app.js index 04d89ec..6519008 100644 --- a/src/public/js/app.js +++ b/src/public/js/app.js @@ -34,6 +34,7 @@ class Main extends React.Component { function mapStateToProps(state) { return { movieStore: state.movieStore, + userStore: state.userStore, } } diff --git a/src/public/js/components/user-login.jsx b/src/public/js/components/user-login.jsx index ad56848..16eb337 100644 --- a/src/public/js/components/user-login.jsx +++ b/src/public/js/components/user-login.jsx @@ -1,6 +1,30 @@ import React from 'react' +import axios from 'axios' +import store from '../store' export default class UserLoginForm extends React.Component { + constructor(props) { + super(props); + this.handleSubmit = this.handleSubmit.bind(this); + } + handleSubmit(e) { + e.preventDefault(); + if (this.props.userStore.userLoading) { + return; + } + const username = this.refs.username.value; + const password = this.refs.password.value; + store.dispatch({ + type: "USER_LOGIN", + payload: axios.post( + '/users/login', + { + username: username, + password: password, + }, + ) + }) + } render() { return (
@@ -8,24 +32,30 @@ export default class UserLoginForm extends React.Component {

Log in


-
+ this.handleSubmit(e)}>

- +


- +

- + {this.props.userStore.userLoading && + + } + {this.props.userStore.userLoading || + + }
- Cancel
diff --git a/src/public/js/reducers/index.js b/src/public/js/reducers/index.js index 407dfcb..3595843 100644 --- a/src/public/js/reducers/index.js +++ b/src/public/js/reducers/index.js @@ -2,10 +2,12 @@ import { combineReducers } from 'redux'; import { routerReducer } from 'react-router-redux' import movieStore from './movie-store' +import userStore from './users' const rootReducer = combineReducers({ routing: routerReducer, - movieStore + movieStore, + userStore }) export default rootReducer; diff --git a/src/public/js/reducers/users.js b/src/public/js/reducers/users.js new file mode 100644 index 0000000..7c9e00e --- /dev/null +++ b/src/public/js/reducers/users.js @@ -0,0 +1,20 @@ +const defaultState = { + userLoading: false, +}; + +// This actions are generated from the promise middleware + +export default function userStore(state = defaultState, action) { + switch (action.type) { + case 'USER_LOGIN_PENDING': + return Object.assign({}, state, { + userLoading: true, + }) + case 'USER_LOGIN_FULFILLED': + return Object.assign({}, state, { + userLoading: false, + }) + default: + return state; + } +} diff --git a/src/public/js/store.js b/src/public/js/store.js index e8a20fb..9181e6b 100644 --- a/src/public/js/store.js +++ b/src/public/js/store.js @@ -1,12 +1,23 @@ -import { createStore, compose } from 'redux'; +import { createStore, applyMiddleware, compose } from 'redux'; import { syncHistoryWithStore } from 'react-router-redux' import { hashHistory } from 'react-router' +import thunk from 'redux-thunk' +import promise from 'redux-promise-middleware' // Import the root reducer import rootReducer from './reducers/index' +const middlewares = [promise(), thunk]; + +// Only use in development mode (set in webpack) +if (process.env.NODE_ENV === `development`) { + const createLogger = require(`redux-logger`); + const logger = createLogger(); + middlewares.push(logger); +} + // Export the store -const store = createStore(rootReducer); +const store = compose(applyMiddleware(...middlewares))(createStore)(rootReducer); // Sync history with store export const history = syncHistoryWithStore(hashHistory, store); diff --git a/webpack.config.babel.js b/webpack.config.babel.js index d637644..10686ee 100644 --- a/webpack.config.babel.js +++ b/webpack.config.babel.js @@ -18,6 +18,9 @@ export default { new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery" + }), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify('development') }) ], resolve: { diff --git a/yarn.lock b/yarn.lock index a3237cd..10ac9b8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -986,6 +986,10 @@ decamelize@^1.0.0, decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" +deep-diff@0.3.4: + version "0.3.4" + resolved "https://registry.yarnpkg.com/deep-diff/-/deep-diff-0.3.4.tgz#aac5c39952236abe5f037a2349060ba01b00ae48" + deep-extend@~0.4.0: version "0.4.1" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.1.tgz#efe4113d08085f4e6f9687759810f807469e2253" @@ -2695,6 +2699,20 @@ redux: loose-envify "^1.1.0" symbol-observable "^1.0.2" +redux-logger: + version "2.7.4" + resolved "https://registry.yarnpkg.com/redux-logger/-/redux-logger-2.7.4.tgz#891e5d29e7f111d08b5781a237b9965b5858c7f8" + dependencies: + deep-diff "0.3.4" + +redux-promise-middleware: + version "4.1.0" + resolved "https://registry.yarnpkg.com/redux-promise-middleware/-/redux-promise-middleware-4.1.0.tgz#8477866fa09837c1f08f5869c473747577f5446a" + +redux-thunk: + version "2.1.0" + resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.1.0.tgz#c724bfee75dbe352da2e3ba9bc14302badd89a98" + regenerate@^1.2.1: version "1.3.2" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260"