From 3a7dba83350fe0f3593b56dedb5aff20a148c4d4 Mon Sep 17 00:00:00 2001 From: Arik Chakma Date: Mon, 11 Mar 2024 20:15:50 +0600 Subject: [PATCH] chore: implement roadmap pagination --- .../ExploreAIRoadmap/ExploreAIRoadmap.tsx | 135 ++++++++++-------- src/lib/number.ts | 7 + 2 files changed, 85 insertions(+), 57 deletions(-) create mode 100644 src/lib/number.ts diff --git a/src/components/ExploreAIRoadmap/ExploreAIRoadmap.tsx b/src/components/ExploreAIRoadmap/ExploreAIRoadmap.tsx index 151e7da72..af03dfd05 100644 --- a/src/components/ExploreAIRoadmap/ExploreAIRoadmap.tsx +++ b/src/components/ExploreAIRoadmap/ExploreAIRoadmap.tsx @@ -1,9 +1,10 @@ -import { useCallback, useEffect, useState } from 'react'; +import { useEffect, useState } from 'react'; import { useToast } from '../../hooks/use-toast'; import { httpGet } from '../../lib/http'; import { getRelativeTimeString } from '../../lib/date'; import { Eye, Loader2, RefreshCcw } from 'lucide-react'; import { AIRoadmapAlert } from '../GenerateRoadmap/AIRoadmapAlert.tsx'; +import { formatCommaNumber } from '../../lib/number.ts'; export interface AIRoadmapDocument { _id?: string; @@ -27,39 +28,33 @@ export function ExploreAIRoadmap() { const toast = useToast(); const [isLoading, setIsLoading] = useState(true); - const [isLoadingMore, setIsLoadingMore] = useState(false); - const [roadmaps, setRoadmaps] = useState([]); - const [currPage, setCurrPage] = useState(1); - const [totalPages, setTotalPages] = useState(1); - - const loadAIRoadmaps = useCallback( - async (currPage: number) => { - const { response, error } = await httpGet( - `${import.meta.env.PUBLIC_API_URL}/v1-list-ai-roadmaps`, - { - currPage, - }, - ); - - if (error || !response) { - toast.error(error?.message || 'Something went wrong'); - return; - } - - const newRoadmaps = [...roadmaps, ...response.data]; - if ( - JSON.stringify(roadmaps) === JSON.stringify(response.data) || - JSON.stringify(roadmaps) === JSON.stringify(newRoadmaps) - ) { - return; - } - - setRoadmaps(newRoadmaps); - setCurrPage(response.currPage); - setTotalPages(response.totalPages); - }, - [currPage, roadmaps], - ); + const [roadmapsResponse, setRoadmapsResponse] = + useState(null); + + const loadAIRoadmaps = async (currPage: number) => { + setIsLoading(true); + const { response, error } = await httpGet( + `${import.meta.env.PUBLIC_API_URL}/v1-list-ai-roadmaps`, + { + currPage, + }, + ); + + if (error || !response) { + toast.error(error?.message || 'Something went wrong'); + return; + } + + setRoadmapsResponse(response); + }; + + const currPage = roadmapsResponse?.currPage || 1; + const totalPages = roadmapsResponse?.totalPages || 1; + const totalCount = roadmapsResponse?.totalCount || 0; + + const perPage = roadmapsResponse?.perPage || 0; + const hasNextPage = currPage < totalPages; + const hasPrevPage = currPage > 1; useEffect(() => { loadAIRoadmaps(currPage).finally(() => { @@ -67,7 +62,51 @@ export function ExploreAIRoadmap() { }); }, []); - const hasMorePages = currPage < totalPages; + const roadmaps = roadmapsResponse?.data || []; + + const paginationBar = ( +
+
+ {hasPrevPage && ( + + )} + {hasNextPage && ( + + )} + +

+ Showing {formatCommaNumber((currPage - 1) * perPage)} to{' '} + {formatCommaNumber((currPage - 1) * perPage + roadmaps.length)} of{' '} + {formatCommaNumber(totalCount)} entries +

+
+
+

+ Page {formatCommaNumber(currPage)} of {formatCommaNumber(totalPages)} +

+
+
+ ); return (
@@ -75,6 +114,8 @@ export function ExploreAIRoadmap() { + {paginationBar} + {isLoading ? (
    {new Array(21).fill(0).map((_, index) => ( @@ -90,7 +131,7 @@ export function ExploreAIRoadmap() {
    No roadmaps found
    ) : ( <> -
      +
        {roadmaps.map((roadmap) => { const roadmapLink = `/ai?id=${roadmap._id}`; return ( @@ -119,27 +160,7 @@ export function ExploreAIRoadmap() { ); })}
      - {hasMorePages && ( -
      - -
      - )} + {paginationBar} )} diff --git a/src/lib/number.ts b/src/lib/number.ts new file mode 100644 index 000000000..6527e13c8 --- /dev/null +++ b/src/lib/number.ts @@ -0,0 +1,7 @@ +export const formatter = Intl.NumberFormat('en-US', { + useGrouping: true, +}); + +export function formatCommaNumber(number: number): string { + return formatter.format(number); +}