Proyectos de Subversion LeadersLinked - SPA

Rev

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