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)));