GladysProject/Gladys

View on GitHub
front/src/routes/signup-gateway/index.js

Summary

Maintainability
A
1 hr
Test Coverage
import { Component } from 'preact';
import { connect } from 'unistore/preact';
import linkState from 'linkstate';
import SignupForm from './SignupForm';
import SignupBase from './SignupBase';
import SignupGeneratingKeys from './SignupGeneratingKeys';

const ACCEPTED_LANGUAGES = ['en', 'fr'];
const DEFAULT_LANGUAGE = 'en';

class SignupPage extends Component {
  state = {
    name: '',
    email: '',
    password: '',
    fieldsErrored: [],
    currentStep: 1,
    accountAlreadyExist: false,
    signupCompleted: false,
    unknownError: false,
    tokenError: false,
    browserCompatible: window.crypto && window.crypto.subtle
  };

  validateEmail = email => {
    let re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; // eslint-disable-line
    return re.test(String(email).toLowerCase());
  };

  validateData = data => {
    let fieldsErrored = [];

    if (!data.name || data.name.length < 2 || data.name.length > 30) {
      fieldsErrored.push('name');
    }

    if (!data.email || !this.validateEmail(data.email)) {
      fieldsErrored.push('email');
    }

    if (!data.password || data.password.length < 8) {
      fieldsErrored.push('password');
    }

    return fieldsErrored;
  };

  validateForm = event => {
    event.preventDefault();

    this.setState({ currentStep: 2 });

    let currentBrowserLanguage = (navigator.language || navigator.userLanguage).toLowerCase().substr(0, 2);

    if (!ACCEPTED_LANGUAGES.includes(currentBrowserLanguage)) {
      currentBrowserLanguage = DEFAULT_LANGUAGE;
    }

    let newUser = {
      name: this.state.name,
      email: this.state.email,
      password: this.state.password,
      language: currentBrowserLanguage
    };

    let fieldsErrored = this.validateData(newUser);

    if (fieldsErrored.length > 0) {
      this.setState({ fieldsErrored, currentStep: 1 });
      return;
    }

    if (!this.props.token) {
      return this.setState({ tokenError: true, currentStep: 1 });
    }

    this.props.session.gatewayClient
      .signup(newUser.name, newUser.email, newUser.password, newUser.language, this.props.token)
      .then(() => {
        setTimeout(() => {
          this.setState({
            fieldsErrored: [],
            currentStep: 2,
            accountAlreadyExist: false,
            unknownError: false,
            tokenError: false,
            signupCompleted: true
          });
        }, 1000);
      })
      .catch(error => {
        this.setState({ currentStep: 1 });
        if (error.response && error.response.status === 422 && error.response.data.details) {
          let fieldsErrored = [];
          error.response.data.details.forEach(err => {
            fieldsErrored.push(err.context.key);
          });
          this.setState({ fieldsErrored });
        } else if (error.response && error.response.status === 409) {
          this.setState({ accountAlreadyExist: true });
        } else {
          console.error(error);
          this.setState({ unknownError: true });
        }
      });
  };

  componentDidMount = () => {
    if (this.props.token) {
      this.props.session.gatewayClient
        .getInvitation(this.props.token)
        .then(invitation => this.setState({ email: invitation.email }))
        .catch(() => this.setState({ invitationError: true }));
    }
  };

  render(
    {},
    {
      name,
      email,
      password,
      fieldsErrored,
      currentStep,
      accountAlreadyExist,
      signupCompleted,
      browserCompatible,
      invitationError,
      isFireFox,
      unknownError,
      tokenError
    }
  ) {
    return (
      <SignupBase currentStep={currentStep}>
        {currentStep === 1 && (
          <SignupForm
            name={name}
            email={email}
            password={password}
            accountAlreadyExist={accountAlreadyExist}
            fieldsErrored={fieldsErrored}
            updateName={linkState(this, 'name')}
            updateEmail={linkState(this, 'email')}
            updatePassword={linkState(this, 'password')}
            validateForm={this.validateForm}
            signupCompleted={signupCompleted}
            browserCompatible={browserCompatible}
            token={this.props.token}
            invitationError={invitationError}
            isFireFox={isFireFox}
            unknownError={unknownError}
            tokenError={tokenError}
          />
        )}
        {currentStep === 2 && <SignupGeneratingKeys signupCompleted={signupCompleted} token={this.props.token} />}
      </SignupBase>
    );
  }
}

export default connect('session', {})(SignupPage);