Add user store and login actions

This commit is contained in:
Grégoire Delattre 2016-11-15 20:21:45 +01:00
parent efcfced18f
commit 0ed8759bab
8 changed files with 97 additions and 9 deletions

View File

@ -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",

View File

@ -34,6 +34,7 @@ class Main extends React.Component {
function mapStateToProps(state) {
return {
movieStore: state.movieStore,
userStore: state.userStore,
}
}

View File

@ -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 (
<div className="container">
@ -8,24 +32,30 @@ export default class UserLoginForm extends React.Component {
<div className="col-md-6 col-md-offset-3 col-xs-12">
<h2>Log in</h2>
<hr/>
<form acceptCharset="UTF-8" action="/users/login" method="POST" className="form-horizontal">
<form ref="loginForm" className="form-horizontal" onSubmit={(e) => this.handleSubmit(e)}>
<div>
<label htmlFor="user_email">Username</label>
<br/>
<input className="form-control" id="username" name="Username" type="username" value=""/>
<input className="form-control" type="username" ref="username"/>
<p></p>
</div>
<div>
<label htmlFor="user_password">Password</label>
<br/>
<input autoComplete="off" className="form-control" id="password" name="Password" type="password"/>
<input className="form-control" type="password" ref="password"/>
<p></p>
</div>
<div>
{this.props.userStore.userLoading &&
<button className="btn btn-primary pull-right">
<i className="fa fa-spinner fa-spin"></i>
</button>
}
{this.props.userStore.userLoading ||
<input className="btn btn-primary pull-right" type="submit" value="Log in"/>
}
<br/>
</div>
<a className="btn btn-default btn-sm pull-left" href="/movies/%3cnil%3e">Cancel</a>
</form>
</div>
</div>

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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);

View File

@ -18,6 +18,9 @@ export default {
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development')
})
],
resolve: {

View File

@ -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"