AugurProject/augur-ui

View on GitHub
src/modules/trading/components/trading--confirm/trading--confirm.jsx

Summary

Maintainability
D
1 day
Test Coverage
import React from "react";
import PropTypes from "prop-types";

import ValueDenomination from "modules/common/components/value-denomination/value-denomination";
import classNames from "classnames";
import { CATEGORICAL } from "modules/markets/constants/market-types";
import { MARKET, BUY, LIMIT, SELL } from "modules/transactions/constants/types";
import {
  CUTOFF_READABLE,
  CUTOFF_URL
} from "modules/markets/constants/cutoff-date";
import { isPastV2Cutoff } from "modules/markets/helpers/is-market-past-v2-cutoff";
import ReactTooltip from "react-tooltip";
import TooltipStyles from "modules/common/less/tooltip.styles";
import { CreateMarketEdit, Hint } from "modules/common/components/icons";
import Styles from "modules/trading/components/trading--confirm/trading--confirm.styles";

const MarketTradingConfirm = ({
  trade,
  isMobile,
  orderType,
  selectedNav,
  prevPage,
  market,
  selectedOutcome,
  doNotCreateOrders,
  showOrderPlaced,
  marketQuantity,
  handleFilledOnly,
  marketReviewModal,
  marketCutoffModal,
  marketReviewSeen,
  closeModal
}) => {
  const {
    numShares,
    limitPrice,
    tradingFees,
    potentialEthProfit,
    potentialProfitPercent,
    potentialEthLoss,
    potentialLossPercent,
    totalCost,
    shareCost
  } = trade;
  const negativeProfit = potentialEthProfit && potentialEthProfit.value <= 0;

  const placeTrade = e => {
    market.onSubmitPlaceTrade(
      selectedOutcome.id,
      (err, tradeGroupID) => {
        // onSent/onFailed CB
        if (!err) {
          showOrderPlaced();
        }
      },
      res => {
        if (doNotCreateOrders && res.res !== res.sharesToFill)
          handleFilledOnly(res.tradeInProgress);
        // onComplete CB
      },
      doNotCreateOrders
    );
    prevPage(e, true);
  };

  const showMarketCutoffModal = () => {
    marketCutoffModal({
      title: "Market notice",
      description: [
        "ETH staked on this market is at risk. <font color='#EB5757'>Users are advised <strong>not to trade.</strong></font>",
        `This market expires after the end-time cutoff date for the Augur v2 release phase. Markets ending after ${CUTOFF_READABLE} are at a higher risk of resolving incorrectly.`,
        `<a href=${CUTOFF_URL} rel="noopener noreferrer" target="_blank"><u>Read more about the V2 launch plan and how it may affect you</u></a>`
      ],
      cancelButtonText: "Cancel",
      submitAction: () => {
        placeTrade();
        closeModal();
      },
      submitButtonText: "Proceed Anyway"
    });
  };

  return (
    <section className={Styles.TradingConfirm}>
      <div className={Styles.TradingConfirm__header}>
        {!isMobile && (
          <div
            className={
              selectedNav === BUY
                ? Styles.TradingConfirm_arrow_buy
                : Styles.TradingConfirm_arrow_sell
            }
          />
        )}
        {!isMobile && <h2>Confirm {selectedNav} order?</h2>}
        {isMobile && (
          <h2
            className={classNames({
              [`${Styles.order__buy}`]: selectedNav === BUY,
              [`${Styles.order__sell}`]: selectedNav === SELL
            })}
          >
            Confirm {selectedNav} order?
          </h2>
        )}
        <span>
          <button onClick={prevPage}>{CreateMarketEdit}</button>
        </span>
      </div>
      <ul className={Styles.TradingConfirm__details}>
        {!isMobile &&
          market.marketType === CATEGORICAL && (
            <li>
              <span>Outcome</span>
              <span>{selectedOutcome.name}</span>
            </li>
          )}
        {orderType === MARKET && (
          <li>
            <span>Total Cost</span>
            <span>
              <ValueDenomination
                formatted={totalCost ? totalCost.formatted : "0"}
              />{" "}
              ETH
            </span>
          </li>
        )}
        {orderType === LIMIT && (
          <li>
            <span>Quantity</span>
            <span>{numShares} Shares</span>
          </li>
        )}
        {orderType === LIMIT && (
          <li>
            <span>Limit Price</span>
            <span>{limitPrice} ETH</span>
          </li>
        )}
        <li>
          <span className={Styles.TradingConfirm__FeeLabel}>Est. Fee</span>
          <span className={Styles.TradingConfirm__TooltipContainer}>
            <label
              className={classNames(
                TooltipStyles.TooltipHint,
                Styles.TradingConfirm__TooltipHint
              )}
              data-tip
              data-for="tooltip--fee"
            >
              {Hint}
            </label>
            <ReactTooltip
              id="tooltip--fee"
              className={TooltipStyles.Tooltip}
              effect="solid"
              place="bottom"
              type="light"
            >
              <p>
                The reporting fee adjusts every week, which may cause the
                market‘s total fee to go up or down.
              </p>
              <a
                href="http://docs.augur.net/#reporting-fee"
                rel="noopener noreferrer"
                target="_blank"
              >
                {" "}
                Learn more here.
              </a>
            </ReactTooltip>
          </span>
          <span>
            {tradingFees ? tradingFees.formattedValue : "0"} <span>ETH</span>
          </span>
        </li>
      </ul>
      {orderType === LIMIT && (
        <ul className={Styles.TradingConfirm__total}>
          <li>
            <span>Est. Cost</span>
          </li>
          <li>
            <span>
              <ValueDenomination
                formatted={totalCost ? totalCost.fullPrecision : "0"}
              />{" "}
              <span>ETH</span>
            </span>
            <span>
              <ValueDenomination
                formatted={shareCost ? shareCost.fullPrecision : "0"}
              />{" "}
              <span>Shares</span>
            </span>
          </li>
        </ul>
      )}
      {orderType === MARKET && (
        <ul className={Styles.TradingConfirm__total}>
          <li>
            <span>Quantity</span>
            <span>{marketQuantity}</span>
          </li>
        </ul>
      )}
      <ul className={Styles.TradingConfirm__potential}>
        <li>
          <span>Potential Profit</span>
          <span
            className={classNames({
              [`${Styles.negative__profit}`]: negativeProfit
            })}
          >
            <ValueDenomination
              formatted={
                potentialEthProfit
                  ? potentialEthProfit.formattedValue.toString()
                  : "0"
              }
            />{" "}
            <span
              className={classNames({
                [`${Styles.negative__profit}`]: negativeProfit
              })}
            >
              ETH (
              {potentialProfitPercent ? potentialProfitPercent.formatted : "0"}
              %)
            </span>
          </span>
        </li>
        <li>
          <span>Potential Loss</span>
          <span>
            <span>
              <ValueDenomination
                formatted={
                  potentialEthLoss
                    ? potentialEthLoss.formattedValue.toString()
                    : "0"
                }
              />{" "}
              <span>
                ETH (
                {potentialLossPercent ? potentialLossPercent.formatted : "0"}
                %)
              </span>
            </span>
          </span>
        </li>
      </ul>
      <div className={Styles.TradingConfirmation__actions}>
        <button
          className={Styles["TradingConfirmation__button--back"]}
          onClick={prevPage}
        >
          Back
        </button>
        <button
          className={Styles["TradingConfirmation__button--submit"]}
          onClick={e => {
            e.preventDefault();
            if (isPastV2Cutoff(market.endTime.timestamp)) {
              showMarketCutoffModal();
            } else if (!marketReviewSeen) {
              marketReviewModal({
                marketId: market.id,
                cb: () => {
                  closeModal();
                  placeTrade(e);
                }
              });
            } else {
              placeTrade(e);
            }
          }}
        >
          Confirm {selectedNav}
        </button>
      </div>
    </section>
  );
};

