fix(donate): remove isDontating check from year-end

This commit is contained in:
Mrugesh Mohapatra
2019-12-18 10:46:13 +05:30
committed by Ahmad Abdolsaheb
parent 663f726c4e
commit 8db0f89634
7 changed files with 95 additions and 132 deletions

View File

@ -273,16 +273,6 @@ export default function donateBoot(app, done) {
}; };
return Promise.resolve(fccUser) return Promise.resolve(fccUser)
.then(nonDonatingUser => {
const { isDonating } = nonDonatingUser;
if (isDonating) {
throw {
message: `User already has active donation(s).`,
type: 'AlreadyDonatingError'
};
}
return nonDonatingUser;
})
.then(createCustomer) .then(createCustomer)
.then(customer => { .then(customer => {
return createOneTimeCharge(customer).then(charge => { return createOneTimeCharge(customer).then(charge => {
@ -292,10 +282,7 @@ export default function donateBoot(app, done) {
}) })
.then(createAsyncUserDonation) .then(createAsyncUserDonation)
.catch(err => { .catch(err => {
if ( if (err.type === 'StripeCardError') {
err.type === 'StripeCardError' ||
err.type === 'AlreadyDonatingError'
) {
return res.status(402).send({ error: err.message }); return res.status(402).send({ error: err.message });
} }
return res return res

View File

@ -9,16 +9,25 @@ const propTypes = {
error: PropTypes.string, error: PropTypes.string,
processing: PropTypes.bool, processing: PropTypes.bool,
reset: PropTypes.func.isRequired, reset: PropTypes.func.isRequired,
success: PropTypes.bool success: PropTypes.bool,
yearEndGift: PropTypes.bool
}; };
function DonateCompletion({ processing, reset, success, error = null }) { function DonateCompletion({
processing,
reset,
success,
error = null,
yearEndGift = false
}) {
/* eslint-disable no-nested-ternary */ /* eslint-disable no-nested-ternary */
const style = processing ? 'info' : success ? 'success' : 'danger'; const style = processing ? 'info' : success ? 'success' : 'danger';
const heading = processing const heading = processing
? 'We are processing your donation.' ? 'We are processing your donation.'
: success : success
? 'Thank you for being a supporter.' ? yearEndGift
? 'Thank you for your donation.'
: 'Thank you for being a supporter.'
: 'Something went wrong with your donation.'; : 'Something went wrong with your donation.';
return ( return (
<Alert bsStyle={style} className='donation-completion'> <Alert bsStyle={style} className='donation-completion'>
@ -34,7 +43,7 @@ function DonateCompletion({ processing, reset, success, error = null }) {
name='line-scale' name='line-scale'
/> />
)} )}
{success && ( {success && !yearEndGift && (
<div> <div>
<p> <p>
Your donation will support free technology education for people Your donation will support free technology education for people
@ -42,6 +51,11 @@ function DonateCompletion({ processing, reset, success, error = null }) {
</p> </p>
</div> </div>
)} )}
{success && yearEndGift && (
<div>
<p>You should receive a receipt in your email.</p>
</div>
)}
{error && <p>{error}</p>} {error && <p>{error}</p>}
</div> </div>
<div className='donation-completion-buttons'> <div className='donation-completion-buttons'>

View File

@ -223,12 +223,14 @@ class DonateFormChildViewForHOC extends Component {
const { const {
donationState: { processing, success, error } donationState: { processing, success, error }
} = this.state; } = this.state;
const { yearEndGift } = this.props;
if (processing || success || error) { if (processing || success || error) {
return this.renderCompletion({ return this.renderCompletion({
processing, processing,
success, success,
error, error,
reset: this.resetDonation reset: this.resetDonation,
yearEndGift
}); });
} }
return this.renderDonateForm(); return this.renderDonateForm();

View File

@ -2,8 +2,6 @@
/* eslint-disable react/jsx-sort-props */ /* eslint-disable react/jsx-sort-props */
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { import {
Row, Row,
Col, Col,
@ -17,20 +15,12 @@ import { Spacer } from '../helpers';
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
import DonateFormChildViewForHOC from '../Donation/components/DonateFormChildViewForHOC'; import DonateFormChildViewForHOC from '../Donation/components/DonateFormChildViewForHOC';
import { userSelector } from '../../redux';
import './YearEndGift.css'; import './YearEndGift.css';
import '../Donation/Donation.css'; import '../Donation/Donation.css';
import DonateCompletion from '../Donation/components/DonateCompletion.js';
import { stripePublicKey } from '../../../../config/env.json'; import { stripePublicKey } from '../../../../config/env.json';
import { stripeScriptLoader } from '../../utils/scriptLoaders'; import { stripeScriptLoader } from '../../utils/scriptLoaders';
const defaultYearEndStateConfig = {
donationAmount: 25000,
donationDuration: 'onetime',
paymentType: 'Card'
};
const numToCommas = num => const numToCommas = num =>
num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,'); num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
@ -43,23 +33,14 @@ const propTypes = {
}) })
}; };
const mapStateToProps = createSelector(
userSelector,
({ isDonating }) => ({
isDonating
})
);
class YearEndDonationForm extends Component { class YearEndDonationForm extends Component {
constructor(...args) { constructor(...args) {
super(...args); super(...args);
this.state = { this.state = {
...defaultYearEndStateConfig, donationAmount: 25000,
showOtherAmounts: false, showOtherAmounts: false,
isDonating: this.props.isDonating,
stripe: null stripe: null
}; };
this.handleSelectPaymentType = this.handleSelectPaymentType.bind(this);
this.handleStripeLoad = this.handleStripeLoad.bind(this); this.handleStripeLoad = this.handleStripeLoad.bind(this);
this.getDonationButtonLabel = this.getDonationButtonLabel.bind(this); this.getDonationButtonLabel = this.getDonationButtonLabel.bind(this);
this.handleSelectAmount = this.handleSelectAmount.bind(this); this.handleSelectAmount = this.handleSelectAmount.bind(this);
@ -96,61 +77,33 @@ class YearEndDonationForm extends Component {
} }
} }
handleSelectPaymentType(e) {
this.setState({
paymentType: e.currentTarget.value
});
}
getFormatedAmountLabel(amount) {
return `$${numToCommas(amount / 100)}`;
}
getDonationButtonLabel() { getDonationButtonLabel() {
const { donationAmount, donationDuration } = this.state; const { donationAmount } = this.state;
let donationBtnLabel = `Confirm your donation`; let donationBtnLabel = `Confirm your donation`;
if (donationDuration === 'onetime') { donationBtnLabel = `Confirm your one-time donation of $${numToCommas(
donationBtnLabel = `Confirm your one-time donation of ${this.getFormatedAmountLabel( donationAmount / 100
donationAmount
)}`; )}`;
} else {
donationBtnLabel = `Confirm your donation of ${this.getFormatedAmountLabel(
donationAmount
)} ${donationDuration === 'month' ? 'per month' : 'per year'}`;
}
return donationBtnLabel; return donationBtnLabel;
} }
renderDonationOptions() { renderDonationOptions() {
const { const { donationAmount, stripe } = this.state;
donationAmount,
donationDuration,
paymentType,
stripe
} = this.state;
const { showCloseBtn, defaultTheme } = this.props; const { showCloseBtn, defaultTheme } = this.props;
return ( return (
<div> <div>
{paymentType === 'Card' ? (
<StripeProvider stripe={stripe}> <StripeProvider stripe={stripe}>
<Elements> <Elements>
<DonateFormChildViewForHOC <DonateFormChildViewForHOC
showCloseBtn={showCloseBtn} showCloseBtn={showCloseBtn}
defaultTheme={defaultTheme} defaultTheme={defaultTheme}
donationAmount={donationAmount} donationAmount={donationAmount}
donationDuration={donationDuration} donationDuration='onetime'
getDonationButtonLabel={this.getDonationButtonLabel} getDonationButtonLabel={this.getDonationButtonLabel}
yearEndGift={true} yearEndGift={true}
/> />
</Elements> </Elements>
</StripeProvider> </StripeProvider>
) : (
<p>
PayPal is currently unavailable. Please use a Credit/Debit card
instead.
</p>
)}
</div> </div>
); );
} }
@ -238,9 +191,9 @@ class YearEndDonationForm extends Component {
type='submit' type='submit'
name='submit' name='submit'
className='btn btn-block' className='btn btn-block'
title='PayPal - The safer, easier way to pay online!' title='Donate to freeCodeCamp.org using PayPal'
alt='Donate with PayPal button' alt='Donate to freeCodeCamp.org using PayPal'
value='Make a PayPal donation' value='Donate using PayPal'
/> />
</form> </form>
); );
@ -285,25 +238,12 @@ class YearEndDonationForm extends Component {
} }
render() { render() {
const { isDonating } = this.props;
if (isDonating) {
return (
<Row>
<Col sm={10} smOffset={1} xs={12}>
<DonateCompletion success={true} />
</Col>
</Row>
);
}
console.log(this.state.donationAmount);
return ( return (
<Row> <Row>
<Col sm={10} smOffset={1} xs={12}> <Col sm={10} smOffset={1} xs={12}>
<b> <b>
Thank you again for supporting freeCodeCamp.org with a one-time year Thank you again for supporting freeCodeCamp.org with a one-time
end gift. Please enter your credit card information below. year-end gift. Please enter your credit card information below.
</b> </b>
<Spacer /> <Spacer />
</Col> </Col>
@ -342,7 +282,4 @@ class YearEndDonationForm extends Component {
YearEndDonationForm.displayName = 'YearEndDonationForm'; YearEndDonationForm.displayName = 'YearEndDonationForm';
YearEndDonationForm.propTypes = propTypes; YearEndDonationForm.propTypes = propTypes;
export default connect( export default YearEndDonationForm;
mapStateToProps,
null
)(YearEndDonationForm);

View File

@ -1,24 +0,0 @@
import React from 'react';
import { Grid } from '@freecodecamp/react-bootstrap';
import { Spacer, FullWidthRow } from '../../components/helpers';
import YearEndDonationForm from './YearEndDonationForm';
const DonateText = () => {
return (
<Grid>
<main>
<Spacer />
<FullWidthRow>
<h1 className='text-center'>Become a Supporter</h1>
<YearEndDonationForm />
</FullWidthRow>
<Spacer />
<Spacer />
</main>
</Grid>
);
};
DonateText.displayName = '';
export default DonateText;

View File

@ -0,0 +1,35 @@
import React from 'react';
import Helmet from 'react-helmet';
import { Grid, Alert } from '@freecodecamp/react-bootstrap';
import { Spacer, FullWidthRow } from '../components/helpers';
import '../components/Donation/Donation.css';
function YearEndGiftPage() {
return (
<>
<Helmet title='Support our nonprofit | freeCodeCamp.org' />
<Grid>
<main>
<Spacer size={3} />
<FullWidthRow>
<Alert bsStyle='success' className='donation-completion'>
<div>
<h4>
<b>Thank you for your donation.</b>
</h4>
<p>You should receive a receipt in your email.</p>
</div>
</Alert>
</FullWidthRow>
<Spacer size={2} />
</main>
</Grid>
</>
);
}
YearEndGiftPage.displayName = 'YearEndGiftPage';
export default YearEndGiftPage;

View File

@ -1,12 +1,24 @@
import React from 'react'; import React from 'react';
import Helmet from 'react-helmet'; import Helmet from 'react-helmet';
import YearEndGift from '../components/YearEndGift'; import { Grid } from '@freecodecamp/react-bootstrap';
import { Spacer, FullWidthRow } from '../components/helpers';
import YearEndDonationForm from '../components/YearEndGift/YearEndDonationForm';
function YearEndGiftPage() { function YearEndGiftPage() {
return ( return (
<> <>
<Helmet title='Support our nonprofit | freeCodeCamp.org' /> <Helmet title='Support our nonprofit | freeCodeCamp.org' />
<YearEndGift /> <Grid>
<main>
<Spacer />
<FullWidthRow>
<YearEndDonationForm />
</FullWidthRow>
<Spacer />
<Spacer />
</main>
</Grid>
</> </>
); );
} }