Untitled

mail@pastecode.io avatar
unknown
plain_text
a month ago
4.2 kB
6
Indexable
Never
import * as s from './ArContactForm.module.scss'

import { Controller, useForm } from 'react-hook-form'
import React, { useState } from 'react'

import { ArButton } from 'src/components/ArButton'
import { ArInput } from 'src/components/ArInput'
import { ArTextarea } from 'src/components/ArTextarea'
import SvgOk from 'src/assets/svg/ok.svg'
import { TArContactFormProps } from './ArContactForm.types'
import classNames from 'classnames'

const FORM_FIELDS = [
  {
    label: 'Full name',
    name: 'fullName',
    inputProps: {
      type: 'text',
    },
  },
  {
    label: 'Email address',
    name: 'emailAddress',
    inputProps: {
      type: 'email',
    },
  },
  {
    label: 'Company name',
    name: 'company',
    inputProps: {
      type: 'text',
    },
  },
  {
    label: 'Message',
    name: 'message',
    inputProps: {
      type: 'textarea',
    },
  },
]

export const ArContactForm: React.FC<TArContactFormProps> = ({ style, className }) => {
  const [isSuccess, setSuccess] = useState<boolean>(false)

  const {
    control,
    handleSubmit,
    formState: { errors },
  } = useForm()

  const onSubmit = async (formData: any) => {
    try {
      grecaptcha.ready(function () {
        grecaptcha.execute(process.env.GATSBY_RECAPTCHA_KEY, { action: 'submit' }).then(async (token: string) => {
          const result = await fetch('/', {
            method: 'POST',
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
            body: new URLSearchParams({
              'form-name': 'contact',
              'data-netlify-recaptcha': true,
              'g-recaptcha-response': token,
              ...formData,
            }).toString(),
          })

          if (result.status === 200) {
            setSuccess(true)
          } else {
            throw new Error()
          }
        })
      })
    } catch (err) {
      alert('Something went wrong. Please try one more time.')
    }
  }

  return (
    <div className={classNames(s.container, className)} style={style}>
      <div>
        <h1>Contact us</h1>
        <p>
          For sales or general enquiries, contact us using this form.
          <br />
          <br />
          Feeling old-fashioned?
          <br />
          Give us a call on <a href="tel:020 3880 8461">020 3880 8461</a>.
        </p>
      </div>
      <div>
        {isSuccess && (
          <div className={s.submitConfirmation}>
            <header>
              <SvgOk />
              <p>Success!</p>
            </header>
            <p>Success! Your message has been sent. We’ll be in touch over the next few days.</p>
          </div>
        )}
        {!isSuccess && (
          <form
            onSubmit={handleSubmit(onSubmit)}
            className={s.form}
            method="POST"
            name="contact"
            // Why I did it this way?
            {...{ 'data-netlify': 'true', 'data-netlify-recaptcha': 'true' }}>
            <input type="hidden" name="form-name" value="contact" />
            {FORM_FIELDS.map((item, i) => (
              <Controller
                key={i}
                name={item.name}
                control={control}
                defaultValue={''}
                rules={{ required: true }}
                render={({ field, fieldState }) => {
                  if (item.inputProps.type === 'textarea') {
                    return <ArTextarea label={item.label} error={fieldState.error} {...field} />
                  }
                  return <ArInput label={item.label} type={item.inputProps.type} error={fieldState.error} {...field} />
                }}
              />
            ))}
            <ArButton theme="primary" type="submit">
              Send
            </ArButton>
            {Object.keys(errors).length > 0 && (
              <p className={s.errorMessage}>
                One or more fields are missing, please fill out all of the required fields.
              </p>
            )}
          </form>
        )}
      </div>
    </div>
  )
}
Leave a Comment