Skip to content

Commit

Permalink
Merge pull request #190 from Web-Dev-Path/bug/MailChimp-not-saving-name
Browse files Browse the repository at this point in the history
Fixing Mailchimp not saving name. Refactor reCaptcha file structure.
  • Loading branch information
tonykieling committed Sep 7, 2023
2 parents beb5c1a + b1b5a5a commit 9a1f263
Show file tree
Hide file tree
Showing 14 changed files with 197 additions and 199 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,5 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Lower the file names of GitHub.svg, LikedIn.svg, and YouTube.svg.
- Fixed Google Analytics 4 Integration
- Fixed CHANGELOG.md inconsistency
- Contact and Subscribe forms are saving Name on Mailchimp
- Fixed Who We Are section on mobile.
Original file line number Diff line number Diff line change
@@ -1,39 +1,10 @@
import { useForm } from 'react-hook-form';
import { useRef } from 'react';
import MailchimpSubscribe from 'react-mailchimp-subscribe';
import ReCAPTCHA from 'react-google-recaptcha';
import Container from '@/components/containers/Container';
import RevealContentContainer from '@/components/containers/RevealContentContainer';
import { SubmitButton } from '@/components/buttons/SubmitButton';
import S from './styles';

export const ContactUsFormSubscribe = ({ setMsg }) => {
return (
<MailchimpSubscribe
url={process.env.NEXT_PUBLIC_MAILCHIMP_URL}
render={({ subscribe, status, message }) => {
console.info(`MailChimp (contact form): ${status} - ${message}`);
return (
<>
<ContactUsForm
subscribe={formData => subscribe(formData)}
setResponseMessage={setMsg}
/>
{status === 'error' && (
<S.ResponseOnErrorMsg>
{`Newsletter subscription error: ${message}`}
</S.ResponseOnErrorMsg>
)}
</>
);
}}
/>
);
};

