src/modules/trading/components/trading--wrapper/trading--wrapper.jsx
import React, { Component } from "react";
import PropTypes from "prop-types";
import classNames from "classnames";
import { Link } from "react-router-dom";
import { BigNumber, createBigNumber } from "utils/create-big-number";
import MarketTradingForm from "modules/trading/components/trading--form/trading--form";
import MarketTradingConfirm from "modules/trading/components/trading--confirm/trading--confirm";
import { Close } from "modules/common/components/icons";
import makePath from "modules/routes/helpers/make-path";
import ValueDenomination from "modules/common/components/value-denomination/value-denomination";
import getValue from "utils/get-value";
import { isEqual } from "lodash";
import { FindReact } from "utils/find-react";
import { BUY, SELL, LIMIT } from "modules/transactions/constants/types";
import { ACCOUNT_DEPOSIT } from "modules/routes/constants/views";
import MarketOutcomeTradingIndicator from "modules/market/containers/market-outcome-trading-indicator";
import Styles from "modules/trading/components/trading--wrapper/trading--wrapper.styles";
class MarketTradingWrapper extends Component {
static propTypes = {
market: PropTypes.object.isRequired,
marketReviewSeen: PropTypes.bool.isRequired,
marketReviewModal: PropTypes.func.isRequired,
marketCutoffModal: PropTypes.func.isRequired,
isLogged: PropTypes.bool.isRequired,
selectedOrderProperties: PropTypes.object.isRequired,
initialMessage: PropTypes.oneOfType([PropTypes.string, PropTypes.bool])
.isRequired,
availableFunds: PropTypes.instanceOf(BigNumber).isRequired,
isMobile: PropTypes.bool.isRequired,
toggleForm: PropTypes.func.isRequired,
showOrderPlaced: PropTypes.func.isRequired,
clearTradeInProgress: PropTypes.func.isRequired,
closeModal: PropTypes.func.isRequired,
selectedOutcome: PropTypes.object,
updateSelectedOrderProperties: PropTypes.func.isRequired,
handleFilledOnly: PropTypes.func.isRequired,
gasPrice: PropTypes.number.isRequired
};
static defaultProps = {
selectedOutcome: null
};
constructor(props) {
super(props);
this.state = {
orderType: LIMIT,
orderPrice: props.selectedOrderProperties.price || "",
orderQuantity: props.selectedOrderProperties.quantity || "",
orderEthEstimate: "0",
orderShareEstimate: "0",
marketOrderTotal: "",
marketQuantity: "",
selectedNav: props.selectedOrderProperties.selectedNav || BUY,
currentPage: 0,
doNotCreateOrders:
props.selectedOrderProperties.doNotCreateOrders || false
};
this.prevPage = this.prevPage.bind(this);
this.nextPage = this.nextPage.bind(this);
this.updateState = this.updateState.bind(this);
this.clearOrderForm = this.clearOrderForm.bind(this);
this.updateOrderEthEstimate = this.updateOrderEthEstimate.bind(this);
this.updateOrderShareEstimate = this.updateOrderShareEstimate.bind(this);
}
componentWillReceiveProps(nextProps) {
const { selectedOrderProperties } = this.props;
if (!nextProps.selectedOutcome || !nextProps.selectedOutcome.trade) {
this.setState({ currentPage: 0 });
return;
}
if (this.props.selectedOutcome === null) return this.clearOrderForm();
if (
this.props.selectedOutcome &&
this.props.selectedOutcome.name !== nextProps.selectedOutcome.name
) {
this.setState({ currentPage: 0 });
}
const nextTotalCost = createBigNumber(
nextProps.selectedOutcome.trade.totalCost.formattedValue,
10
);
const nextShareCost = createBigNumber(
nextProps.selectedOutcome.trade.shareCost.formattedValue,
10
);
// console.log('ests', nextTotalCost.toString(), nextShareCost.toString());
if (nextTotalCost.abs().toString() !== this.state.orderEthEstimate) {
this.setState({
orderEthEstimate: nextTotalCost.abs().toString()
});
}
if (nextShareCost !== this.state.orderShareEstimate) {
this.setState({
orderShareEstimate: nextShareCost.abs().toString()
});
}
// Updates from chart clicks
if (!isEqual(selectedOrderProperties, nextProps.selectedOrderProperties)) {
this.setState({ ...nextProps.selectedOrderProperties });
}
}
prevPage(e, orderSent = false) {
const newPage =
this.state.currentPage <= 0 ? 0 : this.state.currentPage - 1;
if (orderSent) {
this.setState({
currentPage: newPage,
orderPrice: "",
orderQuantity: "",
orderEthEstimate: "0",
orderShareEstimate: "0",
marketOrderTotal: "",
marketQuantity: "",
doNotCreateOrders: false
});
this.props.updateSelectedOrderProperties({
orderPrice: "",
orderQuantity: "",
doNotCreateOrders: false
});
} else {
this.setState({ currentPage: newPage });
}
}
nextPage() {
const newPage =
this.state.currentPage >= 1 ? 1 : this.state.currentPage + 1;
this.setState({ currentPage: newPage });
}
updateState(property, value) {
this.setState({ [property]: value }, () => {
this.props.updateSelectedOrderProperties({
orderPrice: this.state.orderPrice,
orderQuantity: this.state.orderQuantity,
doNotCreateOrders: this.state.doNotCreateOrders,
selectedNav: this.state.selectedNav
});
});
}
clearOrderForm() {
const { clearTradeInProgress, market } = this.props;
if (market.id) clearTradeInProgress(market.id);
this.setState({
orderPrice: "",
orderQuantity: "",
orderEthEstimate: "0",
orderShareEstimate: "0",
marketOrderTotal: "",
marketQuantity: "",
currentPage: 0,
doNotCreateOrders: false
});
}
updateOrderEthEstimate(orderEthEstimate) {
this.setState({
orderEthEstimate
});
}
updateOrderShareEstimate(orderShareEstimate) {
this.setState({
orderShareEstimate
});
}
render() {
const {
availableFunds,
initialMessage,
isLogged,
isMobile,
market,
selectedOutcome,
toggleForm,
showOrderPlaced,
gasPrice,
handleFilledOnly,
marketReviewModal,
marketCutoffModal,
marketReviewSeen,
closeModal
} = this.props;
const s = this.state;
const lastPrice = getValue(
this.props,
"selectedOutcome.lastPrice.formatted"
);
return (
<section className={Styles.TradingWrapper}>
{isMobile && (
<div className={Styles["TradingWrapper__mobile-header"]}>
<button
className={Styles["TradingWrapper__mobile-header-close"]}
onClick={toggleForm}
>
{Close}
</button>
<span className={Styles["TradingWrapper__mobile-header-outcome"]}>
{selectedOutcome.name}
</span>
<span className={Styles["TradingWrapper__mobile-header-last"]}>
<ValueDenomination formatted={lastPrice} />
<MarketOutcomeTradingIndicator
isMobile={isMobile}
outcome={selectedOutcome}
location="modileTradingForm"
/>
</span>
</div>
)}
{s.currentPage === 0 && (
<div>
<ul
className={
s.selectedNav === BUY
? Styles.TradingWrapper__header_buy
: Styles.TradingWrapper__header_sell
}
>
<li
className={classNames({
[`${Styles.active_buy}`]: s.selectedNav === BUY
})}
>
<button onClick={() => this.setState({ selectedNav: BUY })}>
Buy
</button>
</li>
<li
className={classNames({
[`${Styles.active_sell}`]: s.selectedNav === SELL
})}
>
<button onClick={() => this.setState({ selectedNav: SELL })}>
Sell
</button>
</li>
</ul>
{initialMessage && (
<p className={Styles["TradingWrapper__initial-message"]}>
{!isLogged ? (
<span>Signup or login to trade.</span>
) : (
initialMessage
)}
</p>
)}
{!isLogged && (
<button
id="login-button"
className={Styles["TradingWrapper__button--login"]}
onClick={() =>
FindReact(
document.getElementsByClassName(
"connect-account-styles_ConnectAccount"
)[0]
).toggleDropdown()
}
>
Sign in to trade
</button>
)}
{initialMessage &&
isLogged &&
availableFunds &&
availableFunds.lte(0) && (
<Link
className={Styles["TradingWrapper__button--add-funds"]}
to={makePath(ACCOUNT_DEPOSIT)}
>
Add Funds
</Link>
)}
{!initialMessage && (
<MarketTradingForm
market={market}
marketType={getValue(this.props, "market.marketType")}
maxPrice={getValue(this.props, "market.maxPrice")}
minPrice={getValue(this.props, "market.minPrice")}
availableFunds={availableFunds}
selectedNav={s.selectedNav}
orderType={s.orderType}
orderPrice={s.orderPrice}
orderQuantity={s.orderQuantity}
orderEthEstimate={s.orderEthEstimate}
orderShareEstimate={s.orderShareEstimate}
marketOrderTotal={s.marketOrderTotal}
marketQuantity={s.marketQuantity}
doNotCreateOrders={s.doNotCreateOrders}
selectedOutcome={selectedOutcome}
nextPage={this.nextPage}
updateState={this.updateState}
isMobile={isMobile}
gasPrice={gasPrice}
/>
)}
</div>
)}
{s.currentPage === 1 &&
selectedOutcome && (
<MarketTradingConfirm
market={market}
selectedNav={s.selectedNav}
orderType={s.orderType}
orderPrice={s.orderPrice}
orderQuantity={s.orderQuantity}
orderEthEstimate={s.orderEthEstimate}
marketOrderTotal={s.marketOrderTotal}
marketQuantity={s.marketQuantity}
doNotCreateOrders={s.doNotCreateOrders}
selectedOutcome={selectedOutcome}
prevPage={this.prevPage}
trade={selectedOutcome.trade}
isMobile={isMobile}
clearOrderForm={this.clearOrderForm}
showOrderPlaced={showOrderPlaced}
handleFilledOnly={handleFilledOnly}
marketReviewModal={marketReviewModal}
marketCutoffModal={marketCutoffModal}
closeModal={closeModal}
marketReviewSeen={marketReviewSeen}
/>
)}
</section>
);
}
}
export default MarketTradingWrapper;