feat(Tables): implement pagination and loading state handling across multiple tables
- Added `getPaginatedRowNumber` utility function to calculate the correct row number based on pagination. - Integrated `isLoading` prop in `EmptyListWrapper` to conditionally render loading state. - Updated various table components (Admins, CMS, Companies, Inquiries, etc.) to utilize the new pagination logic and loading state handling. - Wrapped pagination components in `IsVisible` to conditionally display based on data availability.
This commit is contained in:
@@ -6,6 +6,7 @@ interface EmptyListWrapperProps<T> {
|
|||||||
emptyMessage: string;
|
emptyMessage: string;
|
||||||
columns: string[];
|
columns: string[];
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
|
isLoading?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function EmptyListWrapper<T>({
|
function EmptyListWrapper<T>({
|
||||||
@@ -13,7 +14,12 @@ function EmptyListWrapper<T>({
|
|||||||
emptyMessage,
|
emptyMessage,
|
||||||
columns,
|
columns,
|
||||||
children,
|
children,
|
||||||
|
isLoading = false,
|
||||||
}: EmptyListWrapperProps<T>) {
|
}: EmptyListWrapperProps<T>) {
|
||||||
|
if (isLoading) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (!list.length) {
|
if (!list.length) {
|
||||||
return (
|
return (
|
||||||
<TableRow>
|
<TableRow>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
import TableSkeleton from "@/components/ui/TableSkeleton";
|
import TableSkeleton from "@/components/ui/TableSkeleton";
|
||||||
import { AdminStatus } from "@/constants/enums";
|
import { AdminStatus } from "@/constants/enums";
|
||||||
import { _TooltipDefaultParams } from "@/constants/tooltip";
|
import { _TooltipDefaultParams } from "@/constants/tooltip";
|
||||||
|
import { getPaginatedRowNumber } from "@/utils/shared";
|
||||||
import { Tooltip } from "react-tooltip";
|
import { Tooltip } from "react-tooltip";
|
||||||
import AdminListFilters from "./AdminListFilters";
|
import AdminListFilters from "./AdminListFilters";
|
||||||
import ChangeStatusModalContent from "./ChangeStatusModalContent";
|
import ChangeStatusModalContent from "./ChangeStatusModalContent";
|
||||||
@@ -77,7 +78,7 @@ const AdminsTable = () => {
|
|||||||
className="odd:bg-gray-2 dark:odd:bg-gray-7"
|
className="odd:bg-gray-2 dark:odd:bg-gray-7"
|
||||||
>
|
>
|
||||||
<TableCell className="text-start" colSpan={100}>
|
<TableCell className="text-start" colSpan={100}>
|
||||||
{index + 1}
|
{getPaginatedRowNumber({ index })}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className="text-start" colSpan={100}>
|
<TableCell className="text-start" colSpan={100}>
|
||||||
{item?.full_name}
|
{item?.full_name}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import Modal from "@/components/ui/modal";
|
|||||||
import { Table, TableBody, TableCell, TableHead } from "@/components/ui/table";
|
import { Table, TableBody, TableCell, TableHead } from "@/components/ui/table";
|
||||||
import TableSkeleton from "@/components/ui/TableSkeleton";
|
import TableSkeleton from "@/components/ui/TableSkeleton";
|
||||||
import { _TooltipDefaultParams } from "@/constants/tooltip";
|
import { _TooltipDefaultParams } from "@/constants/tooltip";
|
||||||
import { unixToDate } from "@/utils/shared";
|
import { getPaginatedRowNumber, unixToDate } from "@/utils/shared";
|
||||||
import { Tooltip } from "react-tooltip";
|
import { Tooltip } from "react-tooltip";
|
||||||
import { TableHeader, TableRow } from "../../ui/table";
|
import { TableHeader, TableRow } from "../../ui/table";
|
||||||
import CmsListFilters from "./CmsListFilters";
|
import CmsListFilters from "./CmsListFilters";
|
||||||
@@ -60,7 +60,11 @@ const CmsTable = () => {
|
|||||||
className="odd:bg-gray-2 dark:odd:bg-gray-7"
|
className="odd:bg-gray-2 dark:odd:bg-gray-7"
|
||||||
>
|
>
|
||||||
<TableCell className="text-start" colSpan={100}>
|
<TableCell className="text-start" colSpan={100}>
|
||||||
{index + 1}
|
{getPaginatedRowNumber({
|
||||||
|
index,
|
||||||
|
page: data?.meta?.page,
|
||||||
|
limit: data?.meta?.limit,
|
||||||
|
})}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className="text-start" colSpan={100}>
|
<TableCell className="text-start" colSpan={100}>
|
||||||
{item.key}
|
{item.key}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import {
|
|||||||
} from "@/components/ui/table";
|
} from "@/components/ui/table";
|
||||||
import TableSkeleton from "@/components/ui/TableSkeleton";
|
import TableSkeleton from "@/components/ui/TableSkeleton";
|
||||||
import { _TooltipDefaultParams } from "@/constants/tooltip";
|
import { _TooltipDefaultParams } from "@/constants/tooltip";
|
||||||
import { unixToDate } from "@/utils/shared";
|
import { getPaginatedRowNumber, unixToDate } from "@/utils/shared";
|
||||||
import { Tooltip } from "react-tooltip";
|
import { Tooltip } from "react-tooltip";
|
||||||
import { Skeleton } from "../../../ui/skeleton";
|
import { Skeleton } from "../../../ui/skeleton";
|
||||||
import useCompanyCategoriesPresenter from "./useCompanyCategoriesPresenter";
|
import useCompanyCategoriesPresenter from "./useCompanyCategoriesPresenter";
|
||||||
@@ -83,7 +83,9 @@ const CompanyCategoriesTable = () => {
|
|||||||
key={category.id}
|
key={category.id}
|
||||||
className="odd:bg-gray-2 dark:odd:bg-gray-7"
|
className="odd:bg-gray-2 dark:odd:bg-gray-7"
|
||||||
>
|
>
|
||||||
<TableCell colSpan={100}>{index + 1}</TableCell>
|
<TableCell colSpan={100}>
|
||||||
|
{getPaginatedRowNumber({ index })}
|
||||||
|
</TableCell>
|
||||||
<TableCell colSpan={100}>{category.name}</TableCell>
|
<TableCell colSpan={100}>{category.name}</TableCell>
|
||||||
<TableCell colSpan={100}>{category.description}</TableCell>
|
<TableCell colSpan={100}>{category.description}</TableCell>
|
||||||
<TableCell colSpan={100}>
|
<TableCell colSpan={100}>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import {
|
|||||||
} from "@/components/ui/table";
|
} from "@/components/ui/table";
|
||||||
import TableSkeleton from "@/components/ui/TableSkeleton";
|
import TableSkeleton from "@/components/ui/TableSkeleton";
|
||||||
import { _TooltipDefaultParams } from "@/constants/tooltip";
|
import { _TooltipDefaultParams } from "@/constants/tooltip";
|
||||||
import { formatPhoneNumber } from "@/utils/shared";
|
import { formatPhoneNumber, getPaginatedRowNumber } from "@/utils/shared";
|
||||||
import { Tooltip } from "react-tooltip";
|
import { Tooltip } from "react-tooltip";
|
||||||
import { useCompanyListPresenter } from "./useCompanyListPresenter";
|
import { useCompanyListPresenter } from "./useCompanyListPresenter";
|
||||||
import ListHeader from "@/components/ui/ListHeader";
|
import ListHeader from "@/components/ui/ListHeader";
|
||||||
@@ -81,7 +81,7 @@ const CompaniesTable = () => {
|
|||||||
className="odd:bg-gray-2 dark:odd:bg-gray-7"
|
className="odd:bg-gray-2 dark:odd:bg-gray-7"
|
||||||
>
|
>
|
||||||
<TableCell className="text-start" colSpan={100}>
|
<TableCell className="text-start" colSpan={100}>
|
||||||
{index + 1}
|
{getPaginatedRowNumber({ index })}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className="text-start" colSpan={100}>
|
<TableCell className="text-start" colSpan={100}>
|
||||||
{company.name}
|
{company.name}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
} from "@/components/ui/table";
|
} from "@/components/ui/table";
|
||||||
import TableSkeleton from "@/components/ui/TableSkeleton";
|
import TableSkeleton from "@/components/ui/TableSkeleton";
|
||||||
import { _TooltipDefaultParams } from "@/constants/tooltip";
|
import { _TooltipDefaultParams } from "@/constants/tooltip";
|
||||||
import { unixToDate } from "@/utils/shared";
|
import { getPaginatedRowNumber, unixToDate } from "@/utils/shared";
|
||||||
import { Tooltip } from "react-tooltip";
|
import { Tooltip } from "react-tooltip";
|
||||||
import { useContactUsListPresenter } from "./useContactUsListPresenter";
|
import { useContactUsListPresenter } from "./useContactUsListPresenter";
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ const ContactUsTable = () => {
|
|||||||
className="odd:bg-gray-2 dark:odd:bg-gray-7"
|
className="odd:bg-gray-2 dark:odd:bg-gray-7"
|
||||||
>
|
>
|
||||||
<TableCell className="text-start" colSpan={100}>
|
<TableCell className="text-start" colSpan={100}>
|
||||||
{index + 1}
|
{getPaginatedRowNumber({ index })}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className="text-start" colSpan={100}>
|
<TableCell className="text-start" colSpan={100}>
|
||||||
{item?.full_name}
|
{item?.full_name}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { ExclamationIcon, PencilSquareIcon, TrashIcon } from "@/assets/icons";
|
|||||||
import EmptyListWrapper from "@/components/HOC/EmptyListWrapper";
|
import EmptyListWrapper from "@/components/HOC/EmptyListWrapper";
|
||||||
import { Building } from "@/components/Layouts/sidebar/icons";
|
import { Building } from "@/components/Layouts/sidebar/icons";
|
||||||
import ConfirmationModal from "@/components/ui/ConfirmationModal";
|
import ConfirmationModal from "@/components/ui/ConfirmationModal";
|
||||||
|
import IsVisible from "@/components/ui/IsVisible";
|
||||||
import ListHeader from "@/components/ui/ListHeader";
|
import ListHeader from "@/components/ui/ListHeader";
|
||||||
import Modal from "@/components/ui/modal";
|
import Modal from "@/components/ui/modal";
|
||||||
import Pagination from "@/components/ui/pagination";
|
import Pagination from "@/components/ui/pagination";
|
||||||
@@ -17,7 +18,7 @@ import {
|
|||||||
} from "@/components/ui/table";
|
} from "@/components/ui/table";
|
||||||
import TableSkeleton from "@/components/ui/TableSkeleton";
|
import TableSkeleton from "@/components/ui/TableSkeleton";
|
||||||
import { _TooltipDefaultParams } from "@/constants/tooltip";
|
import { _TooltipDefaultParams } from "@/constants/tooltip";
|
||||||
import { unixToDate } from "@/utils/shared";
|
import { getPaginatedRowNumber, unixToDate } from "@/utils/shared";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
import { Tooltip } from "react-tooltip";
|
import { Tooltip } from "react-tooltip";
|
||||||
import AssignToCompanyModalContent from "./AssignToCompanyModalContent";
|
import AssignToCompanyModalContent from "./AssignToCompanyModalContent";
|
||||||
@@ -52,7 +53,9 @@ const CustomersTable = () => {
|
|||||||
isMutating,
|
isMutating,
|
||||||
setParams,
|
setParams,
|
||||||
assignCompanyCompaniesQuery,
|
assignCompanyCompaniesQuery,
|
||||||
|
shouldShowPagination,
|
||||||
} = useCustomerListPresenter();
|
} = useCustomerListPresenter();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col rounded-[10px] bg-white px-7.5 pb-4 pt-7.5 shadow-1 dark:bg-gray-dark dark:shadow-card">
|
<div className="flex flex-col rounded-[10px] bg-white px-7.5 pb-4 pt-7.5 shadow-1 dark:bg-gray-dark dark:shadow-card">
|
||||||
<ListHeader
|
<ListHeader
|
||||||
@@ -79,10 +82,17 @@ const CustomersTable = () => {
|
|||||||
list={allCustomers ?? []}
|
list={allCustomers ?? []}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
emptyMessage="No Customers were found"
|
emptyMessage="No Customers were found"
|
||||||
|
isLoading={isPending}
|
||||||
>
|
>
|
||||||
{allCustomers?.map((customer, index) => (
|
{allCustomers?.map((customer, index) => (
|
||||||
<TableRow key={customer?.id ?? index}>
|
<TableRow key={customer?.id ?? index}>
|
||||||
<TableCell colSpan={100}>{index + 1}</TableCell>
|
<TableCell colSpan={100}>
|
||||||
|
{getPaginatedRowNumber({
|
||||||
|
index,
|
||||||
|
page: metadata?.page,
|
||||||
|
limit: metadata?.limit,
|
||||||
|
})}
|
||||||
|
</TableCell>
|
||||||
<TableCell colSpan={100}>{customer?.full_name}</TableCell>
|
<TableCell colSpan={100}>{customer?.full_name}</TableCell>
|
||||||
<TableCell colSpan={100}>{customer?.email}</TableCell>
|
<TableCell colSpan={100}>{customer?.email}</TableCell>
|
||||||
<TableCell colSpan={100}>
|
<TableCell colSpan={100}>
|
||||||
@@ -174,17 +184,19 @@ const CustomersTable = () => {
|
|||||||
</EmptyListWrapper>
|
</EmptyListWrapper>
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
<Pagination
|
<IsVisible condition={shouldShowPagination}>
|
||||||
currentPage={metadata?.page ? metadata?.page - 1 : 0}
|
<Pagination
|
||||||
totalPages={metadata?.pages ?? 1}
|
currentPage={metadata?.page ? metadata?.page - 1 : 0}
|
||||||
onPageChange={(e) => {
|
totalPages={metadata?.pages ?? 1}
|
||||||
setParams((currentParams) => ({
|
onPageChange={(e) => {
|
||||||
...currentParams,
|
setParams((currentParams) => ({
|
||||||
offset: e.selected * (metadata?.limit ?? 10),
|
...currentParams,
|
||||||
limit: metadata?.limit ?? 10,
|
offset: e.selected * (metadata?.limit ?? 10),
|
||||||
}));
|
limit: metadata?.limit ?? 10,
|
||||||
}}
|
}));
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
|
</IsVisible>
|
||||||
<Modal
|
<Modal
|
||||||
isOpen={isFilterModalOpen}
|
isOpen={isFilterModalOpen}
|
||||||
onClose={() => setIsFilterModalOpen(false)}
|
onClose={() => setIsFilterModalOpen(false)}
|
||||||
|
|||||||
@@ -82,6 +82,9 @@ const useCustomerListPresenter = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const customers = data?.data?.customers ?? [];
|
const customers = data?.data?.customers ?? [];
|
||||||
|
const shouldShowPagination =
|
||||||
|
!isPending && (data?.meta?.pages ?? 1) * (data?.meta?.limit ?? 10) > 10;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
allCustomers: customers,
|
allCustomers: customers,
|
||||||
metadata: data?.meta,
|
metadata: data?.meta,
|
||||||
@@ -109,6 +112,7 @@ const useCustomerListPresenter = () => {
|
|||||||
isMutating,
|
isMutating,
|
||||||
setParams,
|
setParams,
|
||||||
assignCompanyCompaniesQuery,
|
assignCompanyCompaniesQuery,
|
||||||
|
shouldShowPagination,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
} from "@/components/ui/table";
|
} from "@/components/ui/table";
|
||||||
import TableSkeleton from "@/components/ui/TableSkeleton";
|
import TableSkeleton from "@/components/ui/TableSkeleton";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { capitalize, unixToDate } from "@/utils/shared";
|
import { capitalize, getPaginatedRowNumber, unixToDate } from "@/utils/shared";
|
||||||
|
|
||||||
import { ShowcaseSection } from "@/components/Layouts/showcase-section";
|
import { ShowcaseSection } from "@/components/Layouts/showcase-section";
|
||||||
import useFeedbackTablePresenter from "./useFeedbackTablePresenter";
|
import useFeedbackTablePresenter from "./useFeedbackTablePresenter";
|
||||||
@@ -60,7 +60,7 @@ const FeedbackTable = ({ id, paramKey }: IProps) => {
|
|||||||
className="odd:bg-gray-2 dark:odd:bg-gray-7"
|
className="odd:bg-gray-2 dark:odd:bg-gray-7"
|
||||||
>
|
>
|
||||||
<TableCell className="text-start" colSpan={100}>
|
<TableCell className="text-start" colSpan={100}>
|
||||||
{index + 1}
|
{getPaginatedRowNumber({ index })}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className="uppercase" colSpan={100}>
|
<TableCell className="uppercase" colSpan={100}>
|
||||||
{item.feedback_type}
|
{item.feedback_type}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import { PencilSquareIcon, TrashIcon } from "@/assets/icons";
|
import { PencilSquareIcon, TrashIcon } from "@/assets/icons";
|
||||||
import EmptyListWrapper from "@/components/HOC/EmptyListWrapper";
|
import EmptyListWrapper from "@/components/HOC/EmptyListWrapper";
|
||||||
import ConfirmationModal from "@/components/ui/ConfirmationModal";
|
import ConfirmationModal from "@/components/ui/ConfirmationModal";
|
||||||
|
import IsVisible from "@/components/ui/IsVisible";
|
||||||
import ListHeader from "@/components/ui/ListHeader";
|
import ListHeader from "@/components/ui/ListHeader";
|
||||||
import Modal from "@/components/ui/modal";
|
import Modal from "@/components/ui/modal";
|
||||||
import Pagination from "@/components/ui/pagination";
|
import Pagination from "@/components/ui/pagination";
|
||||||
@@ -16,7 +17,7 @@ import {
|
|||||||
} from "@/components/ui/table";
|
} from "@/components/ui/table";
|
||||||
import TableSkeleton from "@/components/ui/TableSkeleton";
|
import TableSkeleton from "@/components/ui/TableSkeleton";
|
||||||
import { _TooltipDefaultParams } from "@/constants/tooltip";
|
import { _TooltipDefaultParams } from "@/constants/tooltip";
|
||||||
import { formatPhoneNumber, unixToDate } from "@/utils/shared";
|
import { formatPhoneNumber, getPaginatedRowNumber, unixToDate } from "@/utils/shared";
|
||||||
import { Tooltip } from "react-tooltip";
|
import { Tooltip } from "react-tooltip";
|
||||||
import ChangeStatusForm from "./ChangeStatusForm";
|
import ChangeStatusForm from "./ChangeStatusForm";
|
||||||
import InquiriesListFilters from "./InquiriesListFilters";
|
import InquiriesListFilters from "./InquiriesListFilters";
|
||||||
@@ -45,7 +46,9 @@ const InquiriesTable = () => {
|
|||||||
setFilterValue,
|
setFilterValue,
|
||||||
isMutating,
|
isMutating,
|
||||||
setParams,
|
setParams,
|
||||||
|
shouldShowPagination,
|
||||||
} = useInquiriesListPresenter();
|
} = useInquiriesListPresenter();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col rounded-[10px] bg-white px-7.5 pb-4 pt-7.5 shadow-1 dark:bg-gray-dark dark:shadow-card">
|
<div className="flex flex-col rounded-[10px] bg-white px-7.5 pb-4 pt-7.5 shadow-1 dark:bg-gray-dark dark:shadow-card">
|
||||||
<ListHeader
|
<ListHeader
|
||||||
@@ -68,11 +71,16 @@ const InquiriesTable = () => {
|
|||||||
columns={columns}
|
columns={columns}
|
||||||
list={inquiries ?? []}
|
list={inquiries ?? []}
|
||||||
emptyMessage="No Inquiries were found"
|
emptyMessage="No Inquiries were found"
|
||||||
|
isLoading={isPending}
|
||||||
>
|
>
|
||||||
{inquiries?.map((inquiry, index) => (
|
{inquiries?.map((inquiry, index) => (
|
||||||
<TableRow key={inquiry?.id ?? index}>
|
<TableRow key={inquiry?.id ?? index}>
|
||||||
<TableCell className="text-start" colSpan={100}>
|
<TableCell className="text-start" colSpan={100}>
|
||||||
{index + 1}
|
{getPaginatedRowNumber({
|
||||||
|
index,
|
||||||
|
page: allInquiries?.meta?.page,
|
||||||
|
limit: allInquiries?.meta?.limit,
|
||||||
|
})}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className="text-start" colSpan={100}>
|
<TableCell className="text-start" colSpan={100}>
|
||||||
{inquiry?.company_name}
|
{inquiry?.company_name}
|
||||||
@@ -146,19 +154,21 @@ const InquiriesTable = () => {
|
|||||||
watch={watch}
|
watch={watch}
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
<Pagination
|
<IsVisible condition={shouldShowPagination}>
|
||||||
currentPage={
|
<Pagination
|
||||||
allInquiries?.meta?.page ? allInquiries?.meta?.page - 1 : 0
|
currentPage={
|
||||||
}
|
allInquiries?.meta?.page ? allInquiries?.meta?.page - 1 : 0
|
||||||
totalPages={allInquiries?.meta?.pages ?? 1}
|
}
|
||||||
onPageChange={(e) => {
|
totalPages={allInquiries?.meta?.pages ?? 1}
|
||||||
setParams((currentParams) => ({
|
onPageChange={(e) => {
|
||||||
...currentParams,
|
setParams((currentParams) => ({
|
||||||
offset: e.selected * (allInquiries?.meta?.limit ?? 10),
|
...currentParams,
|
||||||
limit: allInquiries?.meta?.limit ?? 10,
|
offset: e.selected * (allInquiries?.meta?.limit ?? 10),
|
||||||
}));
|
limit: allInquiries?.meta?.limit ?? 10,
|
||||||
}}
|
}));
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
|
</IsVisible>
|
||||||
<Modal
|
<Modal
|
||||||
isOpen={isChangeStatusModalOpen}
|
isOpen={isChangeStatusModalOpen}
|
||||||
onClose={() => setIsChangeStatusModalOpen(false)}
|
onClose={() => setIsChangeStatusModalOpen(false)}
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ const useInquiriesListPresenter = () => {
|
|||||||
}, [searchParams, filterFormReset]);
|
}, [searchParams, filterFormReset]);
|
||||||
|
|
||||||
const { data, isPending } = useGetInquiries(params);
|
const { data, isPending } = useGetInquiries(params);
|
||||||
|
const shouldShowPagination =
|
||||||
|
!isPending && (data?.meta?.pages ?? 1) * (data?.meta?.limit ?? 10) > 10;
|
||||||
const { mutate } = useDeleteInquiry(() => setIsDeleteModalOpen(false));
|
const { mutate } = useDeleteInquiry(() => setIsDeleteModalOpen(false));
|
||||||
const { mutate: changeStatus } =
|
const { mutate: changeStatus } =
|
||||||
useChangeInquiryStatus(() => setIsChangeStatusModalOpen(false));
|
useChangeInquiryStatus(() => setIsChangeStatusModalOpen(false));
|
||||||
@@ -100,6 +102,7 @@ const useInquiriesListPresenter = () => {
|
|||||||
setFilterValue,
|
setFilterValue,
|
||||||
isMutating,
|
isMutating,
|
||||||
setParams,
|
setParams,
|
||||||
|
shouldShowPagination,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import { EyeIcon } from "@/assets/icons";
|
import { EyeIcon } from "@/assets/icons";
|
||||||
import EmptyListWrapper from "@/components/HOC/EmptyListWrapper";
|
import EmptyListWrapper from "@/components/HOC/EmptyListWrapper";
|
||||||
import { ShowcaseSection } from "@/components/Layouts/showcase-section";
|
import { ShowcaseSection } from "@/components/Layouts/showcase-section";
|
||||||
|
import IsVisible from "@/components/ui/IsVisible";
|
||||||
import Pagination from "@/components/ui/pagination";
|
import Pagination from "@/components/ui/pagination";
|
||||||
import Status from "@/components/ui/Status";
|
import Status from "@/components/ui/Status";
|
||||||
import {
|
import {
|
||||||
@@ -14,7 +15,7 @@ import {
|
|||||||
} from "@/components/ui/table";
|
} from "@/components/ui/table";
|
||||||
import TableSkeleton from "@/components/ui/TableSkeleton";
|
import TableSkeleton from "@/components/ui/TableSkeleton";
|
||||||
import { _TooltipDefaultParams } from "@/constants/tooltip";
|
import { _TooltipDefaultParams } from "@/constants/tooltip";
|
||||||
import { truncateString, unixToDate } from "@/utils/shared";
|
import { getPaginatedRowNumber, truncateString, unixToDate } from "@/utils/shared";
|
||||||
import { Tooltip } from "react-tooltip";
|
import { Tooltip } from "react-tooltip";
|
||||||
|
|
||||||
import Boolean from "@/components/ui/Boolean";
|
import Boolean from "@/components/ui/Boolean";
|
||||||
@@ -40,6 +41,7 @@ const NotificationHistoryTable = () => {
|
|||||||
watch,
|
watch,
|
||||||
search,
|
search,
|
||||||
isMutating,
|
isMutating,
|
||||||
|
shouldShowPagination,
|
||||||
} = useNotificationHistoryTablePresenter();
|
} = useNotificationHistoryTablePresenter();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -65,10 +67,17 @@ const NotificationHistoryTable = () => {
|
|||||||
list={notificationHistory ?? []}
|
list={notificationHistory ?? []}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
emptyMessage="No notifications were found"
|
emptyMessage="No notifications were found"
|
||||||
|
isLoading={isLoading}
|
||||||
>
|
>
|
||||||
{(notificationHistory ?? []).map((item, index) => (
|
{(notificationHistory ?? []).map((item, index) => (
|
||||||
<TableRow key={item.id}>
|
<TableRow key={item.id}>
|
||||||
<TableCell colSpan={100}>{index + 1}</TableCell>
|
<TableCell colSpan={100}>
|
||||||
|
{getPaginatedRowNumber({
|
||||||
|
index,
|
||||||
|
page: metadata?.page,
|
||||||
|
limit: metadata?.limit,
|
||||||
|
})}
|
||||||
|
</TableCell>
|
||||||
<TableCell colSpan={100}>{item.title}</TableCell>
|
<TableCell colSpan={100}>{item.title}</TableCell>
|
||||||
<TableCell colSpan={100}>{item.event_type}</TableCell>
|
<TableCell colSpan={100}>{item.event_type}</TableCell>
|
||||||
<TableCell colSpan={100}>
|
<TableCell colSpan={100}>
|
||||||
@@ -117,17 +126,19 @@ const NotificationHistoryTable = () => {
|
|||||||
</EmptyListWrapper>
|
</EmptyListWrapper>
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
<Pagination
|
<IsVisible condition={shouldShowPagination}>
|
||||||
currentPage={metadata?.page ? metadata?.page - 1 : 0}
|
<Pagination
|
||||||
totalPages={metadata?.pages ?? 1}
|
currentPage={metadata?.page ? metadata?.page - 1 : 0}
|
||||||
onPageChange={(e) => {
|
totalPages={metadata?.pages ?? 1}
|
||||||
setParams((currentParams) => ({
|
onPageChange={(e) => {
|
||||||
...currentParams,
|
setParams((currentParams) => ({
|
||||||
offset: e.selected * (metadata?.limit ?? 10),
|
...currentParams,
|
||||||
limit: metadata?.limit ?? 10,
|
offset: e.selected * (metadata?.limit ?? 10),
|
||||||
}));
|
limit: metadata?.limit ?? 10,
|
||||||
}}
|
}));
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
|
</IsVisible>
|
||||||
</ShowcaseSection>
|
</ShowcaseSection>
|
||||||
<Modal
|
<Modal
|
||||||
isOpen={isFilterModalOpen}
|
isOpen={isFilterModalOpen}
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ const useNotificationHistoryTablePresenter = () => {
|
|||||||
...apiDefaultParams,
|
...apiDefaultParams,
|
||||||
});
|
});
|
||||||
const { data, isLoading } = useGetNotificationHistoryQuery(params);
|
const { data, isLoading } = useGetNotificationHistoryQuery(params);
|
||||||
|
const shouldShowPagination =
|
||||||
|
!isLoading && (data?.meta?.pages ?? 1) * (data?.meta?.limit ?? 10) > 10;
|
||||||
const isMutating = useIsMutating();
|
const isMutating = useIsMutating();
|
||||||
const columns: string[] = [
|
const columns: string[] = [
|
||||||
"row",
|
"row",
|
||||||
@@ -54,6 +56,7 @@ const useNotificationHistoryTablePresenter = () => {
|
|||||||
setIsFilterModalOpen,
|
setIsFilterModalOpen,
|
||||||
isMutating,
|
isMutating,
|
||||||
search,
|
search,
|
||||||
|
shouldShowPagination,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -15,12 +15,14 @@ import useTenderListPresenter from "./useTenderListPresenter";
|
|||||||
|
|
||||||
import { ExclamationIcon, EyeIcon } from "@/assets/icons";
|
import { ExclamationIcon, EyeIcon } from "@/assets/icons";
|
||||||
|
|
||||||
|
import IsVisible from "@/components/ui/IsVisible";
|
||||||
import ListHeader from "@/components/ui/ListHeader";
|
import ListHeader from "@/components/ui/ListHeader";
|
||||||
import Modal from "@/components/ui/modal";
|
import Modal from "@/components/ui/modal";
|
||||||
import Pagination from "@/components/ui/pagination";
|
import Pagination from "@/components/ui/pagination";
|
||||||
import TableSkeleton from "@/components/ui/TableSkeleton";
|
import TableSkeleton from "@/components/ui/TableSkeleton";
|
||||||
import { _TooltipDefaultParams } from "@/constants/tooltip";
|
import { _TooltipDefaultParams } from "@/constants/tooltip";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
import { getPaginatedRowNumber } from "@/utils/shared";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import TenderListFilters from "./TenderListFilters";
|
import TenderListFilters from "./TenderListFilters";
|
||||||
const TendersTable = () => {
|
const TendersTable = () => {
|
||||||
@@ -39,6 +41,7 @@ const TendersTable = () => {
|
|||||||
watch,
|
watch,
|
||||||
setFilterValue,
|
setFilterValue,
|
||||||
isMutating,
|
isMutating,
|
||||||
|
shouldShowPagination,
|
||||||
} = useTenderListPresenter();
|
} = useTenderListPresenter();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -64,6 +67,7 @@ const TendersTable = () => {
|
|||||||
list={allTenders?.data.tenders ?? []}
|
list={allTenders?.data.tenders ?? []}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
emptyMessage="No tenders were found"
|
emptyMessage="No tenders were found"
|
||||||
|
isLoading={isPending}
|
||||||
>
|
>
|
||||||
{(allTenders?.data.tenders ?? []).map((item, index) => (
|
{(allTenders?.data.tenders ?? []).map((item, index) => (
|
||||||
<TableRow
|
<TableRow
|
||||||
@@ -71,7 +75,11 @@ const TendersTable = () => {
|
|||||||
className="odd:bg-gray-2 dark:odd:bg-gray-7"
|
className="odd:bg-gray-2 dark:odd:bg-gray-7"
|
||||||
>
|
>
|
||||||
<TableCell className="text-start" colSpan={100}>
|
<TableCell className="text-start" colSpan={100}>
|
||||||
{index + 1}
|
{getPaginatedRowNumber({
|
||||||
|
index,
|
||||||
|
page: allTenders?.meta?.page,
|
||||||
|
limit: allTenders?.meta?.limit,
|
||||||
|
})}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className="text-start" colSpan={100}>
|
<TableCell className="text-start" colSpan={100}>
|
||||||
{item.title}
|
{item.title}
|
||||||
@@ -145,17 +153,19 @@ const TendersTable = () => {
|
|||||||
watch={watch}
|
watch={watch}
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
<Pagination
|
<IsVisible condition={shouldShowPagination}>
|
||||||
currentPage={allTenders?.meta?.page ? allTenders?.meta?.page - 1 : 0}
|
<Pagination
|
||||||
totalPages={allTenders?.meta?.pages ?? 1}
|
currentPage={allTenders?.meta?.page ? allTenders?.meta?.page - 1 : 0}
|
||||||
onPageChange={(e) => {
|
totalPages={allTenders?.meta?.pages ?? 1}
|
||||||
setParams((currentParams) => ({
|
onPageChange={(e) => {
|
||||||
...currentParams,
|
setParams((currentParams) => ({
|
||||||
offset: e.selected * (allTenders?.meta?.limit ?? 10),
|
...currentParams,
|
||||||
limit: allTenders?.meta?.limit ?? 10,
|
offset: e.selected * (allTenders?.meta?.limit ?? 10),
|
||||||
}));
|
limit: allTenders?.meta?.limit ?? 10,
|
||||||
}}
|
}));
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
|
</IsVisible>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ const useTenderListPresenter = () => {
|
|||||||
}, [searchParams, filterFormReset]);
|
}, [searchParams, filterFormReset]);
|
||||||
|
|
||||||
const { data, error, isPending } = useTendersQuery(params);
|
const { data, error, isPending } = useTendersQuery(params);
|
||||||
|
const shouldShowPagination =
|
||||||
|
!isPending && (data?.meta?.pages ?? 1) * (data?.meta?.limit ?? 10) > 10;
|
||||||
|
|
||||||
const search = (data: any) => {
|
const search = (data: any) => {
|
||||||
const newParams = { ...params, ...data, offset: 0 };
|
const newParams = { ...params, ...data, offset: 0 };
|
||||||
@@ -82,6 +84,7 @@ const useTenderListPresenter = () => {
|
|||||||
watch,
|
watch,
|
||||||
setFilterValue,
|
setFilterValue,
|
||||||
isMutating,
|
isMutating,
|
||||||
|
shouldShowPagination,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -111,3 +111,18 @@ export const deleteEmptyKeys = (obj: Record<string, any>) => {
|
|||||||
return newObj;
|
return newObj;
|
||||||
};
|
};
|
||||||
export const isValidAlpha2CountryCode = (code: string) => /^[A-Za-z]{2}$/.test(code);
|
export const isValidAlpha2CountryCode = (code: string) => /^[A-Za-z]{2}$/.test(code);
|
||||||
|
|
||||||
|
export const getPaginatedRowNumber = ({
|
||||||
|
index,
|
||||||
|
page = 1,
|
||||||
|
limit = 10,
|
||||||
|
}: {
|
||||||
|
index: number;
|
||||||
|
page?: number;
|
||||||
|
limit?: number;
|
||||||
|
}) => {
|
||||||
|
const safePage = page > 0 ? page : 1;
|
||||||
|
const safeLimit = limit > 0 ? limit : 10;
|
||||||
|
|
||||||
|
return (safePage - 1) * safeLimit + index + 1;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user