Skip to content

Commit

Permalink
Merge pull request #3055 from jeff1evesque/bug-3051
Browse files Browse the repository at this point in the history
#3051: Ensure after '/register' redirected to '/login'
  • Loading branch information
jeff1evesque committed Oct 14, 2017
2 parents e21a7b6 + 342f484 commit bc1744a
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 48 deletions.
8 changes: 5 additions & 3 deletions src/jsx/import/content/login.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import React from 'react';
import { Redirect } from 'react-router-dom';
import Spinner from '../general/spinner.jsx';
import { setLayout } from '../redux/action/page.jsx';
import { setLayout, setSpinner } from '../redux/action/page.jsx';
import setLoginState from '../redux/action/login.jsx';
import ajaxCaller from '../general/ajax-caller.js';

Expand Down Expand Up @@ -136,8 +136,10 @@ var LoginForm = React.createClass({
},
componentWillMount: function() {
// update redux store
const action = setLayout({'layout': 'login'});
this.props.dispatchLayout(action);
this.props.dispatchLayout(setLayout({'layout': 'login'}));
},
componentDidMount: function() {
this.props.dispatchSpinner(setSpinner({'spinner': false}));
},
// triggered when 'state properties' change
render: function() {
Expand Down
68 changes: 29 additions & 39 deletions src/jsx/import/content/register.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@

import React from 'react';
import { Redirect } from 'react-router-dom';
import Spinner from '../general/spinner.jsx';
import { setLayout } from '../redux/action/page.jsx';
import { setLayout, setSpinner } from '../redux/action/page.jsx';
import setLoginState from '../redux/action/login.jsx';
import ajaxCaller from '../general/ajax-caller.js';
import checkValidString from '../validator/valid-string.js';
Expand All @@ -21,9 +20,7 @@ var RegisterForm = React.createClass({
// initial 'state properties'
getInitialState: function() {
return {
redirect_path: '/',
ajax_done_result: null,
display_spinner: false,
validated_username: true,
validated_email: true,
validated_password: true,
Expand All @@ -35,32 +32,25 @@ var RegisterForm = React.createClass({
value_password: '',
};
},
// callback: used to return spinner
getSpinner: function() {
if (this.state.display_spinner) {
return Spinner;
} else {
return 'span';
}
},
// send form data to serverside on form submission
handleSubmit: function(event) {
// prevent page reload
event.preventDefault();

// display spinner
const action = setSpinner({'spinner': true})
this.props.dispatchSpinner(action);

// local variables
var ajaxEndpoint = '/register';
var ajaxArguments = {
'endpoint': ajaxEndpoint,
'data': new FormData(this.refs.registerForm)
};

// boolean to show ajax spinner
this.setState({display_spinner: true});

// asynchronous callback: ajax 'done' promise
ajaxCaller(function (asynchObject) {
// Append to DOM
// Append to DOM
if (asynchObject && asynchObject.error) {
this.setState({ajax_done_error: asynchObject.error});
}
Expand All @@ -72,6 +62,9 @@ var RegisterForm = React.createClass({
// backend validation: server handles one error at a time
if (!!status || status == 0) {
switch(status) {
case 0:
this.setState({ajax_done_result: result});
break;
case 1:
this.setState({validated_password_server: false});
break;
Expand All @@ -81,21 +74,9 @@ var RegisterForm = React.createClass({
case 3:
this.setState({validated_email_server: false});
break;
default:
this.setState({validated_password_server: true});
this.setState({validated_username_server: true});
this.setState({validated_email_server: true});
break;
}
}

// return server response
this.setState({ajax_done_result: result});
} else {
this.setState({ajax_done_result: null});
}
// boolean to hide ajax spinner
this.setState({display_spinner: false});
}.bind(this),
// asynchronous callback: ajax 'fail' promise
function (asynchStatus, asynchError) {
Expand All @@ -107,8 +88,6 @@ var RegisterForm = React.createClass({
this.setState({ajax_fail_error: asynchError});
console.log('Error Thrown: ' + asynchError);
}
// boolean to hide ajax spinner
this.setState({display_spinner: false});
}.bind(this),
// pass ajax arguments
ajaxArguments);
Expand All @@ -121,6 +100,10 @@ var RegisterForm = React.createClass({
validateUsername: function(event) {
const username = event.target.value;
const check = checkValidString(username) ? true : false;
if (!check) {
const action = setSpinner({'spinner': false})
this.props.dispatchSpinner(action);
}

this.setState({validated_username_server: true});
this.setState({validated_username: check});
Expand All @@ -129,6 +112,10 @@ var RegisterForm = React.createClass({
validateEmail: function(event) {
const email = event.target.value;
const check = checkValidEmail(email) ? true : false;
if (!check) {
const action = setSpinner({'spinner': false})
this.props.dispatchSpinner(action);
}

this.setState({validated_email_server: true});
this.setState({validated_email: check});
Expand All @@ -137,17 +124,17 @@ var RegisterForm = React.createClass({
validatePassword: function(event) {
const password = event.target.value;
const check = checkValidPassword(password) ? true : false;
if (!check) {
const action = setSpinner({'spinner': false})
this.props.dispatchSpinner(action);
}

this.setState({validated_password_server: true});
this.setState({validated_password: check});
this.setState({value_password: password});
},
// triggered when 'state properties' change
render: function() {
// local variables
var redirect = null;
var AjaxSpinner = this.getSpinner();

// frontend validation
var usernameClass = this.state.validated_username ? '' : 'invalid';
var passwordClass = this.state.validated_password ? '' : 'invalid';
Expand Down Expand Up @@ -187,15 +174,19 @@ var RegisterForm = React.createClass({
var emailNote = null;
}

// conditionally render redirect
if (this.state.redirect_push) {
var redirect = <Redirect to={this.state.redirect_path} />;
if (
this.state.ajax_done_result &&
this.state.ajax_done_result.status == '0'
) {
var redirect = <Redirect to='/login' />;
}
else {
var redirect = null;
}

return(
<form onSubmit={this.handleSubmit} ref='registerForm'>
{redirect}

<div className='form-group'>
<label className={'form-label ' + usernameClass}>Username</label>
<input
Expand Down Expand Up @@ -249,7 +240,6 @@ var RegisterForm = React.createClass({
className='btn btn-primary'
value='Create an account'
/>
<AjaxSpinner />
</form>
);
}
Expand Down
15 changes: 14 additions & 1 deletion src/jsx/import/layout/page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,26 @@ import { Provider } from 'react-redux';
import { Route } from 'react-router-dom';
import LoginLayout from './login.jsx';
import RegisterLayout from './register.jsx';
import Spinner from '../general/spinner.jsx';
import HomePageState from '../redux/container/home-page.jsx';
import UserMenuState from '../redux/container/user-menu.jsx';
import HeaderMenuState from '../redux/container/header-menu.jsx';
import AnalysisLayoutState from '../redux/container/analysis-layout.jsx';

var PageLayout = React.createClass({
// callback: used to return spinner
getSpinner: function() {
if (this.props && this.props.effects && this.props.effects.spinner) {
return <Spinner />;
} else {
return null;
}
},
render: function() {
// validate username
// local variables
var spinner = this.getSpinner();

// validate username
if (
this.props &&
this.props.user &&
Expand All @@ -46,6 +58,7 @@ var PageLayout = React.createClass({
<Route path='/session' component={AnalysisLayoutState} />
</div>
<Route exact path='/' component={HomePageState} />
{spinner}
</div>
);
}
Expand Down
16 changes: 15 additions & 1 deletion src/jsx/import/redux/action/page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,19 @@ function setContentType(action) {
};
}

function setSpinner(action) {
return {
type: 'SET-SPINNER',
spinner: action.spinner
};
}

// indicate which class can be exported, and instantiated via 'require'
export { setSvButton, setGotoResultsButton, setLayout, setContentType, setResultsButton }
export {
setSvButton,
setGotoResultsButton,
setLayout,
setContentType,
setResultsButton,
setSpinner
}
5 changes: 3 additions & 2 deletions src/jsx/import/redux/container/login.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import React from 'react';
import { connect } from 'react-redux';
import LoginForm from '../../content/login.jsx';
import setLoginState from '../action/login.jsx';
import { setLayout } from '../action/page.jsx';
import { setLayout, setSpinner } from '../action/page.jsx';

// transforms redux state tree to react properties
const mapStateToProps = (state) => {
Expand All @@ -36,7 +36,8 @@ const mapStateToProps = (state) => {
const mapDispatchToProps = (dispatch) => {
return {
dispatchLogin: dispatch.bind(setLoginState),
dispatchLayout: dispatch.bind(setLayout)
dispatchLayout: dispatch.bind(setLayout),
dispatchSpinner: dispatch.bind(setSpinner)
}
}

Expand Down
15 changes: 15 additions & 0 deletions src/jsx/import/redux/container/page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,25 @@ const mapStateToProps = (state) => {
var username = 'anonymous'
}

// fetch spinner
if (
state &&
state.page &&
state.page.effects &&
state.page.effects.spinner
) {
var spinnerBool = true;
} else {
var spinnerBool = false;
}

// return redux to state
return {
user: {
name: username
},
effects: {
spinner: spinnerBool
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/jsx/import/redux/container/register.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import React from 'react';
import { connect } from 'react-redux';
import RegisterForm from '../../content/register.jsx';
import { setLayout } from '../action/page.jsx';
import { setLayout, setSpinner } from '../action/page.jsx';

// transforms redux state tree to react properties
const mapStateToProps = (state) => {
Expand All @@ -34,7 +34,8 @@ const mapStateToProps = (state) => {
// wraps each function of the object to be dispatch callable
const mapDispatchToProps = (dispatch) => {
return {
dispatchLayout: dispatch.bind(setLayout)
dispatchLayout: dispatch.bind(setLayout),
dispatchSpinner: dispatch.bind(setSpinner)
}
}

Expand Down
11 changes: 11 additions & 0 deletions src/jsx/import/redux/reducer/page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
const page = (state='default', action) => {
var submitButtonAnalysis = false;
var gotoResults = false;
var spinner = false;

// assign elements from action
switch(action.type) {
Expand Down Expand Up @@ -54,6 +55,16 @@ const page = (state='default', action) => {
...state,
content_type: contentType
}
case 'SET-SPINNER':
var spinnerBool = action.spinner;

return {
...state,
effects: {
...state.effects,
spinner: spinnerBool
}
}
default:
return state;
}
Expand Down

0 comments on commit bc1744a

Please sign in to comment.