MarketTradingConfirm.propTypes = {
  market: PropTypes.object.isRequired,
  marketReviewSeen: PropTypes.bool.isRequired,
  selectedNav: PropTypes.string.isRequired,
  orderType: PropTypes.string.isRequired,
  marketQuantity: PropTypes.string.isRequired,
  doNotCreateOrders: PropTypes.bool.isRequired,
  selectedOutcome: PropTypes.object.isRequired,
  prevPage: PropTypes.func.isRequired,
  trade: PropTypes.shape({
    numShares: PropTypes.string,
    limitPrice: PropTypes.string,
    tradingFees: PropTypes.object,
    potentialEthProfit: PropTypes.object,
    potentialProfitPercent: PropTypes.object,
    potentialEthLoss: PropTypes.object,
    potentialLossPercent: PropTypes.object,
    totalCost: PropTypes.object,
    shareCost: PropTypes.object
  }).isRequired,
  isMobile: PropTypes.bool.isRequired,
  showOrderPlaced: PropTypes.func.isRequired,
  handleFilledOnly: PropTypes.func.isRequired,
  marketReviewModal: PropTypes.func.isRequired,
  marketCutoffModal: PropTypes.func.isRequired,
  closeModal: PropTypes.func.isRequired
};

export default MarketTradingConfirm;