function ContactUsForm({ subscribe, setResponseMessage }) {
const contactReCaptchaRef = useRef();

function ContactUsForm({ subscribe, setResponseMessage, getReCaptchaToken }) {
const {
register,
handleSubmit,
Expand All @@ -51,10 +22,14 @@ function ContactUsForm({ subscribe, setResponseMessage }) {
async function onSubmit(data) {
setResponseMessage(['Submitting...']);

contactReCaptchaRef.current.reset();
const gReCaptchaToken = await contactReCaptchaRef.current.executeAsync();
const gReCaptchaToken = await getReCaptchaToken();

const res = await fetch('/api/contact', {
if (!gReCaptchaToken) {
setResponseMessage(['Please, refresh your screen and try it again.']);
return;
}

const res = await fetch('/api/validateReCaptcha', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Expand Down Expand Up @@ -83,7 +58,10 @@ function ContactUsForm({ subscribe, setResponseMessage }) {
}

if (data.Subscribe) {
subscribe({ EMAIL: data.Email });
subscribe({
EMAIL: data.Email,
MERGE1: data.Name,
});
}
reset();
}
Expand Down Expand Up @@ -167,14 +145,10 @@ function ContactUsForm({ subscribe, setResponseMessage }) {
Subscribe to our DevNews!
</S.SubscribeWrapper>
<SubmitButton label='Submit' disabled={isSubmitting} />

<ReCAPTCHA
ref={contactReCaptchaRef}
size='invisible'
sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY}
/>
</S.Form>
</Container>
</RevealContentContainer>
);
}

export default ContactUsForm;
File renamed without changes.
9 changes: 9 additions & 0 deletions components/ContactUs/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react';
import Mailchimp from '../Mailchimp';
import ContactUsForm from '@/components/ContactUs/ContactUsForm';

const ContactUs = ({ setMsg }) => {
return <Mailchimp child={<ContactUsForm setResponseMessage={setMsg} />} />;
};

export default ContactUs;
47 changes: 47 additions & 0 deletions components/Mailchimp/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import MailchimpSubscribe from 'react-mailchimp-subscribe';
import { cloneElement, useRef } from 'react';
import GoogleReCAPTCHA from 'react-google-recaptcha';

const MAILCHIMP_URL = process.env.NEXT_PUBLIC_MAILCHIMP_URL;
const RECAPTCHA_SITE_KEY = process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY;

const Mailchimp = ({ child }) => {
const reCAPTCHARef = useRef(null);
let childToBeRendered = cloneElement(child);

const getReCaptchaToken = async () => {
await reCAPTCHARef.current.reset();
const token = await reCAPTCHARef.current.executeAsync();
return token;
};

return (
<MailchimpSubscribe
url={MAILCHIMP_URL}
render={({ subscribe, status, message }) => {
childToBeRendered = {
...childToBeRendered,
props: {
...child.props,
subscribe,
status,
message,
getReCaptchaToken,
},
};

return (
<GoogleReCAPTCHA
ref={reCAPTCHARef}
size='invisible'
sitekey={RECAPTCHA_SITE_KEY}
>
{childToBeRendered}
</GoogleReCAPTCHA>
);
}}
/>
);
};

export default Mailchimp;
Original file line number Diff line number Diff line change
@@ -1,50 +1,41 @@
import { createRef, useState } from 'react';
import { useEffect, useState } from 'react';
import Image from 'next/image';
import { decode } from 'html-entities';
import ReCAPTCHA from 'react-google-recaptcha';
import { NewsLetterSubmitButton } from '@/components/buttons/SubmitButton';
import S from './styles';

const SITE_KEY = process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY;

const NewsletterForm = ({ status, message, onValidated }) => {
const NewsletterForm = ({ status, message, subscribe, getReCaptchaToken }) => {
const [error, setError] = useState(null);
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const recaptchaRef = createRef();
const [reCaptchaFail, setReCaptchaFail] = useState(false);

useEffect(() => {
if (status === 'success') {
setName('');
setEmail('');
}
}, [status]);

const onReCAPTCHAChange = async captchaCode => {
const validateReCaptcha = async () => {
// If the reCAPTCHA code is null or undefined indicating that
// the reCAPTCHA was expired then return early
if (!captchaCode) {
return;
}
const gReCaptchaToken = await getReCaptchaToken();
if (!gReCaptchaToken) return false;

try {
const response = await fetch('/api/register', {
const response = await fetch('/api/validateReCaptcha', {
method: 'POST',
body: JSON.stringify({ email, name, captcha: captchaCode }),
body: JSON.stringify({ email, name, gReCaptchaToken }),
headers: {
'Content-Type': 'application/json',
},
});
if (response.ok) {
// If the response is ok than show the success console.log
console.log('Email registered successfully');
} else {
// Else throw an error with the message returned
const error = await response.json();
throw new Error(error.message);
}

return response.ok ? true : false;
} catch (error) {
console.log(error?.message || 'Something went wrong');
} finally {
// Reset the reCAPTCHA when the request has failed or succeeded
if (recaptchaRef?.current) {
recaptchaRef.current.reset();
}

setEmail('');
setName('');
return false;
}
};

Expand All @@ -53,9 +44,10 @@ const NewsletterForm = ({ status, message, onValidated }) => {
*
* @return {{value}|*|boolean|null}
*/
const handleFormSubmit = event => {
const handleFormSubmit = async event => {
event.preventDefault();

setReCaptchaFail(false);
setError(null);

if (!name) {
Expand All @@ -68,14 +60,18 @@ const NewsletterForm = ({ status, message, onValidated }) => {
return null;
}

recaptchaRef.current.execute();

const isFormValidated = onValidated({ EMAIL: email });

event.target.reset();
const confirmValidateRecaptcha = await validateReCaptcha();
if (!confirmValidateRecaptcha) {
setReCaptchaFail(true);
} else {
subscribe({
EMAIL: email,
MERGE1: name,
});

// On success return true
return name && email && email.indexOf('@') > -1 && isFormValidated;
event.target.reset();
setReCaptchaFail(false);
}
};

/**
Expand Down Expand Up @@ -144,16 +140,15 @@ const NewsletterForm = ({ status, message, onValidated }) => {
onKeyUp={event => handleInputKeyEvent(event)}
/>
<NewsLetterSubmitButton label='Subscribe' />

<ReCAPTCHA
ref={recaptchaRef}
size='invisible'
sitekey={SITE_KEY}
onChange={onReCAPTCHAChange}
/>
</S.Form>

<S.FormInfo>
{reCaptchaFail && (
<S.FormSending>
Please, refresh your screen and try it again.
</S.FormSending>
)}

{status === 'sending' && <S.FormSending>Sending...</S.FormSending>}
{status === 'error' || error ? (
<S.FormError
Expand Down
8 changes: 8 additions & 0 deletions components/NewsletterSubscribe/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Mailchimp from '../Mailchimp';
import NewsletterForm from '@/components/NewsletterSubscribe/NewsletterForm';

const NewsletterSubscribe = () => {
return <Mailchimp child={<NewsletterForm />} />;
};

export default NewsletterSubscribe;
2 changes: 1 addition & 1 deletion components/layout/Footer/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Image from 'next/image';
import { linksNav, linksSocial } from '@/utils/links';
import NewsletterSubscribe from '@/components/mailchimp/NewsletterSubscribe';
import NewsletterSubscribe from '@/components/NewsletterSubscribe';
import Container from '@/components/containers/Container';
import S from './styles';

Expand Down
24 changes: 0 additions & 24 deletions components/mailchimp/NewsletterSubscribe.js

This file was deleted.

Loading

0 comments on commit 9a1f263

Please sign in to comment.