Proyectos de Subversion LeadersLinked - SPA

Rev

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

Rev Autor Línea Nro. Línea
991 stevensc 1
import React, { useState, useEffect, useRef } from 'react'
979 stevensc 2
import { axios, debounce } from '../../utils'
651 stevensc 3
import { useDispatch, useSelector } from 'react-redux'
2614 stevensc 4
import { useNavigate, useLocation, useParams } from 'react-router-dom'
650 stevensc 5
import { addNotification } from '../../redux/notification/notification.actions'
979 stevensc 6
import { Search } from '@mui/icons-material'
2806 stevensc 7
import { Grid } from '@mui/material'
5 stevensc 8
 
650 stevensc 9
import Spinner from 'components/UI/Spinner'
10
import SearchItem from 'components/search/SearchItem'
11
import EmptySection from 'components/UI/EmptySection'
12
import FiltersSidebar from 'components/search/FiltersSidebar'
13
import CategoryFilter from 'components/search/CategoryFilter'
14
import LocationFilter from 'components/search/LocationFilter'
2864 stevensc 15
import Input from '@components/UI/inputs/Input'
2964 stevensc 16
import Pagination from '@components/common/Pagination'
5 stevensc 17
 
18
const SearchPage = () => {
485 stevensc 19
  const [entities, setEntities] = useState([])
981 stevensc 20
  const [pages, setPages] = useState(1)
485 stevensc 21
  const [loading, setLoading] = useState(true)
970 stevensc 22
  const { search, pathname } = useLocation()
976 stevensc 23
  const { category } = useParams()
991 stevensc 24
  const addressRef = useRef({})
2614 stevensc 25
  const navigate = useNavigate()
979 stevensc 26
  const labels = useSelector(({ intl }) => intl.labels)
651 stevensc 27
  const dispatch = useDispatch()
1193 stevensc 28
  const params = new URLSearchParams(search)
5 stevensc 29
 
975 stevensc 30
  const onChangeKeyword = debounce((value = '') => {
1192 stevensc 31
    const params = new URLSearchParams(search)
970 stevensc 32
    params.set('page', '1')
975 stevensc 33
    params.set('keyword', value)
2614 stevensc 34
    navigate(`${pathname}?${params.toString()}`)
970 stevensc 35
  }, 500)
36
 
37
  const onChangePage = (currentPage = 1) => {
1192 stevensc 38
    const params = new URLSearchParams(search)
970 stevensc 39
    params.set('page', `${currentPage}`)
2614 stevensc 40
    navigate(`${pathname}?${params.toString()}`)
970 stevensc 41
  }
42
 
43
  const onChangeCategory = (newCategory = 'user') => {
1192 stevensc 44
    const params = new URLSearchParams(search)
970 stevensc 45
    params.set('page', '1')
2614 stevensc 46
    navigate(`/search/entity/${newCategory}?${params.toString()}`)
970 stevensc 47
  }
48
 
981 stevensc 49
  const onChangeAddress = (address = {}) => {
1192 stevensc 50
    const params = new URLSearchParams(search)
986 stevensc 51
    params.set('page', '1')
991 stevensc 52
    Object.entries(addressRef.current).forEach(([key]) => {
986 stevensc 53
      if (!['page', 'keyword'].includes(key)) params.delete(key)
991 stevensc 54
    })
982 stevensc 55
 
991 stevensc 56
    addressRef.current = address
983 stevensc 57
 
991 stevensc 58
    Object.entries(address).forEach(
59
      ([key, value]) => value && params.set(key, value)
60
    )
61
 
2614 stevensc 62
    navigate(`${pathname}?${params.toString()}`)
981 stevensc 63
  }
64
 
649 stevensc 65
  useEffect(() => {
1177 stevensc 66
    const searchEntities = async () => {
1188 stevensc 67
      setLoading(true)
1177 stevensc 68
      try {
1193 stevensc 69
        const { data: responseData } = await axios.get(`${pathname}${search}`)
1177 stevensc 70
        const { success, data } = responseData
71
 
72
        if (!success) {
73
          throw new Error(data)
74
        }
75
 
76
        setEntities(data.current.items)
77
        setPages(data.total.pages)
78
      } catch (error) {
79
        dispatch(addNotification({ style: 'danger', msg: error.message }))
1188 stevensc 80
      } finally {
81
        setLoading(false)
1177 stevensc 82
      }
83
    }
84
 
981 stevensc 85
    searchEntities()
1188 stevensc 86
  }, [search, pathname])
5 stevensc 87
 
88
  return (
89
    <>
2806 stevensc 90
      <Input
2864 stevensc 91
        icon={<Search />}
2806 stevensc 92
        onChange={(e) => onChangeKeyword(e.target.value)}
93
        placeholder={labels.search}
94
        defaultValue={params.get('keyword')}
2875 stevensc 95
        variant='search'
2806 stevensc 96
      />
1191 stevensc 97
 
2806 stevensc 98
      <Grid container spacing={2} mt={2}>
99
        <Grid item xs={12} md={4} display='flex' direction='column' gap={2}>
100
          <FiltersSidebar>
101
            <CategoryFilter
102
              currentCategory={category}
103
              onChange={onChangeCategory}
104
            />
1191 stevensc 105
 
2806 stevensc 106
            <LocationFilter onChange={onChangeAddress} />
107
          </FiltersSidebar>
108
        </Grid>
1191 stevensc 109
 
2806 stevensc 110
        <Grid item xs={12} md={8} display='flex' direction='column' gap={2}>
111
          {loading ? (
2864 stevensc 112
            <Spinner />
2806 stevensc 113
          ) : (
114
            <>
115
              <EntitiesList entities={entities} />
2964 stevensc 116
              <Pagination
117
                page={+params.get('page')}
2806 stevensc 118
                pages={pages}
2964 stevensc 119
                onChange={onChangePage}
2806 stevensc 120
              />
121
            </>
122
          )}
1191 stevensc 123
        </Grid>
2806 stevensc 124
      </Grid>
5 stevensc 125
    </>
485 stevensc 126
  )
127
}
5 stevensc 128
 
979 stevensc 129
const EntitiesList = ({ entities = [] }) => {
130
  if (!entities.length) {
131
    return <EmptySection message='No hay resultados' />
132
  }
133
 
134
  return (
135
    <>
136
      {entities.map((entity) => (
137
        <SearchItem key={entity.id} entity={entity} />
138
      ))}
139
    </>
140
  )
141
}
142
 
485 stevensc 143
export default SearchPage