import React, { useState } from 'react'; import { CardNumberElement, CardExpiryElement, useStripe, useElements } from '@stripe/react-stripe-js'; import PropTypes from 'prop-types'; import isEmail from 'validator/lib/isEmail'; import { Row, Col, ControlLabel, FormGroup, Image, Button, Form, FormControl, Alert } from '@freecodecamp/react-bootstrap'; import { withTranslation } from 'react-i18next'; const initialPaymentInfoValidityState = { cardNumber: { complete: false, error: null }, cardExpiry: { complete: false, error: null } }; const propTypes = { getDonationButtonLabel: PropTypes.func.isRequired, onDonationStateChange: PropTypes.func, postStripeDonation: PropTypes.func, t: PropTypes.func.isRequired, theme: PropTypes.string, userEmail: PropTypes.string }; const StripeCardForm = ({ getDonationButtonLabel, theme, t, onDonationStateChange, postStripeDonation, userEmail }) => { const [isSubmissionValid, setSubmissionValidity] = useState(true); const [email, setEmail] = useState(userEmail); const [isEmailValid, setEmailValidity] = useState(true); const [paymentInfoValidation, setPaymentValidity] = useState( initialPaymentInfoValidityState ); const stripe = useStripe(); const elements = useElements(); function handleInputChange(event) { const { elementType, error, complete } = event; setPaymentValidity({ ...paymentInfoValidation, [elementType]: { error, complete } }); } function isPaymentInfoValid() { return Object.keys(paymentInfoValidation) .map(key => paymentInfoValidation[key]) .every(({ complete, error }) => complete && !error); } const options = { style: { base: { fontSize: '18px', color: `${theme === 'night' ? '#fff' : '#0a0a23'}` } } }; const handleSubmit = async event => { event.preventDefault(); if (!isEmailValid || !isPaymentInfoValid()) return setSubmissionValidity(false); else setSubmissionValidity(true); if (!isEmail(email)) { return onDonationStateChange({ error: t('donate.need-email') }); } const { error, token } = await stripe.createToken( elements.getElement(CardNumberElement), { email } ); if (error) { return onDonationStateChange({ error: t('donate.went-wrong') }); } return postStripeDonation(token); }; const handleEmailChange = e => { const newValue = e.target.value; setEmail(newValue); setEmailValidity(true); }; const handleEmailBlur = () => { const newValidation = isEmail(email); setEmailValidity(newValidation); }; const renderErrorMessage = () => { let message = ''; if (!isEmailValid && !isPaymentInfoValid()) message =

{t('donate.valid-info')}

; else if (!isEmailValid) message =

{t('donate.valid-email')}

; else message =

{t('donate.valid-card')}

; return {message}; }; return (
{!isSubmissionValid ? renderErrorMessage() : ''}
{t('donate.email-receipt')}
{t('donate.card-number')} {t('donate.expiration')} payment options
); }; StripeCardForm.displayName = 'StripeCardForm'; StripeCardForm.propTypes = propTypes; export default withTranslation()(StripeCardForm);