frontend: Pagination au scroll
This commit is contained in:
parent
895d0c7f6b
commit
ea13959c91
@ -1,9 +1,9 @@
|
||||
import Link from 'next/link';
|
||||
import { useState, Fragment } from 'react';
|
||||
import { useState, Fragment, forwardRef } from 'react';
|
||||
import Loader from '../Loader/Loader';
|
||||
import './FunctionCard.css';
|
||||
|
||||
const FunctionCard = (props) => {
|
||||
const FunctionCard = forwardRef((props, ref) => {
|
||||
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
@ -14,8 +14,9 @@ const FunctionCard = (props) => {
|
||||
return (
|
||||
<Link href={`/functions/${props.slug}`}>
|
||||
<Fragment>
|
||||
<div className={"FunctionCard col-sm-24 col-md-10 col-xl-7"}>
|
||||
{isLoading && <Loader width="100px" height="100px" />}
|
||||
{/* Elément à une hauteur pendant chargement */}
|
||||
<div ref={ref} style={isLoading ? { height: "200px", justifyContent: "center" } : null} className={"FunctionCard col-sm-24 col-md-10 col-xl-7"}>
|
||||
{isLoading && <Loader width="125px" height="125px" />}
|
||||
<div className={`FunctionCard__container ${isLoading ? "d-none" : ""}`}>
|
||||
<div className="FunctionCard__top">
|
||||
<img onLoad={handleLoad} className="FunctionCard__image" alt={props.title} src={props.image} />
|
||||
@ -31,6 +32,6 @@ const FunctionCard = (props) => {
|
||||
</Fragment>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
})
|
||||
|
||||
export default FunctionCard;
|
@ -1,4 +1,4 @@
|
||||
import { Fragment, useState, useEffect } from 'react';
|
||||
import { Fragment, useState, useEffect, useRef, useCallback } from 'react';
|
||||
import HeadTag from '../components/HeadTag';
|
||||
import FunctionCard from '../components/FunctionCard/FunctionCard';
|
||||
import Loader from '../components/Loader/Loader';
|
||||
@ -18,6 +18,19 @@ const Functions = () => {
|
||||
const [isLoadingFunctions, setLoadingFunctions] = useState(true);
|
||||
const [pageFunctions, setPageFunctions] = useState(1);
|
||||
|
||||
// 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) {
|
||||
setPageFunctions(pageFunctions + 1);
|
||||
}
|
||||
}, { threshold: 1 });
|
||||
if (node) observer.current.observe(node);
|
||||
}, [isLoadingFunctions, functionsData.hasMore]);
|
||||
|
||||
const getFunctionsData = () => {
|
||||
setLoadingFunctions(true);
|
||||
return new Promise(async (next) => {
|
||||
@ -40,10 +53,6 @@ const Functions = () => {
|
||||
getFunctionsData().then((data) => setFunctionsData(data));
|
||||
}, [inputSearch.selectedCategory, inputSearch.search]);
|
||||
|
||||
const loadMore = () => {
|
||||
setPageFunctions(pageFunctions + 1);
|
||||
}
|
||||
|
||||
const handleChange = (event) => {
|
||||
const inputSearchNew = { ...inputSearch };
|
||||
inputSearchNew[event.target.name] = event.target.value;
|
||||
@ -74,20 +83,15 @@ const Functions = () => {
|
||||
</div>
|
||||
|
||||
<div className="row justify-content-center">
|
||||
{functionsData.rows.map((f) => (
|
||||
<FunctionCard key={f.id} slug={f.slug} image={API_URL + f.image} title={f.title} description={f.description} category={f.categorie} publicationDate={new Date(f.createdAt).toLocaleDateString('fr-FR')} />
|
||||
))}
|
||||
{functionsData.rows.map((f, index) => {
|
||||
// Si c'est le dernier élément
|
||||
if (functionsData.rows.length === index + 1) {
|
||||
return <FunctionCard ref={lastFunctionCardRef} key={f.id} slug={f.slug} image={API_URL + f.image} title={f.title} description={f.description} category={f.categorie} publicationDate={new Date(f.createdAt).toLocaleDateString('fr-FR')} />;
|
||||
}
|
||||
return <FunctionCard key={f.id} slug={f.slug} image={API_URL + f.image} title={f.title} description={f.description} category={f.categorie} publicationDate={new Date(f.createdAt).toLocaleDateString('fr-FR')} />;
|
||||
})}
|
||||
</div>
|
||||
{
|
||||
isLoadingFunctions ?
|
||||
<Loader width="100px" height="100px" />
|
||||
: functionsData.hasMore ?
|
||||
<div className="row justify-content-center">
|
||||
<button className="btn btn-dark" style={{marginBottom: "50px"}} onClick={loadMore}>Charger plus de fonctions ?</button>
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
{isLoadingFunctions && <Loader width="100px" height="100px" />}
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
|
Reference in New Issue
Block a user