Swap Part 3 WIP

This commit is contained in:
Daniel Ternyak 2017-07-02 00:45:22 -05:00
parent afe2adbb5a
commit b623a3efe9
8 changed files with 252 additions and 30 deletions

View File

@ -5,7 +5,9 @@ import {
SWAP_ORIGIN_KIND, SWAP_ORIGIN_KIND,
SWAP_UPDATE_BITY_RATES, SWAP_UPDATE_BITY_RATES,
SWAP_PART_ONE_COMPLETE, SWAP_PART_ONE_COMPLETE,
SWAP_RECEIVING_ADDRESS SWAP_PART_TWO_COMPLETE,
SWAP_DESTINATION_ADDRESS,
SWAP_RESTART
} from './swapConstants'; } from './swapConstants';
export const originKindSwap = value => { export const originKindSwap = value => {
@ -50,9 +52,22 @@ export const partOneCompleteSwap = (value: boolean) => {
}; };
}; };
export const receivingAddressSwap = value => { export const partTwoCompleteSwap = (value: boolean) => {
return { return {
type: SWAP_RECEIVING_ADDRESS, type: SWAP_PART_TWO_COMPLETE,
value value
}; };
}; };
export const destinationAddressSwap = value => {
return {
type: SWAP_DESTINATION_ADDRESS,
value
};
};
export const restartSwap = () => {
return {
type: SWAP_RESTART
};
};

View File

@ -4,4 +4,6 @@ export const SWAP_ORIGIN_AMOUNT = 'SWAP_ORIGIN_AMOUNT';
export const SWAP_DESTINATION_AMOUNT = 'SWAP_DESTINATION_AMOUNT'; export const SWAP_DESTINATION_AMOUNT = 'SWAP_DESTINATION_AMOUNT';
export const SWAP_UPDATE_BITY_RATES = 'SWAP_UPDATE_BITY_RATES'; export const SWAP_UPDATE_BITY_RATES = 'SWAP_UPDATE_BITY_RATES';
export const SWAP_PART_ONE_COMPLETE = 'SWAP_PART_ONE_COMPLETE'; export const SWAP_PART_ONE_COMPLETE = 'SWAP_PART_ONE_COMPLETE';
export const SWAP_RECEIVING_ADDRESS = 'SWAP_RECEIVING_ADDRESS'; export const SWAP_PART_TWO_COMPLETE = 'SWAP_PART_TWO_COMPLETE';
export const SWAP_DESTINATION_ADDRESS = 'SWAP_DESTINATION_ADDRESS';
export const SWAP_RESTART = 'SWAP_RESTART';

View File

