Skip to content

Instantly share code, notes, and snippets.

@sheva29
Last active September 13, 2018 01:38
Show Gist options
  • Save sheva29/547766a945606856f17b7eec8ab70ad1 to your computer and use it in GitHub Desktop.
Save sheva29/547766a945606856f17b7eec8ab70ad1 to your computer and use it in GitHub Desktop.
React component - trigger event
import React from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router';
import { Field, Fields, reduxForm, getFormValues, initialize } from 'redux-form';
import { PageHeader, PageBody, PageFooter } from '../../Layout';
import FieldText, { FieldExpDate,
required,
validateName
} from '../../forms/FieldText';
import FieldSelect from '../../forms/FieldSelect';
import classNames from 'classnames';
import countries from '../../forms/FieldSelect/countries.json';
import { getMessage } from '../../Message';
import { cards } from '../../../utils/creditCards';
import { codes } from '../../../utils/postalCodes';
import { saveCardPromise, onChangeCountry, loadEncryptionScript, clearErrors } from '../../../redux/modules/manageBilling';
import { CardIcons, CvvIcons } from '../../Icons';
import css from './CreditCard.css';
import { track } from '../../../utils/tracking';
import {CreditCardNotification} from "./CreditCardNotification";
import { bindActionCreators } from 'redux';
const formId = 'creditCard';
@connect(
state => ({
manageableFi : state.manageBilling.manageableFi,
unmanageableFi : state.manageBilling.unmanageableFi,
initialValues: {
country: 'US',
accountType: state.manageBilling.accountType,
initialError: state.manageBilling.error
},
currentValues: getFormValues(formId)(state),
closedNotifications: state.manageBilling.closedNotifications,
isLoading: state.manageBilling.isLoading,
scriptLoading: state.manageBilling.scriptLoading,
scriptLoadingError: state.manageBilling.scriptLoadingError
}),
dispatch => ({...bindActionCreators({ loadEncryptionScript, clearErrors, onChangeCountry }, dispatch)})
)
@reduxForm({
form: formId,
enableReinitialize: true
})
export default class CreditCard extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
componentWillMount () {
if (this.props.scriptLoading !== 'isLoaded') {
this.props.loadEncryptionScript(this.props);
}
}
componentWillUpdate (nextProps) {
const { initialValues } = nextProps;
if ( initialValues.accountType !== this.props.initialValues.accountType) {
this.props.dispatch(initialize(formId, initialValues));
}
}
componentWillUnmount () {
this.props.clearErrors();
}
componentDidUpdate () {
console.log("props:", this.props);
}
render() {
const {
manageableFi, unmanageableFi,
basePath, location,
error, handleSubmit, reset, submitting, pristine,
currentValues: { country, ccnumber, accountType, initialError } = {},
scriptLoadingError,
onChangeCountry
} = this.props;
const isUS = country === 'US';
const addBillingStreetAddress = accountType === 'hd' || accountType === 'digi_hd';
return (
<div className="credit-card">
<PageHeader/>
<PageBody {...this.props}>
<h2 className="body-title">
<span>Credit Card Information</span>
<Link to={`${basePath}/billing-options${location.search}${location.hash}`} onClick={track('credit_card__link_back')}>
<button name="payment-info-view" className="button-back button-box">
Back
</button>
</Link>
</h2>
{
scriptLoadingError ?
<div className="error server-error">{ getMessage(scriptLoadingError) }</div>
:
initialError &&
<div className="error server-error">{getMessage(initialError) || getMessage('pra-exception')}</div>
}
<form onSubmit={handleSubmit(saveCardPromise)} className={css.formCreditCard}>
<Field name="ccnumber" component={FieldText} label="Card Number"
type="tel" maxLength="19" autoComplete="cc-number"
validate={[cards.validateNumber]} normalize={cards.normalizeNumber}
>
<CardIcons number={ccnumber} country={country}/>
</Field>
<div className="flex-wrapper">
<Fields names={['cc-exp-month', 'cc-exp-year']} component={FieldExpDate}
/>
<Field name="cvv2" component={FieldText} type="tel" label="Security Code"
maxLength="4" placeholder="CVC" autoComplete="off"
validate={[cards.validateCVV]} normalize={cards.normalizeCVV}
>
<CvvIcons number={ccnumber} country={country}/>
</Field>
</div>
<h4>Billing address</h4>
<Field name="country" component={FieldSelect} label="Country"
options={countries} autoComplete="shipping country"
/>
{
addBillingStreetAddress &&
<span>
<Field name="address" component={FieldText} label="Address"
type="text" autoComplete="shipping street-address"
validate={[required('incomplete-address')]}
maxLength="29"
/>
<Field name="apartment" component={FieldText} label="Apartment, Suite or Building (Optional)"
type="text" autoComplete="apartment" maxLength="23"
/>
</span>
}
<Field name="postal-code" component={FieldText} label={isUS ? 'Zip Code' : 'Postal Code'}
type={isUS ? 'tel' : 'text'} maxLength={isUS ? '5' : '9'} autoComplete="shipping postal-code"
validate={[codes.validatePostalCode]} normalize={codes.normalizePostalCode(isUS)}
/>
<div className="flex-wrapper">
<Field name="given-name" component={FieldText} label="First Name"
type="text" autoComplete="given-name"
validate={[required('incomplete-cc-first-name'), validateName('invalid-cc-first-name')]}
maxLength="30"
/>
<Field name="family-name" component={FieldText} label="Last Name"
type="text" autoComplete="family-name"
validate={[required('incomplete-cc-last-name'), validateName('invalid-cc-last-name')]}
maxLength="30"
/>
</div>
<div className="secure-transaction">This is a secure transaction.</div>
<CreditCardNotification
manageableFi={ manageableFi }
unmanageableFi={ unmanageableFi }
/>
{error && <div className="error server-error">{getMessage(error) || getMessage('api-exception')}</div>}
<div className="buttons-holder">
<div className="button-wrapper">
<button
className={classNames({
'button-box primary': true,
'loading': submitting,
'disabled': submitting || scriptLoadingError
})}
type="submit"
disabled={ submitting || scriptLoadingError }
>
Save
</button>
</div>
<div className="button-wrapper">
<button className="button-box" disabled={pristine || submitting} onClick={reset}>Reset</button>
</div>
</div>
</form>
</PageBody>
<PageFooter {...this.props} />
</div>
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment