diff options
| author | Armand Philippot <git@armandphilippot.com> | 2021-12-17 23:28:17 +0100 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2021-12-17 23:28:17 +0100 |
| commit | efed6c0a820c5c47e097fa29455157bbd318ffca (patch) | |
| tree | 0c52968f8619ce62ba6f442c84dec10fbce4214d | |
| parent | 42315639d14ead79b5fac04508df8be793bbbc0b (diff) | |
chore: create mutation to send mail from contact form
| -rw-r--r-- | src/components/Form/Form.tsx | 16 | ||||
| -rw-r--r-- | src/pages/contact.tsx | 24 | ||||
| -rw-r--r-- | src/services/graphql/contact.ts | 49 | ||||
| -rw-r--r-- | src/ts/types/contact.ts | 19 |
4 files changed, 99 insertions, 9 deletions
diff --git a/src/components/Form/Form.tsx b/src/components/Form/Form.tsx index cc97526..5e26e81 100644 --- a/src/components/Form/Form.tsx +++ b/src/components/Form/Form.tsx @@ -1,13 +1,15 @@ -import { FormEvent } from 'react'; +import { ReactNode } from 'react'; import styles from './Form.module.scss'; -const Form: React.FunctionComponent = ({ children }) => { - const submitForm = (e: FormEvent) => { - e.preventDefault(); - }; - +const Form = ({ + children, + submitHandler, +}: { + children: ReactNode; + submitHandler: any; +}) => { return ( - <form onSubmit={submitForm} className={styles.wrapper}> + <form onSubmit={submitHandler} className={styles.wrapper}> {children} </form> ); diff --git a/src/pages/contact.tsx b/src/pages/contact.tsx index 15e1ad5..bfdd681 100644 --- a/src/pages/contact.tsx +++ b/src/pages/contact.tsx @@ -3,17 +3,19 @@ import { Form, FormItem, Input, TextArea } from '@components/Form'; import Layout from '@components/Layouts/Layout'; import { seo } from '@config/seo'; import { t } from '@lingui/macro'; +import { sendMail } from '@services/graphql/contact'; import { NextPageWithLayout } from '@ts/types/app'; import { loadTranslation } from '@utils/helpers/i18n'; import { GetStaticProps, GetStaticPropsContext } from 'next'; import Head from 'next/head'; -import { ReactElement, useState } from 'react'; +import { FormEvent, ReactElement, useState } from 'react'; const ContactPage: NextPageWithLayout = () => { const [name, setName] = useState(''); const [email, setEmail] = useState(''); const [subject, setSubject] = useState(''); const [message, setMessage] = useState(''); + const [status, setStatus] = useState(''); const resetForm = () => { setName(''); @@ -22,6 +24,23 @@ const ContactPage: NextPageWithLayout = () => { setMessage(''); }; + const submitHandler = async (e: FormEvent) => { + e.preventDefault(); + const body = `Message received from ${name} <${email}> on ArmandPhilippot.com.\n\n${message}`; + const replyTo = `${name} <${email}>`; + const mail = await sendMail(subject, body, replyTo, 'contact'); + + if (mail.sent) { + setStatus( + t`Thanks. Your message was successfully sent. I will answer it as soon as possible.` + ); + resetForm(); + } else { + const error = `${t`An error occurred:`} ${mail.message}`; + setStatus(error); + } + }; + return ( <> <Head> @@ -34,7 +53,8 @@ const ContactPage: NextPageWithLayout = () => { </header> <div> <p>{t`All fields marked with * are required.`}</p> - <Form> + {status && <p>{status}</p>} + <Form submitHandler={submitHandler}> <FormItem> <Input id="contact-name" diff --git a/src/services/graphql/contact.ts b/src/services/graphql/contact.ts new file mode 100644 index 0000000..4699688 --- /dev/null +++ b/src/services/graphql/contact.ts @@ -0,0 +1,49 @@ +import { SendMailReturn, SentEmailResponse } from '@ts/types/contact'; +import { gql } from 'graphql-request'; +import { getGraphQLClient } from './client'; + +export const sendMail: SendMailReturn = async ( + subject: string, + body: string, + replyTo: string, + mutationId: string +) => { + const client = getGraphQLClient(); + const mutation = gql` + mutation SendEmail( + $subject: String! + $body: String! + $replyTo: String! + $mutationId: String! + ) { + sendEmail( + input: { + clientMutationId: $mutationId + body: $body + replyTo: $replyTo + subject: $subject + } + ) { + clientMutationId + message + sent + origin + replyTo + to + } + } + `; + + const variables = { subject, body, replyTo, mutationId }; + + try { + const response: SentEmailResponse = await client.request( + mutation, + variables + ); + return response.sendEmail; + } catch (error) { + console.error(error, undefined, 2); + process.exit(1); + } +}; diff --git a/src/ts/types/contact.ts b/src/ts/types/contact.ts new file mode 100644 index 0000000..c0f23e0 --- /dev/null +++ b/src/ts/types/contact.ts @@ -0,0 +1,19 @@ +export type SentEmail = { + clientMutationId: string; + message: string; + origin: string; + replyTo: string; + sent: boolean; + to: string; +}; + +export type SentEmailResponse = { + sendEmail: SentEmail; +}; + +export type SendMailReturn = ( + subject: string, + body: string, + replyTo: string, + mutationId: string +) => Promise<SentEmail>; |
