Proyectos de Subversion LeadersLinked - SPA

Rev

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