2019-01-31 23:40:23 +05:30
|
|
|
import React, { Component } from 'react';
|
2018-06-07 23:13:33 +01:00
|
|
|
import PropTypes from 'prop-types';
|
2019-12-09 22:05:09 +01:00
|
|
|
import { CardNumberElement, CardExpiryElement } from 'react-stripe-elements';
|
2019-12-23 15:31:10 +03:00
|
|
|
import {
|
|
|
|
Row,
|
|
|
|
Col,
|
|
|
|
ControlLabel,
|
|
|
|
FormGroup,
|
|
|
|
Image
|
|
|
|
} from '@freecodecamp/react-bootstrap';
|
2020-12-16 02:02:52 -06:00
|
|
|
import { withTranslation } from 'react-i18next';
|
2018-06-07 23:13:33 +01:00
|
|
|
|
|
|
|
const propTypes = {
|
2019-10-31 20:29:47 +03:00
|
|
|
getValidationState: PropTypes.func.isRequired,
|
2020-12-16 02:02:52 -06:00
|
|
|
t: PropTypes.func.isRequired,
|
2019-10-31 20:29:47 +03:00
|
|
|
theme: PropTypes.string
|
2018-06-07 23:13:33 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
const style = {
|
|
|
|
base: {
|
2019-01-31 23:40:23 +05:30
|
|
|
fontSize: '18px'
|
2018-06-07 23:13:33 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-01-31 23:40:23 +05:30
|
|
|
class StripeCardForm extends Component {
|
2018-06-07 23:13:33 +01:00
|
|
|
constructor(...props) {
|
|
|
|
super(...props);
|
|
|
|
|
|
|
|
this.state = {
|
|
|
|
validation: {
|
|
|
|
cardNumber: {
|
|
|
|
complete: false,
|
|
|
|
error: null
|
|
|
|
},
|
|
|
|
cardExpiry: {
|
|
|
|
complete: false,
|
|
|
|
error: null
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
this.handleInputChange = this.handleInputChange.bind(this);
|
|
|
|
this.isValidInput = this.isValidInput.bind(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
componentDidMount() {
|
|
|
|
this.props.getValidationState(this.isValidInput());
|
|
|
|
}
|
|
|
|
|
|
|
|
handleInputChange(event) {
|
|
|
|
const { elementType, error, complete } = event;
|
|
|
|
return this.setState(
|
|
|
|
state => ({
|
|
|
|
...state,
|
|
|
|
validation: {
|
|
|
|
...state.validation,
|
|
|
|
[elementType]: {
|
|
|
|
error,
|
|
|
|
complete
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
() => this.props.getValidationState(this.isValidInput())
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
isValidInput() {
|
|
|
|
const { validation } = this.state;
|
|
|
|
return Object.keys(validation)
|
|
|
|
.map(key => validation[key])
|
|
|
|
.every(({ complete, error }) => complete && !error);
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
2020-12-16 02:02:52 -06:00
|
|
|
const { t } = this.props;
|
2019-10-31 20:29:47 +03:00
|
|
|
// set color based on theme
|
|
|
|
style.base.color = this.props.theme === 'night' ? '#fff' : '#0a0a23';
|
2018-06-07 23:13:33 +01:00
|
|
|
return (
|
|
|
|
<div className='donation-elements'>
|
|
|
|
<FormGroup>
|
2020-12-16 02:02:52 -06:00
|
|
|
<ControlLabel>{t('donate.card-number')}</ControlLabel>
|
2019-01-31 23:40:23 +05:30
|
|
|
<CardNumberElement
|
2019-02-07 02:39:32 +05:30
|
|
|
className='form-control donate-input-element'
|
2019-01-31 23:40:23 +05:30
|
|
|
onChange={this.handleInputChange}
|
|
|
|
style={style}
|
|
|
|
/>
|
2018-06-07 23:13:33 +01:00
|
|
|
</FormGroup>
|
|
|
|
<FormGroup>
|
2020-12-16 02:02:52 -06:00
|
|
|
<ControlLabel>{t('donate.expiration')}</ControlLabel>
|
2019-12-23 15:31:10 +03:00
|
|
|
<Row>
|
|
|
|
<Col md={5} xs={12}>
|
|
|
|
<CardExpiryElement
|
|
|
|
className='form-control donate-input-element'
|
|
|
|
onChange={this.handleInputChange}
|
|
|
|
style={style}
|
|
|
|
/>
|
|
|
|
</Col>
|
|
|
|
<Col className='form-payments-wrapper' md={7} xs={12}>
|
|
|
|
<Image
|
|
|
|
alt='payment options'
|
|
|
|
className='form-payment-methods'
|
|
|
|
src={
|
|
|
|
'https://cdn.freecodecamp.org' +
|
|
|
|
'/platform/universal/form-payments.png'
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
</Col>
|
|
|
|
</Row>
|
2018-06-07 23:13:33 +01:00
|
|
|
</FormGroup>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-31 23:40:23 +05:30
|
|
|
StripeCardForm.displayName = 'StripeCardForm';
|
|
|
|
StripeCardForm.propTypes = propTypes;
|
2018-06-07 23:13:33 +01:00
|
|
|
|
2020-12-16 02:02:52 -06:00
|
|
|
export default withTranslation()(StripeCardForm);
|