Rev 2798 | Rev 2864 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
import React, { useState, useEffect, useRef } from 'react'
import { axios, debounce } from '../../utils'
import { useDispatch, useSelector } from 'react-redux'
import { useNavigate, useLocation, useParams } from 'react-router-dom'
import { addNotification } from '../../redux/notification/notification.actions'
import { Search } from '@mui/icons-material'
import { Grid } from '@mui/material'
import Input from 'components/UI/Input'
import Spinner from 'components/UI/Spinner'
import SearchItem from 'components/search/SearchItem'
import EmptySection from 'components/UI/EmptySection'
import FiltersSidebar from 'components/search/FiltersSidebar'
import CategoryFilter from 'components/search/CategoryFilter'
import LocationFilter from 'components/search/LocationFilter'
import PaginationComponent from 'components/UI/PaginationComponent'
import LoaderContainer from 'components/UI/LoaderContainer'
const SearchPage = () => {
const [entities, setEntities] = useState([])
const [pages, setPages] = useState(1)
const [loading, setLoading] = useState(true)
const { search, pathname } = useLocation()
const { category } = useParams()
const addressRef = useRef({})
const navigate = useNavigate()
const labels = useSelector(({ intl }) => intl.labels)
const dispatch = useDispatch()
const params = new URLSearchParams(search)
const onChangeKeyword = debounce((value = '') => {
const params = new URLSearchParams(search)
params.set('page', '1')
params.set('keyword', value)
navigate(`${pathname}?${params.toString()}`)
}, 500)
const onChangePage = (currentPage = 1) => {
const params = new URLSearchParams(search)
params.set('page', `${currentPage}`)
navigate(`${pathname}?${params.toString()}`)
}
const onChangeCategory = (newCategory = 'user') => {
const params = new URLSearchParams(search)
params.set('page', '1')
navigate(`/search/entity/${newCategory}?${params.toString()}`)
}
const onChangeAddress = (address = {}) => {
const params = new URLSearchParams(search)
params.set('page', '1')
Object.entries(addressRef.current).forEach(([key]) => {
if (!['page', 'keyword'].includes(key)) params.delete(key)
})
addressRef.current = address
Object.entries(address).forEach(
([key, value]) => value && params.set(key, value)
)
navigate(`${pathname}?${params.toString()}`)
}
useEffect(() => {
const searchEntities = async () => {
setLoading(true)
try {
const { data: responseData } = await axios.get(`${pathname}${search}`)
const { success, data } = responseData
if (!success) {
throw new Error(data)
}
setEntities(data.current.items)
setPages(data.total.pages)
} catch (error) {
dispatch(addNotification({ style: 'danger', msg: error.message }))
} finally {
setLoading(false)
}
}
searchEntities()
}, [search, pathname])
return (
<>
<Input
icon={Search}
onChange={(e) => onChangeKeyword(e.target.value)}
placeholder={labels.search}
defaultValue={params.get('keyword')}
/>
<Grid container spacing={2} mt={2}>
<Grid item xs={12} md={4} display='flex' direction='column' gap={2}>
<FiltersSidebar>
<CategoryFilter
currentCategory={category}
onChange={onChangeCategory}
/>
<LocationFilter onChange={onChangeAddress} />
</FiltersSidebar>
</Grid>
<Grid item xs={12} md={8} display='flex' direction='column' gap={2}>
{loading ? (
<LoaderContainer>
<Spinner />
</LoaderContainer>
) : (
<>
<EntitiesList entities={entities} />
<PaginationComponent
pages={pages}
onChangePage={onChangePage}
currentActivePage={+params.get('page')}
isRow
/>
</>
)}
</Grid>
</Grid>
</>
)
}
const EntitiesList = ({ entities = [] }) => {
if (!entities.length) {
return <EmptySection message='No hay resultados' />
}
return (
<>
{entities.map((entity) => (
<SearchItem key={entity.id} entity={entity} />
))}
</>
)
}
export default SearchPage