Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 172 | Rev 375 | Ir a la última revisión | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
172 stevensc 1
import React, { useState, useRef, useEffect } from "react";
2
import { axios, jsonToParams } from "../../utils";
3
import { Col, Container, Row } from "react-bootstrap";
4
import { useHistory, useLocation } from "react-router-dom";
208 stevensc 5
import styled from "styled-components";
6
import SearchIcon from "@mui/icons-material/Search";
5 stevensc 7
 
172 stevensc 8
import Spinner from "../../components/UI/Spinner";
9
import SearchItem from "../../components/search/SearchItem";
10
import Input from "../../components/UI/Input";
11
import EmptySection from "../../components/UI/EmptySection";
12
import PaginationComponent from "../../components/UI/PaginationComponent";
13
import FiltersSidebar from "../../components/search/FiltersSidebar";
14
import CategoryFilter from "../../components/search/CategoryFilter";
15
import LocationFilter from "../../components/search/LocationFilter";
5 stevensc 16
 
208 stevensc 17
const StyledSearch = styled(Input)`
18
  background-color: var(--bg-color);
19
`;
20
 
5 stevensc 21
const SearchPage = () => {
172 stevensc 22
  const [entities, setEntities] = useState([]);
23
  const [loading, setLoading] = useState(true);
24
  const [category, setCategory] = useState("user");
25
  const [entity, setEntity] = useState("");
26
  const [currentPage, setCurrentPage] = useState(1);
27
  const [pages, setPages] = useState(1);
28
  const activeFilters = useRef([]);
29
  const addressKeys = useRef([]);
5 stevensc 30
 
172 stevensc 31
  const { search, pathname } = useLocation();
32
  const history = useHistory();
5 stevensc 33
 
172 stevensc 34
  const params = new URLSearchParams(search);
35
  const keyword = params.get("keyword");
5 stevensc 36
 
172 stevensc 37
  const loadEntities = async (page = 1, keyword = "", category = "user") => {
38
    setLoading(true);
39
    setCurrentPage(page);
5 stevensc 40
 
172 stevensc 41
    const urlParams = { page, keyword };
5 stevensc 42
 
43
    addressKeys.current.forEach(({ name, type }) => {
172 stevensc 44
      urlParams[type] = name;
45
    });
5 stevensc 46
 
47
    activeFilters.current.forEach(({ name, value }) => {
172 stevensc 48
      urlParams[name] = value;
49
    });
5 stevensc 50
 
51
    await axios
52
      .get(`/search/entity/${category}?${jsonToParams(urlParams)}`)
53
      .then((response) => {
172 stevensc 54
        const { success, data } = response.data;
5 stevensc 55
 
56
        if (success) {
172 stevensc 57
          setEntities(data.current.items);
58
          setPages(data.total.pages);
5 stevensc 59
        }
172 stevensc 60
      });
61
    setLoading(false);
62
  };
5 stevensc 63
 
64
  const onChangePageHandler = (currentPage) => {
172 stevensc 65
    setCurrentPage(currentPage);
66
  };
5 stevensc 67
 
68
  const getAddressHandler = (addresObject) => {
172 stevensc 69
    const { address_components } = addresObject;
5 stevensc 70
    if (address_components) {
172 stevensc 71
      addressKeys.current = [];
5 stevensc 72
      address_components.map((address_component) => {
172 stevensc 73
        const address_component_name = address_component.long_name;
74
        const address_component_type = address_component.types[0];
5 stevensc 75
        switch (address_component_type) {
172 stevensc 76
          case "route":
5 stevensc 77
            addressKeys.current = [
78
              ...addressKeys.current,
172 stevensc 79
              { type: "route", name: address_component_name },
80
            ];
81
            break;
82
          case "sublocality":
5 stevensc 83
            addressKeys.current = [
84
              ...addressKeys.current,
172 stevensc 85
              { type: "sublocality", name: address_component_name },
86
            ];
87
            break;
88
          case "locality":
5 stevensc 89
            addressKeys.current = [
90
              ...addressKeys.current,
172 stevensc 91
              { type: "locality", name: address_component_name },
92
            ];
93
            break;
94
          case "administrative_area_level_2":
5 stevensc 95
            addressKeys.current = [
96
              ...addressKeys.current,
97
              {
172 stevensc 98
                type: "administrative_area_level_2",
5 stevensc 99
                name: address_component_name,
100
              },
172 stevensc 101
            ];
102
            break;
103
          case "administrative_area_level_1":
5 stevensc 104
            addressKeys.current = [
105
              ...addressKeys.current,
106
              {
172 stevensc 107
                type: "administrative_area_level_1",
5 stevensc 108
                name: address_component_name,
109
              },
172 stevensc 110
            ];
111
            break;
112
          case "country":
5 stevensc 113
            addressKeys.current = [
114
              ...addressKeys.current,
172 stevensc 115
              { type: "country", name: address_component_name },
116
            ];
117
            break;
118
          case "postal_code":
5 stevensc 119
            addressKeys.current = [
120
              ...addressKeys.current,
172 stevensc 121
              { type: "postal_code", name: address_component_name },
122
            ];
123
            break;
5 stevensc 124
          default:
172 stevensc 125
            break;
5 stevensc 126
        }
172 stevensc 127
      });
5 stevensc 128
 
172 stevensc 129
      loadEntities();
5 stevensc 130
    } else {
131
      if (addressKeys.current.length) {
172 stevensc 132
        loadEntities();
5 stevensc 133
      }
134
    }
172 stevensc 135
  };
5 stevensc 136
 
172 stevensc 137
  const onSearch = (e) => {
138
    if (e.key !== "Enter") {
139
      return;
140
    }
5 stevensc 141
 
172 stevensc 142
    history.push({ pathname, search: `?keyword=${entity}` });
143
  };
144
 
5 stevensc 145
  const changeCategory = (newCategory) => {
172 stevensc 146
    const urlParams = { keyword };
5 stevensc 147
 
148
    activeFilters.current.forEach(({ name, value }) => {
172 stevensc 149
      urlParams[name] = value;
150
    });
5 stevensc 151
 
172 stevensc 152
    setCategory(newCategory);
153
    history.push(`/search/entity/${newCategory}?${jsonToParams(urlParams)}`);
154
  };
5 stevensc 155
 
156
  useEffect(() => {
172 stevensc 157
    loadEntities(currentPage, keyword, category);
158
    setEntity(keyword);
5 stevensc 159
    return () => {
172 stevensc 160
      setCategory("user");
161
      setEntity("");
162
      activeFilters.current = [];
163
      addressKeys.current = [];
164
    };
165
  }, [keyword, category, currentPage]);
5 stevensc 166
 
167
  return (
168
    <>
169
      <Container as="main">
208 stevensc 170
        <StyledSearch
171
          icon={SearchIcon}
172 stevensc 172
          onKeyDown={onSearch}
5 stevensc 173
          onChange={(e) => setEntity(e.target.value)}
174
          value={entity}
175
        />
176
        <Row className="mt-3">
177
          <Col as="aside" md="4">
178
            <FiltersSidebar>
179
              <CategoryFilter onChange={changeCategory} />
180
              <LocationFilter onChange={getAddressHandler} />
181
            </FiltersSidebar>
182
          </Col>
183
          <Col as="section" md="8">
184
            <div className="posts-section">
185
              {loading && <Spinner />}
186
              {entities.length ? (
187
                entities.map((entity) => (
188
                  <SearchItem
189
                    key={entity.id}
190
                    onChangePage={onChangePageHandler}
191
                    {...entity}
192
                  />
193
                ))
194
              ) : (
195
                <EmptySection message="No hay resultados" />
196
              )}
197
            </div>
198
            <PaginationComponent
199
              pages={pages}
200
              currentActivePage={currentPage}
201
              onChangePage={loadEntities}
202
              isRow
203
            />
204
          </Col>
205
        </Row>
206
      </Container>
207
    </>
172 stevensc 208
  );
209
};
5 stevensc 210
 
172 stevensc 211
export default SearchPage;