Update the user store to be immutable

This commit is contained in:
Grégoire Delattre 2017-06-02 14:39:07 +02:00
parent d0d3f63012
commit 06517be48b
4 changed files with 80 additions and 43 deletions

View File

@ -46,7 +46,7 @@ function mapStateToProps(state) {
torrentCount = state.torrentStore.get('torrents').size;
}
return {
username: state.userStore.username,
username: state.userStore.get('username'),
torrentCount: torrentCount,
alerts: state.alerts,
}

View File

@ -2,11 +2,13 @@ import React from 'react'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { Control, Form } from 'react-redux-form';
import { updateUser } from '../../actions/users'
function mapStateToProps(state) {
return { user: state.userStore };
return {
polochonToken: state.userStore.get('polochonToken'),
polochonUrl: state.userStore.get('polochonUrl'),
};
}
const mapDispatchToProps = (dispatch) =>
bindActionCreators({ updateUser }, dispatch)
@ -14,16 +16,40 @@ const mapDispatchToProps = (dispatch) =>
class UserEdit extends React.Component {
constructor(props) {
super(props);
this.state = {
polochonToken: props.polochonToken,
polochonUrl: props.polochonUrl,
};
this.handleSubmit = this.handleSubmit.bind(this);
this.handleUrlInput = this.handleUrlInput.bind(this);
this.handleTokenInput = this.handleTokenInput.bind(this);
}
handleSubmit() {
handleSubmit(ev) {
ev.preventDefault();
this.props.updateUser({
'polochon_url': this.props.user.polochonUrl,
'polochon_token': this.props.user.polochonToken,
'polochon_url': this.refs.polochonUrl.value,
'polochon_token': this.refs.polochonToken.value,
'password': this.refs.newPassword.value,
'password_confirm': this.refs.newPasswordConfirm.value,
});
}
handleTokenInput() {
this.setState({ polochonToken: this.refs.polochonToken.value });
}
handleUrlInput() {
this.setState({ polochonUrl: this.refs.polochonUrl.value });
}
componentWillReceiveProps(nextProps) {
if ((nextProps.polochonUrl !== "")
&& (this.state.polochonUrl === "")
&& (nextProps.polochonToken !== "")
&& (this.state.polochonToken === "")) {
this.setState({
polochonToken: nextProps.polochonToken,
polochonUrl: nextProps.polochonUrl,
});
}
}
render() {
return (
<div className="container">
@ -31,34 +57,43 @@ class UserEdit extends React.Component {
<div className="col-md-6 col-md-offset-3 col-xs-12">
<h2>Edit user</h2>
<hr />
<Form model="userStore" className="form-horizontal" onSubmit={(val) => this.handleSubmit(val)}>
<form className="form-horizontal" onSubmit={(ev) => this.handleSubmit(ev)}>
<div className="form-group">
<label className="control-label">Polochon URL</label>
<Control.text model="userStore.polochonUrl" className="form-control" />
<input
className="form-control"
value={this.state.polochonUrl}
onChange={this.handleUrlInput}
ref="polochonUrl"
/>
</div>
<div className="form-group">
<label className="control-label">Polochon token</label>
<Control.text model="userStore.polochonToken" className="form-control"/>
<input
className="form-control"
value={this.state.polochonToken}
onChange={this.handleTokenInput}
ref="polochonToken"
/>
</div>
<hr />
<div className="form-group">
<label className="control-label">Password</label>
<input autoComplete="off" className="form-control" ref="newPassword" type="password"/>
<input type="password" autoComplete="off" ref="newPassword" className="form-control"/>
</div>
<div className="form-group">
<label className="control-label">Confirm Password</label>
<input autoComplete="off" className="form-control" ref="newPasswordConfirm" type="password"/>
<input type="password" autoComplete="off" ref="newPasswordConfirm" className="form-control"/>
</div>
<div>
<input className="btn btn-primary pull-right" type="submit" value="Update"/>
<input type="submit" className="btn btn-primary pull-right" value="Update"/>
</div>
</Form>
</form>
</div>
</div>
</div>

View File

@ -5,7 +5,10 @@ import { bindActionCreators } from 'redux'
import { loginUser } from '../../actions/users'
function mapStateToProps(state) {
return { user: state.userStore };
return {
isLogged: state.userStore.get('isLogged'),
loading: state.userStore.get('loading'),
};
}
const mapDispatchToProps = (dispatch) =>
bindActionCreators({ loginUser }, dispatch)
@ -16,7 +19,7 @@ class UserLoginForm extends React.Component {
this.handleSubmit = this.handleSubmit.bind(this);
}
componentWillReceiveProps(nextProps) {
if (!nextProps.user.isLogged) {
if (!nextProps.isLogged) {
return
}
if (!nextProps.location.query.redirect) {
@ -29,7 +32,7 @@ class UserLoginForm extends React.Component {
}
handleSubmit(e) {
e.preventDefault();
if (this.props.user.userLoading) {
if (this.props.loading) {
return;
}
const username = this.refs.username.value;
@ -57,12 +60,12 @@ class UserLoginForm extends React.Component {
<p></p>
</div>
<div>
{this.props.user.userLoading &&
{this.props.loading &&
<button className="btn btn-primary pull-right">
<i className="fa fa-spinner fa-spin"></i>
</button>
}
{this.props.user.userLoading ||
{this.props.loading ||
<input className="btn btn-primary pull-right" type="submit" value="Log in"/>
}
<br/>

View File

@ -1,46 +1,45 @@
import { OrderedMap, Map, fromJS } from 'immutable'
import jwtDecode from 'jwt-decode'
import Cookies from 'universal-cookie'
const defaultState = {
userLoading: false,
const defaultState = Map({
loading: false,
username: "",
isAdmin: false,
isLogged: false,
polochonToken: "",
polochonUrl: "",
};
});
export default function userStore(state = defaultState, action) {
switch (action.type) {
case 'USER_LOGIN_PENDING':
return Object.assign({}, state, {
userLoading: true,
})
return state.set('loading', true);
case 'USER_LOGIN_FULFILLED':
if (action.payload.response.status === "error") {
return logoutUser(state)
return logoutUser()
}
return updateFromToken(state, action.payload.response.data.token)
case 'USER_SET_TOKEN':
return updateFromToken(state, action.payload.token)
case 'USER_LOGOUT':
return logoutUser(state)
return logoutUser()
case 'GET_USER_FULFILLED':
return Object.assign({}, state, {
return state.merge(Map({
polochonToken: action.payload.response.data.token,
polochonUrl: action.payload.response.data.url,
})
}))
default:
return state;
}
}
function logoutUser(state) {
function logoutUser() {
localStorage.removeItem('token');
const cookies = new Cookies();
cookies.remove('token');
return Object.assign({}, state, defaultState)
return defaultState
}
function updateFromToken(state, token) {
@ -50,10 +49,10 @@ function updateFromToken(state, token) {
const cookies = new Cookies();
cookies.set('token', token);
return Object.assign({}, state, {
return state.merge(Map({
userLoading: false,
isLogged: true,
isAdmin: decodedToken.isAdmin,
username: decodedToken.username,
})
}))
}