Commit d15a3cec authored by Kenny Tran's avatar Kenny Tran

Update summary to react to lastEditedField and add summary modal for all pages

parent 9d8c5330
<svg width="12" height="7" viewBox="0 0 12 7" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.4673 6L6.23364 1L0.999995 6" stroke="#388DFF"/>
</svg>
...@@ -2,11 +2,15 @@ import React, { Component } from 'react'; ...@@ -2,11 +2,15 @@ import React, { Component } from 'react';
import { drizzleConnect } from 'drizzle-react'; import { drizzleConnect } from 'drizzle-react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classnames from "classnames"; import classnames from "classnames";
import { CSSTransitionGroup } from "react-transition-group";
import CurrencyInputPanel from '../../components/CurrencyInputPanel'; import CurrencyInputPanel from '../../components/CurrencyInputPanel';
import OversizedPanel from '../../components/OversizedPanel'; import OversizedPanel from '../../components/OversizedPanel';
import NavigationTabs from '../../components/NavigationTabs'; import NavigationTabs from '../../components/NavigationTabs';
import Modal from '../../components/Modal';
import { selectors, sync } from '../../ducks/web3connect'; import { selectors, sync } from '../../ducks/web3connect';
import ArrowDown from '../../assets/images/arrow-down-blue.svg'; import ArrowDown from '../../assets/images/arrow-down-blue.svg';
import DropdownBlue from "../../assets/images/dropdown-blue.svg";
import DropupBlue from "../../assets/images/dropup-blue.svg";
import ModeSelector from './ModeSelector'; import ModeSelector from './ModeSelector';
import {BigNumber as BN} from 'bignumber.js'; import {BigNumber as BN} from 'bignumber.js';
import EXCHANGE_ABI from '../../abi/exchange'; import EXCHANGE_ABI from '../../abi/exchange';
...@@ -33,11 +37,12 @@ class AddLiquidity extends Component { ...@@ -33,11 +37,12 @@ class AddLiquidity extends Component {
inputCurrency: 'ETH', inputCurrency: 'ETH',
outputCurrency: '', outputCurrency: '',
lastEditedField: '', lastEditedField: '',
showSummaryModal: false,
}; };
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps, nextState) {
const { isConnected, account, exchangeAddresses, balances, web3 } = this.props; const { isConnected, account, exchangeAddresses, balances, web3 } = this.props;
const { inputValue, outputValue, inputCurrency, outputCurrency, lastEditedField } = this.state; const { inputValue, outputValue, inputCurrency, outputCurrency, lastEditedField, showSummaryModal } = this.state;
return isConnected !== nextProps.isConnected || return isConnected !== nextProps.isConnected ||
account !== nextProps.account || account !== nextProps.account ||
...@@ -48,7 +53,8 @@ class AddLiquidity extends Component { ...@@ -48,7 +53,8 @@ class AddLiquidity extends Component {
outputValue !== nextState.outputValue || outputValue !== nextState.outputValue ||
inputCurrency !== nextState.inputCurrency || inputCurrency !== nextState.inputCurrency ||
outputCurrency !== nextState.outputCurrency || outputCurrency !== nextState.outputCurrency ||
lastEditedField !== nextState.lastEditedField; lastEditedField !== nextState.lastEditedField ||
showSummaryModal !== nextState.showSummaryModal;
} }
getBalance(currency) { getBalance(currency) {
...@@ -306,6 +312,34 @@ class AddLiquidity extends Component { ...@@ -306,6 +312,34 @@ class AddLiquidity extends Component {
) )
} }
return [
<div
key="open-details"
className="swap__summary-wrapper swap__open-details-container"
onClick={() => this.setState({showSummaryModal: true})}
>
<span>Transaction Details</span>
<img src={DropdownBlue} />
</div>,
this.renderSummaryModal()
];
}
renderSummaryModal() {
const { selectors, exchangeAddresses: { fromToken } } = this.props;
const {
inputValue,
outputValue,
inputCurrency,
outputCurrency,
showSummaryModal,
} = this.state;
if (!showSummaryModal) {
return null;
}
const { value, decimals, label } = selectors().getTokenBalance(outputCurrency, fromToken[outputCurrency]);
const SLIPPAGE = 0.025; const SLIPPAGE = 0.025;
const minOutput = BN(outputValue).multipliedBy(1 - SLIPPAGE); const minOutput = BN(outputValue).multipliedBy(1 - SLIPPAGE);
const maxOutput = BN(outputValue).multipliedBy(1 + SLIPPAGE); const maxOutput = BN(outputValue).multipliedBy(1 + SLIPPAGE);
...@@ -314,13 +348,34 @@ class AddLiquidity extends Component { ...@@ -314,13 +348,34 @@ class AddLiquidity extends Component {
const maxPercentage = maxOutput.dividedBy(maxOutput.plus(tokenReserve)).multipliedBy(100); const maxPercentage = maxOutput.dividedBy(maxOutput.plus(tokenReserve)).multipliedBy(100);
return ( return (
<div key="summary" className="swap__summary-wrapper"> <Modal key="modal" onClose={() => this.setState({ showSummaryModal: false })}>
<CSSTransitionGroup
transitionName="summary-modal"
transitionAppear={true}
transitionLeave={true}
transitionAppearTimeout={200}
transitionLeaveTimeout={200}
transitionEnterTimeout={200}
>
<div className="swap__summary-modal">
<div
key="open-details"
className="swap__open-details-container"
onClick={() => this.setState({showSummaryModal: false})}
>
<span>Transaction Details</span>
<img src={DropupBlue} />
</div>
<div>
<div>You are adding between {b(`${minOutput.toFixed(5)} - ${maxOutput.toFixed(5)} ${label}`)} + {b(`${BN(inputValue).toFixed(5)} ETH`)} into the liquidity pool.</div> <div>You are adding between {b(`${minOutput.toFixed(5)} - ${maxOutput.toFixed(5)} ${label}`)} + {b(`${BN(inputValue).toFixed(5)} ETH`)} into the liquidity pool.</div>
<div className="pool__last-summary-text"> <div className="pool__last-summary-text">
You will receive between {b(`${minPercentage.toFixed(5)}%`)} and {b(`${maxPercentage.toFixed(5)}%`)} of the {`${label}/ETH`} pool tokens. You will receive between {b(`${minPercentage.toFixed(5)}%`)} and {b(`${maxPercentage.toFixed(5)}%`)} of the {`${label}/ETH`} pool tokens.
</div> </div>
</div> </div>
) </div>
</CSSTransitionGroup>
</Modal>
);
} }
render() { render() {
......
...@@ -3,12 +3,16 @@ import { drizzleConnect } from 'drizzle-react'; ...@@ -3,12 +3,16 @@ import { drizzleConnect } from 'drizzle-react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classnames from 'classnames'; import classnames from 'classnames';
import {BigNumber as BN} from "bignumber.js"; import {BigNumber as BN} from "bignumber.js";
import { CSSTransitionGroup } from "react-transition-group";
import { selectors } from '../../ducks/web3connect'; import { selectors } from '../../ducks/web3connect';
import Header from '../../components/Header'; import Header from '../../components/Header';
import NavigationTabs from '../../components/NavigationTabs'; import NavigationTabs from '../../components/NavigationTabs';
import AddressInputPanel from '../../components/AddressInputPanel'; import AddressInputPanel from '../../components/AddressInputPanel';
import CurrencyInputPanel from '../../components/CurrencyInputPanel'; import CurrencyInputPanel from '../../components/CurrencyInputPanel';
import Modal from '../../components/Modal';
import OversizedPanel from '../../components/OversizedPanel'; import OversizedPanel from '../../components/OversizedPanel';
import DropdownBlue from "../../assets/images/dropdown-blue.svg";
import DropupBlue from "../../assets/images/dropup-blue.svg";
import ArrowDown from '../../assets/images/arrow-down-blue.svg'; import ArrowDown from '../../assets/images/arrow-down-blue.svg';
import EXCHANGE_ABI from '../../abi/exchange'; import EXCHANGE_ABI from '../../abi/exchange';
...@@ -34,6 +38,7 @@ class Send extends Component { ...@@ -34,6 +38,7 @@ class Send extends Component {
inputAmountB: '', inputAmountB: '',
lastEditedField: '', lastEditedField: '',
recipient: '', recipient: '',
showSummaryModal: false,
}; };
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps, nextState) {
...@@ -49,6 +54,7 @@ class Send extends Component { ...@@ -49,6 +54,7 @@ class Send extends Component {
inputAmountB: '', inputAmountB: '',
lastEditedField: '', lastEditedField: '',
recipient: '', recipient: '',
showSummaryModal: false,
}); });
} }
...@@ -525,20 +531,129 @@ class Send extends Component { ...@@ -525,20 +531,129 @@ class Send extends Component {
) )
} }
const SLIPPAGE = 0.025; return [
const minOutput = BN(outputValue).multipliedBy(1 - SLIPPAGE).toFixed(5); <div
const maxOutput = BN(outputValue).multipliedBy(1 + SLIPPAGE).toFixed(5); key="open-details"
className="swap__summary-wrapper swap__open-details-container"
onClick={() => this.setState({showSummaryModal: true})}
>
<span>Transaction Details</span>
<img src={DropdownBlue} />
</div>,
this.renderSummaryModal()
];
}
return ( renderSummaryModal() {
<div className="swap__summary-wrapper"> const {
inputValue,
inputCurrency,
inputError,
outputValue,
outputCurrency,
outputError,
recipient,
showSummaryModal,
inputAmountB,
lastEditedField,
} = this.state;
const { selectors, account } = this.props;
if (!this.state.showSummaryModal) {
return null;
}
const ALLOWED_SLIPPAGE = 0.025;
const TOKEN_ALLOWED_SLIPPAGE = 0.04;
const type = getSendType(inputCurrency, outputCurrency);
const { label: inputLabel, decimals: inputDecimals } = selectors().getBalance(account, inputCurrency);
const { label: outputLabel, decimals: outputDecimals } = selectors().getBalance(account, outputCurrency);
const label = lastEditedField === INPUT ? outputLabel : inputLabel;
let minOutput;
let maxInput;
if (lastEditedField === INPUT) {
switch(type) {
case 'ETH_TO_TOKEN':
minOutput = BN(outputValue).multipliedBy(1 - ALLOWED_SLIPPAGE).toFixed(5)
break;
case 'TOKEN_TO_ETH':
minOutput = BN(outputValue).multipliedBy(1 - ALLOWED_SLIPPAGE).toFixed(5);
break;
case 'TOKEN_TO_TOKEN':
minOutput = BN(outputValue).multipliedBy(1 - TOKEN_ALLOWED_SLIPPAGE).toFixed(5);
break;
default:
break;
}
}
if (lastEditedField === OUTPUT) {
switch (type) {
case 'ETH_TO_TOKEN':
maxInput = BN(inputValue).multipliedBy(1 + ALLOWED_SLIPPAGE).toFixed(5);
break;
case 'TOKEN_TO_ETH':
maxInput = BN(inputValue).multipliedBy(1 + ALLOWED_SLIPPAGE).toFixed(5);
break;
case 'TOKEN_TO_TOKEN':
maxInput = BN(inputValue).multipliedBy(1 + TOKEN_ALLOWED_SLIPPAGE).toFixed(5);
break;
default:
break;
}
}
let description;
if (lastEditedField === INPUT) {
description = (
<div> <div>
You are selling {b(`${inputValue} ${inputLabel}`)} <div>
You are selling {b(`${inputValue} ${inputLabel}`)}.
</div> </div>
<div className="send__last-summary-text"> <div className="send__last-summary-text">
<span className="swap__highlight-text">{recipient.slice(0, 6)}</span> will receive between {b(`${minOutput} ${outputLabel}`)} and {b(`${maxOutput} ${outputLabel}`)} <span className="swap__highlight-text">{recipient.slice(0, 6)}</span> will receive between {b(`${minOutput} ${outputLabel}`)} and {b(`${outputValue} ${outputLabel}`)}.
</div> </div>
</div> </div>
) );
} else {
description = (
<div>
<div>
You are selling between {b(`${inputValue} ${inputLabel}`)} to {b(`${maxInput} ${inputLabel}`)}.
</div>
<div className="send__last-summary-text">
<span className="swap__highlight-text">{recipient.slice(0, 6)}</span> will receive {b(`${outputValue} ${outputLabel}`)}.
</div>
</div>
);
}
return (
<Modal key="modal" onClose={() => this.setState({ showSummaryModal: false })}>
<CSSTransitionGroup
transitionName="summary-modal"
transitionAppear={true}
transitionLeave={true}
transitionAppearTimeout={200}
transitionLeaveTimeout={200}
transitionEnterTimeout={200}
>
<div className="swap__summary-modal">
<div
key="open-details"
className="swap__open-details-container"
onClick={() => this.setState({showSummaryModal: false})}
>
<span>Transaction Details</span>
<img src={DropupBlue} />
</div>
{description}
</div>
</CSSTransitionGroup>
</Modal>
);
} }
renderExchangeRate() { renderExchangeRate() {
......
...@@ -4,10 +4,14 @@ import PropTypes from 'prop-types'; ...@@ -4,10 +4,14 @@ import PropTypes from 'prop-types';
import classnames from 'classnames'; import classnames from 'classnames';
import {BigNumber as BN} from "bignumber.js"; import {BigNumber as BN} from "bignumber.js";
import { selectors } from '../../ducks/web3connect'; import { selectors } from '../../ducks/web3connect';
import { CSSTransitionGroup } from "react-transition-group";
import Header from '../../components/Header'; import Header from '../../components/Header';
import NavigationTabs from '../../components/NavigationTabs'; import NavigationTabs from '../../components/NavigationTabs';
import Modal from '../../components/Modal';
import CurrencyInputPanel from '../../components/CurrencyInputPanel'; import CurrencyInputPanel from '../../components/CurrencyInputPanel';
import OversizedPanel from '../../components/OversizedPanel'; import OversizedPanel from '../../components/OversizedPanel';
import DropdownBlue from "../../assets/images/dropdown-blue.svg";
import DropupBlue from "../../assets/images/dropup-blue.svg";
import ArrowDown from '../../assets/images/arrow-down-blue.svg'; import ArrowDown from '../../assets/images/arrow-down-blue.svg';
import EXCHANGE_ABI from '../../abi/exchange'; import EXCHANGE_ABI from '../../abi/exchange';
...@@ -33,6 +37,7 @@ class Swap extends Component { ...@@ -33,6 +37,7 @@ class Swap extends Component {
outputCurrency: '', outputCurrency: '',
inputAmountB: '', inputAmountB: '',
lastEditedField: '', lastEditedField: '',
showSummaryModal: false,
}; };
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps, nextState) {
...@@ -47,6 +52,7 @@ class Swap extends Component { ...@@ -47,6 +52,7 @@ class Swap extends Component {
outputCurrency: '', outputCurrency: '',
inputAmountB: '', inputAmountB: '',
lastEditedField: '', lastEditedField: '',
showSummaryModal: false,
}); });
} }
...@@ -477,12 +483,6 @@ class Swap extends Component { ...@@ -477,12 +483,6 @@ class Swap extends Component {
outputCurrency, outputCurrency,
} = this.state; } = this.state;
const { selectors, account } = this.props;
const { label: inputLabel } = selectors().getBalance(account, inputCurrency);
const { label: outputLabel } = selectors().getBalance(account, outputCurrency);
const SLIPPAGE = 0.025;
const minOutput = BN(outputValue).multipliedBy(1 - SLIPPAGE).toFixed(5);
const maxOutput = BN(outputValue).multipliedBy(1 + SLIPPAGE).toFixed(5);
const inputIsZero = BN(inputValue).isEqualTo(BN(0)); const inputIsZero = BN(inputValue).isEqualTo(BN(0));
const outputIsZero = BN(outputValue).isEqualTo(BN(0)); const outputIsZero = BN(outputValue).isEqualTo(BN(0));
...@@ -518,12 +518,128 @@ class Swap extends Component { ...@@ -518,12 +518,128 @@ class Swap extends Component {
); );
} }
return [
<div
key="open-details"
className="swap__summary-wrapper swap__open-details-container"
onClick={() => this.setState({showSummaryModal: true})}
>
<span>Transaction Details</span>
<img src={DropdownBlue} />
</div>,
this.renderSummaryModal()
];
}
renderSummaryModal() {
const {
inputValue,
inputCurrency,
inputError,
outputValue,
outputCurrency,
outputError,
showSummaryModal,
inputAmountB,
lastEditedField,
} = this.state;
const { selectors, account } = this.props;
if (!this.state.showSummaryModal) {
return null;
}
const ALLOWED_SLIPPAGE = 0.025;
const TOKEN_ALLOWED_SLIPPAGE = 0.04;
const type = getSwapType(inputCurrency, outputCurrency);
const { label: inputLabel, decimals: inputDecimals } = selectors().getBalance(account, inputCurrency);
const { label: outputLabel, decimals: outputDecimals } = selectors().getBalance(account, outputCurrency);
const label = lastEditedField === INPUT ? outputLabel : inputLabel;
let minOutput;
let maxInput;
if (lastEditedField === INPUT) {
switch(type) {
case 'ETH_TO_TOKEN':
minOutput = BN(outputValue).multipliedBy(1 - ALLOWED_SLIPPAGE).toFixed(5)
break;
case 'TOKEN_TO_ETH':
minOutput = BN(outputValue).multipliedBy(1 - ALLOWED_SLIPPAGE).toFixed(5);
break;
case 'TOKEN_TO_TOKEN':
minOutput = BN(outputValue).multipliedBy(1 - TOKEN_ALLOWED_SLIPPAGE).toFixed(5);
break;
default:
break;
}
}
if (lastEditedField === OUTPUT) {
switch (type) {
case 'ETH_TO_TOKEN':
maxInput = BN(inputValue).multipliedBy(1 + ALLOWED_SLIPPAGE).toFixed(5);
break;
case 'TOKEN_TO_ETH':
maxInput = BN(inputValue).multipliedBy(1 + ALLOWED_SLIPPAGE).toFixed(5);
break;
case 'TOKEN_TO_TOKEN':
maxInput = BN(inputValue).multipliedBy(1 + TOKEN_ALLOWED_SLIPPAGE).toFixed(5);
break;
default:
break;
}
}
let description;
if (lastEditedField === INPUT) {
description = (
<div>
<div>
You are selling {b(`${inputValue} ${inputLabel}`)}.
</div>
<div className="send__last-summary-text">
You will receive between {b(`${minOutput} ${outputLabel}`)} and {b(`${outputValue} ${outputLabel}`)}.
</div>
</div>
);
} else {
description = (
<div>
<div>
You are selling between {b(`${inputValue} ${inputLabel}`)} to {b(`${maxInput} ${inputLabel}`)}.
</div>
<div className="send__last-summary-text">
You will receive {b(`${outputValue} ${outputLabel}`)}.
</div>
</div>
);
}
return ( return (
<div className="swap__summary-wrapper"> <Modal key="modal" onClose={() => this.setState({ showSummaryModal: false })}>
<div>You are selling {b(`${inputValue} ${inputLabel}`)}</div> <CSSTransitionGroup
<div>You will receive between {b(minOutput)} and {b(`${maxOutput} ${outputLabel}`)}</div> transitionName="summary-modal"
transitionAppear={true}
transitionLeave={true}
transitionAppearTimeout={200}
transitionLeaveTimeout={200}
transitionEnterTimeout={200}
>
<div className="swap__summary-modal">
<div
key="open-details"
className="swap__open-details-container"
onClick={() => this.setState({showSummaryModal: false})}
>
<span>Transaction Details</span>
<img src={DropupBlue} />
</div> </div>
) {description}
</div>
</CSSTransitionGroup>
</Modal>
);
} }
renderExchangeRate() { renderExchangeRate() {
......
...@@ -51,6 +51,37 @@ ...@@ -51,6 +51,37 @@
text-align: center; text-align: center;
} }
&__summary-modal {
background-color: $white;
position: relative;
bottom: 12rem;
height: 12rem;
z-index: 2000;
padding: 1rem;
border-top-left-radius: 1rem;
border-top-right-radius: 1rem;
transition: 250ms ease-in-out;
.swap__open-details-container {
padding: 0.5rem 0;
margin-bottom: 1rem;
}
}
&__open-details-container {
@extend %row-nowrap;
align-items: center;
justify-content: space-between;
padding: .625rem 1rem;
font-size: .75rem;
color: $royal-blue;
img {
height: .75rem;
width: .75rem;
}
}
&__highlight-text { &__highlight-text {
color: $royal-blue; color: $royal-blue;
} }
...@@ -73,3 +104,11 @@ ...@@ -73,3 +104,11 @@
margin-top: 5px; margin-top: 5px;
} }
} }
.summary-modal-appear {
bottom: 0;
}
.summary-modal-appear.modal-container-appear-active {
bottom: 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment