diff --git a/common/containers/Tabs/Swap/components/CurrencySwap.scss b/common/containers/Tabs/Swap/components/CurrencySwap.scss index fb5e2f67603..3bc9c89764d 100644 --- a/common/containers/Tabs/Swap/components/CurrencySwap.scss +++ b/common/containers/Tabs/Swap/components/CurrencySwap.scss @@ -1,4 +1,4 @@ -@import "common/sass/variables"; +@import 'common/sass/variables'; .CurrencySwap { text-align: center; @@ -13,6 +13,30 @@ display: inline-block; vertical-align: top; } + &-input-group { + display: inline-block; + } + &-error-message { + display: block; + min-height: 25px; + color: $brand-danger; + text-align: left; + } + &-inner-wrap { + display: block; + } + @media (min-width: $screen-xs-min) { + &-inner-wrap { + display: flex; + align-items: center; + justify-content: center; + } + } + &-dropdown { + display: inline-block; + margin-top: 0.6rem; + margin-bottom: 0.6rem; + } &-input { width: 100%; diff --git a/common/containers/Tabs/Swap/components/CurrencySwap.tsx b/common/containers/Tabs/Swap/components/CurrencySwap.tsx index 3cd3ef424b1..5e76b3a05f1 100644 --- a/common/containers/Tabs/Swap/components/CurrencySwap.tsx +++ b/common/containers/Tabs/Swap/components/CurrencySwap.tsx @@ -13,6 +13,7 @@ import translate from 'translations'; import { combineAndUpper, toFixedIfLarger } from 'utils/formatters'; import './CurrencySwap.scss'; import { Dropdown } from 'components/ui'; +import Spinner from 'components/ui/Spinner'; export interface StateProps { bityRates: any; @@ -36,6 +37,8 @@ export interface ActionProps { interface State { disabled: boolean; showedMinMaxError: boolean; + originErr: string; + destinationErr: string; } export default class CurrencySwap extends Component< @@ -44,9 +47,31 @@ export default class CurrencySwap extends Component< > { public state = { disabled: true, - showedMinMaxError: false + showedMinMaxError: false, + originErr: '', + destinationErr: '' }; + public componentWillReceiveProps(newProps) { + const { + originAmount, + originKind, + destinationKind, + destinationAmount + } = newProps; + if ( + originKind !== this.props.originKind || + destinationKind !== this.props.destinationKind + ) { + this.setDisabled( + originAmount, + originKind, + destinationKind, + destinationAmount + ); + } + } + public isMinMaxValid = (amount, kind) => { let bityMin; let bityMax; @@ -70,38 +95,86 @@ export default class CurrencySwap extends Component< return !(hasOriginAmountAndDestinationAmount && minMaxIsValid); }; - public setDisabled(originAmount, originKind, destinationAmount) { + public setDisabled( + originAmount, + originKind, + destinationKind, + destinationAmount + ) { const disabled = this.isDisabled( originAmount, originKind, destinationAmount ); - if (disabled && originAmount && !this.state.showedMinMaxError) { + if (disabled && originAmount) { const { bityRates } = this.props; const ETHMin = generateKindMin(bityRates.BTCETH, 'ETH'); const ETHMax = generateKindMax(bityRates.BTCETH, 'ETH'); const REPMin = generateKindMin(bityRates.BTCREP, 'REP'); - const notificationMessage = ` - Minimum amount ${bityConfig.BTCMin} BTC, - ${toFixedIfLarger(ETHMin, 3)} ETH. - Max amount ${bityConfig.BTCMax} BTC, - ${toFixedIfLarger(ETHMax, 3)} ETH, or - ${toFixedIfLarger(REPMin, 3)} REP - `; - - this.setState( - { - disabled, - showedMinMaxError: true - }, - () => { - this.props.showNotification('danger', notificationMessage, 10000); + const getRates = kind => { + let minAmount; + let maxAmount; + switch (kind) { + case 'BTC': + minAmount = toFixedIfLarger(bityConfig.BTCMin, 3); + maxAmount = toFixedIfLarger(bityConfig.BTCMax, 3); + break; + case 'ETH': + minAmount = toFixedIfLarger(ETHMin, 3); + maxAmount = toFixedIfLarger(ETHMax, 3); + break; + case 'REP': + minAmount = toFixedIfLarger(REPMin, 3); + break; + default: + if (this.state.showedMinMaxError) { + this.setState( + { + showedMinMaxError: true + }, + () => { + this.props.showNotification( + 'danger', + "Couldn't get match currency kind. Something went terribly wrong", + 10000 + ); + } + ); + } + } + return { minAmount, maxAmount }; + }; + + const createErrString = (kind, amount, rate) => { + let errString; + if (amount > rate.maxAmount) { + errString = `Maximum ${kind} is ${rate.maxAmount} ${kind}`; + } else { + errString = `Minimum ${kind} is ${rate.minAmount} ${kind}`; } + + return errString; + }; + const originRate = getRates(originKind); + const destinationRate = getRates(destinationKind); + const originErr = createErrString(originKind, originAmount, originRate); + const destinationErr = createErrString( + destinationKind, + destinationAmount, + destinationRate ); + + this.setState({ + originErr, + destinationErr, + disabled: true + }); } else { this.setState({ + originErr: '', + destinationErr: '', disabled }); } @@ -114,7 +187,12 @@ export default class CurrencySwap extends Component< public setOriginAndDestinationToNull = () => { this.props.originAmountSwap(null); this.props.destinationAmountSwap(null); - this.setDisabled(null, this.props.originKind, null); + this.setDisabled( + null, + this.props.originKind, + this.props.destinationKind, + null + ); }; public onChangeOriginAmount = ( @@ -129,7 +207,12 @@ export default class CurrencySwap extends Component< this.props.originAmountSwap(originAmountAsNumber); const destinationAmount = originAmountAsNumber * bityRate; this.props.destinationAmountSwap(destinationAmount); - this.setDisabled(originAmountAsNumber, originKind, destinationAmount); + this.setDisabled( + originAmountAsNumber, + originKind, + destinationKind, + destinationAmount + ); } else { this.setOriginAndDestinationToNull(); } @@ -147,7 +230,12 @@ export default class CurrencySwap extends Component< const bityRate = this.props.bityRates[pairNameReversed]; const originAmount = destinationAmountAsNumber * bityRate; this.props.originAmountSwap(originAmount); - this.setDisabled(originAmount, originKind, destinationAmountAsNumber); + this.setDisabled( + originAmount, + originKind, + destinationKind, + destinationAmountAsNumber + ); } else { this.setOriginAndDestinationToNull(); } @@ -160,69 +248,90 @@ export default class CurrencySwap extends Component< originKind, destinationKind, destinationKindOptions, - originKindOptions + originKindOptions, + bityRates } = this.props; + const { originErr, destinationErr } = this.state; + const OriginKindDropDown = Dropdown as new () => Dropdown< typeof originKind >; const DestinationKindDropDown = Dropdown as new () => Dropdown< typeof destinationKind >; - + const pairName = combineAndUpper(originKind, destinationKind); + const bityLoaded = bityRates[pairName]; return (

{translate('SWAP_init_1')}

- -
- - - - -

{translate('SWAP_init_2')}

- - - - -
+ {bityLoaded ? ( +
+
+ {originErr} + +
+ +
+
+

{translate('SWAP_init_2')}

+
+ + {destinationErr} + + +
+ +
+
+
+ ) : ( + + )}
{ {/*Amount to send*/} {!this.isExpanded() && (
-

- {` ${originAmount} ${originKind}`} -

+

{` ${originAmount} ${originKind}`}

{translate('SEND_amount')}

@@ -113,7 +111,7 @@ export default class SwapInfoHeader extends Component { {`${computedOriginDestinationRatio && toFixedIfLarger( computedOriginDestinationRatio - )} ${originKind}/${destinationKind}`} + )} ${destinationKind}/${originKind}`}

{translate('SWAP_your_rate')}