fix(donate): implement donate page
This commit is contained in:
committed by
mrugesh
parent
5609a1303e
commit
e4590fed5c
@ -170,16 +170,6 @@ export default function donateBoot(app, done) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return Promise.resolve(user)
|
return Promise.resolve(user)
|
||||||
.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 duration === 'onetime'
|
return duration === 'onetime'
|
||||||
@ -194,10 +184,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
|
||||||
|
@ -7,7 +7,7 @@ import { createSelector } from 'reselect';
|
|||||||
import { Grid, Row, Col, Image, Button } from '@freecodecamp/react-bootstrap';
|
import { Grid, Row, Col, Image, Button } from '@freecodecamp/react-bootstrap';
|
||||||
import FreeCodeCampLogo from '../assets/icons/freeCodeCampLogo';
|
import FreeCodeCampLogo from '../assets/icons/freeCodeCampLogo';
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
import MinimalDonateForm from '../components/Donation/components/MinimalDonateForm';
|
import MinimalDonateForm from '../components/Donation/MinimalDonateForm';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
showCertSelector,
|
showCertSelector,
|
||||||
|
@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
|||||||
import { Alert, Button } from '@freecodecamp/react-bootstrap';
|
import { Alert, Button } from '@freecodecamp/react-bootstrap';
|
||||||
import Spinner from 'react-spinkit';
|
import Spinner from 'react-spinkit';
|
||||||
|
|
||||||
import '../Donation.css';
|
import './Donation.css';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
error: PropTypes.string,
|
error: PropTypes.string,
|
@ -18,19 +18,17 @@ import {
|
|||||||
durationsConfig,
|
durationsConfig,
|
||||||
defaultAmount,
|
defaultAmount,
|
||||||
defaultStateConfig
|
defaultStateConfig
|
||||||
} from '../../../../../config/donation-settings';
|
} from '../../../../config/donation-settings';
|
||||||
import { apiLocation } from '../../../../config/env.json';
|
import { apiLocation } from '../../../../config/env.json';
|
||||||
import Spacer from '../../helpers/Spacer';
|
import Spacer from '../helpers/Spacer';
|
||||||
import DonateFormChildViewForHOC from './DonateFormChildViewForHOC';
|
import DonateFormChildViewForHOC from './DonateFormChildViewForHOC';
|
||||||
import {
|
import {
|
||||||
userSelector,
|
|
||||||
isSignedInSelector,
|
isSignedInSelector,
|
||||||
signInLoadingSelector,
|
signInLoadingSelector,
|
||||||
hardGoTo as navigate
|
hardGoTo as navigate
|
||||||
} from '../../../redux';
|
} from '../../redux';
|
||||||
|
|
||||||
import '../Donation.css';
|
import './Donation.css';
|
||||||
import DonateCompletion from './DonateCompletion.js';
|
|
||||||
|
|
||||||
const numToCommas = num =>
|
const numToCommas = num =>
|
||||||
num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
|
num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
|
||||||
@ -46,11 +44,9 @@ const propTypes = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = createSelector(
|
const mapStateToProps = createSelector(
|
||||||
userSelector,
|
|
||||||
signInLoadingSelector,
|
signInLoadingSelector,
|
||||||
isSignedInSelector,
|
isSignedInSelector,
|
||||||
({ isDonating }, showLoading, isSignedIn) => ({
|
(showLoading, isSignedIn) => ({
|
||||||
isDonating,
|
|
||||||
isSignedIn,
|
isSignedIn,
|
||||||
showLoading
|
showLoading
|
||||||
})
|
})
|
||||||
@ -74,8 +70,7 @@ class DonateForm extends Component {
|
|||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
...defaultStateConfig,
|
...defaultStateConfig,
|
||||||
processing: false,
|
processing: false
|
||||||
isDonating: this.props.isDonating
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getActiveDonationAmount = this.getActiveDonationAmount.bind(this);
|
this.getActiveDonationAmount = this.getActiveDonationAmount.bind(this);
|
||||||
@ -222,17 +217,7 @@ class DonateForm extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { isSignedIn, navigate, showLoading, isDonating } = this.props;
|
const { isSignedIn, navigate, showLoading } = this.props;
|
||||||
|
|
||||||
if (isDonating) {
|
|
||||||
return (
|
|
||||||
<Row>
|
|
||||||
<Col sm={10} smOffset={1} xs={12}>
|
|
||||||
<DonateCompletion success={true} />
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row>
|
<Row>
|
@ -15,8 +15,8 @@ import { injectStripe } from 'react-stripe-elements';
|
|||||||
|
|
||||||
import StripeCardForm from './StripeCardForm';
|
import StripeCardForm from './StripeCardForm';
|
||||||
import DonateCompletion from './DonateCompletion';
|
import DonateCompletion from './DonateCompletion';
|
||||||
import { postChargeStripe } from '../../../utils/ajax';
|
import { postChargeStripe } from '../../utils/ajax';
|
||||||
import { userSelector } from '../../../redux';
|
import { userSelector } from '../../redux';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
showCloseBtn: PropTypes.func,
|
showCloseBtn: PropTypes.func,
|
39
client/src/components/Donation/DonateText.js
Normal file
39
client/src/components/Donation/DonateText.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Row, Col } from '@freecodecamp/react-bootstrap';
|
||||||
|
|
||||||
|
const DonateText = () => {
|
||||||
|
return (
|
||||||
|
<Row className='donate-text'>
|
||||||
|
<Col sm={10} smOffset={1} xs={12}>
|
||||||
|
<p>freeCodeCamp is a highly efficient education nonprofit.</p>
|
||||||
|
<p>
|
||||||
|
In 2019 alone, we provided 18 million hours of free education to
|
||||||
|
people around the world.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Since freeCodeCamp's total budget is only $373,000, that means every
|
||||||
|
dollar you donate to freeCodeCamp translates into 50 hours worth of
|
||||||
|
technology education.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
When you donate to freeCodeCamp, you help people learn new skills and
|
||||||
|
provide for their families.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
You also help us create new resources for you to use to expand your
|
||||||
|
own technology skills.
|
||||||
|
</p>
|
||||||
|
<hr />
|
||||||
|
<h4>
|
||||||
|
<b>Need help with your existing or past donations?</b>
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
Send an email to team@freeCodeCamp.org with a copy of your donation
|
||||||
|
receipt and we will be happy to resolve your query.
|
||||||
|
</p>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
DonateText.displayName = 'DonateText';
|
||||||
|
export default DonateText;
|
@ -5,22 +5,22 @@ import { bindActionCreators } from 'redux';
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
import { Modal, Button, Col, Row } from '@freecodecamp/react-bootstrap';
|
import { Modal, Button, Col, Row } from '@freecodecamp/react-bootstrap';
|
||||||
import { Spacer } from '../../../components/helpers';
|
import { Spacer } from '../helpers';
|
||||||
import { blockNameify } from '../../../../utils/blockNameify';
|
import { blockNameify } from '../../../utils/blockNameify';
|
||||||
import Heart from '../../../assets/icons/Heart';
|
import Heart from '../../assets/icons/Heart';
|
||||||
import Cup from '../../../assets/icons/Cup';
|
import Cup from '../../assets/icons/Cup';
|
||||||
import MinimalDonateForm from './MinimalDonateForm';
|
import MinimalDonateForm from './MinimalDonateForm';
|
||||||
|
|
||||||
import ga from '../../../analytics';
|
import ga from '../../analytics';
|
||||||
import {
|
import {
|
||||||
closeDonationModal,
|
closeDonationModal,
|
||||||
isDonationModalOpenSelector,
|
isDonationModalOpenSelector,
|
||||||
isBlockDonationModalSelector
|
isBlockDonationModalSelector
|
||||||
} from '../../../redux';
|
} from '../../redux';
|
||||||
|
|
||||||
import { challengeMetaSelector } from '../../../templates/Challenges/redux';
|
import { challengeMetaSelector } from '../../templates/Challenges/redux';
|
||||||
|
|
||||||
import '../Donation.css';
|
import './Donation.css';
|
||||||
|
|
||||||
const mapStateToProps = createSelector(
|
const mapStateToProps = createSelector(
|
||||||
isDonationModalOpenSelector,
|
isDonationModalOpenSelector,
|
@ -1,5 +1,3 @@
|
|||||||
/* eslint-disable react/sort-prop-types */
|
|
||||||
/* 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 { connect } from 'react-redux';
|
||||||
@ -10,23 +8,19 @@ import { StripeProvider, Elements } from 'react-stripe-elements';
|
|||||||
import {
|
import {
|
||||||
amountsConfig,
|
amountsConfig,
|
||||||
durationsConfig,
|
durationsConfig,
|
||||||
defaultStateConfig
|
modalDefaultStateConfig
|
||||||
} from '../../../../../config/donation-settings';
|
} from '../../../../config/donation-settings';
|
||||||
|
import { stripePublicKey } from '../../../../config/env.json';
|
||||||
|
import { stripeScriptLoader } from '../../utils/scriptLoaders';
|
||||||
import DonateFormChildViewForHOC from './DonateFormChildViewForHOC';
|
import DonateFormChildViewForHOC from './DonateFormChildViewForHOC';
|
||||||
import { userSelector } from '../../../redux';
|
import { userSelector } from '../../redux';
|
||||||
|
|
||||||
import '../Donation.css';
|
import './Donation.css';
|
||||||
import DonateCompletion from './DonateCompletion.js';
|
|
||||||
import { stripePublicKey } from '../../../../../config/env.json';
|
|
||||||
import { stripeScriptLoader } from '../../../utils/scriptLoaders';
|
|
||||||
|
|
||||||
const numToCommas = num =>
|
|
||||||
num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
|
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
showCloseBtn: PropTypes.func,
|
|
||||||
defaultTheme: PropTypes.string,
|
defaultTheme: PropTypes.string,
|
||||||
isDonating: PropTypes.bool,
|
isDonating: PropTypes.bool,
|
||||||
|
showCloseBtn: PropTypes.func,
|
||||||
stripe: PropTypes.shape({
|
stripe: PropTypes.shape({
|
||||||
createToken: PropTypes.func.isRequired
|
createToken: PropTypes.func.isRequired
|
||||||
})
|
})
|
||||||
@ -39,7 +33,7 @@ const mapStateToProps = createSelector(
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
class ModalDonateForm extends Component {
|
class MinimalDonateForm extends Component {
|
||||||
constructor(...args) {
|
constructor(...args) {
|
||||||
super(...args);
|
super(...args);
|
||||||
|
|
||||||
@ -47,13 +41,11 @@ class ModalDonateForm extends Component {
|
|||||||
this.amounts = amountsConfig;
|
this.amounts = amountsConfig;
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
...defaultStateConfig,
|
...modalDefaultStateConfig,
|
||||||
isDonating: this.props.isDonating,
|
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@ -85,91 +77,36 @@ class ModalDonateForm extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSelectPaymentType(e) {
|
render() {
|
||||||
this.setState({
|
const { donationAmount, donationDuration, stripe } = this.state;
|
||||||
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;
|
const { showCloseBtn, defaultTheme } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<Row>
|
||||||
{paymentType === 'Card' ? (
|
<Col sm={10} smOffset={1} xs={12}>
|
||||||
<StripeProvider stripe={stripe}>
|
<StripeProvider stripe={stripe}>
|
||||||
<Elements>
|
<Elements>
|
||||||
<DonateFormChildViewForHOC
|
<DonateFormChildViewForHOC
|
||||||
showCloseBtn={showCloseBtn}
|
|
||||||
defaultTheme={defaultTheme}
|
defaultTheme={defaultTheme}
|
||||||
donationAmount={donationAmount}
|
donationAmount={donationAmount}
|
||||||
donationDuration={donationDuration}
|
donationDuration={donationDuration}
|
||||||
getDonationButtonLabel={this.getDonationButtonLabel}
|
getDonationButtonLabel={() =>
|
||||||
|
`Confirm your donation of $5 per month`
|
||||||
|
}
|
||||||
|
showCloseBtn={showCloseBtn}
|
||||||
/>
|
/>
|
||||||
</Elements>
|
</Elements>
|
||||||
</StripeProvider>
|
</StripeProvider>
|
||||||
) : (
|
|
||||||
<p>
|
|
||||||
PayPal is currently unavailable. Please use a Credit/Debit card
|
|
||||||
instead.
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { isDonating } = this.props;
|
|
||||||
|
|
||||||
if (isDonating) {
|
|
||||||
return (
|
|
||||||
<Row>
|
|
||||||
<Col sm={10} smOffset={1} xs={12}>
|
|
||||||
<DonateCompletion success={true} />
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Row>
|
|
||||||
<Col sm={10} smOffset={1} xs={12}>
|
|
||||||
{this.renderDonationOptions()}
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ModalDonateForm.displayName = 'ModalDonateForm';
|
MinimalDonateForm.displayName = 'MinimalDonateForm';
|
||||||
ModalDonateForm.propTypes = propTypes;
|
MinimalDonateForm.propTypes = propTypes;
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
mapStateToProps,
|
mapStateToProps,
|
||||||
null
|
null
|
||||||
)(ModalDonateForm);
|
)(MinimalDonateForm);
|
@ -1,66 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { Spacer, Link } from '../../../components/helpers';
|
|
||||||
|
|
||||||
const DonateText = () => {
|
|
||||||
return (
|
|
||||||
<div className='donate-text'>
|
|
||||||
<Spacer />
|
|
||||||
<h3>How to donate to freeCodeCamp.org</h3>
|
|
||||||
|
|
||||||
<p>freeCodeCamp is a tax-exempt 501(c)(3) public charity.</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
We get almost all of our budget from our supporters, who donate $5 per
|
|
||||||
month to our nonprofit.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
To become a supporter, just{' '}
|
|
||||||
<Link to='/learn'>start going through the curriculum</Link> and you will
|
|
||||||
see a prompt to donate.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
If you want to make a larger one-time donation, set up employer
|
|
||||||
matching, or support us in other ways, email team@freecodecamp.org and
|
|
||||||
we can help make that happen.
|
|
||||||
</p>
|
|
||||||
<Spacer />
|
|
||||||
|
|
||||||
<h3> How does freeCodeCamp use these donations?</h3>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
100% of donations go to pay for servers, and to pay teachers and
|
|
||||||
developers who help build our learning resources.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
We earned the 2019 Platinum Seal of Transparency from Guidestar.org. You
|
|
||||||
can view all our nonprofit's details and download our accounting
|
|
||||||
documents{' '}
|
|
||||||
<Link to='https://www.guidestar.org/profile/82-0779546'>there.</Link>
|
|
||||||
</p>
|
|
||||||
<Spacer />
|
|
||||||
|
|
||||||
<h3> How do I stop my monthly recurring donation.</h3>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Easy. Just forward a donation receipt to team@freecodecamp.org and we'll
|
|
||||||
stop it.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<Spacer />
|
|
||||||
<h3>How do I restart my monthly recurring donation?</h3>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Email one of your old donation receipts to team@freecodecamp.org and
|
|
||||||
we'll restart it for you.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
DonateText.displayName = 'DonateText';
|
|
||||||
|
|
||||||
export default DonateText;
|
|
@ -14,7 +14,7 @@ import { StripeProvider, Elements } from 'react-stripe-elements';
|
|||||||
import { Spacer } from '../helpers';
|
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/DonateFormChildViewForHOC';
|
||||||
|
|
||||||
import './YearEndGift.css';
|
import './YearEndGift.css';
|
||||||
import '../Donation/Donation.css';
|
import '../Donation/Donation.css';
|
||||||
|
@ -11,7 +11,7 @@ import {
|
|||||||
tryToShowDonationModal
|
tryToShowDonationModal
|
||||||
} from '../../redux';
|
} from '../../redux';
|
||||||
import createRedirect from '../../components/createRedirect';
|
import createRedirect from '../../components/createRedirect';
|
||||||
import DonateModal from '../Donation/components/DonationModal';
|
import DonateModal from '../Donation/DonationModal';
|
||||||
|
|
||||||
import 'prismjs/themes/prism.css';
|
import 'prismjs/themes/prism.css';
|
||||||
import './prism.css';
|
import './prism.css';
|
||||||
|
@ -1,29 +1,108 @@
|
|||||||
import React, { Fragment } from 'react';
|
import React, { Component, Fragment } from 'react';
|
||||||
import Helmet from 'react-helmet';
|
import Helmet from 'react-helmet';
|
||||||
import { Grid } from '@freecodecamp/react-bootstrap';
|
import PropTypes from 'prop-types';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { createSelector } from 'reselect';
|
||||||
|
import { Grid, Row, Col } from '@freecodecamp/react-bootstrap';
|
||||||
|
|
||||||
import { Spacer, FullWidthRow } from '../components/helpers';
|
import { stripePublicKey } from '../../config/env.json';
|
||||||
import DonateText from '../components/Donation/components/DonateText';
|
import { Spacer, Loader } from '../components/helpers';
|
||||||
|
import DonateForm from '../components/Donation/DonateForm';
|
||||||
|
import DonateText from '../components/Donation/DonateText';
|
||||||
|
import { signInLoadingSelector, userSelector } from '../redux';
|
||||||
|
import { stripeScriptLoader } from '../utils/scriptLoaders';
|
||||||
|
|
||||||
|
const propTypes = {
|
||||||
|
isDonating: PropTypes.bool,
|
||||||
|
showLoading: PropTypes.bool.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapStateToProps = createSelector(
|
||||||
|
userSelector,
|
||||||
|
signInLoadingSelector,
|
||||||
|
({ isDonating }, showLoading) => ({
|
||||||
|
isDonating,
|
||||||
|
showLoading
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
export class DonatePage extends Component {
|
||||||
|
constructor(...props) {
|
||||||
|
super(...props);
|
||||||
|
this.state = {
|
||||||
|
stripe: null,
|
||||||
|
enableSettings: false
|
||||||
|
};
|
||||||
|
|
||||||
|
this.handleStripeLoad = this.handleStripeLoad.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
|
||||||
|
console.info('stripe has loaded');
|
||||||
|
this.setState(state => ({
|
||||||
|
...state,
|
||||||
|
stripe: window.Stripe(stripePublicKey)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { stripe } = this.state;
|
||||||
|
const { showLoading } = this.props;
|
||||||
|
|
||||||
|
if (showLoading) {
|
||||||
|
return <Loader fullScreen={true} />;
|
||||||
|
}
|
||||||
|
|
||||||
function DonatePage() {
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<Helmet title='Support our nonprofit | freeCodeCamp.org' />
|
<Helmet title='Support our nonprofit | freeCodeCamp.org' />
|
||||||
<Grid>
|
<Grid>
|
||||||
<main>
|
|
||||||
<Spacer />
|
<Spacer />
|
||||||
<FullWidthRow>
|
<Row>
|
||||||
|
<Col sm={10} smOffset={1} xs={12}>
|
||||||
<h1 className='text-center'>Become a Supporter</h1>
|
<h1 className='text-center'>Become a Supporter</h1>
|
||||||
|
<Spacer />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col md={6}>
|
||||||
|
<DonateForm
|
||||||
|
enableDonationSettingsPage={this.enableDonationSettingsPage}
|
||||||
|
stripe={stripe}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
<Col md={6}>
|
||||||
<DonateText />
|
<DonateText />
|
||||||
</FullWidthRow>
|
</Col>
|
||||||
|
</Row>
|
||||||
<Spacer />
|
<Spacer />
|
||||||
<Spacer />
|
|
||||||
</main>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DonatePage.displayName = 'DonatePage';
|
DonatePage.displayName = 'DonatePage';
|
||||||
|
DonatePage.propTypes = propTypes;
|
||||||
|
|
||||||
export default DonatePage;
|
export default connect(mapStateToProps)(DonatePage);
|
||||||
|
@ -11,7 +11,7 @@ const amountsConfig = {
|
|||||||
};
|
};
|
||||||
const defaultAmount = {
|
const defaultAmount = {
|
||||||
year: 25000,
|
year: 25000,
|
||||||
month: 500,
|
month: 3500,
|
||||||
onetime: 25000
|
onetime: 25000
|
||||||
};
|
};
|
||||||
const defaultStateConfig = {
|
const defaultStateConfig = {
|
||||||
@ -19,6 +19,11 @@ const defaultStateConfig = {
|
|||||||
donationDuration: 'month',
|
donationDuration: 'month',
|
||||||
paymentType: 'Card'
|
paymentType: 'Card'
|
||||||
};
|
};
|
||||||
|
const modalDefaultStateConfig = {
|
||||||
|
donationAmount: 500,
|
||||||
|
donationDuration: 'month',
|
||||||
|
paymentType: 'Card'
|
||||||
|
};
|
||||||
|
|
||||||
// Configuration for server side
|
// Configuration for server side
|
||||||
const durationKeysConfig = ['year', 'month', 'onetime'];
|
const durationKeysConfig = ['year', 'month', 'onetime'];
|
||||||
@ -41,5 +46,6 @@ module.exports = {
|
|||||||
defaultStateConfig,
|
defaultStateConfig,
|
||||||
durationKeysConfig,
|
durationKeysConfig,
|
||||||
donationOneTimeConfig,
|
donationOneTimeConfig,
|
||||||
donationSubscriptionConfig
|
donationSubscriptionConfig,
|
||||||
|
modalDefaultStateConfig
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user