Commit 9091910e authored by Kenny Tran's avatar Kenny Tran Committed by Chi Kei Chan

Create ContextualInfo component and refactor pages (#107)

* Add contextual info to Remove Liquidity page

* Create ContextualInfo component and refactor pages

* Add contextual info to remove liq and refactor

* Add modalClass attribute to ContextualInfo

* Mirror add liquidity text
parent ab1e68f5
@import '../../variables.scss';
.contextual-info {
&__summary-wrapper {
background-color: $concrete-gray;
border-top-left-radius: 1rem;
border-top-right-radius: 1rem;
padding: 1rem;
color: #737373;
font-size: .75rem;
text-align: center;
cursor: pointer;
}
&--error {
color: $salmon-red;
}
&__summary-modal {
background-color: $white;
position: relative;
bottom: 12rem;
min-height: 12rem;
max-height: 12rem;
z-index: 2000;
padding: 1rem;
border-top-left-radius: 1rem;
border-top-right-radius: 1rem;
transition: 250ms ease-in-out;
@media only screen and (min-device-width : 768px) {
max-width: 560px;
position: absolute;
margin-left: auto;
margin-right: auto;
border-radius: 1rem;
padding-bottom: 1rem;
left: 0;
right: 0;
bottom: 0;
top: 0;
margin-top: 4rem;
}
.swap__open-details-container {
padding: 0.5rem 0;
margin-bottom: 1rem;
cursor: pointer;
}
}
&__open-details-container {
@extend %row-nowrap;
align-items: center;
justify-content: space-between;
font-size: .75rem;
color: $royal-blue;
img {
height: .75rem;
width: .75rem;
}
}
&__modal-button {
padding: 0.5rem 0;
margin-bottom: 1rem;
}
}
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import c from 'classnames';
import { CSSTransitionGroup } from "react-transition-group";
import Modal from '../Modal';
import DropdownBlue from "../../assets/images/dropdown-blue.svg";
import DropupBlue from "../../assets/images/dropup-blue.svg";
import './contextual-info.scss';
class ContextualInfo extends Component {
static propTypes = {
openModalText: PropTypes.string,
renderTransactionDetails: PropTypes.func,
contextualInfo: PropTypes.string,
modalClass: PropTypes.string,
isError: PropTypes.bool,
};
static defaultProps = {
openModalText: 'Transaction Details',
renderTransactionDetails() {},
contextualInfo: '',
modalClass: '',
isError: false,
};
state = {
showDetailModal: false,
};
renderModal() {
if (!this.state.showDetailModal) {
return null;
}
const { modalClass } = this.props;
return (
<Modal key="modal" onClose={() => this.setState({ showDetailModal: false })}>
<CSSTransitionGroup
transitionName="summary-modal"
transitionAppear={true}
transitionLeave={true}
transitionAppearTimeout={200}
transitionLeaveTimeout={200}
transitionEnterTimeout={200}
>
<div className={c('contextual-info__summary-modal', modalClass)}>
<div
key="open-details"
className="contextual-info__open-details-container contextual-info__modal-button"
onClick={() => this.setState({showDetailModal: false})}
>
<span>Transaction Details</span>
<img src={DropupBlue} />
</div>
{this.props.renderTransactionDetails()}
</div>
</CSSTransitionGroup>
</Modal>
);
}
render() {
const {
openModalText,
contextualInfo,
isError,
} = this.props;
if (contextualInfo) {
return (
<div className={c({ 'contextual-info--error': isError }, 'contextual-info__summary-wrapper')}>
<div>{contextualInfo}</div>
</div>
);
}
return [
<div
key="open-details"
className="contextual-info__summary-wrapper contextual-info__open-details-container"
onClick={() => this.setState({showDetailModal: true})}
>
<span>{openModalText}</span>
<img src={DropdownBlue} />
</div>,
this.renderModal()
]
}
}
export default ContextualInfo;
import { combineReducers } from 'redux';
import addresses from './addresses';
import send from './send';
import app from './app';
import pending from './pending';
import web3connect from './web3connect';
......@@ -9,6 +8,5 @@ export default combineReducers({
app,
addresses,
pending,
send,
web3connect,
});
const UPDATE_FIELD = 'app/send/updateField';
const ADD_ERROR = 'app/send/addError';
const REMOVE_ERROR = 'app/send/removeError';
const RESET_SEND = 'app/send/resetSend';
const getInitialState = () => {
return {
input: '',
output: '',
inputCurrency: '',
outputCurrency: '',
recipient: '',
lastEditedField: '',
inputErrors: [],
outputErrors: [],
};
};
export const isValidSend = (state) => {
const { send } = state;
return send.outputCurrency !== '' &&
send.inputCurrency !== '' &&
send.input !== '' &&
send.output !== '' &&
send.recipient !== '' &&
send.inputErrors.length === 0 &&
send.outputErrors.length === 0;
};
export const updateField = ({ name, value }) => ({
type: UPDATE_FIELD,
payload: { name, value },
});
export const addError = ({ name, value }) => ({
type: ADD_ERROR,
payload: { name, value },
});
export const removeError = ({ name, value }) => ({
type: REMOVE_ERROR,
payload: { name, value },
});
export const resetSend = () => ({
type: RESET_SEND,
});
function reduceAddError(state, payload) {
const { name, value } = payload;
let nextErrors = state[name];
if (nextErrors.indexOf(value) === -1) {
nextErrors = [...nextErrors, value];
}
return {
...state,
[name]: nextErrors,
};
}
function reduceRemoveError(state, payload) {
const { name, value } = payload;
return {
...state,
[name]: state[name].filter(error => error !== value),
};
}
export default function sendReducer(state = getInitialState(), { type, payload }) {
switch (type) {
case UPDATE_FIELD:
return {
...state,
[payload.name]: payload.value,
};
case ADD_ERROR:
return reduceAddError(state, payload);
case REMOVE_ERROR:
return reduceRemoveError(state, payload);
case RESET_SEND:
return getInitialState();
default:
return state;
}
}
......@@ -2,11 +2,10 @@ import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import classnames from "classnames";
import { CSSTransitionGroup } from "react-transition-group";
import CurrencyInputPanel from '../../components/CurrencyInputPanel';
import OversizedPanel from '../../components/OversizedPanel';
import ContextualInfo from '../../components/ContextualInfo';
import NavigationTabs from '../../components/NavigationTabs';
import Modal from '../../components/Modal';
import { selectors, addPendingTx } from '../../ducks/web3connect';
import PlusBlue from '../../assets/images/plus-blue.svg';
import PlusGrey from '../../assets/images/plus-grey.svg';
......@@ -40,7 +39,6 @@ class AddLiquidity extends Component {
outputCurrency: '',
lastEditedField: '',
totalSupply: BN(0),
showSummaryModal: false,
};
reset = () => {
......@@ -48,13 +46,12 @@ class AddLiquidity extends Component {
inputValue: '',
outputValue: '',
lastEditedField: '',
showSummaryModal: false,
});
};
shouldComponentUpdate(nextProps, nextState) {
const { isConnected, account, exchangeAddresses, balances, web3 } = this.props;
const { inputValue, outputValue, inputCurrency, outputCurrency, lastEditedField, showSummaryModal } = this.state;
const { inputValue, outputValue, inputCurrency, outputCurrency, lastEditedField } = this.state;
return isConnected !== nextProps.isConnected ||
account !== nextProps.account ||
......@@ -65,8 +62,7 @@ class AddLiquidity extends Component {
outputValue !== nextState.outputValue ||
inputCurrency !== nextState.inputCurrency ||
outputCurrency !== nextState.outputCurrency ||
lastEditedField !== nextState.lastEditedField ||
showSummaryModal !== nextState.showSummaryModal;
lastEditedField !== nextState.lastEditedField;
}
componentWillReceiveProps() {
......@@ -384,7 +380,7 @@ class AddLiquidity extends Component {
)
}
renderSummary() {
renderSummary(inputError, outputError) {
const { selectors, exchangeAddresses: { fromToken } } = this.props;
const {
inputValue,
......@@ -395,81 +391,45 @@ class AddLiquidity extends Component {
const inputIsZero = BN(inputValue).isZero();
const outputIsZero = BN(outputValue).isZero();
if (!inputCurrency || !outputCurrency) {
return (
<div key="summary" className="swap__summary-wrapper">
<div>Select a token to continue.</div>
</div>
)
}
if (inputCurrency === outputCurrency) {
return (
<div key="summary" className="swap__summary-wrapper">
<div>Must be different token.</div>
</div>
)
}
if (![inputCurrency, outputCurrency].includes('ETH')) {
return (
<div key="summary" className="swap__summary-wrapper">
<div>One of the input must be ETH.</div>
</div>
)
}
if (inputIsZero || outputIsZero) {
return (
<div key="summary" className="swap__summary-wrapper">
<div>Amount cannot be zero.</div>
</div>
)
}
if (this.isUnapproved()) {
return (
<div key="summary" className="swap__summary-wrapper">
<div>Please unlock token to continue.</div>
</div>
)
}
let contextualInfo = '';
let isError = false;
const { label } = selectors().getTokenBalance(outputCurrency, fromToken[outputCurrency]);
if (!inputValue || !outputValue) {
return (
<div key="summary" className="swap__summary-wrapper">
<div>{`Enter a ${inputCurrency} or ${label} value to continue.`}</div>
</div>
)
if (inputError || outputError) {
contextualInfo = inputError || outputError;
isError = true;
} else if (!inputCurrency || !outputCurrency) {
contextualInfo = 'Select a token to continue.';
} else if (inputCurrency === outputCurrency) {
contextualInfo = 'Must be different token.';
} else if (![inputCurrency, outputCurrency].includes('ETH')) {
contextualInfo = 'One of the input must be ETH.';
} else if (inputIsZero || outputIsZero) {
contextualInfo = 'Amount cannot be zero.';
} else if (this.isUnapproved()) {
contextualInfo = 'Please unlock token to continue.';
} else if (!inputValue || !outputValue) {
contextualInfo = `Enter a ${inputCurrency} or ${label} value to continue.`;
}
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()
];
return (
<ContextualInfo
key="context-info"
contextualInfo={contextualInfo}
isError={isError}
modalClass="pool__summary-modal"
renderTransactionDetails={this.renderTransactionDetails}
/>
);
}
renderSummaryModal() {
renderTransactionDetails = () => {
const { selectors, exchangeAddresses: { fromToken }, account } = this.props;
const {
inputValue,
outputValue,
outputCurrency,
showSummaryModal,
totalSupply,
} = this.state;
if (!showSummaryModal) {
return null;
}
ReactGA.event({
category: 'TransactionDetail',
......@@ -489,33 +449,12 @@ class AddLiquidity extends Component {
const adjTotalSupply = totalSupply.dividedBy(10 ** poolTokenDecimals);
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="pool__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 className="pool__summary-modal__item">You are adding between {b(`${+BN(inputValue).toFixed(7)} ETH`)} and {b(`${+minOutput.toFixed(7)} - ${+maxOutput.toFixed(7)} ${label}`)} into the liquidity pool.</div>
<div className="pool__summary-modal__item">You will mint {b(+liquidityMinted.toFixed(7))} liquidity tokens.</div>
<div className="pool__summary-modal__item">Current total supply of liquidity tokens is {b(+adjTotalSupply.toFixed(7))}</div>
<div className="pool__summary-modal__item">At current exchange rate, each pool token is worth {b(+ethReserve.dividedBy(totalSupply).toFixed(7))} ETH and {b(+tokenReserve.dividedBy(totalSupply).toFixed(7))} {label}</div>
</div>
</div>
</CSSTransitionGroup>
</Modal>
<div>
<div className="pool__summary-modal__item">You are adding between {b(`${+BN(inputValue).toFixed(7)} ETH`)} and {b(`${+minOutput.toFixed(7)} - ${+maxOutput.toFixed(7)} ${label}`)} into the liquidity pool.</div>
<div className="pool__summary-modal__item">You will mint {b(+liquidityMinted.toFixed(7))} liquidity tokens.</div>
<div className="pool__summary-modal__item">Current total supply of liquidity tokens is {b(+adjTotalSupply.toFixed(7))}</div>
<div className="pool__summary-modal__item">At current exchange rate, each pool token is worth {b(+ethReserve.dividedBy(totalSupply).toFixed(7))} ETH and {b(+tokenReserve.dividedBy(totalSupply).toFixed(7))} {label}</div>
</div>
);
}
......@@ -608,7 +547,7 @@ class AddLiquidity extends Component {
</button>
</div>
</div>,
this.renderSummary()
this.renderSummary(inputError, outputError)
];
}
}
......
......@@ -7,6 +7,7 @@ import NavigationTabs from "../../components/NavigationTabs";
import ModeSelector from "./ModeSelector";
import CurrencyInputPanel from "../../components/CurrencyInputPanel";
import { selectors, addPendingTx } from '../../ducks/web3connect';
import ContextualInfo from "../../components/ContextualInfo";
import OversizedPanel from "../../components/OversizedPanel";
import ArrowDownBlue from "../../assets/images/arrow-down-blue.svg";
import ArrowDownGrey from "../../assets/images/arrow-down-grey.svg";
......@@ -148,6 +149,85 @@ class RemoveLiquidity extends Component {
return `Balance: ${value.dividedBy(10 ** decimals).toFixed(7)}`;
};
renderSummary(errorMessage) {
const { selectors, exchangeAddresses: { fromToken } } = this.props;
const {
value: input,
tokenAddress,
} = this.state;
const inputIsZero = BN(input).isZero();
let contextualInfo = '';
let isError = false;
if (errorMessage) {
contextualInfo = errorMessage;
isError = true;
} else if (!tokenAddress) {
contextualInfo = 'Select a token to continue.';
} else if (inputIsZero) {
contextualInfo = 'Amount cannot be zero.';
} else if (!input) {
const { label } = selectors().getTokenBalance(tokenAddress, fromToken[tokenAddress]);
contextualInfo = `Enter a ${label} value to continue.`;
}
return (
<ContextualInfo
key="context-info"
contextualInfo={contextualInfo}
isError={isError}
modalClass="pool__summary-modal"
renderTransactionDetails={this.renderTransactionDetails}
/>
);
}
renderTransactionDetails = () => {
const { tokenAddress, value: input, totalSupply } = this.state;
const {
exchangeAddresses: { fromToken },
web3,
selectors,
account,
} = this.props;
const exchangeAddress = fromToken[tokenAddress];
const { getBalance } = selectors();
if (!exchangeAddress) {
return null;
}
ReactGA.event({
category: 'TransactionDetail',
action: 'Open',
});
const SLIPPAGE = 0.025;
const { value: liquidityBalance, decimals } = getBalance(account, exchangeAddress);
const { value: ethReserve } = getBalance(exchangeAddress);
const { value: tokenReserve, label, decimals: reserveDecimals } = getBalance(exchangeAddress, tokenAddress);
const ethPer = ethReserve.dividedBy(totalSupply);
const tokenPer = tokenReserve.dividedBy(totalSupply);
const ethWithdrawn = ethPer.multipliedBy(input);
const tokenWithdrawn = tokenPer.multipliedBy(input);
const minTokenWithdrawn = tokenWithdrawn.multipliedBy(1 - SLIPPAGE).toFixed(7);
const maxTokenWithdrawn = tokenWithdrawn.multipliedBy(1 + SLIPPAGE).toFixed(7);
const adjTotalSupply = totalSupply.dividedBy(10 ** decimals).minus(input);
return (
<div>
<div className="pool__summary-modal__item">You are removing between {b(`${+BN(ethWithdrawn).toFixed(7)} ETH`)} and {b(`${+minTokenWithdrawn} - ${+maxTokenWithdrawn} ${label}`)} into the liquidity pool.</div>
<div className="pool__summary-modal__item">You will remove {b(+input)} liquidity tokens.</div>
<div className="pool__summary-modal__item">Current total supply of liquidity tokens is {b(+adjTotalSupply.toFixed(7))}</div>
<div className="pool__summary-modal__item">At current exchange rate, each pool token is worth {b(+ethReserve.dividedBy(totalSupply).toFixed(7))} ETH and {b(+tokenReserve.dividedBy(totalSupply).toFixed(7))} {label}</div>
</div>
);
}
renderOutput() {
const {
exchangeAddresses: { fromToken },
......@@ -253,7 +333,7 @@ class RemoveLiquidity extends Component {
const { tokenAddress, value } = this.state;
const { isValid, errorMessage } = this.validate();
return (
return [
<div
key="content"
className={classnames('swap__content', {
......@@ -294,8 +374,9 @@ class RemoveLiquidity extends Component {
Remove Liquidity
</button>
</div>
</div>
);
</div>,
this.renderSummary(errorMessage)
];
}
}
......@@ -312,3 +393,7 @@ export default connect(
addPendingTx: id => dispatch(addPendingTx(id)),
})
)(RemoveLiquidity);
function b(text) {
return <span className="swap__highlight-text">{text}</span>
}
......@@ -3,13 +3,12 @@ import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import {BigNumber as BN} from "bignumber.js";
import { CSSTransitionGroup } from "react-transition-group";
import { selectors, addPendingTx } from '../../ducks/web3connect';
import Header from '../../components/Header';
import NavigationTabs from '../../components/NavigationTabs';
import AddressInputPanel from '../../components/AddressInputPanel';
import CurrencyInputPanel from '../../components/CurrencyInputPanel';
import Modal from '../../components/Modal';
import ContextualInfo from '../../components/ContextualInfo';
import OversizedPanel from '../../components/OversizedPanel';
import DropdownBlue from "../../assets/images/dropdown-blue.svg";
import DropupBlue from "../../assets/images/dropup-blue.svg";
......@@ -41,7 +40,6 @@ class Send extends Component {
inputAmountB: '',
lastEditedField: '',
recipient: '',
showSummaryModal: false,
};
componentWillMount() {
......@@ -59,7 +57,6 @@ class Send extends Component {
inputAmountB: '',
lastEditedField: '',
recipient: '',
showSummaryModal: false,
});
}
......@@ -514,14 +511,12 @@ class Send extends Component {
}
};
renderSummary() {
renderSummary(inputError, outputError) {
const {
inputValue,
inputCurrency,
inputError,
outputValue,
outputCurrency,
outputError,
recipient,
} = this.state;
const { web3 } = this.props;
......@@ -533,64 +528,49 @@ class Send extends Component {
const inputIsZero = BN(inputValue).isZero();
const outputIsZero = BN(outputValue).isZero();
let nextStepMessage;
let contextualInfo = '';
let isError = false;
if (inputError || outputError) {
nextStepMessage = inputError || outputError;
contextualInfo = inputError || outputError;
isError = true;
} else if (!inputCurrency || !outputCurrency) {
nextStepMessage = 'Select a token to continue.';
contextualInfo = 'Select a token to continue.';
} else if (inputCurrency === outputCurrency) {
nextStepMessage = 'Must be different token.';
contextualInfo = 'Must be different token.';
} else if (!inputValue || !outputValue) {
const missingCurrencyValue = !inputValue ? inputLabel : outputLabel;
nextStepMessage = `Enter a ${missingCurrencyValue} value to continue.`;
contextualInfo = `Enter a ${missingCurrencyValue} value to continue.`;
} else if (inputIsZero || outputIsZero) {
nextStepMessage = 'No liquidity.';
contextualInfo = 'No liquidity.';
} else if (this.isUnapproved()) {
nextStepMessage = 'Please unlock token to continue.';
contextualInfo = 'Please unlock token to continue.';
} else if (!recipient) {
nextStepMessage = 'Enter a wallet address to send to.';
contextualInfo = 'Enter a wallet address to send to.';
} else if (!validRecipientAddress) {
nextStepMessage = 'Please enter a valid wallet address recipient.';
contextualInfo = 'Please enter a valid wallet address recipient.';
}
if (nextStepMessage) {
return (
<div className="swap__summary-wrapper">
<div>{nextStepMessage}</div>
</div>
)
}
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()
];
return (
<ContextualInfo
contextualInfo={contextualInfo}
isError={isError}
renderTransactionDetails={this.renderTransactionDetails}
/>
);
}
renderSummaryModal() {
renderTransactionDetails = () => {
const {
inputValue,
inputCurrency,
inputError,
outputValue,
outputCurrency,
outputError,
recipient,
showSummaryModal,
inputAmountB,
lastEditedField,
} = this.state;
const { selectors, account } = this.props;
if (!this.state.showSummaryModal) {
return null;
}
ReactGA.event({
category: 'TransactionDetail',
......@@ -640,10 +620,9 @@ class Send extends Component {
}
}
let description;
const recipientText = b(`${recipient.slice(0, 6)}...${recipient.slice(-4)}`);
if (lastEditedField === INPUT) {
description = (
return (
<div>
<div>
You are selling {b(`${+inputValue} ${inputLabel}`)}.
......@@ -654,7 +633,7 @@ class Send extends Component {
</div>
);
} else {
description = (
return (
<div>
<div>
You are sending {b(`${+outputValue} ${outputLabel}`)} to {recipientText}.
......@@ -667,31 +646,6 @@ class Send extends Component {
</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() {
......@@ -810,7 +764,7 @@ class Send extends Component {
</button>
</div>
</div>
{ this.renderSummary() }
{ this.renderSummary(inputError, outputError) }
</div>
);
}
......
......@@ -6,11 +6,10 @@ import {BigNumber as BN} from "bignumber.js";
import MediaQuery from 'react-responsive';
import ReactGA from 'react-ga';
import { selectors, addPendingTx } from '../../ducks/web3connect';
import { CSSTransitionGroup } from "react-transition-group";
import Header from '../../components/Header';
import NavigationTabs from '../../components/NavigationTabs';
import Modal from '../../components/Modal';
import CurrencyInputPanel from '../../components/CurrencyInputPanel';
import ContextualInfo from '../../components/ContextualInfo';
import OversizedPanel from '../../components/OversizedPanel';
import DropdownBlue from "../../assets/images/dropdown-blue.svg";
import DropupBlue from "../../assets/images/dropup-blue.svg";
......@@ -40,7 +39,6 @@ class Swap extends Component {
outputCurrency: '',
inputAmountB: '',
lastEditedField: '',
showSummaryModal: false,
};
componentWillMount() {
......@@ -57,7 +55,6 @@ class Swap extends Component {
outputValue: '',
inputAmountB: '',
lastEditedField: '',
showSummaryModal: false,
});
}
......@@ -505,7 +502,7 @@ class Swap extends Component {
}
};
renderSummary() {
renderSummary(inputError, outputError) {
const {
inputValue,
inputCurrency,
......@@ -515,53 +512,40 @@ class Swap extends Component {
const inputIsZero = BN(inputValue).isZero();
const outputIsZero = BN(outputValue).isZero();
let contextualInfo = '';
let isError = false;
if (!inputCurrency || !outputCurrency) {
return (
<div className="swap__summary-wrapper">
<div>Select a token to continue.</div>
</div>
)
contextualInfo = 'Select a token to continue.';
}
if (!inputValue || !outputValue) {
return (
<div className="swap__summary-wrapper">
<div>Enter a value to continue.</div>
</div>
)
contextualInfo = 'Enter a value to continue.';
}
if (inputError || outputError) {
contextualInfo = inputError || outputError;
isError = true;
}
if (inputIsZero || outputIsZero) {
return (
<div className="swap__summary-wrapper">
<div>No liquidity.</div>
</div>
)
contextualInfo = 'No liquidity.';
}
if (this.isUnapproved()) {
return (
<div className="swap__summary-wrapper">
<div>Please unlock token to continue.</div>
</div>
);
contextualInfo = 'Please unlock token to continue.';
}
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()
];
return (
<ContextualInfo
contextualInfo={contextualInfo}
isError={isError}
renderTransactionDetails={this.renderTransactionDetails}
/>
);
}
renderSummaryModal() {
renderTransactionDetails = () => {
const {
inputValue,
inputCurrency,
......@@ -570,9 +554,6 @@ class Swap extends Component {
lastEditedField,
} = this.state;
const { selectors, account } = this.props;
if (!this.state.showSummaryModal) {
return null;
}
ReactGA.event({
category: 'TransactionDetail',
......@@ -622,9 +603,8 @@ class Swap extends Component {
}
}
let description;
if (lastEditedField === INPUT) {
description = (
return (
<div>
<div>
You are selling {b(`${+inputValue} ${inputLabel}`)}.
......@@ -635,7 +615,7 @@ class Swap extends Component {
</div>
);
} else {
description = (
return (
<div>
<div>
You are buying {b(`${+outputValue} ${outputLabel}`)}.
......@@ -646,31 +626,6 @@ class Swap extends Component {
</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() {
......@@ -780,7 +735,7 @@ class Swap extends Component {
</button>
</div>
</div>
{ this.renderSummary() }
{ this.renderSummary(inputError, outputError) }
</div>
);
}
......
......@@ -44,63 +44,6 @@
color: $chalice-gray;
}
&__summary-wrapper {
background-color: $concrete-gray;
border-top-left-radius: 1rem;
border-top-right-radius: 1rem;
padding: 1rem;
color: #737373;
font-size: .75rem;
text-align: center;
cursor: pointer;
}
&__summary-modal {
background-color: $white;
position: relative;
bottom: 12rem;
min-height: 12rem;
max-height: 12rem;
z-index: 2000;
padding: 1rem;
border-top-left-radius: 1rem;
border-top-right-radius: 1rem;
transition: 250ms ease-in-out;
@media only screen and (min-device-width : 768px) {
max-width: 560px;
position: absolute;
margin-left: auto;
margin-right: auto;
border-radius: 1rem;
padding-bottom: 1rem;
left: 0;
right: 0;
bottom: 0;
top: 0;
margin-top: 4rem;
}
.swap__open-details-container {
padding: 0.5rem 0;
margin-bottom: 1rem;
cursor: pointer;
}
}
&__open-details-container {
@extend %row-nowrap;
align-items: center;
justify-content: space-between;
font-size: .75rem;
color: $royal-blue;
img {
height: .75rem;
width: .75rem;
}
}
&__highlight-text {
color: $royal-blue;
}
......
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