tutorbookapp/tutorbook

View on GitHub
components/calendar/search-bar.tsx

Summary

Maintainability
A
1 hr
Test Coverage
import { memo, useCallback } from 'react';
import { IconButton } from '@rmwc/icon-button';
import { TextField } from '@rmwc/textfield';
import { dequal } from 'dequal/lite';

import DownloadIcon from 'components/icons/download';
import FilterListIcon from 'components/icons/filter-list';

import { Callback } from 'lib/model/callback';
import { MeetingsQuery } from 'lib/model/query/meetings';

import styles from './search-bar.module.scss';

export interface SearchBarProps {
  query: MeetingsQuery;
  setQuery: Callback<MeetingsQuery>;
  setFiltersOpen: Callback<boolean>;
  byOrg?: boolean;
}

function SearchBar({
  query,
  setQuery,
  setFiltersOpen,
  byOrg,
}: SearchBarProps): JSX.Element {
  const downloadResults = useCallback(() => {
    window.open(query.getURL('/api/meetings/csv'));
  }, [query]);

  return (
    <div className={styles.filters}>
      <div className={styles.left}>
        {byOrg && (
          <IconButton
            data-cy='filters-button'
            className={styles.filtersButton}
            onClick={() => setFiltersOpen((prev) => !prev)}
            icon={<FilterListIcon />}
          />
        )}
        {byOrg && (
          <IconButton
            data-cy='download-button'
            onClick={downloadResults}
            icon={<DownloadIcon />}
          />
        )}
      </div>
      <div className={styles.right}>
        <TextField
          outlined
          placeholder='Search by description'
          className={styles.searchField}
          value={query.search}
          onChange={(evt) => {
            const search = evt.currentTarget.value;
            setQuery((prev) => new MeetingsQuery({ ...prev, search }));
          }}
        />
      </div>
    </div>
  );
}

export default memo(SearchBar, dequal);