added cursor based pagination for links

This commit is contained in:
Daniel
2023-06-15 02:04:54 +03:30
parent 6323badbaf
commit 1b6d902c75
29 changed files with 507 additions and 182 deletions
+25
View File
@@ -0,0 +1,25 @@
import { useState, useEffect } from "react";
const useDetectPageBottom = () => {
const [reachedBottom, setReachedBottom] = useState<boolean>(false);
useEffect(() => {
const handleScroll = () => {
const offsetHeight = document.documentElement.offsetHeight;
const innerHeight = window.innerHeight;
const scrollTop = document.documentElement.scrollTop;
const hasReachedBottom = offsetHeight - (innerHeight + scrollTop) <= 100;
setReachedBottom(hasReachedBottom);
};
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
return reachedBottom;
};
export default useDetectPageBottom;
+2 -2
View File
@@ -9,14 +9,14 @@ export default function useInitialData() {
const { status, data } = useSession();
const { setCollections } = useCollectionStore();
const { setTags } = useTagStore();
const { setLinks } = useLinkStore();
// const { setLinks } = useLinkStore();
const { setAccount } = useAccountStore();
useEffect(() => {
if (status === "authenticated") {
setCollections();
setTags();
setLinks();
// setLinks();
setAccount(data.user.email as string);
}
}, [status]);
+58
View File
@@ -0,0 +1,58 @@
import { LinkRequestQuery } from "@/types/global";
import { useEffect } from "react";
import useDetectPageBottom from "./useDetectPageBottom";
import { useRouter } from "next/router";
import useLinkStore from "@/store/links";
export default function useLinks({
sort,
searchFilter,
searchQuery,
pinnedOnly,
collectionId,
tagId,
}: Omit<LinkRequestQuery, "cursor"> = {}) {
const { links, setLinks, resetLinks } = useLinkStore();
const router = useRouter();
const hasReachedBottom = useDetectPageBottom();
const getLinks = async (isInitialCall: boolean, cursor?: number) => {
const response = await fetch(
`/api/routes/links?cursor=${cursor}${
(sort ? "&sort=" + sort : "") +
(searchQuery && searchFilter
? "&searchQuery=" +
searchQuery +
"&searchFilter=" +
searchFilter.name +
"-" +
searchFilter.url +
"-" +
searchFilter.description +
"-" +
searchFilter.collection +
"-" +
searchFilter.tags
: "") +
(collectionId ? "&collectionId=" + collectionId : "") +
(tagId ? "&tagId=" + tagId : "") +
(pinnedOnly ? "&pinnedOnly=" + pinnedOnly : "")
}`
);
const data = await response.json();
if (response.ok) setLinks(data.response, isInitialCall);
};
useEffect(() => {
resetLinks();
getLinks(true);
}, [router, sort, searchFilter]);
useEffect(() => {
if (hasReachedBottom) getLinks(false, links?.at(-1)?.id);
}, [hasReachedBottom]);
}
+3 -3
View File
@@ -1,12 +1,12 @@
import {
CollectionIncludingMembers,
LinkIncludingCollectionAndTags,
LinkIncludingShortenedCollectionAndTags,
Sort,
} from "@/types/global";
import { SetStateAction, useEffect } from "react";
type Props<
T extends CollectionIncludingMembers | LinkIncludingCollectionAndTags
T extends CollectionIncludingMembers | LinkIncludingShortenedCollectionAndTags
> = {
sortBy: Sort;
@@ -15,7 +15,7 @@ type Props<
};
export default function useSort<
T extends CollectionIncludingMembers | LinkIncludingCollectionAndTags
T extends CollectionIncludingMembers | LinkIncludingShortenedCollectionAndTags
>({ sortBy, data, setData }: Props<T>) {
useEffect(() => {
const dataArray = [...data];