diff options
| author | Armand Philippot <git@armandphilippot.com> | 2022-02-10 16:51:08 +0100 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2022-02-10 16:51:08 +0100 |
| commit | 82e387d33fc296b1e5a08fef17bcd4595e0c7071 (patch) | |
| tree | 780a3886a5e33804b16a335b37bd14bcaa1f6ed3 /src/components | |
| parent | f2be002df3b13254a5b549dd1589089545c53f02 (diff) | |
refactor: extract contact form from contact page
The contact page file was too long. By extracting the contact form the
readability is improved.
Diffstat (limited to 'src/components')
| -rw-r--r-- | src/components/ContactForm/ContactForm.module.scss | 21 | ||||
| -rw-r--r-- | src/components/ContactForm/ContactForm.tsx | 155 |
2 files changed, 176 insertions, 0 deletions
diff --git a/src/components/ContactForm/ContactForm.module.scss b/src/components/ContactForm/ContactForm.module.scss new file mode 100644 index 0000000..3f0e861 --- /dev/null +++ b/src/components/ContactForm/ContactForm.module.scss @@ -0,0 +1,21 @@ +@use "@styles/abstracts/functions" as fun; + +.status { + max-width: max-content; + margin: var(--spacing-md) 0; + padding: var(--spacing-sm); + border: fun.convert-px(3) solid var(--color-border-light); + border-radius: fun.convert-px(5); + + &--error { + border-color: var(--color-token-red); + } + + &--success { + border-color: var(--color-token-green); + } + + &--warning { + border-color: var(--color-token-orange); + } +} diff --git a/src/components/ContactForm/ContactForm.tsx b/src/components/ContactForm/ContactForm.tsx new file mode 100644 index 0000000..6ab1e2b --- /dev/null +++ b/src/components/ContactForm/ContactForm.tsx @@ -0,0 +1,155 @@ +import { ButtonSubmit } from '@components/Buttons'; +import { Form, FormItem, Input, TextArea } from '@components/Form'; +import { sendMail } from '@services/graphql/mutations'; +import { settings } from '@utils/config'; +import { FormEvent, useState } from 'react'; +import { useIntl } from 'react-intl'; +import styles from './ContactForm.module.scss'; + +type Status = 'success' | 'error' | 'warning'; + +const ContactForm = () => { + const intl = useIntl(); + const [name, setName] = useState(''); + const [email, setEmail] = useState(''); + const [subject, setSubject] = useState(''); + const [message, setMessage] = useState(''); + const [status, setStatus] = useState<Status>(); + const [statusMessage, setStatusMessage] = useState<string>(''); + + const resetForm = () => { + setName(''); + setEmail(''); + setSubject(''); + setMessage(''); + }; + + const submitHandler = async (e: FormEvent) => { + e.preventDefault(); + + if (!name || !email || !message) { + setStatus('warning'); + setStatusMessage( + intl.formatMessage({ + defaultMessage: + 'Warning: mail not sent. Some required fields are empty.', + description: 'ContactForm: missing fields message.', + }) + ); + return; + } + + const messageHTML = message.replace(/\r?\n/g, '<br />'); + const body = `Message received from ${name} <${email}> on ${settings.url}.<br /><br />${messageHTML}`; + const replyTo = `${name} <${email}>`; + const data = { + body, + mutationId: 'contact', + replyTo, + subject, + }; + const mail = await sendMail(data); + + if (mail.sent) { + setStatus('success'); + setStatusMessage( + intl.formatMessage({ + defaultMessage: + 'Thanks. Your message was successfully sent. I will answer it as soon as possible.', + description: 'ContactForm: success message', + }) + ); + resetForm(); + } else { + const errorPrefix = intl.formatMessage({ + defaultMessage: 'An error occurred:', + description: 'ContactForm: error message', + }); + const error = `${errorPrefix} ${mail.message}`; + setStatus('error'); + setStatusMessage(error); + } + }; + + const getStatus = () => { + if (!status) return <></>; + + const statusModifier = `status--${status}`; + + return ( + <p className={`${styles.status} ${styles[statusModifier]}`}> + {statusMessage} + </p> + ); + }; + + return ( + <> + <Form submitHandler={submitHandler}> + <FormItem> + <Input + id="contact-name" + name="name" + value={name} + setValue={setName} + label={intl.formatMessage({ + defaultMessage: 'Name', + description: 'ContactForm: name field label', + })} + required={true} + /> + </FormItem> + <FormItem> + <Input + id="contact-email" + type="email" + name="email" + value={email} + setValue={setEmail} + label={intl.formatMessage({ + defaultMessage: 'Email', + description: 'ContactForm: email field label', + })} + required={true} + /> + </FormItem> + <FormItem> + <Input + id="contact-subject" + name="subject" + value={subject} + setValue={setSubject} + label={intl.formatMessage({ + defaultMessage: 'Subject', + description: 'ContactForm: subject field label', + })} + /> + </FormItem> + <FormItem> + <TextArea + id="contact-message" + name="message" + value={message} + setValue={setMessage} + label={intl.formatMessage({ + defaultMessage: 'Message', + description: 'ContactForm: message field label', + })} + required={true} + /> + </FormItem> + <FormItem> + <ButtonSubmit> + {intl.formatMessage({ + defaultMessage: 'Send', + description: 'ContactForm: send button text', + })} + </ButtonSubmit> + </FormItem> + </Form> + {getStatus()} + </> + ); +}; + +export default ContactForm; |
