From e4dbddc5de2b0787d42e044b6aade920a50612ad Mon Sep 17 00:00:00 2001 From: Yash Raj Date: Sun, 19 Oct 2025 11:56:28 +0530 Subject: [PATCH 1/2] Replace links with buttons in pagination component Updated pagination component to use buttons for navigation, enhancing user interaction with loading states. - To prevent the loading API spam --- .../(public)/repos/_components/pagination.tsx | 76 +++++++++++++++---- 1 file changed, 62 insertions(+), 14 deletions(-) diff --git a/src/app/(public)/repos/_components/pagination.tsx b/src/app/(public)/repos/_components/pagination.tsx index 1329d7d..b480fbf 100644 --- a/src/app/(public)/repos/_components/pagination.tsx +++ b/src/app/(public)/repos/_components/pagination.tsx @@ -1,6 +1,9 @@ +'use client'; + import { Button } from '@/app/(public)/_components/button'; -import { ArrowLeft, ArrowRight } from 'lucide-react'; -import Link from 'next/link'; +import { ArrowLeft, ArrowRight, Loader2 } from 'lucide-react'; +import { useRouter } from 'next/navigation'; +import { useState } from 'react'; import type { SearchParams } from '@/types'; const MAX_PER_PAGE = 21; @@ -15,24 +18,69 @@ export function Pagination({ totalCount, searchParams }: PaginationProps) { + const [isLoading, setIsLoading] = useState(false); + const router = useRouter(); + + const handlePrevPage = (e: React.MouseEvent) => { + e.preventDefault(); + setIsLoading(true); + const newParams = { ...searchParams, p: page - 1 }; + const queryString = new URLSearchParams( + Object.entries(newParams).map(([k, v]) => [k, String(v)]) + ).toString(); + router.push(`?${queryString}`); + }; + + const handleNextPage = (e: React.MouseEvent) => { + e.preventDefault(); + setIsLoading(true); + const newParams = { ...searchParams, p: page + 1 }; + const queryString = new URLSearchParams( + Object.entries(newParams).map(([k, v]) => [k, String(v)]) + ).toString(); + router.push(`?${queryString}`); + }; + return (
{page > 1 && ( - - - + )} {totalCount >= MAX_PER_PAGE && page < Math.ceil(totalCount / MAX_PER_PAGE) && ( - - - + )}
); From edc8d0937d529ac06b37bdb1fee0f7386eead27d Mon Sep 17 00:00:00 2001 From: Yash Raj Date: Sun, 19 Oct 2025 13:16:38 +0530 Subject: [PATCH 2/2] Refactor pagination component to use useTransition refactor `pagination.tsx` by: - adding a cleaner delta logic suggested by @max-programming - making sure the state resets after page is loaded --- .../(public)/repos/_components/pagination.tsx | 43 ++++++++----------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/src/app/(public)/repos/_components/pagination.tsx b/src/app/(public)/repos/_components/pagination.tsx index b480fbf..5d105a0 100644 --- a/src/app/(public)/repos/_components/pagination.tsx +++ b/src/app/(public)/repos/_components/pagination.tsx @@ -3,7 +3,7 @@ import { Button } from '@/app/(public)/_components/button'; import { ArrowLeft, ArrowRight, Loader2 } from 'lucide-react'; import { useRouter } from 'next/navigation'; -import { useState } from 'react'; +import { useTransition } from 'react'; import type { SearchParams } from '@/types'; const MAX_PER_PAGE = 21; @@ -18,38 +18,29 @@ export function Pagination({ totalCount, searchParams }: PaginationProps) { - const [isLoading, setIsLoading] = useState(false); const router = useRouter(); + const [isPending, startTransition] = useTransition(); - const handlePrevPage = (e: React.MouseEvent) => { - e.preventDefault(); - setIsLoading(true); - const newParams = { ...searchParams, p: page - 1 }; - const queryString = new URLSearchParams( - Object.entries(newParams).map(([k, v]) => [k, String(v)]) - ).toString(); - router.push(`?${queryString}`); - }; + function changePage(delta: number) { + const params = new URLSearchParams( + Object.entries(searchParams).map(([k, v]) => [k, String(v)]) + ); + params.set('p', String(page + delta)); - const handleNextPage = (e: React.MouseEvent) => { - e.preventDefault(); - setIsLoading(true); - const newParams = { ...searchParams, p: page + 1 }; - const queryString = new URLSearchParams( - Object.entries(newParams).map(([k, v]) => [k, String(v)]) - ).toString(); - router.push(`?${queryString}`); - }; + startTransition(() => { + router.push(`?${params.toString()}`); + }); + } return (
{page > 1 && (