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 (