From 07fd4e1d2dc945bf66a5f65f19aa143cee2bd13e Mon Sep 17 00:00:00 2001 From: hosseintaromi Date: Fri, 26 Sep 2025 10:17:38 +0330 Subject: [PATCH] feat(orders): optimize API calls and add comprehensive filters - Update OrderFilters interface to match complete API documentation - Add all supported query parameters (user_id, invoice_id, transaction_id, discount_code, etc.) - Optimize useOrderStats to prevent duplicate API calls by making it dependent on orders query - Add payment status filter to orders list page - Replace order number search with general search field supporting order numbers, transaction IDs, and discount codes - Maintain backward compatibility with legacy filter names - Add stale time to stats query for better caching --- src/pages/discount-codes/core/_requests.ts | 4 +-- .../DiscountCodeFormPage.tsx | 2 +- .../DiscountCodesListPage.tsx | 2 +- src/pages/orders/core/_hooks.ts | 4 ++- src/pages/orders/core/_models.ts | 28 ++++++++++++--- src/pages/orders/core/_requests.ts | 34 +++++++++++++++---- .../orders/orders-list/OrdersListPage.tsx | 29 ++++++++++++---- src/pages/users-admin/core/_requests.ts | 10 +++--- .../user-admin-form/UserAdminFormPage.tsx | 4 +-- .../users-admin-list/UsersAdminListPage.tsx | 2 ++ 10 files changed, 91 insertions(+), 28 deletions(-) diff --git a/src/pages/discount-codes/core/_requests.ts b/src/pages/discount-codes/core/_requests.ts index d2bb6e5..e0eef13 100644 --- a/src/pages/discount-codes/core/_requests.ts +++ b/src/pages/discount-codes/core/_requests.ts @@ -15,7 +15,7 @@ import { } from "./_models"; export const getDiscountCodes = async (filters?: DiscountCodeFilters) => { - const queryParams: Record = {}; + const queryParams: Record = {}; if (filters?.page) queryParams.page = filters.page; if (filters?.limit) queryParams.limit = filters.limit; @@ -25,7 +25,7 @@ export const getDiscountCodes = async (filters?: DiscountCodeFilters) => { queryParams.application_level = filters.application_level; if (filters?.code) queryParams.code = filters.code; if (typeof filters?.active_only === "boolean") - queryParams.active_only = filters.active_only; + queryParams.active_only = filters.active_only ? "true" : "false"; const response = await httpGetRequest( APIUrlGenerator(API_ROUTES.GET_DISCOUNT_CODES, queryParams) diff --git a/src/pages/discount-codes/discount-code-form/DiscountCodeFormPage.tsx b/src/pages/discount-codes/discount-code-form/DiscountCodeFormPage.tsx index 3e4aa21..b8a59fd 100644 --- a/src/pages/discount-codes/discount-code-form/DiscountCodeFormPage.tsx +++ b/src/pages/discount-codes/discount-code-form/DiscountCodeFormPage.tsx @@ -108,7 +108,7 @@ const DiscountCodeFormPage = () => { })); const { register, handleSubmit, formState: { errors, isValid }, reset } = useForm({ - resolver: yupResolver(schema), + resolver: yupResolver(schema as any), mode: 'onChange', defaultValues: { status: 'active', type: 'percentage', application_level: 'invoice', single_use: false } }); diff --git a/src/pages/discount-codes/discount-codes-list/DiscountCodesListPage.tsx b/src/pages/discount-codes/discount-codes-list/DiscountCodesListPage.tsx index 92ba913..e5b938a 100644 --- a/src/pages/discount-codes/discount-codes-list/DiscountCodesListPage.tsx +++ b/src/pages/discount-codes/discount-codes-list/DiscountCodesListPage.tsx @@ -126,7 +126,7 @@ const DiscountCodesListPage = () => { {isLoading ? ( - +
) : !discountCodes || discountCodes.length === 0 ? (
diff --git a/src/pages/orders/core/_hooks.ts b/src/pages/orders/core/_hooks.ts index 3dfd395..820ab05 100644 --- a/src/pages/orders/core/_hooks.ts +++ b/src/pages/orders/core/_hooks.ts @@ -24,10 +24,12 @@ export const useOrder = (id: string) => { }); }; -export const useOrderStats = () => { +export const useOrderStats = (enabled: boolean = true) => { return useQuery({ queryKey: [QUERY_KEYS.GET_ORDERS, "stats"], queryFn: getOrderStats, + enabled, + staleTime: 5 * 60 * 1000, // 5 minutes }); }; diff --git a/src/pages/orders/core/_models.ts b/src/pages/orders/core/_models.ts index f7b10be..7d5cddc 100644 --- a/src/pages/orders/core/_models.ts +++ b/src/pages/orders/core/_models.ts @@ -84,17 +84,37 @@ export interface Order { } export interface OrderFilters { + // Pagination page?: number; limit?: number; offset?: number; + + // Filter Parameters + user_id?: number; + invoice_id?: number; status?: OrderStatus; payment_status?: PaymentStatus; customer_id?: number; order_number?: string; - date_from?: string; - date_to?: string; - min_amount?: number; - max_amount?: number; + transaction_id?: string; + discount_code?: string; + + // Amount Range Parameters + min_total?: number; + max_total?: number; + min_amount?: number; // legacy support + max_amount?: number; // legacy support + + // Date Range Parameters + created_from?: string; + created_to?: string; + updated_from?: string; + updated_to?: string; + date_from?: string; // legacy support + date_to?: string; // legacy support + + // Search Parameter + search?: string; } export interface PaginatedOrdersResponse { diff --git a/src/pages/orders/core/_requests.ts b/src/pages/orders/core/_requests.ts index 229118e..dfacfdb 100644 --- a/src/pages/orders/core/_requests.ts +++ b/src/pages/orders/core/_requests.ts @@ -10,23 +10,43 @@ import { PaginatedOrdersResponse, UpdateOrderStatusRequest, OrderStats, + OrderStatus, } from "./_models"; export const getOrders = async (filters?: OrderFilters) => { - const queryParams: Record = {}; + const queryParams: Record = {}; + // Pagination if (filters?.page) queryParams.page = filters.page; if (filters?.limit) queryParams.limit = filters.limit; if (filters?.offset) queryParams.offset = filters.offset; + + // Filter Parameters + if (filters?.user_id) queryParams.user_id = filters.user_id; + if (filters?.invoice_id) queryParams.invoice_id = filters.invoice_id; if (filters?.status) queryParams.status = filters.status; - if (filters?.payment_status) - queryParams.payment_status = filters.payment_status; + if (filters?.payment_status) queryParams.payment_status = filters.payment_status; if (filters?.customer_id) queryParams.customer_id = filters.customer_id; if (filters?.order_number) queryParams.order_number = filters.order_number; - if (filters?.date_from) queryParams.date_from = filters.date_from; - if (filters?.date_to) queryParams.date_to = filters.date_to; - if (filters?.min_amount) queryParams.min_amount = filters.min_amount; - if (filters?.max_amount) queryParams.max_amount = filters.max_amount; + if (filters?.transaction_id) queryParams.transaction_id = filters.transaction_id; + if (filters?.discount_code) queryParams.discount_code = filters.discount_code; + + // Amount Range Parameters (prefer new API naming) + if (filters?.min_total) queryParams.min_total = filters.min_total; + if (filters?.max_total) queryParams.max_total = filters.max_total; + if (filters?.min_amount && !filters?.min_total) queryParams.min_total = filters.min_amount; + if (filters?.max_amount && !filters?.max_total) queryParams.max_total = filters.max_amount; + + // Date Range Parameters (prefer new API naming) + if (filters?.created_from) queryParams.created_from = filters.created_from; + if (filters?.created_to) queryParams.created_to = filters.created_to; + if (filters?.updated_from) queryParams.updated_from = filters.updated_from; + if (filters?.updated_to) queryParams.updated_to = filters.updated_to; + if (filters?.date_from && !filters?.created_from) queryParams.created_from = filters.date_from; + if (filters?.date_to && !filters?.created_to) queryParams.created_to = filters.date_to; + + // Search Parameter + if (filters?.search) queryParams.search = filters.search; const response = await httpGetRequest( APIUrlGenerator(API_ROUTES.GET_ORDERS, queryParams) diff --git a/src/pages/orders/orders-list/OrdersListPage.tsx b/src/pages/orders/orders-list/OrdersListPage.tsx index c792f61..a02e32b 100644 --- a/src/pages/orders/orders-list/OrdersListPage.tsx +++ b/src/pages/orders/orders-list/OrdersListPage.tsx @@ -67,10 +67,12 @@ const OrdersListPage = () => { limit: 20, order_number: '', status: undefined, + payment_status: undefined, + search: '', }); const { data: ordersData, isLoading, error } = useOrders(filters); - const { data: stats, isLoading: statsLoading } = useOrderStats(); + const { data: stats, isLoading: statsLoading } = useOrderStats(!isLoading); const { mutate: updateStatus, isPending: isUpdating } = useUpdateOrderStatus(); const columns: TableColumn[] = useMemo(() => [ @@ -219,14 +221,14 @@ const OrdersListPage = () => { {/* فیلترها */}
-
+
setFilters(prev => ({ ...prev, order_number: e.target.value, page: 1 }))} + placeholder="جستجو عمومی (شماره سفارش، کد تراکنش، کد تخفیف)..." + value={filters.search || ''} + onChange={(e) => setFilters(prev => ({ ...prev, search: e.target.value, page: 1 }))} className="w-full pr-10 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-1 focus:ring-primary-500 dark:bg-gray-700 dark:text-gray-100" />
@@ -247,9 +249,24 @@ const OrdersListPage = () => {
+
+ +
+