OperationCode/front-end

View on GitHub
components/Forms/ResourceSearchForm/ResourceSearchForm.js

Summary

Maintainability
A
0 mins
Test Coverage
B
86%
import { Field, Formik } from 'formik';
import omit from 'lodash/omit';
import styles from 'styles/resources.module.css';
import { string, func, shape, array } from 'prop-types';
import Button from 'components/Buttons/Button/Button';
import Form from 'components/Form/Form';
import Input from 'components/Form/Input/Input';
import Select from 'components/Form/Select/Select';
import {
  RESOURCE_SEARCH,
  RESOURCE_SEARCH_BUTTON,
  RESOURCE_RESET_BUTTON,
} from 'common/constants/testIDs';

ResourceSearchForm.propTypes = {
  setIsLoading: func.isRequired,
  updateQuery: func.isRequired,
  setErrorMessage: func.isRequired,
  allLanguages: array.isRequired,
  allCategories: array.isRequired,
  fields: shape({
    languages: string,
    category: string,
    paid: string,
    q: string,
  }).isRequired,
};

function ResourceSearchForm({
  fields,
  setIsLoading,
  updateQuery,
  setErrorMessage,
  allCategories,
  allLanguages,
}) {
  const initialValues = {
    category: fields.category || '',
    q: fields.q || '',
    languages: Array.isArray(fields.languages)
      ? fields.languages
      : [fields.languages].filter(Boolean),
    free: fields.free || false,
  };

  const costOptions = [
    { value: 'false', label: 'Paid' },
    { value: 'true', label: 'Free' },
  ];

  const handleSubmit = (values, actions) => {
    setIsLoading(true);
    const emptyQueryParameters = Object.entries(values).filter(
      item => item[1] === null || !item[1].length,
    );
    const activeParameters = omit(
      values,
      emptyQueryParameters.map(parameter => parameter[0]),
    );

    updateQuery(activeParameters);
    setTimeout(() => {
      actions.setSubmitting(false);
    }, 500);
  };

  const handleReset = () => {
    setErrorMessage(null);
    updateQuery('');
  };

  return (
    <Formik
      enableReinitialize
      initialValues={initialValues}
      onSubmit={(values, actions) => {
        handleSubmit(values, actions);
        actions.setSubmitting(true);
      }}
    >
      {({ isSubmitting }) => (
        <Form role="search" onReset={handleReset}>
          <Field
            hasValidationStyling={false}
            data-testid={RESOURCE_SEARCH}
            disabled={isSubmitting}
            type="search"
            name="q"
            label="Search Keywords"
            component={Input}
          />

          <div className={styles.formContainer}>
            <div className={styles.selectColumn}>
              <Field
                hasValidationStyling={false}
                isDisabled={isSubmitting}
                placeholder="Start typing a category..."
                label="By Category"
                name="category"
                options={allCategories}
                component={Select}
              />
            </div>

            <div className={styles.selectColumn}>
              <Field
                hasValidationStyling={false}
                isDisabled={isSubmitting}
                placeholder="Resource cost..."
                label="By Cost"
                name="free"
                options={costOptions}
                component={Select}
              />
            </div>

            <div className={styles.selectColumn}>
              <Field
                hasValidationStyling={false}
                isDisabled={isSubmitting}
                placeholder="Start typing a language..."
                isMulti
                label="By Language(s)"
                name="languages"
                options={allLanguages}
                component={Select}
              />
            </div>
          </div>

          <div className={styles.buttonGroup}>
            <Button
              className={styles.buttonSingle}
              data-testid={RESOURCE_SEARCH_BUTTON}
              disabled={isSubmitting}
              theme="secondary"
              type="submit"
            >
              Search
            </Button>

            <Button
              className={styles.buttonSingle}
              data-testid={RESOURCE_RESET_BUTTON}
              disabled={isSubmitting}
              theme="secondary"
              type="reset"
            >
              Reset
            </Button>
          </div>
        </Form>
      )}
    </Formik>
  );
}

export default ResourceSearchForm;