fix(donate): remove isDontating check from year-end
This commit is contained in:
committed by
Ahmad Abdolsaheb
parent
663f726c4e
commit
8db0f89634
@ -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
|
||||||
|
@ -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'>
|
||||||
|
@ -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();
|
||||||
|
@ -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='onetime'
|
||||||
donationDuration={donationDuration}
|
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);
|
|
||||||
|
@ -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;
|
|
35
client/src/pages/year-end-gift-successful.js
Normal file
35
client/src/pages/year-end-gift-successful.js
Normal 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;
|
@ -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>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user