text: import React, { Component } from 'react';
  import { connect } from 'react-redux';
  
  import Aux from '../../hoc/Aux/Aux';
  import Burger from '../../components/Burger/Burger';
  import BuildControls from '../../components/Burger/BuildControls/BuildControls';
  import Modal from '../../components/UI/Modal/Modal';
  import OrderSummary from '../../components/Burger/OrderSummary/OrderSummary';
  import Spinner from '../../components/UI/Spinner/Spinner';
  import withErrorHandler from '../../hoc/withErrorHandler/withErrorHandler';
  import axios from '../../axios-order';
  import * as burgerBuilderActions from '../../store/actions/index';
  
  /**
   * @class BurgerBuilder
   * 
   * This class manges the ingredients of the burger, and controls the price as well as add & remove button,
   * also provide order function.
   * 
   * Adding export for testing
   */
  export class BurgerBuilder extends Component {
  
      state = {
          purchaseable: false,
          purchasing: false,
          loading: false,
      }
  
      /**
       * @function updatePurchaseState
       * @param ingredients updated ingredients after added or removed
       * 
       * Sum the total ingredients and decide weather the burger is purchaseable
       */
      updatePurchaseState = (ingredients) => {
          const sum = Object.keys(ingredients).map(igKey => {
              return ingredients[igKey]
          }).reduce((sum, el) => {
              return sum + el;
          }, 0);
          return sum > 0;
      }
  
      /**
      * 
      * get ingredients from database manged by redux
      */
      componentDidMount() {
          this.props.onInitIngredients();
      }
  
      /**
       * This method will be passed into BuildControls.js, when the order button click, the method will be executed
       * and the Modal will be popup. If purchasing is false, the Modal will disappear.
       */
      purchaseHandler = () => {
          // if user not login, it will redirect to auth, and the path will be set to /checkout, which means 
          // once user login or register, the path will be changed to checkout instead of root
          if (this.props.isAuthenticated) {
              this.setState({ purchasing: true });
          } else {
              this.props.onSetAuthRedirectPath('/checkout');
              this.props.history.push('/auth');
          }
          
      }
  
      purchaseCancelHandler = () => {
          this.setState({ purchasing: false });
      }
  
      purchaseContinueHandler = () => {
          this.props.onPurchaseInit();
          this.props.history.push('/checkout');
      }
  
      render() {
          // check whether the ingredient is 0, if 0 save fase and send to buildControl component to disable the button
          const disableInfo = { ...this.props.ings };
          for (let key in disableInfo) {
              disableInfo[key] = disableInfo[key] <= 0;
          }
  
          let orderSummary = null;
  
  
          let burger = <Spinner />;
          if (this.props.ings) {
              burger = (
                  <Aux>
                      <Burger ingredients={this.props.ings} />
                      <BuildControls
                          ingredientAdded={this.props.onIngredientAdded}
                          ingredientRemoved={this.props.onIngredientRemoved}
                          disabled={disableInfo}
                          price={this.props.price}
                          purchaseable={this.updatePurchaseState(this.props.ings)}
                          isAuth={this.props.isAuthenticated}
                          ordered={this.purchaseHandler} />
                  </Aux>
              );
              orderSummary = <OrderSummary
                  ingredients={this.props.ings}
                  purchaseCanceled={this.purchaseCancelHandler}
                  purchaseContinued={this.purchaseContinueHandler}
                  price={this.props.price} />;
          }
          if (this.state.loading) {
              orderSummary = <Spinner />;
          }
  
          return (
              <Aux>
                  <Modal show={this.state.purchasing} modalColsed={this.purchaseCancelHandler} >
                      {orderSummary}
                  </Modal>
                  {burger}
              </Aux>
          );
      }
  }
  
  // map the redux global state to local state
  const mapStateToProps = state => {
      return {
          ings: state.burgerBuilder.ingredients,
          price: state.burgerBuilder.totalPrice,
          error: state.burgerBuilder.error,
          isAuthenticated: state.auth.token,
      }
  }
  
  // map redux dispatch so that can be access by props
  const mapDispatchToProps = (dispatch) => {
      return {
          onIngredientAdded: (ingName) => dispatch(burgerBuilderActions.addIngredient(ingName)),
          onIngredientRemoved: (ingName) => dispatch(burgerBuilderActions.removeIngredient(ingName)),
          onInitIngredients:() => dispatch(burgerBuilderActions.initIngredients()),
          onPurchaseInit: () => dispatch(burgerBuilderActions.purchaseInit()),
          onSetAuthRedirectPath: (path) => dispatch(burgerBuilderActions.setAuthRedirectPath(path)),
      }
  }
  
  export default connect(mapStateToProps, mapDispatchToProps)(withErrorHandler(BurgerBuilder, axios));