feat(tenders): enhance pagination functionality and styling

- Added absoluteCurrentPage to the useTenderListPresenter for better pagination state management.
- Updated the TendersTable component to utilize absoluteCurrentPage in the pagination key.
- Enhanced the Pagination component to support a new "tenders" variant for improved styling.
- Introduced custom styles for the active page in the tenders pagination, ensuring a distinct visual representation.
- Refactored the useHybridPagination hook to maintain accurate page tracking with cursor navigation.
This commit is contained in:
AmirReza Jamali
2026-05-20 15:48:29 +03:30
parent f080d51e63
commit f6eaac94c6
5 changed files with 144 additions and 33 deletions
+3
View File
@@ -46,6 +46,7 @@ const TendersTable = () => {
getRowNumber,
formatDateTimeCell,
pagination,
absoluteCurrentPage,
} = useTenderListPresenter();
return (
@@ -155,12 +156,14 @@ const TendersTable = () => {
</div>
<IsVisible condition={shouldShowPagination}>
<Pagination
key={`pagination-tenders-${absoluteCurrentPage}`}
currentPage={pagination.currentPage}
totalPages={pagination.totalPages}
onPageChange={handlePaginationChange}
pageRangeDisplayed={3}
marginPagesDisplayed={1}
pageLabelBuilder={buildWindowedPageLabel}
variant="tenders"
/>
</IsVisible>
</ListWrapper>
@@ -539,6 +539,7 @@ const useTenderListPresenter = () => {
getRowNumber,
formatDateTimeCell,
pagination: windowedPagination,
absoluteCurrentPage: pagination.currentPage,
};
};
+22 -4
View File
@@ -1,5 +1,8 @@
import { FC, Fragment } from "react";
import { FC } from "react";
import ReactPaginate, { ReactPaginateProps } from "react-paginate";
type PaginationVariant = "default" | "tenders";
interface IProps {
currentPage: number;
totalPages: number;
@@ -7,8 +10,21 @@ interface IProps {
pageRangeDisplayed?: number;
marginPagesDisplayed?: number;
pageLabelBuilder?: ReactPaginateProps["pageLabelBuilder"];
variant?: PaginationVariant;
}
const activeClassNames: Record<PaginationVariant, string> = {
default:
"flex h-9 min-w-9 items-center justify-center rounded-xl border border-white/35 bg-gradient-to-br from-primary/85 via-primary/75 to-primary/65 px-3 text-sm font-semibold !text-white shadow-theme-xs shadow-primary/20 backdrop-blur-md transition-all duration-300 before:pointer-events-none before:absolute before:inset-x-0 before:top-0 before:h-1/2 before:rounded-t-xl before:bg-gradient-to-b before:from-white/30 before:to-transparent dark:border-white/20 dark:before:from-white/20",
tenders:
"pagination-tenders-active relative flex h-9 min-w-9 items-center justify-center rounded-xl border border-white/35 !bg-gradient-to-br !from-primary/85 !via-primary/75 !to-primary/65 px-3 text-sm font-semibold !text-white shadow-theme-xs shadow-primary/20 backdrop-blur-md transition-all duration-300 before:pointer-events-none before:absolute before:inset-x-0 before:top-0 before:h-1/2 before:rounded-t-xl before:bg-gradient-to-b before:from-white/30 before:to-transparent hover:!border-white/35 hover:!text-white dark:!from-primary/85 dark:!via-primary/75 dark:!to-primary/65 dark:border-white/20 dark:before:from-white/20",
};
const activeLinkClassNames: Record<PaginationVariant, string | undefined> = {
default: undefined,
tenders: "!text-white",
};
/** Full-cell hit target: styles live on <li>, but react-paginate puts clicks on the inner <a>. */
const pageLinkClassName =
"absolute inset-0 z-[1] flex cursor-pointer items-center justify-center select-none";
@@ -20,9 +36,10 @@ const Pagination: FC<IProps> = ({
pageRangeDisplayed = 5,
marginPagesDisplayed = 3,
pageLabelBuilder,
variant = "default",
}) => {
return (
<Fragment>
<nav data-pagination-variant={variant} aria-label="Pagination">
<ReactPaginate
key={currentPage}
pageCount={totalPages}
@@ -32,7 +49,8 @@ const Pagination: FC<IProps> = ({
pageRangeDisplayed={pageRangeDisplayed}
marginPagesDisplayed={marginPagesDisplayed}
pageLabelBuilder={pageLabelBuilder}
activeClassName="flex h-9 min-w-9 items-center justify-center rounded-xl border border-white/35 bg-gradient-to-br from-primary/85 via-primary/75 to-primary/65 px-3 text-sm font-semibold !text-white shadow-theme-xs shadow-primary/20 backdrop-blur-md transition-all duration-300 before:pointer-events-none before:absolute before:inset-x-0 before:top-0 before:h-1/2 before:rounded-t-xl before:bg-gradient-to-b before:from-white/30 before:to-transparent dark:border-white/20 dark:before:from-white/20"
activeClassName={activeClassNames[variant]}
activeLinkClassName={activeLinkClassNames[variant]}
onPageChange={(e) => {
if (!onPageChange) return;
window.scrollTo({ top: 0, behavior: "smooth" });
@@ -46,7 +64,7 @@ const Pagination: FC<IProps> = ({
previousLinkClassName={pageLinkClassName}
nextLinkClassName={pageLinkClassName}
/>
</Fragment>
</nav>
);
};