pagination orders list
This commit is contained in:
@@ -21,7 +21,6 @@ const OrdersList: FC = () => {
|
|||||||
apiParams,
|
apiParams,
|
||||||
handleFiltersChange,
|
handleFiltersChange,
|
||||||
handlePageChange,
|
handlePageChange,
|
||||||
limit,
|
|
||||||
} = useOrderFilters()
|
} = useOrderFilters()
|
||||||
|
|
||||||
const { data: ordersData, isLoading } = useGetOrders(apiParams)
|
const { data: ordersData, isLoading } = useGetOrders(apiParams)
|
||||||
@@ -30,7 +29,7 @@ const OrdersList: FC = () => {
|
|||||||
const columns = getOrderTableColumns({ t })
|
const columns = getOrderTableColumns({ t })
|
||||||
const filterFields = useOrderFiltersFields()
|
const filterFields = useOrderFiltersFields()
|
||||||
|
|
||||||
const totalPages = Math.ceil(orders.length / limit) || 1
|
const totalPages = ordersData?.meta?.totalPages || 1
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='mt-5'>
|
<div className='mt-5'>
|
||||||
|
|||||||
@@ -1,14 +1,80 @@
|
|||||||
import { useState, useMemo } from "react";
|
import { useState, useMemo, useCallback, useEffect } from "react";
|
||||||
|
import { useSearchParams } from "react-router-dom";
|
||||||
import type { FilterValues } from "@/components/Filters";
|
import type { FilterValues } from "@/components/Filters";
|
||||||
|
|
||||||
const DEFAULT_PAGE = 1;
|
const DEFAULT_PAGE = 1;
|
||||||
const DEFAULT_LIMIT = 10;
|
const DEFAULT_LIMIT = 10;
|
||||||
|
const DEFAULT_FILTERS: FilterValues = {
|
||||||
|
statuses: [],
|
||||||
|
paymentStatus: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
const getFiltersFromParams = (searchParams: URLSearchParams): FilterValues => {
|
||||||
|
const filters: FilterValues = { ...DEFAULT_FILTERS };
|
||||||
|
const search = searchParams.get("search");
|
||||||
|
const statuses = searchParams.getAll("statuses");
|
||||||
|
const paymentStatus = searchParams.get("paymentStatus");
|
||||||
|
|
||||||
|
if (search) filters.search = search;
|
||||||
|
if (statuses.length > 0) filters.statuses = statuses;
|
||||||
|
if (paymentStatus) filters.paymentStatus = paymentStatus;
|
||||||
|
|
||||||
|
return filters;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getPageFromParams = (searchParams: URLSearchParams): number => {
|
||||||
|
const page = searchParams.get("page");
|
||||||
|
const parsed = page ? parseInt(page, 10) : DEFAULT_PAGE;
|
||||||
|
return Number.isNaN(parsed) || parsed < 1 ? DEFAULT_PAGE : parsed;
|
||||||
|
};
|
||||||
|
|
||||||
|
const buildSearchParams = (filters: FilterValues, page: number): URLSearchParams => {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
|
||||||
|
if (page > DEFAULT_PAGE) {
|
||||||
|
params.set("page", String(page));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filters.search) {
|
||||||
|
params.set("search", filters.search as string);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filters.statuses && Array.isArray(filters.statuses) && filters.statuses.length > 0) {
|
||||||
|
(filters.statuses as string[]).forEach((status) => {
|
||||||
|
params.append("statuses", status);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filters.paymentStatus) {
|
||||||
|
params.set("paymentStatus", filters.paymentStatus as string);
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
export const useOrderFilters = () => {
|
export const useOrderFilters = () => {
|
||||||
const [filters, setFilters] = useState<FilterValues>({});
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
const [currentPage, setCurrentPage] = useState(DEFAULT_PAGE);
|
|
||||||
|
const [filters, setFilters] = useState<FilterValues>(() =>
|
||||||
|
getFiltersFromParams(searchParams),
|
||||||
|
);
|
||||||
|
const [currentPage, setCurrentPage] = useState(() =>
|
||||||
|
getPageFromParams(searchParams),
|
||||||
|
);
|
||||||
const [limit] = useState(DEFAULT_LIMIT);
|
const [limit] = useState(DEFAULT_LIMIT);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setFilters(getFiltersFromParams(searchParams));
|
||||||
|
setCurrentPage(getPageFromParams(searchParams));
|
||||||
|
}, [searchParams]);
|
||||||
|
|
||||||
|
const updateUrlParams = useCallback(
|
||||||
|
(newFilters: FilterValues, page: number) => {
|
||||||
|
setSearchParams(buildSearchParams(newFilters, page), { replace: true });
|
||||||
|
},
|
||||||
|
[setSearchParams],
|
||||||
|
);
|
||||||
|
|
||||||
const apiParams = useMemo(() => {
|
const apiParams = useMemo(() => {
|
||||||
const params: Record<string, string | number | string[]> = {
|
const params: Record<string, string | number | string[]> = {
|
||||||
page: currentPage,
|
page: currentPage,
|
||||||
@@ -30,14 +96,22 @@ export const useOrderFilters = () => {
|
|||||||
return params;
|
return params;
|
||||||
}, [filters, currentPage, limit]);
|
}, [filters, currentPage, limit]);
|
||||||
|
|
||||||
const handleFiltersChange = (newFilters: FilterValues) => {
|
const handleFiltersChange = useCallback(
|
||||||
setFilters(newFilters);
|
(newFilters: FilterValues) => {
|
||||||
setCurrentPage(DEFAULT_PAGE);
|
setFilters(newFilters);
|
||||||
};
|
setCurrentPage(DEFAULT_PAGE);
|
||||||
|
updateUrlParams(newFilters, DEFAULT_PAGE);
|
||||||
|
},
|
||||||
|
[updateUrlParams],
|
||||||
|
);
|
||||||
|
|
||||||
const handlePageChange = (page: number) => {
|
const handlePageChange = useCallback(
|
||||||
setCurrentPage(page);
|
(page: number) => {
|
||||||
};
|
setCurrentPage(page);
|
||||||
|
updateUrlParams(filters, page);
|
||||||
|
},
|
||||||
|
[filters, updateUrlParams],
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
filters,
|
filters,
|
||||||
|
|||||||
@@ -218,7 +218,16 @@ export interface Order extends RowDataType {
|
|||||||
items: OrderItem[];
|
items: OrderItem[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetOrdersResponse = IResponse<Order[]>;
|
export type PaginationMeta = {
|
||||||
|
total: number;
|
||||||
|
page: number;
|
||||||
|
limit: number;
|
||||||
|
totalPages: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type GetOrdersResponse = IResponse<Order[]> & {
|
||||||
|
meta: PaginationMeta;
|
||||||
|
};
|
||||||
export type GetOrderByIdResponse = IResponse<Order>;
|
export type GetOrderByIdResponse = IResponse<Order>;
|
||||||
|
|
||||||
export interface FoodOrderReportFood {
|
export interface FoodOrderReportFood {
|
||||||
|
|||||||
Reference in New Issue
Block a user