import { useState, useEffect, useRef, useCallback } from 'react' import { useRouter } from 'next/router' import FunctionCard from '../FunctionCard/FunctionCard' import Loader from '../Loader' import api from '../../utils/api' import useAPI from '../../hooks/useAPI' import './FunctionsList.css' let pageFunctions = 1 const FunctionsList = props => { const { categoryId } = useRouter().query // State de recherche et de catégories const [, categories] = useAPI('/categories') const [inputSearch, setInputSearch] = useState({ search: '', selectedCategory: categoryId || '0' }) // State pour afficher les fonctions const [functionsData, setFunctionsData] = useState({ hasMore: true, rows: [] }) const [isLoadingFunctions, setLoadingFunctions] = useState(true) // Récupère la catégorie avec la query categoryId useEffect(() => { if (categoryId) { handleChange({ target: { name: 'selectedCategory', value: categoryId } }) } }, [categoryId]) // Récupère les fonctions si la catégorie/recherche change useEffect(() => { pageFunctions = 1 getFunctionsData().then(data => setFunctionsData(data)) }, [inputSearch]) // Permet la pagination au scroll const observer = useRef() const lastFunctionCardRef = useCallback( node => { if (isLoadingFunctions) return if (observer.current) observer.current.disconnect() observer.current = new window.IntersectionObserver( entries => { if (entries[0].isIntersecting && functionsData.hasMore) { pageFunctions += 1 getFunctionsData().then(data => { setFunctionsData(oldData => { return { hasMore: data.hasMore, rows: [...oldData.rows, ...data.rows] } }) }) } }, { threshold: 1 } ) if (node) observer.current.observe(node) }, [isLoadingFunctions, functionsData.hasMore] ) const getFunctionsData = async () => { setLoadingFunctions(true) const URL = `${ props.isAdmin ? '/admin/functions' : '/functions' }?page=${pageFunctions}&limit=10&categoryId=${ inputSearch.selectedCategory }&search=${inputSearch.search}` const { data } = await api.get(URL, { headers: { ...(props.isAdmin && props.token != null && { Authorization: props.token }) } }) setLoadingFunctions(false) return data } const handleChange = event => { const inputSearchNew = { ...inputSearch } inputSearchNew[event.target.name] = event.target.value setInputSearch(inputSearchNew) } return (
{props.children}
{functionsData.rows.map((currentFunction, index) => { // Si c'est le dernier élément if (functionsData.rows.length === index + 1) { return ( ) } return ( ) })}
{isLoadingFunctions && }
) } export default FunctionsList