Skip to content

Commit

Permalink
bug(errors): fix uniform display of error messages throughout the app…
Browse files Browse the repository at this point in the history
…lication

                    - fix double lines under profile inputs
                    - refactor signup view test
                    - add commmon styling
                    - add input display error helper function
                    - fix signup error message
                    - fix login input error messages
                    - fix missing inactive account error message
                    - fix reset password view error message
                    - fix confirm password view error message
                    - restructure confirm password view tests
                    - fix test coverage for Profile components
                    - fix missing Loader button on confirm and reset password
                    - add redirect to login page for successfull password reset

                    [Fixes #166562971]
  • Loading branch information
Siffersari committed Jun 12, 2019
1 parent 958fc27 commit de4d0c7
Show file tree
Hide file tree
Showing 22 changed files with 485 additions and 143 deletions.
3 changes: 3 additions & 0 deletions src/assets/styles/common.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.hidden {
display: none;
}
66 changes: 60 additions & 6 deletions src/components/auth/LoginForm.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { Button, Form, Spinner } from 'react-bootstrap';
import PropTypes from 'prop-types';
import SocialLogin from './Social';
import displayError from '../../helpers/inputerror';
import '../../assets/styles/login.scss';
import '../../assets/styles/common.scss';

/*
* LoginForm Component
*
*@return {jsx}
*/

class LoginForm extends Component {
render() {
const { onSubmit, onChange, email, password, isLoading } = this.props;
const {
onSubmit, onChange, error, email, password, isLoading,
} = this.props;

return (
<div className="sign-in-page">
<h1>Authors Haven</h1>
Expand All @@ -16,13 +28,41 @@ class LoginForm extends Component {
<Form.Group>
<Form.Label>Email</Form.Label>
<Form.Control
isInvalid={
!!(
(error && error.data && error.data.errors && error.data.errors.error)
|| (error && error.data && error.data.user)
)
}
placeholder="Enter email"
type="email"
id="email"
data-test="email1"
onChange={onChange}
required
/>
<Form.Control.Feedback id="email-error" type="invalid">
{error
&& error.data
&& error.data.errors
&& error.data.errors
&& error.data.errors.error[0]}
{error
&& error.data
&& error.data.errors
&& error.data.errors
&& error.data.errors.error
? displayError('email-error')
: ''}

{error
&& error.data
&& error.data.user
&& 'This user account is not active. Check your email for activation instructions.'}
{error && error.data && error.data.user && error.data.user.detail
? displayError('email-error')
: ''}
</Form.Control.Feedback>
</Form.Group>

<Form.Group>
Expand All @@ -44,8 +84,8 @@ class LoginForm extends Component {
id="login-btn"
block
disabled={
!email.match(/^[a-zA-z0-9_.]+@[a-zA-z0-9-]+\.[a-z]+$/) ||
!password.match(/^[a-zA-Z0-9]{8,}$/)
!email.match(/^[a-zA-z0-9_.]+@[a-zA-z0-9-]+\.[a-z]+$/)
|| !password.match(/^[a-zA-Z0-9]{8,}$/)
}
>
Login
Expand All @@ -65,9 +105,7 @@ class LoginForm extends Component {
)}
</Form>
<div className="forgot-password-link">
<Link to="/reset_password">
Forgot your password?
</Link>
<Link to="/reset_password">Forgot your password?</Link>
</div>
<div>
<div className="separator">
Expand All @@ -91,4 +129,20 @@ class LoginForm extends Component {
}
}

LoginForm.propTypes = {
onSubmit: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
error: PropTypes.shape({}),
email: PropTypes.string,
password: PropTypes.string,
isLoading: PropTypes.bool,
};

LoginForm.defaultProps = {
error: {},
email: '',
password: '',
isLoading: false,
};

export default LoginForm;
67 changes: 63 additions & 4 deletions src/components/auth/PasswordConfirmForm.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,89 @@
import React, { Component } from 'react';
import { Form, Button } from 'react-bootstrap';
import { Form, Button, Spinner } from 'react-bootstrap';
import { ToastContainer } from 'react-toastify';
import PropTypes from 'prop-types';

import displayError from '../../helpers/inputerror';
import '../../assets/styles/common.scss';

require('../../assets/styles/reset_password.css');
require('../../assets/styles/ReactToastify.css');

/*
* PasswordConfirmForm Component
*
*@return {jsx}
*/

export class PasswordConfirmForm extends Component {
render() {
const { onChange, handleConfirmPassword, onSubmit } = this.props;
const {
onChange,
error,
state: { isInvalid, confirmPassword },
handleConfirmPassword,
onSubmit,
isLoading,
} = this.props;

return (
<div className="box">
<Form onSubmit={onSubmit}>
<Form.Group>
<p id="error" />
<Form.Label>Enter new password:</Form.Label>
<Form.Control
isInvalid={!!(error && error.data && error.data)}
id="password"
type="password"
name="password"
placeholder="Enter password"
required
onChange={onChange}
/>
<Form.Control.Feedback id="password-error" type="invalid">
{error && error.data && error.data.user && error.data.user.error}
{error && error.data && error.data.user && error.data.user.error
? displayError('password-error')
: ''}

{error && error.data && error.data.errors
? 'Kindly resend password change request again'
: ''}

{error && error.data && error.data.errors ? displayError('password-error') : ''}
</Form.Control.Feedback>
<Form.Text className="text-muted">
Must be a strong password with alphanumeric characters.
</Form.Text>
<Form.Label>Confirm new password:</Form.Label>
<Form.Control
isInvalid={!!confirmPassword && isInvalid}
id="myDiv"
type="password"
name="passwordConfirm"
placeholder="Confirm password"
required
onChange={handleConfirmPassword}
/>
<Form.Control.Feedback id="confirm-error" type="invalid" />
</Form.Group>
<div className="col-md-12 text-center">
<Button variant="primary" type="submit" id="passButton">
Submit
<Button variant="primary" className="box-form-button" type="submit">
{isLoading ? (
<Spinner
as="span"
animation="border"
id="loading-btn"
size="sm"
role="status"
aria-hidden="true"
/>
) : (
''
)}

{isLoading ? 'Loading...' : 'Submit'}
</Button>
</div>
</Form>
Expand All @@ -47,4 +93,17 @@ export class PasswordConfirmForm extends Component {
}
}

PasswordConfirmForm.propTypes = {
onSubmit: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
handleConfirmPassword: PropTypes.func.isRequired,
error: PropTypes.shape({}),
state: PropTypes.shape({}),
};

PasswordConfirmForm.defaultProps = {
error: {},
state: { isInvalid: true, confirmPassword: '' },
};

export default PasswordConfirmForm;
46 changes: 43 additions & 3 deletions src/components/auth/ResetPasswordForm.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,60 @@
import React, { Component } from 'react';
import { Button, Form } from 'react-bootstrap';
import { Button, Form, Spinner } from 'react-bootstrap';
import { ToastContainer } from 'react-toastify';
import PropTypes from 'prop-types';

import displayError from '../../helpers/inputerror';
import '../../assets/styles/common.scss';

require('../../assets/styles/reset_password.css');

/*
* ResetPasswordForm Component
*
*@return {jsx}
*/

export class ResetPasswordForm extends Component {
render() {
const { onSubmit, onChange } = this.props;
const {
onSubmit, onChange, error, isLoading,
} = this.props;
return (
<div className="box">
<Form className="box-form" onSubmit={onSubmit}>
<Form.Group>
<p id="error" />
<Form.Label>Enter your email:</Form.Label>
<Form.Control
isInvalid={!!(error && error.data && error.data)}
id="email"
type="email"
name="email"
placeholder="Enter Email"
required
onChange={onChange}
/>
<Form.Control.Feedback id="email-error" type="invalid">
{error && error.data && error.data.message && 'User with this email not found.'}
{error && error.data && error.data.message ? displayError('email-error') : ''}
</Form.Control.Feedback>
</Form.Group>
<div className="col-md-12 text-center">
<Button variant="primary" className="box-form-button" type="submit">
Submit
{isLoading ? (
<Spinner
as="span"
animation="border"
id="loading-btn"
size="sm"
role="status"
aria-hidden="true"
/>
) : (
''
)}

{isLoading ? 'Loading...' : 'Submit'}
</Button>
</div>
</Form>
Expand All @@ -33,4 +63,14 @@ export class ResetPasswordForm extends Component {
);
}
}

ResetPasswordForm.propTypes = {
onSubmit: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
error: PropTypes.shape({}),
};

ResetPasswordForm.defaultProps = {
error: {},
};
export default ResetPasswordForm;
36 changes: 33 additions & 3 deletions src/components/auth/Signup.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,27 @@ import React, { Component } from 'react';
import { Form, Button, Spinner } from 'react-bootstrap';
import { Link } from 'react-router-dom';
import SocialLogin from './Social';
import displayError from '../../helpers/inputerror';
import '../../assets/styles/signup.scss';
import '../../assets/styles/social.scss';
import '../../assets/styles/common.scss';

/*
* SignupForm Component
*
*@return {jsx}
*/

class SignupForm extends Component {
render() {
const { onSubmit, onChange, error, handleConfirmPassword, isLoading, social } = this.props;
const {
onSubmit,
onChange,
error,
handleConfirmPassword,
isLoading,
state: { confirm_password: confirmPassword, isInvalid },
} = this.props;
return (
<div className="signup-page">
<h1>Authors Haven</h1>
Expand All @@ -25,8 +40,9 @@ class SignupForm extends Component {
onChange={onChange}
required
/>
<Form.Control.Feedback type="invalid">
<Form.Control.Feedback id="email-error" type="invalid">
{error.errors && error.errors.email && error.errors.email[0]}
{error.errors && error.errors.email ? displayError('email-error') : ''}
</Form.Control.Feedback>
</Form.Group>

Expand All @@ -40,8 +56,9 @@ class SignupForm extends Component {
onChange={onChange}
required
/>
<Form.Control.Feedback id="username-error" type="invalid">
<Form.Control.Feedback id="username-error" type="invalid" className="">
{error.errors && error.errors.username && error.errors.username[0]}
{error.errors && error.errors.username ? displayError('username-error') : ''}
</Form.Control.Feedback>
</Form.Group>

Expand All @@ -58,19 +75,22 @@ class SignupForm extends Component {
/>
<Form.Control.Feedback type="invalid">
{error.errors && error.errors.password && error.errors.password[0]}
{error.errors && error.errors.password ? displayError('username-error') : ''}
</Form.Control.Feedback>
</Form.Group>

<Form.Group>
<Form.Label>Confirm Password</Form.Label>
<Form.Control
isInvalid={!!confirmPassword && isInvalid}
type="password"
placeholder="Confirm password"
id="match"
onChange={handleConfirmPassword}
name="confirm_password"
required
/>
<Form.Control.Feedback id="confirm-error" type="invalid" className="" />
</Form.Group>

<div />
Expand Down Expand Up @@ -112,6 +132,16 @@ class SignupForm extends Component {
SignupForm.propTypes = {
onSubmit: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
handleConfirmPassword: PropTypes.func.isRequired,
error: PropTypes.shape({}),
state: PropTypes.shape({}),
isLoading: PropTypes.bool,
};

SignupForm.defaultProps = {
error: {},
state: { isInvalid: true, confirmPassword: '' },
isLoading: false,
};

export default SignupForm;
Loading

0 comments on commit de4d0c7

Please sign in to comment.