'use strict'; import React, { Props } from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage, FormattedNumber, injectIntl, intlShape } from 'react-intl'; import { bindActionCreators } from 'redux'; import { connect } from 'react-redux'; import { withRouter, Redirect } from 'react-router-dom'; import moment from 'moment'; import Loading from '../../shared/Loading'; import * as paymentActions from '../actions/paymentActions'; import * as userMgmtActions from '../actions/userMgmtActions'; import { enterContract } from '../api'; class PaymentPage extends React.Component { static get propTypes() { return { intl: intlShape.isRequired, shopType: PropTypes.string.isRequired, productInfo: PropTypes.object.isRequired, contractInfo: PropTypes.object.isRequired, payed: PropTypes.bool.isRequired, user: PropTypes.object, paymentActions: PropTypes.object.isRequired, userMgmtActions: PropTypes.object.isRequired }; } constructor(props) { super(props); this.inTransaction = false; this.state = { loading: false }; this.order = this.order.bind(this); this.executeTransaction = this.executeTransaction.bind(this); } order() { this.setState({ loading: true }, async () => { this.props.paymentActions.pay(); await this.executeTransaction(); this.setState({ redirectToNext: true }); }); } async executeTransaction() { if (this.inTransaction) { return; } this.inTransaction = true; const { contractInfo, productInfo, userMgmtActions } = this.props; const { email, firstName, lastName } = contractInfo; const user = { username: email, firstName, lastName }; const loginInfo = await enterContract(user, contractInfo.uuid, { item: { id: parseInt(productInfo.index), brand: productInfo.brand, model: productInfo.model, price: productInfo.price, serialNo: productInfo.serialNo, description: productInfo.description }, startDate: new Date(contractInfo.startDate), endDate: new Date(contractInfo.endDate) }); userMgmtActions.setUser({ firstName, lastName, username: email, password: loginInfo.password }); this.inTransaction = false; } render() { let paymentStatus; const { intl, productInfo, contractInfo } = this.props; const { redirectToNext } = this.state; const startDate = moment(new Date(contractInfo.startDate)); const endDate = moment(new Date(contractInfo.endDate)); const dateDiff = moment.duration(endDate.diff(startDate)).asDays(); const insurancePrice = dateDiff * ( contractInfo.formulaPerDay(productInfo.price)); const total = productInfo.price + insurancePrice; if (redirectToNext) { return ( <Redirect to='/summary' /> ); } if (!productInfo) { return ( <Redirect to='/' /> ); } return ( <Loading hidden={!this.state.loading} text={intl.formatMessage({ id: 'Processing Transaction...' })}> <div> <div className='ibm-columns'> <div className='ibm-col-2-1 ibm-col-medium-5-3 ibm-col-small-1-1'> <h3 className='ibm-h3'> <FormattedMessage id='Payment' /> </h3> </div> </div> <div className='ibm-columns'> <div className='ibm-col-2-1 ibm-col-medium-5-3 ibm-col-small-1-1'> <table cols='2' style={{ width: '100%' }}> <tbody> <tr> <td style={{ padding: '.3em' }} colSpan='2' className='ibm-background-blue-20'> <h4 className='ibm-h4'> <FormattedMessage id='Product' /> </h4> </td> </tr> <tr> <td> {productInfo.brand} <br /> {productInfo.model} <br /> <FormattedMessage id='Serial No.' />: {productInfo.serialNo} </td> <td className='ibm-right'> <FormattedNumber style='currency' currency={intl.formatMessage({ id: 'currency code' })} value={productInfo.price} minimumFractionDigits={2} /> </td> </tr> <tr> <td style={{ padding: '.3em' }} colSpan='2' className='ibm-background-blue-20'> <h4 className='ibm-h4'> <FormattedMessage id='Services' /> </h4> </td> </tr> <tr> <td> <FormattedMessage id='Insurance' /> </td> <td className='ibm-right'> <FormattedNumber style='currency' currency={intl.formatMessage({ id: 'currency code' })} value={insurancePrice} minimumFractionDigits={2} /> </td> </tr> <tr> <td className='ibm-background-gray-10' style={{ padding: '.3em' }}> <h3 className='ibm-h3'> <FormattedMessage id='Total' /> </h3> </td> <td className='ibm-background-gray-10 ibm-right'> <h3 className='ibm-h3'> <FormattedNumber style='currency' currency={intl.formatMessage({ id: 'currency code' })} value={total} minimumFractionDigits={2} /> </h3> </td> </tr> </tbody> </table> </div> </div> <div className='ibm-columns'> <div className='ibm-col-2-1 ibm-col-medium-5-3 ibm-col-small-1-1 ibm-right'> <button type='button' className='ibm-btn-pri ibm-btn-blue-50' onClick={this.order}><FormattedMessage id='Order' /></button> </div> </div> </div> </Loading> ); } } function mapStateToProps(state, ownProps) { return { shopType: state.shop.type, productInfo: state.shop.productInfo, contractInfo: state.insurance.contractInfo, payed: state.payment.payed, user: state.userMgmt.user }; } function mapDispatchToProps(dispatch) { return { paymentActions: bindActionCreators(paymentActions, dispatch), userMgmtActions: bindActionCreators(userMgmtActions, dispatch) }; } export default withRouter( connect(mapStateToProps, mapDispatchToProps)(injectIntl(PaymentPage)));