Untitled

mail@pastecode.io avatar
unknown
jsx
2 years ago
5.2 kB
1
Indexable
Never
import React from "react";
import styles from "./filter.module.scss";
import stores from "../../../data/stores/stores.json";
import { useState } from "react";
import Link from "next/link";
import Container from "@/components/atoms/Container";
import { useEffect } from "react";
import Select from "react-select";

const Filter = ({ data }) => {
  const alphabet = "#abcdefghijklmnopqrstuvwxyz".toUpperCase().split("");
  alphabet.unshift("All");
  const alphabetWithoutAll = alphabet.slice(1);
  const [filteredChar, setFilteredChar] = useState("All");
  const [filterByCategory, setFilterByCategory] = useState("All categories");
  const [isClickAndCollect, setIsClickAndCollect] = useState(false);
  const [results, setResults] = useState(stores);
  const [sortedResults, setSortedResults] = useState(sortResults(results));

  const colourStyles = {
    container: (styles) => ({
      ...styles,
      width: 250,
      "&:highlighted": {
        backgroundColor: "black",
        color: "white",
      },
    }),
    control: (styles) => ({
      ...styles,
      background: "white",
      width: 250,
      outline: "none",
    }),
    option: (styles) => {
      return {
        ...styles,
        background: "white",
        color: "black",
        cursor: "pointer",

        "&:hover": {
          backgroundColor: "black",
          color: "white",
        },
      };
    },
  };

  function sortResults(array) {
    const result = [];
    array.forEach((store) => {
      if (!result[store.title.charAt(0)]) {
        result[store.title.charAt(0)] = [];
      }
      result[store.title.charAt(0)].push(store);
    });
    return result;
  }

  const usedLetters = Object.keys(sortResults(stores));

  useEffect(() => {
    setResults(
      stores.filter((store) => {
        if (filterByCategory !== "All categories" && filterByCategory !== store.category) {
          return false;
        }
        if (filteredChar !== "All" && !store.title.startsWith(filteredChar)) {
          return false;
        }
        if (isClickAndCollect && !store.clickAndCollect) {
          return false;
        }
        return store;
      })
    );
  }, [filterByCategory, filteredChar, isClickAndCollect]);

  useEffect(() => {
    setSortedResults(sortResults(results));
  }, [results]);

  const selectCategory = (selectedOption) => {
    setFilterByCategory(selectedOption.label);
  };

  return (
    <div className={styles.component}>
      <div className={styles.component_intro}>
        <div className={styles.title}>{data?.content?.title}</div>
        <div className={styles.body}>{data?.content?.body}</div>

        <div className={styles.component_categories}>
          {/* Category select */}
          <Select
            name="categories"
            id="categories-filter"
            styles={colourStyles}
            options={data.content.sortBy.categories}
            onChange={selectCategory}
          ></Select>
        </div>

        {/* Click and collect filter */}
        <div className={styles.clickAndCollect}>
          <input type="checkbox" id="clickAndCollect" onClick={() => setIsClickAndCollect(!isClickAndCollect)} />
          <label htmlFor="clickAndCollect" className={styles.clickAndCollect_label}>
            {data?.content?.clickAndCollect?.label}
          </label>
        </div>
      </div>
      {/* Letter list */}
      <Container type="content" className={styles.letter_list_wrap}>
        <div className={styles.letter_list}>
          {alphabet.map((letter, index) => (
            <button
              className={letter === filteredChar ? styles.letter_list_item_active : styles.letter_list_item}
              onClick={() => setFilteredChar(letter)}
              disabled={!usedLetters.includes(letter || letter.toLowerCase()) && letter !== "All"}
              key={index}
            >
              {letter}
            </button>
          ))}
        </div>
      </Container>

      {/* Results table */}
      <Container type="content" className={styles.results}>
        {filteredChar === "All" ? (
          alphabetWithoutAll.map((letter, index) => (
            <div className={styles.results_item} key={index}>
              <span className={styles.letter}>{letter}</span>
              <div className={styles.result}>
                <ul>
                  {sortedResults[letter]?.map((result, index) => (
                    <li className={styles.result_item} key={index}>
                      <Link href={result.slug}>{result.title}</Link>
                    </li>
                  ))}
                </ul>
              </div>
            </div>
          ))
        ) : (
          <div className={styles.results_item}>
            <span className={styles.letter}>{filteredChar}</span>
            <div className={styles.result}>
              <ul>
                {sortedResults[filteredChar]?.map((result, index) => (
                  <li key={index}>
                    <Link href={result.slug}>{result?.title}</Link>
                  </li>
                ))}
              </ul>
            </div>
          </div>
        )}
      </Container>
    </div>
  );
};

export default Filter;