github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/build-blockchain-insurance-app-master/web/src/shop/components/PaymentPage.js (about) 1 'use strict'; 2 3 import React, { Props } from 'react'; 4 import PropTypes from 'prop-types'; 5 import { FormattedMessage, FormattedNumber, injectIntl, intlShape } from 'react-intl'; 6 import { bindActionCreators } from 'redux'; 7 import { connect } from 'react-redux'; 8 import { withRouter, Redirect } from 'react-router-dom'; 9 import moment from 'moment'; 10 11 import Loading from '../../shared/Loading'; 12 import * as paymentActions from '../actions/paymentActions'; 13 import * as userMgmtActions from '../actions/userMgmtActions'; 14 import { enterContract } from '../api'; 15 16 class PaymentPage extends React.Component { 17 18 static get propTypes() { 19 return { 20 intl: intlShape.isRequired, 21 shopType: PropTypes.string.isRequired, 22 productInfo: PropTypes.object.isRequired, 23 contractInfo: PropTypes.object.isRequired, 24 payed: PropTypes.bool.isRequired, 25 user: PropTypes.object, 26 paymentActions: PropTypes.object.isRequired, 27 userMgmtActions: PropTypes.object.isRequired 28 }; 29 } 30 31 constructor(props) { 32 super(props); 33 34 this.inTransaction = false; 35 this.state = { loading: false }; 36 this.order = this.order.bind(this); 37 this.executeTransaction = this.executeTransaction.bind(this); 38 } 39 40 order() { 41 this.setState({ loading: true }, async () => { 42 this.props.paymentActions.pay(); 43 await this.executeTransaction(); 44 this.setState({ redirectToNext: true }); 45 }); 46 } 47 48 async executeTransaction() { 49 if (this.inTransaction) { 50 return; 51 } 52 this.inTransaction = true; 53 const { contractInfo, productInfo, userMgmtActions } = this.props; 54 const { email, firstName, lastName } = contractInfo; 55 const user = { username: email, firstName, lastName }; 56 const loginInfo = await enterContract(user, contractInfo.uuid, { 57 item: { 58 id: parseInt(productInfo.index), 59 brand: productInfo.brand, 60 model: productInfo.model, 61 price: productInfo.price, 62 serialNo: productInfo.serialNo, 63 description: productInfo.description 64 }, 65 startDate: new Date(contractInfo.startDate), 66 endDate: new Date(contractInfo.endDate) 67 }); 68 userMgmtActions.setUser({ 69 firstName, lastName, 70 username: email, password: loginInfo.password 71 }); 72 this.inTransaction = false; 73 } 74 75 render() { 76 let paymentStatus; 77 78 const { intl, productInfo, contractInfo } = this.props; 79 const { redirectToNext } = this.state; 80 81 const startDate = moment(new Date(contractInfo.startDate)); 82 const endDate = moment(new Date(contractInfo.endDate)); 83 const dateDiff = moment.duration(endDate.diff(startDate)).asDays(); 84 85 const insurancePrice = dateDiff * ( 86 contractInfo.formulaPerDay(productInfo.price)); 87 const total = productInfo.price + insurancePrice; 88 89 if (redirectToNext) { 90 return ( 91 <Redirect to='/summary' /> 92 ); 93 } 94 95 if (!productInfo) { 96 return ( 97 <Redirect to='/' /> 98 ); 99 } 100 101 return ( 102 <Loading hidden={!this.state.loading} text={intl.formatMessage({ 103 id: 'Processing Transaction...' 104 })}> 105 <div> 106 <div className='ibm-columns'> 107 <div className='ibm-col-2-1 ibm-col-medium-5-3 ibm-col-small-1-1'> 108 <h3 className='ibm-h3'> 109 <FormattedMessage id='Payment' /> 110 </h3> 111 </div> 112 </div> 113 <div className='ibm-columns'> 114 <div className='ibm-col-2-1 ibm-col-medium-5-3 ibm-col-small-1-1'> 115 <table cols='2' style={{ width: '100%' }}> 116 <tbody> 117 <tr> 118 <td style={{ padding: '.3em' }} colSpan='2' 119 className='ibm-background-blue-20'> 120 <h4 className='ibm-h4'> 121 <FormattedMessage id='Product' /> 122 </h4> 123 </td> 124 </tr> 125 <tr> 126 <td> 127 {productInfo.brand} 128 <br /> 129 {productInfo.model} 130 <br /> 131 <FormattedMessage id='Serial No.' />: {productInfo.serialNo} 132 </td> 133 <td className='ibm-right'> 134 <FormattedNumber style='currency' 135 currency={intl.formatMessage({ id: 'currency code' })} 136 value={productInfo.price} minimumFractionDigits={2} /> 137 </td> 138 </tr> 139 <tr> 140 <td style={{ padding: '.3em' }} colSpan='2' 141 className='ibm-background-blue-20'> 142 <h4 className='ibm-h4'> 143 <FormattedMessage id='Services' /> 144 </h4> 145 </td> 146 </tr> 147 <tr> 148 <td> 149 <FormattedMessage id='Insurance' /> 150 </td> 151 <td className='ibm-right'> 152 <FormattedNumber style='currency' 153 currency={intl.formatMessage({ id: 'currency code' })} 154 value={insurancePrice} minimumFractionDigits={2} /> 155 </td> 156 </tr> 157 <tr> 158 <td className='ibm-background-gray-10' 159 style={{ padding: '.3em' }}> 160 <h3 className='ibm-h3'> 161 <FormattedMessage id='Total' /> 162 </h3> 163 </td> 164 <td className='ibm-background-gray-10 ibm-right'> 165 <h3 className='ibm-h3'> 166 <FormattedNumber style='currency' 167 currency={intl.formatMessage({ id: 'currency code' })} 168 value={total} minimumFractionDigits={2} /> 169 </h3> 170 </td> 171 </tr> 172 </tbody> 173 </table> 174 </div> 175 </div> 176 <div className='ibm-columns'> 177 <div className='ibm-col-2-1 ibm-col-medium-5-3 ibm-col-small-1-1 ibm-right'> 178 <button type='button' className='ibm-btn-pri ibm-btn-blue-50' 179 onClick={this.order}><FormattedMessage id='Order' /></button> 180 </div> 181 </div> 182 </div> 183 </Loading> 184 ); 185 } 186 } 187 188 function mapStateToProps(state, ownProps) { 189 return { 190 shopType: state.shop.type, 191 productInfo: state.shop.productInfo, 192 contractInfo: state.insurance.contractInfo, 193 payed: state.payment.payed, 194 user: state.userMgmt.user 195 }; 196 } 197 198 function mapDispatchToProps(dispatch) { 199 return { 200 paymentActions: bindActionCreators(paymentActions, dispatch), 201 userMgmtActions: bindActionCreators(userMgmtActions, dispatch) 202 }; 203 } 204 205 export default withRouter( 206 connect(mapStateToProps, mapDispatchToProps)(injectIntl(PaymentPage)));