diff --git a/client/src/assets/icons/DonateWithPayPal.js b/client/src/assets/icons/DonateWithPayPal.js
new file mode 100644
index 0000000000..657550c7ae
--- /dev/null
+++ b/client/src/assets/icons/DonateWithPayPal.js
@@ -0,0 +1,58 @@
+/* eslint-disable max-len */
+import React, { Fragment } from 'react';
+
+const propTypes = {};
+
+function DonateWithPayPal(props) {
+ return (
+
+ Donate with PayPal
+
+
+ );
+}
+
+DonateWithPayPal.displayName = 'DonateWithPayPal';
+DonateWithPayPal.propTypes = propTypes;
+
+export default DonateWithPayPal;
diff --git a/client/src/assets/icons/Payapl.js b/client/src/assets/icons/Payapl.js
deleted file mode 100644
index be51879a70..0000000000
--- a/client/src/assets/icons/Payapl.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/* eslint-disable max-len */
-import React, { Fragment } from 'react';
-
-const propTypes = {};
-
-function Paypal(props) {
- return (
-
- Paypal
-
-
- );
-}
-
-Paypal.displayName = 'Paypal';
-Paypal.propTypes = propTypes;
-
-export default Paypal;
diff --git a/client/src/components/Donation/DonateFormChildViewForHOC.js b/client/src/components/Donation/DonateFormChildViewForHOC.js
index 6a7545644a..54c2de93ea 100644
--- a/client/src/components/Donation/DonateFormChildViewForHOC.js
+++ b/client/src/components/Donation/DonateFormChildViewForHOC.js
@@ -1,4 +1,3 @@
-/* eslint-disable react/sort-prop-types */
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
@@ -9,7 +8,8 @@ import {
ControlLabel,
Form,
FormControl,
- FormGroup
+ FormGroup,
+ Alert
} from '@freecodecamp/react-bootstrap';
import { injectStripe } from 'react-stripe-elements';
@@ -19,13 +19,13 @@ import { postChargeStripe } from '../../utils/ajax';
import { userSelector } from '../../redux';
const propTypes = {
- showCloseBtn: PropTypes.func,
defaultTheme: PropTypes.string,
donationAmount: PropTypes.number.isRequired,
donationDuration: PropTypes.string.isRequired,
email: PropTypes.string,
getDonationButtonLabel: PropTypes.func.isRequired,
isSignedIn: PropTypes.bool,
+ showCloseBtn: PropTypes.func,
stripe: PropTypes.shape({
createToken: PropTypes.func.isRequired
}),
@@ -53,16 +53,18 @@ class DonateFormChildViewForHOC extends Component {
...initialState,
donationAmount: this.props.donationAmount,
donationDuration: this.props.donationDuration,
+ isSubmitionValid: null,
email: null,
+ isEmailValid: true,
isFormValid: false
};
- this.getUserEmail = this.getUserEmail.bind(this);
this.getValidationState = this.getValidationState.bind(this);
this.handleEmailChange = this.handleEmailChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.postDonation = this.postDonation.bind(this);
this.resetDonation = this.resetDonation.bind(this);
+ this.handleEmailBlur = this.handleEmailBlur.bind(this);
}
getUserEmail() {
@@ -80,14 +82,28 @@ class DonateFormChildViewForHOC extends Component {
handleEmailChange(e) {
const newValue = e.target.value;
- return this.setState(state => ({
- ...state,
- email: newValue
- }));
+ return this.setState({
+ email: newValue,
+ // reset validation
+ isEmailValid: true
+ });
}
handleSubmit(e) {
e.preventDefault();
+
+ const { isEmailValid, isFormValid } = this.state;
+
+ if ((!isEmailValid, !isFormValid)) {
+ return this.setState({
+ isSubmitionValid: false
+ });
+ }
+
+ this.setState({
+ isSubmitionValid: null
+ });
+
const email = this.getUserEmail();
if (!email || !isEmail(email)) {
return this.setState(state => ({
@@ -181,21 +197,54 @@ class DonateFormChildViewForHOC extends Component {
return ;
}
+ handleEmailBlur() {
+ const emailValue = this.state.email;
+ const newValidation = isEmail(emailValue);
+ return this.setState({
+ isEmailValid: newValidation
+ });
+ }
+
+ renderErrorMessage() {
+ const { isEmailValid, isFormValid } = this.state;
+ let message = '';
+ if (!isEmailValid && !isFormValid)
+ message = (
+
+ Please enter valid email address, credit card number, and expiration
+ date.
+
+ );
+ else if (!isEmailValid)
+ message = Please enter a valid email address.
;
+ else
+ message = (
+ Please enter valid credit card number and expiration date.
+ );
+
+ return {message};
+ }
+
renderDonateForm() {
- const { isFormValid } = this.state;
+ const { isEmailValid, isSubmitionValid, email } = this.state;
const { getDonationButtonLabel, theme, defaultTheme } = this.props;
+
return (
);
}
diff --git a/client/src/pages/certification.css b/client/src/pages/certification.css
index 8515534f14..c175c4fdef 100644
--- a/client/src/pages/certification.css
+++ b/client/src/pages/certification.css
@@ -42,20 +42,20 @@
padding: 20px 0px;
}
-.certificate-outer-wrapper .btn {
+.certificate-outer-wrapper .donation-completion .btn {
background-color: var(--gray-15);
border-color: var(--gray-85);
color: var(--gray-85);
}
-.certificate-outer-wrapper .btn:hover {
+.certificate-outer-wrapper .donation-completion .btn:hover {
border-color: var(--gray-85);
background-color: var(--gray-85);
color: var(--gray-05);
}
-.certificate-outer-wrapper .btn[disabled],
-.certificate-outer-wrapper .btn[disabled]:hover {
+.certificate-outer-wrapper .donation-completion .btn[disabled],
+.certificate-outer-wrapper .donation-completion .btn[disabled]:hover {
background-color: var(--gray-15);
border-color: var(--quaternary-color);
color: var(--quaternary-color);