@ -4,8 +4,8 @@ import translate from 'translations';
import { combineAndUpper } from 'api/bity'; import { combineAndUpper } from 'api/bity';
class CoinTypeDropDown extends Component { class CoinTypeDropDown extends Component {
constructor(props, context) { constructor(props) {
super(props, context); super(props);
} }
static propTypes = { static propTypes = {
@ -34,6 +34,9 @@ class CoinTypeDropDown extends Component {
export default class CurrencySwap extends Component { export default class CurrencySwap extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = {
disabled: false
};
} }
static propTypes = { static propTypes = {
@ -146,9 +149,13 @@ export default class CurrencySwap extends Component {
/> />
<div className="col-xs-12 clearfix text-center"> <div className="col-xs-12 clearfix text-center">
<a onClick={this.onClickStartSwap} className="btn btn-info btn-lg"> <button
disabled={this.state.disabled}
onClick={this.onClickStartSwap}
className="btn btn-info btn-lg"
>
<span>{translate('SWAP_init_CTA')}</span> <span>{translate('SWAP_init_CTA')}</span>
</a> </button>
</div> </div>
</article> </article>
); );

View File

@ -0,0 +1,87 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { toFixedIfLarger } from 'utils/formatters';
import translate from 'translations';
export default class OnGoingSwapInformation extends Component {
constructor(props) {
super(props);
}
static propTypes = {
referenceNumber: PropTypes.string.isRequired,
timeRemaining: PropTypes.any, // FIXME
originAmount: PropTypes.number.isRequired,
originKind: PropTypes.string.isRequired,
destinationKind: PropTypes.string.isRequired,
destinationAmount: PropTypes.number.isRequired,
restartSwap: PropTypes.func.isRequired
};
computedOriginDestinationRatio = () => {
return toFixedIfLarger(
this.props.destinationAmount / this.props.originAmount,
6
);
};
render() {
const {
referenceNumber,
timeRemaining,
originAmount,
originKind,
destinationKind,
restartSwap
} = this.props;
return (
<div>
<section className="row text-center">
<div className="col-xs-3 text-left">
<button className="btn btn-danger btn-xs" onClick={restartSwap}>
Start New Swap
</button>
</div>
<h5 className="col-xs-6 ng-scope">{translate('SWAP_information')}</h5>
<div className="col-xs-3">
<a
className="link"
href="https://bity.com/af/jshkb37v"
target="_blank"
rel="noopener"
>
<img
className="pull-right"
src={'https://www.myetherwallet.com/images/logo-bity.svg'}
width={100}
height={38}
/>
</a>
</div>
</section>
<section className="row order-info-wrap">
<div className="col-sm-3 order-info">
<h4>{referenceNumber}</h4>
<p>{translate('SWAP_ref_num')}</p>
</div>
<div className="col-sm-3 order-info">
<h4>{timeRemaining}</h4>
<p>
{translate('SWAP_time')}
</p>
</div>
<div className="col-sm-3 order-info">
<h4>{originAmount} {originKind}</h4>
<p>{translate('SWAP_rec_amt')}</p>
</div>
<div className="col-sm-3 order-info">
<h4>
{`${this.computedOriginDestinationRatio()} ${destinationKind}/${originKind}`}
</h4>
<p>{translate('SWAP_your_rate')}</p>
</div>
</section>
</div>
);
}
}

View File

@ -15,13 +15,14 @@ export default class ReceivingAddress extends Component {
static propTypes = { static propTypes = {
destinationKind: PropTypes.string.isRequired, destinationKind: PropTypes.string.isRequired,
receivingAddressSwap: PropTypes.func.isRequired, destinationAddressSwap: PropTypes.func.isRequired,
receivingAddress: PropTypes.string destinationAddress: PropTypes.string,
partTwoCompleteSwap: PropTypes.func
}; };
onChangeReceivingAddress = event => { onChangeDestinationAddress = event => {
const value = event.target.value; const value = event.target.value;
this.props.receivingAddressSwap(value); this.props.destinationAddressSwap(value);
let validAddress; let validAddress;
// TODO - find better pattern here once currencies move beyond BTC, ETH, REP // TODO - find better pattern here once currencies move beyond BTC, ETH, REP
if (this.props.destinationKind === 'BTC') { if (this.props.destinationKind === 'BTC') {
@ -32,8 +33,12 @@ export default class ReceivingAddress extends Component {
this.setState({ validAddress }); this.setState({ validAddress });
}; };
onClickPartTwoComplete = () => {
this.props.partTwoCompleteSwap(true);
};
render() { render() {
const { destinationKind, receivingAddress } = this.props; const { destinationKind, destinationAddress } = this.props;
const { validAddress } = this.state; const { validAddress } = this.state;
return ( return (
<article className="swap-start"> <article className="swap-start">
@ -49,14 +54,18 @@ export default class ReceivingAddress extends Component {
? 'is-valid' ? 'is-valid'
: 'is-invalid'}`} : 'is-invalid'}`}
type="text" type="text"
value={receivingAddress} value={destinationAddress}
onChange={this.onChangeReceivingAddress} onChange={this.onChangeDestinationAddress}
placeholder={DONATION_ADDRESSES_MAP[destinationKind]} placeholder={DONATION_ADDRESSES_MAP[destinationKind]}
/> />
</div> </div>
</section> </section>
<section className="row text-center"> <section className="row text-center">
<button disabled={!validAddress} className="btn btn-primary btn-lg"> <button
disabled={!validAddress}
onClick={this.onClickPartTwoComplete}
className="btn btn-primary btn-lg"
>
<span>{translate('SWAP_start_CTA')}</span> <span>{translate('SWAP_start_CTA')}</span>
</button> </button>
</section> </section>

View File

@ -0,0 +1,56 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
// import { toFixedIfLarger } from 'utils/formatters';
// import translate from 'translations';
export default class SwapProgress extends Component {
constructor(props) {
super(props);
}
static propTypes = {
numberOfConfirmations: PropTypes.number,
destinationKind: PropTypes.string,
originKind: PropTypes.string,
activeStep: PropTypes.number
};
render() {
const { numberOfConfirmations, destinationKind, originKind } = this.props;
return (
<section className="row swap-progress">
<div className="sep" />
<div className="progress-item progress-true">
<div className="progress-circle"><i>1</i></div>
<p className="ng-scope">Order Initiated</p>
</div>
<div className="progress-item progress-true">
<div className="progress-circle"><i>2</i></div>
<p>
<span className="ng-scope">Waiting for your </span>{originKind}...
</p>
</div>
<div className="progress-item progress-active">
<div className="progress-circle"><i>3</i></div>
<p>
ETH <span className="ng-scope">Received!</span>
</p>
</div>
<div className="progress-item">
<div className="progress-circle"><i>4</i></div>
<p>
<span className="ng-scope">destination your</span>{' '}
{destinationKind} <br />
<small>
Waiting for {numberOfConfirmations} confirmations...
</small>
</p>
</div>
<div className="progress-item">
<div className="progress-circle"><i>5</i></div>
<p className="ng-scope">Order Complete</p>
</div>
</section>
);
}
}

View File

@ -3,7 +3,8 @@ import CurrencySwap from './components/currencySwap';
import SwapInformation from './components/swapInformation'; import SwapInformation from './components/swapInformation';
import CurrentRates from './components/currentRates'; import CurrentRates from './components/currentRates';
import ReceivingAddress from './components/receivingAddress'; import ReceivingAddress from './components/receivingAddress';
import SwapProgress from './components/swapProgress';
import OnGoingSwapInformation from './components/onGoingSwapInformation';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import * as swapActions from 'actions/swap'; import * as swapActions from 'actions/swap';
@ -25,14 +26,17 @@ class Swap extends Component {
destinationKind: PropTypes.string, destinationKind: PropTypes.string,
destinationKindOptions: PropTypes.array, destinationKindOptions: PropTypes.array,
originKindOptions: PropTypes.array, originKindOptions: PropTypes.array,
receivingAddress: PropTypes.string, destinationAddress: PropTypes.string,
originKindSwap: PropTypes.func, originKindSwap: PropTypes.func,
destinationKindSwap: PropTypes.func, destinationKindSwap: PropTypes.func,
originAmountSwap: PropTypes.func, originAmountSwap: PropTypes.func,
destinationAmountSwap: PropTypes.func, destinationAmountSwap: PropTypes.func,
updateBityRatesSwap: PropTypes.func, updateBityRatesSwap: PropTypes.func,
partOneCompleteSwap: PropTypes.func, partOneCompleteSwap: PropTypes.func,
receivingAddressSwap: PropTypes.func destinationAddressSwap: PropTypes.func,
restartSwap: PropTypes.func,
partTwoCompleteSwap: PropTypes.func,
partTwoComplete: PropTypes.bool
}; };
componentDidMount() { componentDidMount() {
@ -65,8 +69,11 @@ class Swap extends Component {
destinationAmountSwap, destinationAmountSwap,
partOneComplete, partOneComplete,
partOneCompleteSwap, partOneCompleteSwap,
receivingAddressSwap, destinationAddressSwap,
receivingAddress destinationAddress,
restartSwap,
partTwoCompleteSwap,
partTwoComplete
} = this.props; } = this.props;
let wantToSwapMyProps = { let wantToSwapMyProps = {
@ -91,10 +98,26 @@ class Swap extends Component {
destinationKind destinationKind
}; };
let yourReceivingProps = { let receivingAddressProps = {
destinationKind, destinationKind,
receivingAddressSwap, destinationAddressSwap,
receivingAddress destinationAddress,
partTwoCompleteSwap
};
const referenceNumber = '2341asdfads';
const timeRemaining = '2:30';
let onGoingSwapInformationProps = {
// from bity
referenceNumber: referenceNumber,
timeRemaining: timeRemaining,
originAmount,
originKind,
destinationKind,
destinationAmount,
restartSwap
}; };
return ( return (
@ -102,14 +125,22 @@ class Swap extends Component {
<div className="tab-content"> <div className="tab-content">
<main className="tab-pane swap-tab"> <main className="tab-pane swap-tab">
{!partOneComplete && {!partOneComplete &&
!partTwoComplete &&
<div> <div>
<CurrentRates {...bityRates} /> <CurrentRates {...bityRates} />
<CurrencySwap {...wantToSwapMyProps} /> <CurrencySwap {...wantToSwapMyProps} />
</div>} </div>}
{partOneComplete && {partOneComplete &&
!partTwoComplete &&
<div> <div>
<SwapInformation {...yourInformationProps} /> <SwapInformation {...yourInformationProps} />
<ReceivingAddress {...yourReceivingProps} /> <ReceivingAddress {...receivingAddressProps} />
</div>}
{partOneComplete &&
partTwoComplete &&
<div>
<OnGoingSwapInformation {...onGoingSwapInformationProps} />
<SwapProgress {...onGoingSwapInformationProps} />
</div>} </div>}
</main> </main>
</div> </div>
@ -120,7 +151,8 @@ class Swap extends Component {
function mapStateToProps(state) { function mapStateToProps(state) {
return { return {
receivingAddress: state.swap.receivingAddress, partTwoComplete: state.swap.partTwoComplete,
destinationAddress: state.swap.destinationAddress,
partOneComplete: state.swap.partOneComplete, partOneComplete: state.swap.partOneComplete,
originAmount: state.swap.originAmount, originAmount: state.swap.originAmount,
destinationAmount: state.swap.destinationAmount, destinationAmount: state.swap.destinationAmount,

View File

@ -5,7 +5,9 @@ import {
SWAP_ORIGIN_KIND, SWAP_ORIGIN_KIND,
SWAP_UPDATE_BITY_RATES, SWAP_UPDATE_BITY_RATES,
SWAP_PART_ONE_COMPLETE, SWAP_PART_ONE_COMPLETE,
SWAP_RECEIVING_ADDRESS SWAP_DESTINATION_ADDRESS,
SWAP_RESTART,
SWAP_PART_TWO_COMPLETE
} from 'actions/swapConstants'; } from 'actions/swapConstants';
import { combineAndUpper } from 'api/bity'; import { combineAndUpper } from 'api/bity';
@ -23,8 +25,9 @@ const initialState = {
element => element !== 'REP' element => element !== 'REP'
), ),
partOneComplete: false, partOneComplete: false,
partTwoComplete: false,
bityRates: {}, bityRates: {},
receivingAddress: '' destinationAddress: ''
}; };
const buildDestinationAmount = ( const buildDestinationAmount = (
@ -103,10 +106,21 @@ export function swap(state = initialState, action) {
...state, ...state,
partOneComplete: action.value partOneComplete: action.value
}; };
case SWAP_RECEIVING_ADDRESS: case SWAP_PART_TWO_COMPLETE:
return { return {
...state, ...state,
receivingAddress: action.value partTwoComplete: action.value
};
case SWAP_DESTINATION_ADDRESS:
return {
...state,
destinationAddress: action.value
};
case SWAP_RESTART:
return {
...state,
...initialState,
bityRates: state.bityRates
}; };
default: default:
return state; return state;