feat(pdf pagination)

This commit is contained in:
2025-09-22 21:50:30 +05:30
parent decdef3522
commit 460b3b53ac

View File

@@ -14,14 +14,24 @@ import { Eye, Trash, Download, FolderOpen } from "lucide-react";
import { DeleteConfirmationDialog } from "@/components/ui/deleteDialog"; import { DeleteConfirmationDialog } from "@/components/ui/deleteDialog";
import { PatientTable } from "@/components/patients/patient-table"; import { PatientTable } from "@/components/patients/patient-table";
import { Patient, PdfFile } from "@repo/db/types"; import { Patient, PdfFile } from "@repo/db/types";
import {
Pagination,
PaginationContent,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from "@/components/ui/pagination";
export default function DocumentsPage() { export default function DocumentsPage() {
const [selectedPatient, setSelectedPatient] = useState<Patient | null>(null); const [selectedPatient, setSelectedPatient] = useState<Patient | null>(null);
const [expandedGroupId, setExpandedGroupId] = useState<number | null>(null); const [expandedGroupId, setExpandedGroupId] = useState<number | null>(null);
// pagination state for the expanded group // pagination state for the expanded group
// pagination state
const [currentPage, setCurrentPage] = useState<number>(1);
const [limit, setLimit] = useState<number>(5); const [limit, setLimit] = useState<number>(5);
const [offset, setOffset] = useState<number>(0); const offset = (currentPage - 1) * limit;
const [totalForExpandedGroup, setTotalForExpandedGroup] = useState< const [totalForExpandedGroup, setTotalForExpandedGroup] = useState<
number | null number | null
>(null); >(null);
@@ -37,7 +47,7 @@ export default function DocumentsPage() {
useEffect(() => { useEffect(() => {
setExpandedGroupId(null); setExpandedGroupId(null);
setLimit(5); setLimit(5);
setOffset(0); setCurrentPage(1);
setTotalForExpandedGroup(null); setTotalForExpandedGroup(null);
setFileBlobUrl(null); setFileBlobUrl(null);
}, [selectedPatient]); }, [selectedPatient]);
@@ -90,7 +100,7 @@ export default function DocumentsPage() {
refetch: refetchGroupPdfs, refetch: refetchGroupPdfs,
isFetching: isFetchingPdfs, isFetching: isFetchingPdfs,
} = useQuery({ } = useQuery({
queryKey: ["groupPdfs", expandedGroupId, limit, offset], queryKey: ["groupPdfs", expandedGroupId, currentPage, limit],
enabled: !!expandedGroupId, enabled: !!expandedGroupId,
queryFn: async () => { queryFn: async () => {
// API should accept ?limit & ?offset and also return total count // API should accept ?limit & ?offset and also return total count
@@ -115,11 +125,9 @@ export default function DocumentsPage() {
onSuccess: () => { onSuccess: () => {
setIsDeletePdfOpen(false); setIsDeletePdfOpen(false);
setCurrentPdf(null); setCurrentPdf(null);
if (expandedGroupId != null) {
queryClient.invalidateQueries({ queryClient.invalidateQueries({
queryKey: ["groupPdfs", expandedGroupId], queryKey: ["groupPdfs", expandedGroupId],
}); });
}
toast({ title: "Success", description: "PDF deleted successfully!" }); toast({ title: "Success", description: "PDF deleted successfully!" });
}, },
onError: (error: any) => { onError: (error: any) => {
@@ -169,20 +177,43 @@ export default function DocumentsPage() {
const toggleExpandGroup = (groupId: number) => { const toggleExpandGroup = (groupId: number) => {
if (expandedGroupId === groupId) { if (expandedGroupId === groupId) {
setExpandedGroupId(null); setExpandedGroupId(null);
setOffset(0); setCurrentPage(1);
setLimit(5); setLimit(5);
setTotalForExpandedGroup(null); setTotalForExpandedGroup(null);
} else { } else {
setExpandedGroupId(groupId); setExpandedGroupId(groupId);
setOffset(0); setCurrentPage(1);
setLimit(5); setLimit(5);
setTotalForExpandedGroup(null); setTotalForExpandedGroup(null);
} }
}; };
const handleLoadMore = () => { // pagintaion helper
setOffset((prev) => prev + limit); const totalPages = totalForExpandedGroup
}; ? Math.ceil(totalForExpandedGroup / limit)
: 1;
const startItem = totalForExpandedGroup ? offset + 1 : 0;
const endItem = totalForExpandedGroup
? Math.min(offset + limit, totalForExpandedGroup)
: 0;
function getPageNumbers(current: number, total: number) {
const delta = 2;
const range: (number | "...")[] = [];
for (
let i = Math.max(2, current - delta);
i <= Math.min(total - 1, current + delta);
i++
) {
range.push(i);
}
if (current - delta > 2) range.unshift("...");
if (current + delta < total - 1) range.push("...");
range.unshift(1);
if (total > 1) range.push(total);
return range;
}
return ( return (
<div> <div>
@@ -309,28 +340,87 @@ export default function DocumentsPage() {
</div> </div>
))} ))}
{/* pagination controls */} {/* Pagination */}
<div className="flex items-center gap-2"> {totalPages > 1 && (
{totalForExpandedGroup !== null && <div className="bg-white px-4 py-3 border-t border-gray-200 rounded">
totalForExpandedGroup > <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between">
offset + limit && ( <div className="text-sm text-muted-foreground mb-2 sm:mb-0 whitespace-nowrap">
<Button Showing {startItem}{endItem} of{" "}
size="sm" {totalForExpandedGroup || 0}{" "}
onClick={handleLoadMore} results
> </div>
Load more <Pagination>
</Button> <PaginationContent>
)} <PaginationItem>
<PaginationPrevious
href="#"
onClick={(e) => {
e.preventDefault();
if (currentPage > 1)
setCurrentPage(
currentPage - 1
);
}}
className={
currentPage === 1
? "pointer-events-none opacity-50"
: ""
}
/>
</PaginationItem>
<div className="ml-auto text-sm text-muted-foreground"> {getPageNumbers(
Showing{" "} currentPage,
{Math.min( totalPages
offset + limit, ).map((page, idx) => (
totalForExpandedGroup ?? 0 <PaginationItem key={idx}>
)}{" "} {page === "..." ? (
of {totalForExpandedGroup ?? "?"} <span className="px-2 text-gray-500">
...
</span>
) : (
<PaginationLink
href="#"
onClick={(e) => {
e.preventDefault();
setCurrentPage(
page as number
);
}}
isActive={
currentPage === page
}
>
{page}
</PaginationLink>
)}
</PaginationItem>
))}
<PaginationItem>
<PaginationNext
href="#"
onClick={(e) => {
e.preventDefault();
if (
currentPage < totalPages
)
setCurrentPage(
currentPage + 1
);
}}
className={
currentPage === totalPages
? "pointer-events-none opacity-50"
: ""
}
/>
</PaginationItem>
</PaginationContent>
</Pagination>
</div> </div>
</div> </div>
)}
</div> </div>
)} )}
</div> </div>