text: import React, { Component } from 'react';
  import { connect } from 'react-redux';
  import { Redirect } from 'react-router-dom';
  
  import Input from '../../components/UI/Input/Input';
  import Button from '../../components/UI/Button/Button';
  import Spinner from '../../components/UI/Spinner/Spinner';
  import classes from './Auth.css';
  import * as actions from '../../store/actions/index';
  import { updateObject, checkValidity } from '../../shared/utility';
  
  /**
   * @class Auth
   * 
   * Login
   */
  class Auth extends Component {
      state = {
          controls: {
              email: {
                  elementType: 'input',
                  elementConfig: {
                      type: 'email',
                      placeholder: 'Mail Address'
                  },
                  value: '',
                  validation: {
                      required: true,
                      isEmail: true
                  },
                  valid: false,
                  touched: false,
              },
              password: {
                  elementType: 'input',
                  elementConfig: {
                      type: 'password',
                      placeholder: 'Password'
                  },
                  value: '',
                  validation: {
                      required: true,
                      minLength: 6
                  },
                  valid: false,
                  touched: false,
              },
          },
          isSignup: true,
      };
  
      // check whether user has built the burger (reducer/burgerBuilder.js) 
      // and redirect path (reducer/authRedirectPath.js) is root, if both not 
      // which means the user hasn't build the burger, then set the path to root.
      componentDidMount() {
          if (!this.props.buildingBurger && this.props.authRedirectPath !== '/') {
              this.props.onSetAuthRedirectPath();
          }
      }
  
      // Listener for all input, and update the state
      inputChangedHandler = (event, controlName) => {
  
          // update nested object
          const updatedControls = updateObject(this.state.controls, {
              [controlName]:
                  updateObject(this.state.controls[controlName], {
                      value: event.target.value,
                      valid: checkValidity(event.target.value, this.state.controls[controlName].validation),
                      touched: true
                  })
          });
          this.setState({ controls: updatedControls });
      }
  
      submitHandler = (event) => {
          // avoid default submit
          event.preventDefault();
          this.props.onAuth(this.state.controls.email.value, this.state.controls.password.value, this.state.isSignup);
      }
  
      // Switch between sign or login
      switchAuthModeHandler = () => {
          this.setState(preState => {
              return { isSignup: !preState.isSignup }
          })
      }
  
      render() {
          const formElementsArray = [];
          for (let key in this.state.controls) {
              formElementsArray.push({
                  id: key,
                  config: this.state.controls[key]
              });
          }
  
          let form = formElementsArray.map(formElement => (
              <Input
                  key={formElement.id}
                  elementType={formElement.config.elementType}
                  changed={(event) => this.inputChangedHandler(event, formElement.id)}
                  elementConfig={formElement.config.elementConfig}
                  value={formElement.config.value}
                  invalid={!formElement.config.valid}
                  touched={formElement.config.touched}
                  shouldValidate={formElement.config.validation} />
  
          ));
  
          // Before we get the message from server, the form will change to spinner
          if (this.props.loading) {
              form = <Spinner />
          }
  
          // If the server sends back error message, showing as the Modal
          let errorMessage = null;
          if (this.props.error) {
              errorMessage = (
                  <p>{this.props.error.message}</p>
              )
          }
  
          /**
           * If the user successed login, then redirect to either /root or /checkout, 
           * based on the whether user has built the burger
           */
          let authRedirect = null;
          if (this.props.isAuthenticated) {
              authRedirect = <Redirect to={this.props.authRedirectPath} />
          }
  
          return (
              <div className={classes.Auth}>
                  {authRedirect}
                  {errorMessage}
                  <h2>{this.state.isSignup ? 'Register' : 'Login'}</h2>
                  <form onSubmit={this.submitHandler}>
                      {form}
                      <Button btnType="Success">Submit</Button>
                  </form>
                  <Button btnType="Danger" clicked={this.switchAuthModeHandler}>Switch to {this.state.isSignup ? 'Login' : 'Sign Up'}</Button>
              </div>
          );
      }
  }
  
  const mapStateToProps = (state) => {
      return {
          loading: state.auth.loading,
          error: state.auth.error,
          isAuthenticated: state.auth.token !== null,
          buildingBurger: state.burgerBuilder.building,
          authRedirectPath: state.auth.authRedirectPath
      }
  }
  
  const mapDispatchToProps = (dispatch) => {
      return {
          onAuth: (email, password, isSignup) => dispatch(actions.auth(email, password, isSignup)),
          onSetAuthRedirectPath: () => dispatch(actions.setAuthRedirectPath('/')),
      }
  }
  
  export default connect(mapStateToProps, mapDispatchToProps)(Auth);