github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/build-blockchain-insurance-app-master/web/src/shop/components/ChooseInsurancePage.js (about) 1 'use strict'; 2 3 import React, { Props } from 'react'; 4 import PropTypes from 'prop-types'; 5 import { bindActionCreators } from 'redux'; 6 import { connect } from 'react-redux'; 7 import { FormattedMessage, injectIntl, intlShape } from 'react-intl'; 8 import { withRouter, Redirect } from 'react-router-dom'; 9 10 import Loading from '../../shared/Loading'; 11 import SelectList from '../../shared/SelectList'; 12 import DateInput from '../../shared/DateInput'; 13 import * as insuranceActions from '../actions/insuranceActions'; 14 15 class ChooseInsurancePage extends React.Component { 16 17 static get propTypes() { 18 return { 19 intl: intlShape.isRequired, 20 shopType: PropTypes.string.isRequired, 21 productInfo: PropTypes.object.isRequired, 22 contractsLoaded: PropTypes.bool.isRequired, 23 contractTypes: PropTypes.array.isRequired, 24 contractInfo: PropTypes.object, 25 insuranceActions: PropTypes.object.isRequired, 26 history: PropTypes.object.isRequired 27 }; 28 } 29 30 constructor(props) { 31 super(props); 32 33 this.state = { 34 contractType: {}, 35 dailyPrice: '', 36 contractInfo: props.contractInfo || { 37 firstName: '', 38 lastName: '', 39 email: '', 40 startDate: 0, 41 endDate: 0 42 } 43 }; 44 45 this.nextStep = this.nextStep.bind(this); 46 this.setContractType = this.setContractType.bind(this); 47 this.setContractInfo = this.setContractInfo.bind(this); 48 this.getContractCaption = elem => elem.description; 49 this.setStartDate = date => this.setContractInfo( 50 { element: 'startDateField', value: date }); 51 this.setEndDate = date => this.setContractInfo( 52 { element: 'endDateField', value: date }); 53 } 54 55 componentWillMount() { 56 if (this.props.contractsLoaded && !this.state.contractType.uuid) { 57 const contractType = this.props.contractInfo ? 58 this.props.contractTypes.find( 59 ct => ct.id === this.props.contractInfo.uuid) : 60 // Fallback to the first one, if none is defined. 61 this.props.contractTypes[0]; 62 63 this.setContractType(contractType); 64 } 65 } 66 67 componentWillReceiveProps(nextProps) { 68 if (nextProps.contractsLoaded && !this.state.contractType.uuid) { 69 const contractType = nextProps.contractInfo ? 70 nextProps.contractTypes.find( 71 ct => ct.id === nextProps.contractInfo.uuid) : 72 // Fallback to the first contract type 73 nextProps.contractTypes[0]; 74 75 this.setContractType(contractType); 76 } 77 } 78 79 setContractType(contractType) { 80 this.setState(Object.assign({}, this.state, 81 { 82 contractType, 83 dailyPrice: contractType.formulaPerDay(this.props.productInfo.price) 84 })); 85 } 86 87 setContractInfo(event) { 88 let obj; 89 if (event.target) { 90 switch (event.target) { 91 case this.refs.firstNameField: 92 obj = { firstName: event.target.value }; 93 break; 94 case this.refs.lastNameField: 95 obj = { lastName: event.target.value }; 96 break; 97 case this.refs.emailField: 98 obj = { email: event.target.value }; 99 break; 100 default: 101 return; 102 } 103 } else if (typeof event.element === 'string') { 104 switch (event.element) { 105 case 'startDateField': 106 obj = { startDate: event.value }; 107 break; 108 case 'endDateField': 109 obj = { endDate: event.value }; 110 break; 111 default: 112 return; 113 } 114 } else { 115 return; 116 } 117 this.setState(Object.assign({}, 118 this.state, 119 { contractInfo: Object.assign({}, this.state.contractInfo, obj) })); 120 } 121 122 nextStep() { 123 // Persist data 124 this.props.insuranceActions.submitContract( 125 Object.assign({}, this.state.contractInfo, this.state.contractType)); 126 // Navigate to the next page 127 this.setState({ redirectToNext: true }); 128 } 129 130 render() { 131 let messageAtTop; 132 switch (this.props.shopType) { 133 case 'bikes': 134 messageAtTop = <FormattedMessage id='Buy Insurance for the Bike' />; 135 break; 136 case 'smart-phones': 137 messageAtTop = <FormattedMessage 138 id='Buy Insurance for the Smart Phone' />; 139 break; 140 case 'skis': 141 messageAtTop = <FormattedMessage id='Buy Insurance the Pair of Skis' />; 142 break; 143 } 144 145 let { contractType, contractInfo, dailyPrice, redirectToNext } = this.state; 146 let { intl, contractsLoaded, contractTypes } = this.props; 147 148 if (redirectToNext) { 149 return ( 150 <Redirect to='/payment' /> 151 ); 152 } 153 154 return ( 155 <Loading hidden={contractsLoaded} 156 text={intl.formatMessage({ id: 'Loading Contracts...' })}> 157 <div> 158 <div className='ibm-columns'> 159 <div className='ibm-col-1-1'> 160 <h3 className='ibm-h3'>{messageAtTop}</h3> 161 </div> 162 </div> 163 <div className='ibm-columns'> 164 <div className='ibm-col-2-1 ibm-col-medium-5-3 ibm-col-small-1-1'> 165 <div className='ibm-column-form'> 166 <p> 167 <label><FormattedMessage id='Contract' />:</label> 168 <span> 169 <SelectList options={contractTypes} 170 getCaptionFunc={this.getContractCaption} 171 onChange={this.setContractType} 172 selectedItemIndex={contractTypes.indexOf(contractType)} /> 173 </span> 174 </p> 175 <p> 176 <label><FormattedMessage id='Daily Price' />:</label> 177 <span> 178 <input type='text' readOnly value={ 179 intl.formatNumber(dailyPrice, 180 { 181 style: 'currency', 182 currency: intl.formatMessage({ id: 'currency code' }), 183 minimumFractionDigits: 2 184 })} /> 185 </span> 186 </p> 187 <p className='ibm-form-elem-grp'> 188 <label><FormattedMessage className='ibm-field-label' 189 id='Theft Protection' />:</label> 190 <span className='ibm-input-group'> 191 <input type='checkbox' className='ibm-styled-checkbox' 192 ref='theftInsuredField' 193 checked={contractType.theftInsured} readOnly /> 194 <label className='ibm-field-label' 195 htmlFor='theftInsuredField' /> 196 </span> 197 </p> 198 <p> 199 <label><FormattedMessage id='Contract Terms' />:</label> 200 <span> 201 <textarea value={contractType.conditions} readOnly /> 202 </span> 203 </p> 204 <p> 205 <label><FormattedMessage id='First Name' />: 206 <span className='ibm-required'>*</span></label> 207 <span> 208 <input ref='firstNameField' value={contractInfo.firstName} 209 type='text' onChange={this.setContractInfo} /> 210 </span> 211 </p> 212 <p> 213 <label><FormattedMessage id='Last Name' />: 214 <span className='ibm-required'>*</span></label> 215 <span> 216 <input ref='lastNameField' value={contractInfo.lastName} 217 type='text' onChange={this.setContractInfo} /> 218 </span> 219 </p> 220 <p> 221 <label><FormattedMessage id='E-mail Address' />: 222 <span className='ibm-required'>*</span></label> 223 <span> 224 <input ref='emailField' value={contractInfo.email} 225 type='text' onChange={this.setContractInfo} /> 226 </span> 227 </p> 228 <p> 229 <label><FormattedMessage id='Start Date' />: 230 <span className='ibm-required'>*</span></label> 231 <span> 232 <DateInput value={contractInfo.startDate} 233 onChange={this.setStartDate} /> 234 </span> 235 </p> 236 <p> 237 <label><FormattedMessage id='End Date' />: 238 <span className='ibm-required'>*</span></label> 239 <span> 240 <DateInput value={contractInfo.endDate} 241 onChange={this.setEndDate} /> 242 </span> 243 </p> 244 </div> 245 </div> 246 </div> 247 <div className='ibm-columns'> 248 <div className='ibm-col-2-1 ibm-col-medium-5-3 ibm-col-small-1-1 ibm-right'> 249 <button type='button' className='ibm-btn-pri ibm-btn-blue-50' 250 onClick={this.nextStep}> 251 <FormattedMessage id='Next' /> 252 </button> 253 </div> 254 </div> 255 </div> 256 </Loading> 257 ); 258 } 259 } 260 261 function mapStateToProps(state, ownProps) { 262 return { 263 shopType: state.shop.type, 264 productInfo: state.shop.productInfo, 265 contractsLoaded: Array.isArray(state.insurance.contractTypes), 266 contractTypes: state.insurance.contractTypes || [], 267 contractInfo: state.insurance.contractInfo 268 }; 269 } 270 271 function mapDispatchToProps(dispatch) { 272 return { 273 insuranceActions: bindActionCreators(insuranceActions, dispatch) 274 }; 275 } 276 277 export default withRouter(connect(mapStateToProps, mapDispatchToProps)( 278 injectIntl(ChooseInsurancePage)));