December-software-project/sort-algo

View on GitHub
src/contactus/body/Form.js

Summary

Maintainability
A
0 mins
Test Coverage
F
0%
import React, { useState } from 'react';
import './styles.css';
import { Dropdown, Menu } from 'antd';
import { DownOutlined } from '@ant-design/icons';
import { Formik } from 'formik';
import * as yup from 'yup';
import emailjs from 'emailjs-com';
import IsVisibleYDirection from '../../component/IsVisibleYDirection/IsVisibleYDirection';
import Notification from './Notification';

/**
 * A form for user to fill in their details.
 *
 * @component
 * @category Contact Us
 */
const Form = () => {
  const [type, setType] = useState('Type (Optional)');
  const [isShowMessage, setIsShowMessage] = useState(false);

  const listOfTypes = [
    { type: 'Type (Optional)', key: 0 },
    { type: 'Collaboration', key: 1 },
    { type: 'Improvement', key: 2 },
    { type: 'Issue', key: 3 },
    { type: 'Others', key: 4 },
  ];

  /**
   * Change the type of message.
   *
   * @param {string} type Type of input form.
   */
  const handleMenuClick = (type) => {
    setType(type);
  };

  /**
   * A drop down list to provide a list of types of message to choose from.
   *
   * @type {JSX.Element}
   */
  const menu = (
    <Menu style={{ transform: 'translateY(-5px)' }}>
      {listOfTypes.map(({ type, key }) => {
        return (
          <Menu.Item key={key} onClick={() => handleMenuClick(type)} style={{ color: '#8789B5' }}>
            {type}
          </Menu.Item>
        );
      })}
    </Menu>
  );

  /**
   * Sends a message to the users and the developers upon the user sends a message.
   *
   * @param {Object} values User's details
   */
  const sendMessage = (values) => {
    const message = {
      name: values.name,
      email: values.email,
      type: type,
      message: values.message,
    };
    emailjs
      .send('service_qua6c3o', 'template_l85e43l', message, 'user_Tvjdrhs7WD4QYNebwjcAw')
      .then((r) => {});
  };

  /**
   * A Schema which checks the validity of the inputs from the user.
   */
  const reviewSchema = yup.object({
    name: yup.string().required(),
    email: yup
      .string()
      .required()
      .email('Invalid email')
      .test('check if email is in use', 'Email has been registered', (val) => {
        const emailRegex = /^([a-zA-Z0-9_.-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$/;
        return emailRegex.test(val);
      }),
    message: yup.string().required(),
  });

  const yValue = `translateY(50px)`;

  return (
    <Formik
      initialValues={{ name: '', email: '', type: '', message: '' }}
      validationSchema={reviewSchema}
      onSubmit={(values, actions) => {
        sendMessage(values);
        setType('Type (Optional)');
        setIsShowMessage(true);
        setTimeout(() => setIsShowMessage(false), 5000);
        actions.resetForm();
      }}
    >
      {(props) => (
        <>
          <div className="form-box">
            <div className="form-particulars" id="form-particulars">
              <IsVisibleYDirection classNameToUse="form-particular-error-holder" yValue={yValue}>
                <div className="form-particulars-holder">
                  <input
                    placeholder="Name"
                    required={true}
                    onChange={props.handleChange}
                    value={props.values.name}
                    name="name"
                  />
                </div>
                <span>{props.touched.name && props.errors.name && 'Name is a required field'}</span>
              </IsVisibleYDirection>
              <IsVisibleYDirection classNameToUse="form-particular-error-holder" yValue={yValue}>
                <div className="form-particulars-holder">
                  <input
                    placeholder="Email"
                    required={true}
                    onChange={props.handleChange}
                    value={props.values.email}
                    name="email"
                  />
                </div>
                <span>
                  {props.touched.email && props.errors.email && 'Email is a required field'}
                </span>
              </IsVisibleYDirection>
              <IsVisibleYDirection classNameToUse="form-particular-error-holder" yValue={yValue}>
                <div className="form-particulars-holder">
                  <span>{type}</span>
                  <Dropdown overlay={menu} trigger={['click']} placement={'bottomCenter'}>
                    <a
                      className="ant-dropdown-link"
                      onClick={(e) => e.preventDefault()}
                      id="drop-down-arrow-holder"
                    >
                      <DownOutlined style={{ transform: 'translateX(-20px)' }} />
                    </a>
                  </Dropdown>
                </div>
              </IsVisibleYDirection>
            </div>
            <IsVisibleYDirection classNameToUse="form-details" yValue={yValue}>
              <div className="form-details-error-holder">
                <div className="form-details-holder">
                  <textarea
                    placeholder="Message"
                    required={true}
                    onChange={props.handleChange}
                    value={props.values.message}
                    name="message"
                  />
                </div>
                <span>
                  {props.touched.message && props.errors.message && 'Message is a required field'}
                </span>
              </div>
            </IsVisibleYDirection>
            <IsVisibleYDirection classNameToUse="form-submit-button-box" yValue={yValue}>
              <button className="form-submit-button" onClick={props.handleSubmit} type="submit">
                <span>SEND MESSAGE</span>
              </button>
            </IsVisibleYDirection>
          </div>
          <Notification isShowMessage={isShowMessage} setIsShowMessage={setIsShowMessage} />
        </>
      )}
    </Formik>
  );
};

export default Form;