Reminders pagination

This commit is contained in:
Vins 2024-11-28 11:26:01 +01:00
parent 5f28aa9268
commit 0cb1b1709b
4 changed files with 236 additions and 12 deletions

View File

@ -7,6 +7,12 @@ export interface IGetDocumentRemindersparams {
where?: {}; where?: {};
include?: {}; include?: {};
orderBy?: {}; orderBy?: {};
skip?: number;
take?: number;
}
export interface IGetDocumentRemindersCountresponse {
count: number;
} }
// TODO Type getbyuid query params // TODO Type getbyuid query params
@ -38,4 +44,14 @@ export default class DocumentReminders extends BaseNotary {
return Promise.reject(err); return Promise.reject(err);
} }
} }
public count = async (): Promise<IGetDocumentRemindersCountresponse> => {
const url = new URL(this.baseURl.concat("/count"));
try {
return await this.getRequest<IGetDocumentRemindersCountresponse>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
};
} }

View File

@ -53,7 +53,7 @@ export default function MuiTable(props: IProps) {
<InfiniteScroll orientation="vertical" onNext={props.onNext} offset={0}> <InfiniteScroll orientation="vertical" onNext={props.onNext} offset={0}>
<TableContainer <TableContainer
className={classes["root"]} className={classes["root"]}
sx={{ maxHeight: "80vh", overflowY: "auto", overflowX: "hidden", backgroundColor: "var(--table-background-default)" }}> sx={{ height: "45vh", overflowY: "auto", overflowX: "hidden", backgroundColor: "var(--table-background-default)" }}>
<Table aria-label="simple table" sx={{ border: "0" }}> <Table aria-label="simple table" sx={{ border: "0" }}>
<TableHead <TableHead
sx={{ sx={{
@ -93,8 +93,7 @@ export default function MuiTable(props: IProps) {
<Typography <Typography
className={classes["content"]} className={classes["content"]}
typo={ETypo.TEXT_MD_REGULAR} typo={ETypo.TEXT_MD_REGULAR}
color={ETypoColor.COLOR_NEUTRAL_900} color={ETypoColor.COLOR_NEUTRAL_900}>
>
{cell.value && typeof cell.value === "object" && "content" in cell.value {cell.value && typeof cell.value === "object" && "content" in cell.value
? cell.value.content ? cell.value.content
: cell.value} : cell.value}

View File

@ -23,4 +23,74 @@
@media screen and (max-width: $screen-s) { @media screen and (max-width: $screen-s) {
padding: var(--spacing-2); padding: var(--spacing-2);
} }
.pagination {
display: flex;
align-items: center;
gap: 6px; /* Adds gap between each button */
.active {
background-color: var(--color-primary-800); /* Dark blue for active button */
border-color: var(--color-primary-800); /* Dark blue border for active button */
color: white; /* White text for active button */
}
button {
width: 50px; /* Fixed width */
height: 50px; /* Fixed height */
font-size: 14px;
text-align: center;
cursor: pointer;
transition: background-color 0.3s;
}
}
// .pagination button {
// width: 40px;
// height: 40px;
// background-color: var(--color-primary-500); /* Light blue background for inactive buttons */
// border: 1px solid var(--color-primary-500); /* Light blue border */
// color: #ffffff; /* Text color for inactive buttons */
// padding: 8px 16px;
// font-size: 14px;
// cursor: pointer;
// transition: background-color 0.3s;
// &:hover {
// background-color: #b2ebf2; /* Lighter blue on hover */
// }
// &.active {
// background-color: var(--color-primary-800); /* Dark blue for active button */
// border-color: var(--color-primary-800); /* Dark blue border for active button */
// color: white; /* White text for active button */
// }
// &.disabled {
// background-color: #f1f1f1; /* Light gray background for disabled buttons */
// color: #9e9e9e; /* Gray text for disabled buttons */
// cursor: not-allowed;
// }
// }
// .pagination button.prev,
// .pagination button.next {
// background-color: var(--color-primary-50); /* Dark teal background for Prev/Next buttons */
// color: var(--color-primary-500); /* White text for Prev/Next buttons */
// padding: 5px 10px;
// border-radius: 8px; /* Make the Prev/Next buttons circular */
// font-size: 14px;
// border: none; /* Remove the border for a cleaner look */
// }
// .pagination button.prev:hover,
// .pagination button.next:hover {
// border-color: var(--button-contained-neutral-hovered-border);
// background: var(--button-contained-neutral-hovered-background);
// }
// .pagination span {
// color: #00796b; /* Color for ellipsis */
// font-size: 14px;
// }
} }

View File

@ -16,6 +16,7 @@ import { useRouter } from "next/router";
import React, { useCallback, useEffect, useMemo, useState } from "react"; import React, { useCallback, useEffect, useMemo, useState } from "react";
import classes from "./classes.module.scss"; import classes from "./classes.module.scss";
import Button, { EButtonstyletype, EButtonVariant } from "@Front/Components/DesignSystem/Button";
type IProps = {}; type IProps = {};
@ -50,8 +51,21 @@ export default function DocumentsReminderHistory(props: IProps) {
const [customers, setCustomers] = useState<Customer[] | null>(null); const [customers, setCustomers] = useState<Customer[] | null>(null);
const [customerOption, setCustomerOption] = useState<IOption | null>(null); const [customerOption, setCustomerOption] = useState<IOption | null>(null);
const router = useRouter(); const router = useRouter();
const [page, setPage] = useState(1); // Current page number
const [pageSize, setPageSize] = useState(10); // Number of items per page
const [totalPages, setTotalPages] = useState(1); // Total number of pages
let { folderUid } = router.query; let { folderUid } = router.query;
const fetchTotalPages = useCallback(() => {
DocumentReminders.getInstance()
.count()
.then((response) => {
const totalPages = Math.ceil(response.count / pageSize);
setTotalPages(totalPages);
})
.catch((e) => console.warn(e));
}, [pageSize]);
const fetchReminders = useCallback(() => { const fetchReminders = useCallback(() => {
DocumentReminders.getInstance() DocumentReminders.getInstance()
.get({ .get({
@ -69,10 +83,14 @@ export default function DocumentsReminderHistory(props: IProps) {
}, },
}, },
orderBy: { reminder_date: "desc" }, orderBy: { reminder_date: "desc" },
skip: (page - 1) * pageSize, // Skip based on the page number
take: pageSize, // Take the number of items for the page
})
.then((response) => {
setReminders(response); // Set the reminders
}) })
.then((reminders) => setReminders(reminders))
.catch((e) => console.warn(e)); .catch((e) => console.warn(e));
}, [customerOption]); }, [customerOption, page, pageSize]); // Update on page change
const fetchCustomers = useCallback(async () => { const fetchCustomers = useCallback(async () => {
if (!folderUid) return; if (!folderUid) return;
@ -108,13 +126,64 @@ export default function DocumentsReminderHistory(props: IProps) {
}, [customers]); }, [customers]);
useEffect(() => { useEffect(() => {
fetchTotalPages();
fetchReminders(); fetchReminders();
fetchCustomers(); fetchCustomers();
}, [fetchCustomers, fetchReminders]); }, [fetchTotalPages, fetchCustomers, fetchReminders]);
const onSelectionChange = useCallback((option: IOption | null) => { const generatePageNumbers = (currentPage: number, totalPages: number) => {
setCustomerOption(option ?? null); const pageNumbers = [];
}, []); const maxPagesToShow = 7; // Maximum number of page buttons, including ellipsis
// Case 1: If total pages are <= 5, show all pages
if (totalPages <= 5) {
for (let i = 1; i <= totalPages; i++) {
pageNumbers.push(i);
}
}
// Case 2: If current page is <= 3, and totalPages > 5, show the first 4 pages + ellipsis
else if (currentPage <= 3) {
for (let i = 1; i <= 4; i++) {
pageNumbers.push(i);
}
pageNumbers.push("...");
}
// Case 3: If current page is in the middle, show ellipses and surrounding pages
else if (currentPage > 3 && currentPage < totalPages - 2) {
pageNumbers.push("...");
pageNumbers.push(currentPage - 1);
pageNumbers.push(currentPage);
pageNumbers.push(currentPage + 1);
pageNumbers.push("...");
}
// Case 4: If current page is near the end, show ellipsis and last 4 pages
else if (currentPage >= totalPages - 2) {
pageNumbers.push("...");
for (let i = totalPages - 3; i <= totalPages; i++) {
pageNumbers.push(i);
}
}
// Ensure the pagination length is exactly maxPagesToShow (counting ellipses as one)
if (pageNumbers.length > maxPagesToShow) {
// Remove ellipsis at the start or end if pagination exceeds max length
if (pageNumbers[0] === "...") {
pageNumbers.shift(); // Remove first ellipsis if it's the first item
}
if (pageNumbers.length > maxPagesToShow && pageNumbers[pageNumbers.length - 1] === "...") {
pageNumbers.pop(); // Remove last ellipsis if it's the last item
}
}
return pageNumbers;
};
// Handle page change
const handlePageChange = (newPage: number) => {
if (newPage >= 1 && newPage <= totalPages) {
setPage(newPage);
}
};
return ( return (
<DefaultTemplate title={"Historique des relances de documents"} isPadding={false}> <DefaultTemplate title={"Historique des relances de documents"} isPadding={false}>
@ -131,11 +200,81 @@ export default function DocumentsReminderHistory(props: IProps) {
<Dropdown <Dropdown
className={classes["customer-filter"]} className={classes["customer-filter"]}
options={customersOptions} options={customersOptions}
onSelectionChange={onSelectionChange} onSelectionChange={(option) => setCustomerOption(option ?? null)}
selectedOption={customerOption ?? customersOptions?.[0]} selectedOption={customerOption ?? customersOptions?.[0]}
label="Client" label="Client"
/> />
{/* Page Size Selector */}
<Dropdown
className={classes["page-size-selector"]}
options={[
{ id: "10", label: "10 par page" },
{ id: "20", label: "20 par page" },
{ id: "50", label: "50 par page" },
]}
selectedOption={{ id: `${pageSize}`, label: `${pageSize} par page` }}
onSelectionChange={(option) => {
setPageSize(parseInt(option.id, 10)); // Update the page size
setPage(1); // Reset the page to 1
}}
label="Items par page"
/>
<Table className={classes["table"]} header={header} rows={buildRows(reminders)} /> <Table className={classes["table"]} header={header} rows={buildRows(reminders)} />
<div className={classes["pagination"]}>
{/* Left Arrow (Prev) */}
<Button
variant={EButtonVariant.PRIMARY}
styletype={EButtonstyletype.OUTLINED}
className={`${page === 1 ? classes["disabled"] : ""} ${classes["prev"]}`}
onClick={() => handlePageChange(page - 1)}>
&lt;
</Button>
{/* <button
className={`${page === 1 ? classes["disabled"] : ""} ${classes["prev"]}`}
onClick={() => handlePageChange(page - 1)}
aria-label="Previous Page">
&lt;
</button> */}
{/* Page numbers */}
{generatePageNumbers(page, totalPages).map((pageNum, index) => (
<React.Fragment key={index}>
{pageNum === "..." ? (
<Button variant={EButtonVariant.PRIMARY}>...</Button>
) : (
<Button
variant={EButtonVariant.PRIMARY}
className={page === pageNum ? classes["active"] : ""}
onClick={() => handlePageChange(pageNum as number)}>
{pageNum}
</Button>
// <button
// className={page === pageNum ? classes["active"] : ""}
// onClick={() => handlePageChange(pageNum as number)}
// aria-label={`Go to page ${pageNum}`}>
// {pageNum}
// </button>
)}
</React.Fragment>
))}
{/* Right Arrow (Next) */}
<Button
variant={EButtonVariant.PRIMARY}
styletype={EButtonstyletype.OUTLINED}
className={`${page === totalPages ? classes["disabled"] : ""} ${classes["next"]}`}
onClick={() => handlePageChange(page + 1)}>
&gt;
</Button>
{/* <button
className={`${page === totalPages ? classes["disabled"] : ""} ${classes["next"]}`}
onClick={() => handlePageChange(page + 1)}
aria-label="Next Page">
&gt;
</button> */}
</div>
</div> </div>
</DefaultTemplate> </DefaultTemplate>
); );