From 08d6c0625093c37d631658ea4750a3eea656f01f Mon Sep 17 00:00:00 2001 From: Mrugesh Mohapatra Date: Mon, 28 Jan 2019 20:25:59 +0530 Subject: [PATCH] feat(donate): intial port from the donate app --- client/src/components/Donation/Donation.js | 3 + .../Donation/components/CardForm.js | 7 +- .../Donation/components/DonateCompletion.js | 9 +- .../Donation/components/DonateForm.js | 89 ++++++--------- .../Donation/components/StripeCardForm.js | 10 +- .../src/components/icons/poweredByStripe.js | 31 +++++ client/src/pages/donate.js | 108 ++++++++++++++++++ 7 files changed, 188 insertions(+), 69 deletions(-) create mode 100644 client/src/components/icons/poweredByStripe.js create mode 100644 client/src/pages/donate.js diff --git a/client/src/components/Donation/Donation.js b/client/src/components/Donation/Donation.js index 515fc1270a..d5e70772d5 100644 --- a/client/src/components/Donation/Donation.js +++ b/client/src/components/Donation/Donation.js @@ -104,7 +104,10 @@ class DonationModal extends Component { diff --git a/client/src/components/Donation/components/CardForm.js b/client/src/components/Donation/components/CardForm.js index 5da0f1be26..64910c5895 100644 --- a/client/src/components/Donation/components/CardForm.js +++ b/client/src/components/Donation/components/CardForm.js @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import { Button } from '@freecodecamp/react-bootstrap'; @@ -9,7 +9,7 @@ const propTypes = { handleSubmit: PropTypes.func.isRequired }; -class CardForm extends Component { +class CardForm extends PureComponent { constructor(...props) { super(...props); @@ -44,9 +44,10 @@ class CardForm extends Component { bsSize='lg' bsStyle='primary' disabled={!isFormValid} + id='confirm-donation-btn' type='submit' > - {`Confirm Monthly Donation of $${amount}`} + {`Confirm your donation of $${amount} / month`} ); diff --git a/client/src/components/Donation/components/DonateCompletion.js b/client/src/components/Donation/components/DonateCompletion.js index 3c0f33ab60..615ed06c1d 100644 --- a/client/src/components/Donation/components/DonateCompletion.js +++ b/client/src/components/Donation/components/DonateCompletion.js @@ -11,14 +11,14 @@ const propTypes = { success: PropTypes.bool }; -function DonateCompletion({ close, processing, reset, success, error = null }) { +function DonateCompletion({ processing, reset, success, error = null }) { /* eslint-disable no-nested-ternary */ const style = processing ? 'info' : success ? 'success' : 'danger'; const heading = processing - ? 'We are processing your donation' + ? 'We are processing your donation.' : success - ? 'Donation successful. Thank you for supporting the freeCodeCamp ' + - 'community!' + ? 'Your donation was successful. Thank you for supporting the ' + + 'freeCodeCamp.org community.' : 'Something went wrong with your donation'; return ( @@ -43,7 +43,6 @@ function DonateCompletion({ close, processing, reset, success, error = null }) { )} - {!processing && }

); diff --git a/client/src/components/Donation/components/DonateForm.js b/client/src/components/Donation/components/DonateForm.js index 33666a1164..2c683d2d9d 100644 --- a/client/src/components/Donation/components/DonateForm.js +++ b/client/src/components/Donation/components/DonateForm.js @@ -1,14 +1,13 @@ -import React, { Component, Fragment } from 'react'; +import React, { Component } from 'react'; import PropTypes from 'prop-types'; import isEmail from 'validator/lib/isEmail'; import CardForm from './CardForm'; import { injectStripe } from 'react-stripe-elements'; -import postUpdate$ from '../../../templates/Challenges/utils/postUpdate$'; +import { postJSON$ } from '../../../templates/Challenges/utils/ajax-stream.js'; const propTypes = { email: PropTypes.string, - maybeButton: PropTypes.func.isRequired, renderCompletion: PropTypes.func.isRequired, stripe: PropTypes.shape({ createToken: PropTypes.func.isRequired @@ -26,33 +25,19 @@ const initialSate = { class DonateForm extends Component { constructor(...args) { super(...args); - const [props] = args; this.state = { ...initialSate, - email: props.email + email: null }; - this.buttonAmounts = [500, 1000, 3500, 5000, 25000]; - - this.handleAmountClick = this.handleAmountClick.bind(this); + this.getUserEmail = this.getUserEmail.bind(this); this.handleEmailChange = this.handleEmailChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); - this.isActive = this.isActive.bind(this); - this.renderAmountButtons = this.renderAmountButtons.bind(this); this.postDonation = this.postDonation.bind(this); this.resetDonation = this.resetDonation.bind(this); } - handleAmountClick(e) { - e.preventDefault(); - const donationAmount = parseInt(e.target.id, 10); - return this.setState(state => ({ - ...state, - donationAmount - })); - } - handleEmailChange(e) { const newValue = e.target.value; return this.setState(state => ({ @@ -62,14 +47,15 @@ class DonateForm extends Component { } handleSubmit() { - const { email } = this.state; + const email = this.getUserEmail(); if (!email || !isEmail(email)) { return this.setState(state => ({ ...state, donationState: { ...state.donationState, error: - 'We need a valid email address to send your donation tax receipt to' + 'We need a valid email address to which we can send your' + + ' donation tax receipt.' } })); } @@ -89,8 +75,10 @@ class DonateForm extends Component { }); } - isActive(amount) { - return this.state.donationAmount === amount; + getUserEmail() { + const { email: stateEmail } = this.state; + const { email: propsEmail } = this.props; + return stateEmail || propsEmail || ''; } postDonation(token) { @@ -102,7 +90,8 @@ class DonateForm extends Component { processing: true } })); - return postUpdate$('/donate/charge-stripe', { + const chargeStripePath = '/unauthenticated/donate/charge-stripe'; + return postJSON$(chargeStripePath, { token, amount }).subscribe( @@ -129,52 +118,40 @@ class DonateForm extends Component { ); } - renderAmountButtons() { - return this.buttonAmounts.map(amount => ( -
  • - -
  • - )); - } - renderDonateForm() { return ( - -

    - freeCodeCamp is completely free. But it costs our nonprofit a lot of - money to run it. Help us pay for servers. Set up a tax-deductible - monthly donation you can afford. -

    -