diff --git a/client/src/components/YearEndGift/YearEndDonationForm.js b/client/src/components/YearEndGift/YearEndDonationForm.js new file mode 100644 index 0000000000..d1ab5f6bd8 --- /dev/null +++ b/client/src/components/YearEndGift/YearEndDonationForm.js @@ -0,0 +1,347 @@ +/* eslint-disable react/sort-prop-types */ +/* eslint-disable react/jsx-sort-props */ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { connect } from 'react-redux'; +import { createSelector } from 'reselect'; +import { + Row, + Col, + ControlLabel, + FormControl, + FormGroup, + Button +} from '@freecodecamp/react-bootstrap'; +import { StripeProvider, Elements } from 'react-stripe-elements'; +import { Spacer } from '../helpers'; + +// eslint-disable-next-line max-len +import DonateFormChildViewForHOC from '../Donation/components/DonateFormChildViewForHOC'; +import { userSelector } from '../../redux'; + +import './YearEndGift.css'; +import '../Donation/Donation.css'; +import DonateCompletion from '../Donation/components/DonateCompletion.js'; +import { stripePublicKey } from '../../../../config/env.json'; +import { stripeScriptLoader } from '../../utils/scriptLoaders'; + +const defaultYearEndStateConfig = { + donationAmount: 25000, + donationDuration: 'onetime', + paymentType: 'Card' +}; + +const numToCommas = num => + num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,'); + +const propTypes = { + showCloseBtn: PropTypes.func, + defaultTheme: PropTypes.string, + isDonating: PropTypes.bool, + stripe: PropTypes.shape({ + createToken: PropTypes.func.isRequired + }) +}; + +const mapStateToProps = createSelector( + userSelector, + ({ isDonating }) => ({ + isDonating + }) +); + +class YearEndDonationForm extends Component { + constructor(...args) { + super(...args); + this.state = { + ...defaultYearEndStateConfig, + showOtherAmounts: false, + isDonating: this.props.isDonating, + stripe: null + }; + this.handleSelectPaymentType = this.handleSelectPaymentType.bind(this); + this.handleStripeLoad = this.handleStripeLoad.bind(this); + this.getDonationButtonLabel = this.getDonationButtonLabel.bind(this); + this.handleSelectAmount = this.handleSelectAmount.bind(this); + this.handleChange = this.handleChange.bind(this); + this.handleClick = this.handleClick.bind(this); + } + + componentDidMount() { + if (window.Stripe) { + this.handleStripeLoad(); + } else if (document.querySelector('#stripe-js')) { + document + .querySelector('#stripe-js') + .addEventListener('load', this.handleStripeLoad); + } else { + stripeScriptLoader(this.handleStripeLoad); + } + } + + componentWillUnmount() { + const stripeMountPoint = document.querySelector('#stripe-js'); + if (stripeMountPoint) { + stripeMountPoint.removeEventListener('load', this.handleStripeLoad); + } + } + + handleStripeLoad() { + // Create Stripe instance once Stripe.js loads + if (stripePublicKey) { + this.setState(state => ({ + ...state, + stripe: window.Stripe(stripePublicKey) + })); + } + } + + handleSelectPaymentType(e) { + this.setState({ + paymentType: e.currentTarget.value + }); + } + + getFormatedAmountLabel(amount) { + return `$${numToCommas(amount / 100)}`; + } + + getDonationButtonLabel() { + const { donationAmount, donationDuration } = this.state; + let donationBtnLabel = `Confirm your donation`; + if (donationDuration === 'onetime') { + donationBtnLabel = `Confirm your one-time donation of ${this.getFormatedAmountLabel( + donationAmount + )}`; + } else { + donationBtnLabel = `Confirm your donation of ${this.getFormatedAmountLabel( + donationAmount + )} ${donationDuration === 'month' ? 'per month' : 'per year'}`; + } + return donationBtnLabel; + } + + renderDonationOptions() { + const { + donationAmount, + donationDuration, + paymentType, + stripe + } = this.state; + + const { showCloseBtn, defaultTheme } = this.props; + return ( +
+ PayPal is currently unavailable. Please use a Credit/Debit card + instead. +
+ )} +