Proyectos de Subversion LeadersLinked - SPA

Rev

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