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'; const FunctionsList = (props) => { const { categoryId } = useRouter().query; let pageFunctions = 1; // 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 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 result = await api.get(URL, { headers: { ...(props.isAdmin && props.token != undefined) && { 'Authorization': props.token } } }); setLoadingFunctions(false); return result.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;