Skip to content

Commit

Permalink
integrate mailchimp with an api function
Browse files Browse the repository at this point in the history
  • Loading branch information
pettinarip committed Feb 10, 2022
1 parent 8246cb8 commit f5e8c44
Show file tree
Hide file tree
Showing 6 changed files with 232 additions and 20 deletions.
10 changes: 10 additions & 0 deletions .env.local.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# grants list
GOOGLE_GRANTS_SHEET_API_URL=

# project grants application
PROJECT_GRANTS_DOWNLOAD_FILE_URL=

# mailchimp
MAILCHIMP_APIKEY=
MAILCHIMP_SERVER=
MAILCHIMP_LIST_ID=
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"@emotion/react": "^11",
"@emotion/styled": "^11",
"@fontsource/libre-franklin": "^4.5.0",
"@mailchimp/mailchimp_marketing": "^3.0.74",
"chakra-react-select": "^3.0.1",
"chakra-ui-markdown-renderer": "^4.0.0",
"focus-visible": "^5.2.0",
Expand All @@ -30,6 +31,7 @@
},
"devDependencies": {
"@types/jsforce": "^1.9.37",
"@types/mailchimp__mailchimp_marketing": "^3.0.3",
"@types/node": "17.0.0",
"@types/papaparse": "^5.3.2",
"@types/react": "17.0.37",
Expand Down
59 changes: 42 additions & 17 deletions src/components/forms/NewsletterSignup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
Stack,
useToast
} from '@chakra-ui/react';
import type { UseToastOptions } from '@chakra-ui/react';
import { FC } from 'react';
import { useForm } from 'react-hook-form';
import { motion } from 'framer-motion';
Expand All @@ -20,9 +21,20 @@ import { PageText } from '../UI/text';
import { useShadowAnimation } from '../../hooks';
import { NewsletterFormData } from '../../types';

import { API_NEWSLETTER_SIGNUP_URL } from '../../constants';

const MotionBox = motion<BoxProps>(Box);
const MotionButton = motion<ButtonProps>(Button);

const toastOptions: UseToastOptions = {
position: 'top-right',
duration: 5000,
isClosable: true,
containerStyle: {
fontFamily: 'fonts.heading'
}
};

export const NewsletterSignup: FC = () => {
const {
handleSubmit,
Expand All @@ -35,29 +47,42 @@ export const NewsletterSignup: FC = () => {
const toast = useToast();
const { shadowBoxControl, setButtonHovered } = useShadowAnimation();

const onSubmit = (data: NewsletterFormData) => {
const onSubmit = async (data: NewsletterFormData) => {
if (errors.email) {
toast({
position: 'top-right',
...toastOptions,
title: 'Email is not valid, please try again.',
status: 'error',
duration: 5000,
isClosable: true,
containerStyle: {
fontFamily: 'fonts.heading'
}
status: 'error'
});
} else {
toast({
position: 'top-right',
title: 'Success!',
status: 'success',
duration: 5000,
isClosable: true,
containerStyle: {
fontFamily: 'fonts.heading'
try {
const response = await fetch(API_NEWSLETTER_SIGNUP_URL, {
method: 'POST',
body: data.email
});

if (!response.ok) {
const errorText = await response.text();
toast({
...toastOptions,
title: errorText,
status: 'error'
});
return;
}
});

toast({
...toastOptions,
title: 'You have signed up correctly!',
status: 'success'
});
} catch (error) {
toast({
...toastOptions,
title: 'Something unexpected happened, try again',
status: 'error'
});
}
}

reset();
Expand Down
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ export const ETHRESEARCH_URL = 'https://ethresear.ch/';

// api
export const API_DOWNLOAD_APPLICATION_URL = '/api/download-application';
export const API_NEWSLETTER_SIGNUP_URL = '/api/newsletter-signup';

// grants list
export const CURRENT_GRANTS_QUARTERS = ['3', '4'];
35 changes: 35 additions & 0 deletions src/pages/api/newsletter-signup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import mailchimp from '@mailchimp/mailchimp_marketing';

mailchimp.setConfig({
apiKey: process.env.MAILCHIMP_APIKEY,
server: process.env.MAILCHIMP_SERVER
});

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const { body, method } = req;

if (method !== 'POST') {
return res.status(405).end(`Method ${method} Not Allowed`);
}

try {
await mailchimp.lists.addListMember(process.env.MAILCHIMP_LIST_ID!, {
email_address: body,
status: 'subscribed'
});

res.status(200).end();
} catch (err: any) {
console.error(err);

if (err.response) {
// return the mailchimp error code & message
// docs: https://mailchimp.com/developer/marketing/docs/errors/
const body = err.response.body;
res.status(body.status).end(body.detail);
} else {
res.status(500).end();
}
}
}
Loading

0 comments on commit f5e8c44

Please sign in to comment.