diff --git a/dongle/app/admin/page.tsx b/dongle/app/admin/page.tsx
index 5f6cacc..8f5e151 100644
--- a/dongle/app/admin/page.tsx
+++ b/dongle/app/admin/page.tsx
@@ -17,6 +17,8 @@ import { reviewService } from "@/services/review/review.service";
import { auditLogService } from "@/services/audit/audit-log.service";
import { ReviewReport, ModerationAction, Review } from "@/types/review";
import AuditLogViewer from "@/components/admin/AuditLogViewer";
+import Pagination from "@/components/ui/Pagination";
+import { usePagination } from "@/hooks/usePagination";
interface VerificationRequest {
id: string;
@@ -170,6 +172,12 @@ export default function AdminDashboard() {
const pendingClaimRequests = claimRequests.filter((request) => request.status === "pending");
const resolvedProjectReports = projectReports.filter((report) => report.status !== "pending");
+ // Pagination hooks
+ const verificationPagination = usePagination({ items: requests, itemsPerPage: 10 });
+ const reportsPagination = usePagination({ items: pendingReports, itemsPerPage: 10 });
+ const projectReportsPagination = usePagination({ items: pendingProjectReports, itemsPerPage: 10 });
+ const claimsPagination = usePagination({ items: pendingClaimRequests, itemsPerPage: 10 });
+
if (gate.state !== "ready") {
return (
diff --git a/dongle/components/ui/Pagination.tsx b/dongle/components/ui/Pagination.tsx
new file mode 100644
index 0000000..4161c37
--- /dev/null
+++ b/dongle/components/ui/Pagination.tsx
@@ -0,0 +1,107 @@
+"use client";
+
+import { ChevronLeft, ChevronRight } from "lucide-react";
+
+interface PaginationProps {
+ currentPage: number;
+ totalPages: number;
+ onPageChange: (page: number) => void;
+ itemsPerPage?: number;
+ totalItems?: number;
+ showItemCount?: boolean;
+}
+
+export default function Pagination({
+ currentPage,
+ totalPages,
+ onPageChange,
+ itemsPerPage,
+ totalItems,
+ showItemCount = true,
+}: PaginationProps) {
+ const getPageNumbers = () => {
+ const pages: (number | string)[] = [];
+ const maxVisible = 5;
+
+ if (totalPages <= maxVisible) {
+ for (let i = 1; i <= totalPages; i++) {
+ pages.push(i);
+ }
+ } else {
+ pages.push(1);
+
+ if (currentPage > 3) {
+ pages.push("...");
+ }
+
+ const start = Math.max(2, currentPage - 1);
+ const end = Math.min(totalPages - 1, currentPage + 1);
+
+ for (let i = start; i <= end; i++) {
+ pages.push(i);
+ }
+
+ if (currentPage < totalPages - 2) {
+ pages.push("...");
+ }
+
+ pages.push(totalPages);
+ }
+
+ return pages;
+ };
+
+ const startItem = (currentPage - 1) * (itemsPerPage || 0) + 1;
+ const endItem = Math.min(currentPage * (itemsPerPage || 0), totalItems || 0);
+
+ return (
+
+ {showItemCount && itemsPerPage && totalItems !== undefined && (
+
+ Showing {startItem} to{" "}
+ {endItem} of{" "}
+ {totalItems} items
+
+ )}
+
+
+
+
+
+ {getPageNumbers().map((page, index) => (
+
+ ))}
+
+
+
+
+
+ );
+}
diff --git a/dongle/hooks/usePagination.ts b/dongle/hooks/usePagination.ts
new file mode 100644
index 0000000..b69a889
--- /dev/null
+++ b/dongle/hooks/usePagination.ts
@@ -0,0 +1,64 @@
+import { useState, useMemo } from "react";
+
+interface UsePaginationProps
{
+ items: T[];
+ itemsPerPage?: number;
+}
+
+interface UsePaginationResult {
+ currentPage: number;
+ totalPages: number;
+ paginatedItems: T[];
+ goToPage: (page: number) => void;
+ nextPage: () => void;
+ previousPage: () => void;
+ itemsPerPage: number;
+ totalItems: number;
+ hasNextPage: boolean;
+ hasPreviousPage: boolean;
+}
+
+export function usePagination({
+ items,
+ itemsPerPage = 10,
+}: UsePaginationProps): UsePaginationResult {
+ const [currentPage, setCurrentPage] = useState(1);
+
+ const totalPages = Math.ceil(items.length / itemsPerPage);
+
+ const paginatedItems = useMemo(() => {
+ const startIndex = (currentPage - 1) * itemsPerPage;
+ const endIndex = startIndex + itemsPerPage;
+ return items.slice(startIndex, endIndex);
+ }, [items, currentPage, itemsPerPage]);
+
+ const goToPage = (page: number) => {
+ const validPage = Math.max(1, Math.min(page, totalPages));
+ setCurrentPage(validPage);
+ };
+
+ const nextPage = () => {
+ if (currentPage < totalPages) {
+ setCurrentPage((prev) => prev + 1);
+ }
+ };
+
+ const previousPage = () => {
+ if (currentPage > 1) {
+ setCurrentPage((prev) => prev - 1);
+ }
+ };
+
+ return {
+ currentPage,
+ totalPages,
+ paginatedItems,
+ goToPage,
+ nextPage,
+ previousPage,
+ itemsPerPage,
+ totalItems: items.length,
+ hasNextPage: currentPage < totalPages,
+ hasPreviousPage: currentPage > 1,
+ };
+}