From af212c95c94740cc18cfbf8bd1fc0a9568cd1f68 Mon Sep 17 00:00:00 2001 From: Emilio Silva Schlenker Date: Wed, 6 Mar 2019 15:13:39 -0300 Subject: [PATCH] Payments processing (#78) The tip page has a new layout. On the right side, it watches for any incoming payments and registers them on the left side, which uses the component RecentPayments, with a few modifications. --- src/class/WatcherTx.js | 2 +- .../components/RecentPayments/index.js | 8 +- src/pages/Dashboard/components/Tip.js | 115 +++++++++++++++++- src/pages/Dashboard/desktop.view.js | 12 +- src/pages/Dashboard/index.js | 4 + src/pages/Payment/components/QrCode.js | 12 +- 6 files changed, 140 insertions(+), 13 deletions(-) diff --git a/src/class/WatcherTx.js b/src/class/WatcherTx.js index c90fef9..eb0af7e 100644 --- a/src/class/WatcherTx.js +++ b/src/class/WatcherTx.js @@ -75,7 +75,7 @@ export default class WatcherTx { if (!toValid) return false; const walletToValid = trx.to.toLowerCase() === recipient.toLowerCase(); - const amountValid = + const amountValid = total === null || web3Http.utils.toWei(total.toString(), 'ether') === trx.value; return toValid && amountValid && walletToValid; diff --git a/src/pages/Dashboard/components/RecentPayments/index.js b/src/pages/Dashboard/components/RecentPayments/index.js index a1e6da1..b93353c 100644 --- a/src/pages/Dashboard/components/RecentPayments/index.js +++ b/src/pages/Dashboard/components/RecentPayments/index.js @@ -25,6 +25,7 @@ const LeftSide = styled.div` class RecentPayments extends React.Component { state = { + type: "transactions", transactions: [], isLoading: true }; @@ -41,15 +42,18 @@ class RecentPayments extends React.Component { isLoading: false }); }); + if(this.props.type) { + this.setState({ type: this.props.type }); + } } render() { const { transactions, isLoading } = this.state; return ( - {isLoading &&

Loading recent transactions.

} + {isLoading &&

Loading recent {this.state.type}.

} {transactions.length === 0 && !isLoading && ( -

No recent transactions found.

+

No recent {this.state.type} found.

)} {transactions.map(item => ( diff --git a/src/pages/Dashboard/components/Tip.js b/src/pages/Dashboard/components/Tip.js index 73dc785..ff3eb5c 100644 --- a/src/pages/Dashboard/components/Tip.js +++ b/src/pages/Dashboard/components/Tip.js @@ -1,13 +1,118 @@ import React, { Component } from 'react'; -import Modal from 'react-responsive-modal'; +import styled from 'styled-components'; +import CryptoAmount from '../../Payment/components/CryptoAmount'; import QrCode from '../../Payment/components/QrCode'; +import WatcherTx from '../../../class/WatcherTx'; +import { Query } from 'react-apollo'; +import { store } from '../../../store'; +import AddressClipboard from '../../Payment/components/AddressClipboard'; +import NetworkStatus from '../../Payment/components/NetworkStatus'; + +const Container = styled.div` + display: flex; + flex-direction: column; +`; + +const FiatContainer = styled.div` + padding: 10px 75px 0px 75px; + border-bottom: ${props => `1px solid ${props.theme.borderColor}`}; + text-align: center; +`; + +const Title = styled.span``; + +const PaymentInfo = styled.div` + padding: 12px 75px; +`; class Tip extends Component { + constructor(props) { + super(props); + this.state = { + posAddress: null, + txState: null, + txHashes: [], + }; + } + + startWatcher() { + this.setState({ txState: WatcherTx.STATES.PENDING }); + this.tipWatcher = new WatcherTx(WatcherTx.NETWORKS.XDAI); + this.tipWatcher.xdaiTransfer(this.state.posAddress, null, data => { + this.setState(prevState => { + //console.log(prevState); + return { + txState: data.state, + //txHashes: prevState.txHashes.push(data.txHash), + }; + }); + if (data.state === WatcherTx.STATES.CONFIRMED) { + this.props.onPaymentReceived(); + } + }); + } + + stopWatcher() { + if(this.tipWatcher) { + this.tipWatcher.pollingOn = false; + this.setState({ txState: null }); + } + } + + componentDidMount() { + store.fetch.pos().subscribe(async result => { + const posAddress = result.data.pos.address; + this.setState({ posAddress }); + }); + this.startWatcher(); + } + + componentWillReceiveProps(nextProps) { + if(nextProps.active) { + this.startWatcher(); + } + else { + this.stopWatcher(); + console.log(this.state); + } + } + render() { - return ( - - - + const { txState } = this.state; + let title = ''; + if (txState === WatcherTx.STATES.PENDING) { + title = `1 / 3 Awaiting Payment`; + } else if (txState === WatcherTx.STATES.DETECTED) { + title = `2 / 3 Pending Payment`; + } else if (txState === WatcherTx.STATES.CONFIRMED) { + title = `3 / 3 Payment Successful`; + } + + return this.props.active && ( + + + + {title} + + + + {({ data }) => ( + + + {this.tipWatcher ? ( + + ) : null} + + )} + + ); }; }; diff --git a/src/pages/Dashboard/desktop.view.js b/src/pages/Dashboard/desktop.view.js index 7739830..ca8a419 100644 --- a/src/pages/Dashboard/desktop.view.js +++ b/src/pages/Dashboard/desktop.view.js @@ -62,15 +62,21 @@ export default function() { } /> )} - {activeTab === 'tip' && ( - - )} + {activeTab === 'tip' && } + {activeTab !== 'tip' && ( + )} + {activeTab !== 'tip' && ( + )} + ) : ( diff --git a/src/pages/Dashboard/index.js b/src/pages/Dashboard/index.js index 0639f47..bb1cb8d 100644 --- a/src/pages/Dashboard/index.js +++ b/src/pages/Dashboard/index.js @@ -63,6 +63,10 @@ class Dashboard extends Component { }, 5000); }; + onTipReceived = () => { + + } + handleNavItemChange = activeTab => { // eslint-disable-next-line const currentTab = this.state.activeTab; diff --git a/src/pages/Payment/components/QrCode.js b/src/pages/Payment/components/QrCode.js index a626be9..d70425c 100644 --- a/src/pages/Payment/components/QrCode.js +++ b/src/pages/Payment/components/QrCode.js @@ -14,17 +14,24 @@ const Container = styled.div` class QrCode extends React.Component { state = { - address: null + address: null, + noValue: false, }; componentDidMount() { store.fetch.pos().subscribe(res => { this.setState({ address: res.data.pos.address }); }); + if(this.props.noValue) { + this.setState({ noValue: this.props.noValue }); + } } getQrData(value) { const { address } = this.state; + if(this.state.noValue) { + return `ethereum:${address}@100`; + } return `ethereum:${address}@100?value=${value}e18`; } @@ -45,7 +52,8 @@ QrCode.propTypes = { }; QrCode.propTypes = { - valueCrypto: PropTypes.string.isRequired + valueCrypto: PropTypes.string.isRequired, + noValue: PropTypes.bool, }; export default QrCode;