AugurProject/augur-ui

View on GitHub
src/modules/reporting/components/reporting-dispute/reporting-dispute.jsx

Summary

Maintainability
F
3 days
Test Coverage
import React, { Component } from "react";
import PropTypes from "prop-types";
import classNames from "classnames";
import { Helmet } from "react-helmet";

import speedomatic from "speedomatic";
import { createBigNumber } from "utils/create-big-number";
import { ZERO } from "modules/trades/constants/numbers";
import { formatGasCostToEther } from "utils/format-number";
import MarketPreview from "modules/market/containers/market-preview";
import NullStateMessage from "modules/common/components/null-state-message/null-state-message";
import ReportingDisputeForm from "modules/reporting/containers/reporting-dispute-form";
import ReportingDisputeConfirm from "modules/reporting/components/reporting-dispute-confirm/reporting-dispute-confirm";
import { TYPE_VIEW } from "modules/markets/constants/link-types";
import { isEmpty } from "lodash";
import FormStyles from "modules/common/less/form";
import Styles from "modules/reporting/components/reporting-report/reporting-report.styles";
import InvalidMessage from "modules/reporting/components/common/invalid-message";

export default class ReportingDispute extends Component {
  static propTypes = {
    history: PropTypes.object.isRequired,
    isConnected: PropTypes.bool.isRequired,
    isLogged: PropTypes.bool.isRequired,
    isMarketLoaded: PropTypes.bool.isRequired,
    loadFullMarket: PropTypes.func.isRequired,
    location: PropTypes.object.isRequired,
    market: PropTypes.object.isRequired,
    marketId: PropTypes.string.isRequired,
    submitMarketContribute: PropTypes.func.isRequired,
    universe: PropTypes.string.isRequired,
    availableRep: PropTypes.string.isRequired,
    gasPrice: PropTypes.number.isRequired
  };

  constructor(props) {
    super(props);

    this.state = {
      currentStep: 0,
      gasEstimate: "0",
      isMarketInValid: null,
      selectedOutcome: "",
      selectedOutcomeName: "",
      stakeInfo: { displayValue: 0, repValue: "0" },
      validations: {
        stake: false,
        selectedOutcome: null
      }
    };

    this.prevPage = this.prevPage.bind(this);
    this.nextPage = this.nextPage.bind(this);
    this.updateState = this.updateState.bind(this);
  }

  componentWillMount() {
    const { isConnected, isMarketLoaded, loadFullMarket } = this.props;
    if (isConnected && !isMarketLoaded) {
      loadFullMarket();
    }
  }

  componentWillReceiveProps(nextProps) {
    if (
      this.props.gasPrice !== nextProps.gasPrice &&
      this.state.currentStep === 1
    ) {
      this.calculateGasEstimates(nextProps.gasPrice);
    }
  }

  prevPage() {
    this.setState({
      currentStep: this.state.currentStep <= 0 ? 0 : this.state.currentStep - 1
    });
  }

  nextPage() {
    this.setState({
      currentStep: this.state.currentStep >= 1 ? 1 : this.state.currentStep + 1
    });
    this.calculateGasEstimates(this.props.gasPrice);
  }

  updateState(newState) {
    this.setState(newState);
  }

  calculateGasEstimates(gasPrice) {
    const { submitMarketContribute, market } = this.props;
    const { selectedOutcome, isMarketInValid, stakeInfo } = this.state;
    if (createBigNumber(stakeInfo.repValue).gt(ZERO)) {
      const amount = speedomatic.fix(stakeInfo.repValue, "hex");
      submitMarketContribute({
        estimateGas: true,
        marketId: market.id,
        selectedOutcome,
        invalid: isMarketInValid,
        amount,
        history: null,
        returnPath: null,
        callback: (err, gasEstimateValue) => {
          if (err) return console.error(err);

          this.setState({
            gasEstimate: formatGasCostToEther(
              gasEstimateValue,
              { decimalsRounded: 4 },
              gasPrice
            )
          });
        }
      });
    }
  }

  render() {
    const {
      history,
      isLogged,
      location,
      market,
      submitMarketContribute,
      availableRep
    } = this.props;
    const s = this.state;

    return (
      <section>
        <Helmet>
          <title>Submit Dispute</title>
        </Helmet>
        {!isEmpty(market) && (
          <MarketPreview
            {...market}
            isLogged={isLogged}
            location={location}
            history={history}
            cardStyle="single-card"
            linkType={TYPE_VIEW}
            buttonText="View"
            showAdditionalDetailsToggle
            showDisputeRound
            hideCutoff
          />
        )}
        {!isEmpty(market) && (
          <article className={FormStyles.Form}>
            {s.currentStep === 0 && (
              <div className={Styles.ReportingReport_form_message}>
                <div>
                  <InvalidMessage />
                  <ReportingDisputeForm
                    market={market}
                    updateState={this.updateState}
                    stakeInfo={s.stakeInfo}
                    availableRep={availableRep}
                  />
                  <InvalidMessage />
                </div>
              </div>
            )}
            {s.currentStep === 1 && (
              <ReportingDisputeConfirm
                isMarketInValid={s.isMarketInValid}
                selectedOutcome={s.selectedOutcomeName}
                stakeInfo={s.stakeInfo}
                gasEstimate={s.gasEstimate}
              />
            )}
            <div className={FormStyles.Form__navigation}>
              <button
                className={classNames(FormStyles.Form__prev, {
                  [`${FormStyles["hide-button"]}`]: s.currentStep === 0
                })}
                onClick={this.prevPage}
              >
                Previous
              </button>
              <button
                className={classNames(FormStyles.Form__next, {
                  [`${FormStyles["hide-button"]}`]: s.currentStep === 1
                })}
                disabled={
                  !Object.keys(s.validations).every(
                    key => s.validations[key] === true
                  )
                }
                onClick={
                  Object.keys(s.validations).every(
                    key => s.validations[key] === true
                  )
                    ? this.nextPage
                    : undefined
                }
              >
                Review
              </button>
              {s.currentStep === 1 && (
                <button
                  className={FormStyles.Form__submit}
                  onClick={() =>
                    submitMarketContribute({
                      estimateGas: false,
                      marketId: market.id,
                      selectedOutcome: s.selectedOutcome,
                      invalid: s.isMarketInValid,
                      amount: speedomatic.fix(s.stakeInfo.repValue, "hex"),
                      history
                    })
                  }
                >
                  Submit
                </button>
              )}
            </div>
          </article>
        )}
        {isEmpty(market) && (
          <div className={Styles.NullState}>
            <NullStateMessage
              message="Market not found"
              className={Styles.NullState}
            />
          </div>
        )}
      </section>
    );
  }
}