Skip to content

Commit e4dbddc

Browse files
authored
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
1 parent 55d5ed8 commit e4dbddc

File tree

1 file changed

+62
-14
lines changed

1 file changed

+62
-14
lines changed

src/app/(public)/repos/_components/pagination.tsx

Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
'use client';
2+
13
import { Button } from '@/app/(public)/_components/button';
2-
import { ArrowLeft, ArrowRight } from 'lucide-react';
3-
import Link from 'next/link';
4+
import { ArrowLeft, ArrowRight, Loader2 } from 'lucide-react';
5+
import { useRouter } from 'next/navigation';
6+
import { useState } from 'react';
47
import type { SearchParams } from '@/types';
58

69
const MAX_PER_PAGE = 21;
@@ -15,24 +18,69 @@ export function Pagination({
1518
totalCount,
1619
searchParams
1720
}: PaginationProps) {
21+
const [isLoading, setIsLoading] = useState(false);
22+
const router = useRouter();
23+
24+
const handlePrevPage = (e: React.MouseEvent<HTMLButtonElement>) => {
25+
e.preventDefault();
26+
setIsLoading(true);
27+
const newParams = { ...searchParams, p: page - 1 };
28+
const queryString = new URLSearchParams(
29+
Object.entries(newParams).map(([k, v]) => [k, String(v)])
30+
).toString();
31+
router.push(`?${queryString}`);
32+
};
33+
34+
const handleNextPage = (e: React.MouseEvent<HTMLButtonElement>) => {
35+
e.preventDefault();
36+
setIsLoading(true);
37+
const newParams = { ...searchParams, p: page + 1 };
38+
const queryString = new URLSearchParams(
39+
Object.entries(newParams).map(([k, v]) => [k, String(v)])
40+
).toString();
41+
router.push(`?${queryString}`);
42+
};
43+
1844
return (
1945
<div className="flex flex-col items-center gap-4 my-6 justify-evenly sm:gap-0 sm:flex-row">
2046
{page > 1 && (
21-
<Link href={{ query: { ...searchParams, p: page - 1 } }}>
22-
<Button className="btn-wide hover:bg-primary-btn-hover-gradient hover:text-hacktoberfest-dark-green">
23-
<ArrowLeft />
24-
<span className="ml-2">Previous Page</span>
25-
</Button>
26-
</Link>
47+
<Button
48+
onClick={handlePrevPage}
49+
disabled={isLoading}
50+
className="btn-wide hover:bg-primary-btn-hover-gradient hover:text-hacktoberfest-dark-green disabled:opacity-50 disabled:cursor-not-allowed"
51+
>
52+
{isLoading ? (
53+
<>
54+
<Loader2 className="animate-spin" />
55+
<span className="ml-2">Loading...</span>
56+
</>
57+
) : (
58+
<>
59+
<ArrowLeft />
60+
<span className="ml-2">Previous Page</span>
61+
</>
62+
)}
63+
</Button>
2764
)}
2865
{totalCount >= MAX_PER_PAGE &&
2966
page < Math.ceil(totalCount / MAX_PER_PAGE) && (
30-
<Link href={{ query: { ...searchParams, p: page + 1 } }}>
31-
<Button className="btn-wide hover:bg-primary-btn-hover-gradient hover:text-hacktoberfest-dark-green">
32-
<span className="mr-2">Next Page</span>
33-
<ArrowRight />
34-
</Button>
35-
</Link>
67+
<Button
68+
onClick={handleNextPage}
69+
disabled={isLoading}
70+
className="btn-wide hover:bg-primary-btn-hover-gradient hover:text-hacktoberfest-dark-green disabled:opacity-50 disabled:cursor-not-allowed"
71+
>
72+
{isLoading ? (
73+
<>
74+
<span className="mr-2">Loading...</span>
75+
<Loader2 className="animate-spin" />
76+
</>
77+
) : (
78+
<>
79+
<span className="mr-2">Next Page</span>
80+
<ArrowRight />
81+
</>
82+
)}
83+
</Button>
3684
)}
3785
</div>
3886
);

0 commit comments

Comments
 (0)