Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 486 | Rev 650 | 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, debounce, 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'
import { useDispatch } from 'react-redux'
import { addNotification } from '../../redux/notification/notification.actions'

const SearchPage = () => {
  const [entities, setEntities] = useState([])
  const [loading, setLoading] = useState(true)
  const [category, setCategory] = useState('user')
  const [entity, setEntity] = useState('')
  const [address, setAddress] = useState({})
  const [currentPage, setCurrentPage] = useState(1)
  const [pages, setPages] = useState(1)
  const activeFilters = useRef([])
  const { search } = useLocation()
  const history = useHistory()
  const dispatch = useDispatch()

  const params = new URLSearchParams(search)
  const keyword = params.get('keyword')

  const searchEntities = (
    page = 1,
    keyword = '',
    category = 'user',
    address = {}
  ) => {
    setLoading(true)
    const urlParams = { page, keyword }

    Object.entries(address).forEach(([key, value]) => (urlParams[key] = value))

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

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

        if (!success) {
          throw new Error(data)
        }

        setEntities(data.current.items)
        setPages(data.total.pages)
      })
      .catch((err) => {
        dispatch(addNotification({ style: 'danger', msg: err }))
      })
      .finally(() => setLoading(false))
  }

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

  const addressHandler = (address) => {
    setAddress(address)
  }

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

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

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

  const onSearch = debounce((value) => setEntity(value), 500)

  useEffect(() => {
    searchEntities(currentPage, entity, category, address)
  }, [entity, category, currentPage, address])

  useEffect(() => {
    setEntity(keyword)
  }, [])

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

export default SearchPage