Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 208 | Rev 485 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |

import React, { useState, useRef, useEffect } from "react";
import { axios, jsonToParams } from "../../utils";
import { Col, Container, Row } from "react-bootstrap";
import { useHistory, useLocation } from "react-router-dom";
import SearchIcon from "@mui/icons-material/Search";

import Spinner from "../../components/UI/Spinner";
import SearchItem from "../../components/search/SearchItem";
import Input from "../../components/UI/Input";
import EmptySection from "../../components/UI/EmptySection";
import PaginationComponent from "../../components/UI/PaginationComponent";
import FiltersSidebar from "../../components/search/FiltersSidebar";
import CategoryFilter from "../../components/search/CategoryFilter";
import LocationFilter from "../../components/search/LocationFilter";

const SearchPage = () => {
  const [entities, setEntities] = useState([]);
  const [loading, setLoading] = useState(true);
  const [category, setCategory] = useState("user");
  const [entity, setEntity] = useState("");
  const [currentPage, setCurrentPage] = useState(1);
  const [pages, setPages] = useState(1);
  const activeFilters = useRef([]);
  const addressKeys = useRef([]);

  const { search, pathname } = useLocation();
  const history = useHistory();

  const params = new URLSearchParams(search);
  const keyword = params.get("keyword");

  const loadEntities = async (page = 1, keyword = "", category = "user") => {
    setLoading(true);
    setCurrentPage(page);

    const urlParams = { page, keyword };

    addressKeys.current.forEach(({ name, type }) => {
      urlParams[type] = name;
    });

    activeFilters.current.forEach(({ name, value }) => {
      urlParams[name] = value;
    });

    await axios
      .get(`/search/entity/${category}?${jsonToParams(urlParams)}`)
      .then((response) => {
        const { success, data } = response.data;

        if (success) {
          setEntities(data.current.items);
          setPages(data.total.pages);
        }
      });
    setLoading(false);
  };

  const onChangePageHandler = (currentPage) => {
    setCurrentPage(currentPage);
  };

  const getAddressHandler = (addresObject) => {
    const { address_components } = addresObject;
    if (address_components) {
      addressKeys.current = [];
      address_components.map((address_component) => {
        const address_component_name = address_component.long_name;
        const address_component_type = address_component.types[0];
        switch (address_component_type) {
          case "route":
            addressKeys.current = [
              ...addressKeys.current,
              { type: "route", name: address_component_name },
            ];
            break;
          case "sublocality":
            addressKeys.current = [
              ...addressKeys.current,
              { type: "sublocality", name: address_component_name },
            ];
            break;
          case "locality":
            addressKeys.current = [
              ...addressKeys.current,
              { type: "locality", name: address_component_name },
            ];
            break;
          case "administrative_area_level_2":
            addressKeys.current = [
              ...addressKeys.current,
              {
                type: "administrative_area_level_2",
                name: address_component_name,
              },
            ];
            break;
          case "administrative_area_level_1":
            addressKeys.current = [
              ...addressKeys.current,
              {
                type: "administrative_area_level_1",
                name: address_component_name,
              },
            ];
            break;
          case "country":
            addressKeys.current = [
              ...addressKeys.current,
              { type: "country", name: address_component_name },
            ];
            break;
          case "postal_code":
            addressKeys.current = [
              ...addressKeys.current,
              { type: "postal_code", name: address_component_name },
            ];
            break;
          default:
            break;
        }
      });

      loadEntities();
    } else {
      if (addressKeys.current.length) {
        loadEntities();
      }
    }
  };

  const onSearch = (e) => {
    if (e.key !== "Enter") {
      return;
    }

    history.push({ pathname, search: `?keyword=${entity}` });
  };

  const changeCategory = (newCategory) => {
    const urlParams = { keyword };

    activeFilters.current.forEach(({ name, value }) => {
      urlParams[name] = value;
    });

    setCategory(newCategory);
    history.push(`/search/entity/${newCategory}?${jsonToParams(urlParams)}`);
  };

  useEffect(() => {
    loadEntities(currentPage, keyword, category);
    setEntity(keyword);
    return () => {
      setCategory("user");
      setEntity("");
      activeFilters.current = [];
      addressKeys.current = [];
    };
  }, [keyword, category, currentPage]);

  return (
    <>
      <Container as="main">
        <Input
          icon={SearchIcon}
          onKeyDown={onSearch}
          onChange={(e) => setEntity(e.target.value)}
          value={entity}
        />
        <Row className="mt-3">
          <Col as="aside" md="4">
            <FiltersSidebar>
              <CategoryFilter onChange={changeCategory} />
              <LocationFilter onChange={getAddressHandler} />
            </FiltersSidebar>
          </Col>
          <Col as="section" md="8">
            <div className="posts-section">
              {loading && <Spinner />}
              {entities.length ? (
                entities.map((entity) => (
                  <SearchItem
                    key={entity.id}
                    onChangePage={onChangePageHandler}
                    {...entity}
                  />
                ))
              ) : (
                <EmptySection message="No hay resultados" />
              )}
            </div>
            <PaginationComponent
              pages={pages}
              currentActivePage={currentPage}
              onChangePage={loadEntities}
              isRow
            />
          </Col>
        </Row>
      </Container>
    </>
  );
};

export default SearchPage;