diff --git a/client/src/components/Footer/__snapshots__/Footer.test.js.snap b/client/src/components/Footer/__snapshots__/Footer.test.js.snap index 9a2882a7ba..013453cc21 100644 --- a/client/src/components/Footer/__snapshots__/Footer.test.js.snap +++ b/client/src/components/Footer/__snapshots__/Footer.test.js.snap @@ -23,9 +23,7 @@ exports[` matches snapshot 1`] = ` Donations to freeCodeCamp go toward our education initiatives, and help pay for servers, services, and staff. You canĀ make a tax-deductible donation here @@ -48,9 +46,7 @@ exports[` matches snapshot 1`] = ` About Donate diff --git a/client/src/components/Footer/footerLinks.json b/client/src/components/Footer/footerLinks.json index 82f2f7a7cd..18d014edb1 100644 --- a/client/src/components/Footer/footerLinks.json +++ b/client/src/components/Footer/footerLinks.json @@ -4,7 +4,7 @@ "title": "Our Nonprofit", "links": [ { "to": "/news/about/", "text": "About" }, - { "to": "https://donate.freecodecamp.org", "text": "Donate" }, + { "to": "/donate", "text": "Donate", "internal": true }, { "to": "/news/shop/", "text": "Shop" }, { "to": "https://www.linkedin.com/school/free-code-camp/people/", diff --git a/client/src/components/Footer/index.js b/client/src/components/Footer/index.js index 8e27033e81..666f6ff1ca 100644 --- a/client/src/components/Footer/index.js +++ b/client/src/components/Footer/index.js @@ -38,11 +38,7 @@ function Footer() {
Donations to freeCodeCamp go toward our education initiatives, and
help pay for servers, services, and staff. You can
-
+
make a tax-deductible donation here
.
diff --git a/client/src/pages/donate.js b/client/src/pages/donate.js
new file mode 100644
index 0000000000..c510aadfe1
--- /dev/null
+++ b/client/src/pages/donate.js
@@ -0,0 +1,137 @@
+import React, { Component, Fragment } from 'react';
+import PropTypes from 'prop-types';
+import Helmet from 'react-helmet';
+import { StripeProvider, Elements } from 'react-stripe-elements';
+import { Grid, Row, Col, Button } from '@freecodecamp/react-bootstrap';
+import { connect } from 'react-redux';
+import { createSelector } from 'reselect';
+
+import { stripePublicKey, apiLocation } from '../../config/env.json';
+import { Spacer, Loader } from '../components/helpers';
+import DonateOther from '../components/Donation/components/DonateOther';
+import DonateForm from '../components/Donation/components/DonateForm';
+import DonateText from '../components/Donation/components/DonateText';
+import PoweredByStripe from '../components/Donation/components/poweredByStripe';
+import { signInLoadingSelector, isSignedInSelector, hardGoTo } from '../redux';
+
+const mapStateToProps = createSelector(
+ signInLoadingSelector,
+ isSignedInSelector,
+ (showLoading, isSignedIn) => ({
+ showLoading,
+ isSignedIn
+ })
+);
+
+const mapDispatchToProps = dispatch => ({
+ navigate: location => dispatch(hardGoTo(location))
+});
+
+const propTypes = {
+ isSignedIn: PropTypes.bool.isRequired,
+ navigate: PropTypes.func.isRequired,
+ showLoading: PropTypes.bool.isRequired
+};
+
+export class DonatePage extends Component {
+ constructor(...props) {
+ super(...props);
+ this.state = {
+ stripe: null,
+ showOtherOptions: false
+ };
+ this.handleStripeLoad = this.handleStripeLoad.bind(this);
+ this.toggleOtherOptions = this.toggleOtherOptions.bind(this);
+ }
+ componentDidMount() {
+ if (window.Stripe) {
+ /* eslint-disable react/no-did-mount-set-state */
+ this.setState(state => ({
+ ...state,
+ stripe: window.Stripe(stripePublicKey)
+ }));
+ } else if (document.querySelector('#stripe-js')) {
+ document
+ .querySelector('#stripe-js')
+ .addEventListener('load', 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)
+ }));
+ }
+
+ toggleOtherOptions() {
+ this.setState(({ showOtherOptions }) => ({
+ showOtherOptions: !showOtherOptions
+ }));
+ }
+
+ render() {
+ const { showOtherOptions, stripe } = this.state;
+ const { showLoading, isSignedIn, navigate } = this.props;
+
+ if (showLoading) {
+ return Become a Supporter
+
+