Add frontend order API
This commit is contained in:
332
frontend/src/api/hooks/orders.ts
Normal file
332
frontend/src/api/hooks/orders.ts
Normal file
@@ -0,0 +1,332 @@
|
||||
/**
|
||||
* Orders React Query hooks
|
||||
*/
|
||||
import { useMutation, useQuery, useQueryClient, UseQueryOptions, UseMutationOptions } from '@tanstack/react-query';
|
||||
import { OrdersService } from '../services/orders';
|
||||
import {
|
||||
OrderResponse,
|
||||
OrderCreate,
|
||||
OrderUpdate,
|
||||
CustomerResponse,
|
||||
CustomerCreate,
|
||||
CustomerUpdate,
|
||||
OrdersDashboardSummary,
|
||||
DemandRequirements,
|
||||
BusinessModelDetection,
|
||||
ServiceStatus,
|
||||
GetOrdersParams,
|
||||
GetCustomersParams,
|
||||
UpdateOrderStatusParams,
|
||||
GetDemandRequirementsParams,
|
||||
} from '../types/orders';
|
||||
import { ApiError } from '../client/apiClient';
|
||||
|
||||
// Query Keys
|
||||
export const ordersKeys = {
|
||||
all: ['orders'] as const,
|
||||
|
||||
// Orders
|
||||
orders: () => [...ordersKeys.all, 'orders'] as const,
|
||||
ordersList: (params: GetOrdersParams) => [...ordersKeys.orders(), 'list', params] as const,
|
||||
order: (tenantId: string, orderId: string) => [...ordersKeys.orders(), 'detail', tenantId, orderId] as const,
|
||||
|
||||
// Customers
|
||||
customers: () => [...ordersKeys.all, 'customers'] as const,
|
||||
customersList: (params: GetCustomersParams) => [...ordersKeys.customers(), 'list', params] as const,
|
||||
customer: (tenantId: string, customerId: string) => [...ordersKeys.customers(), 'detail', tenantId, customerId] as const,
|
||||
|
||||
// Dashboard & Analytics
|
||||
dashboard: (tenantId: string) => [...ordersKeys.all, 'dashboard', tenantId] as const,
|
||||
demandRequirements: (params: GetDemandRequirementsParams) => [...ordersKeys.all, 'demand', params] as const,
|
||||
businessModel: (tenantId: string) => [...ordersKeys.all, 'business-model', tenantId] as const,
|
||||
|
||||
// Status
|
||||
status: (tenantId: string) => [...ordersKeys.all, 'status', tenantId] as const,
|
||||
} as const;
|
||||
|
||||
// ===== Order Queries =====
|
||||
|
||||
export const useOrders = (
|
||||
params: GetOrdersParams,
|
||||
options?: Omit<UseQueryOptions<OrderResponse[], ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<OrderResponse[], ApiError>({
|
||||
queryKey: ordersKeys.ordersList(params),
|
||||
queryFn: () => OrdersService.getOrders(params),
|
||||
staleTime: 2 * 60 * 1000, // 2 minutes
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
export const useOrder = (
|
||||
tenantId: string,
|
||||
orderId: string,
|
||||
options?: Omit<UseQueryOptions<OrderResponse, ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<OrderResponse, ApiError>({
|
||||
queryKey: ordersKeys.order(tenantId, orderId),
|
||||
queryFn: () => OrdersService.getOrder(tenantId, orderId),
|
||||
staleTime: 1 * 60 * 1000, // 1 minute
|
||||
enabled: !!tenantId && !!orderId,
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
// ===== Customer Queries =====
|
||||
|
||||
export const useCustomers = (
|
||||
params: GetCustomersParams,
|
||||
options?: Omit<UseQueryOptions<CustomerResponse[], ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<CustomerResponse[], ApiError>({
|
||||
queryKey: ordersKeys.customersList(params),
|
||||
queryFn: () => OrdersService.getCustomers(params),
|
||||
staleTime: 5 * 60 * 1000, // 5 minutes
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
export const useCustomer = (
|
||||
tenantId: string,
|
||||
customerId: string,
|
||||
options?: Omit<UseQueryOptions<CustomerResponse, ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<CustomerResponse, ApiError>({
|
||||
queryKey: ordersKeys.customer(tenantId, customerId),
|
||||
queryFn: () => OrdersService.getCustomer(tenantId, customerId),
|
||||
staleTime: 5 * 60 * 1000, // 5 minutes
|
||||
enabled: !!tenantId && !!customerId,
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
// ===== Dashboard & Analytics Queries =====
|
||||
|
||||
export const useOrdersDashboard = (
|
||||
tenantId: string,
|
||||
options?: Omit<UseQueryOptions<OrdersDashboardSummary, ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<OrdersDashboardSummary, ApiError>({
|
||||
queryKey: ordersKeys.dashboard(tenantId),
|
||||
queryFn: () => OrdersService.getDashboardSummary(tenantId),
|
||||
staleTime: 1 * 60 * 1000, // 1 minute
|
||||
enabled: !!tenantId,
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
export const useDemandRequirements = (
|
||||
params: GetDemandRequirementsParams,
|
||||
options?: Omit<UseQueryOptions<DemandRequirements, ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<DemandRequirements, ApiError>({
|
||||
queryKey: ordersKeys.demandRequirements(params),
|
||||
queryFn: () => OrdersService.getDemandRequirements(params),
|
||||
staleTime: 30 * 60 * 1000, // 30 minutes
|
||||
enabled: !!params.tenant_id && !!params.target_date,
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
export const useBusinessModelDetection = (
|
||||
tenantId: string,
|
||||
options?: Omit<UseQueryOptions<BusinessModelDetection, ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<BusinessModelDetection, ApiError>({
|
||||
queryKey: ordersKeys.businessModel(tenantId),
|
||||
queryFn: () => OrdersService.detectBusinessModel(tenantId),
|
||||
staleTime: 60 * 60 * 1000, // 1 hour
|
||||
enabled: !!tenantId,
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
export const useOrdersServiceStatus = (
|
||||
tenantId: string,
|
||||
options?: Omit<UseQueryOptions<ServiceStatus, ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<ServiceStatus, ApiError>({
|
||||
queryKey: ordersKeys.status(tenantId),
|
||||
queryFn: () => OrdersService.getServiceStatus(tenantId),
|
||||
staleTime: 30 * 1000, // 30 seconds
|
||||
enabled: !!tenantId,
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
// ===== Order Mutations =====
|
||||
|
||||
export const useCreateOrder = (
|
||||
options?: UseMutationOptions<OrderResponse, ApiError, OrderCreate>
|
||||
) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<OrderResponse, ApiError, OrderCreate>({
|
||||
mutationFn: (orderData: OrderCreate) => OrdersService.createOrder(orderData),
|
||||
onSuccess: (data, variables) => {
|
||||
// Invalidate orders list for this tenant
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersKeys.orders(),
|
||||
predicate: (query) => {
|
||||
const queryKey = query.queryKey as string[];
|
||||
return queryKey.includes('list') &&
|
||||
JSON.stringify(queryKey).includes(variables.tenant_id);
|
||||
},
|
||||
});
|
||||
|
||||
// Invalidate dashboard
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersKeys.dashboard(variables.tenant_id),
|
||||
});
|
||||
|
||||
// Add the new order to cache
|
||||
queryClient.setQueryData(
|
||||
ordersKeys.order(variables.tenant_id, data.id),
|
||||
data
|
||||
);
|
||||
},
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
export const useUpdateOrderStatus = (
|
||||
options?: UseMutationOptions<OrderResponse, ApiError, UpdateOrderStatusParams>
|
||||
) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<OrderResponse, ApiError, UpdateOrderStatusParams>({
|
||||
mutationFn: (params: UpdateOrderStatusParams) => OrdersService.updateOrderStatus(params),
|
||||
onSuccess: (data, variables) => {
|
||||
// Update the specific order in cache
|
||||
queryClient.setQueryData(
|
||||
ordersKeys.order(variables.tenant_id, variables.order_id),
|
||||
data
|
||||
);
|
||||
|
||||
// Invalidate orders list for this tenant
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersKeys.orders(),
|
||||
predicate: (query) => {
|
||||
const queryKey = query.queryKey as string[];
|
||||
return queryKey.includes('list') &&
|
||||
JSON.stringify(queryKey).includes(variables.tenant_id);
|
||||
},
|
||||
});
|
||||
|
||||
// Invalidate dashboard
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersKeys.dashboard(variables.tenant_id),
|
||||
});
|
||||
},
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
// ===== Customer Mutations =====
|
||||
|
||||
export const useCreateCustomer = (
|
||||
options?: UseMutationOptions<CustomerResponse, ApiError, CustomerCreate>
|
||||
) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<CustomerResponse, ApiError, CustomerCreate>({
|
||||
mutationFn: (customerData: CustomerCreate) => OrdersService.createCustomer(customerData),
|
||||
onSuccess: (data, variables) => {
|
||||
// Invalidate customers list for this tenant
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersKeys.customers(),
|
||||
predicate: (query) => {
|
||||
const queryKey = query.queryKey as string[];
|
||||
return queryKey.includes('list') &&
|
||||
JSON.stringify(queryKey).includes(variables.tenant_id);
|
||||
},
|
||||
});
|
||||
|
||||
// Add the new customer to cache
|
||||
queryClient.setQueryData(
|
||||
ordersKeys.customer(variables.tenant_id, data.id),
|
||||
data
|
||||
);
|
||||
|
||||
// Invalidate dashboard (for customer metrics)
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersKeys.dashboard(variables.tenant_id),
|
||||
});
|
||||
},
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
export const useUpdateCustomer = (
|
||||
options?: UseMutationOptions<CustomerResponse, ApiError, { tenantId: string; customerId: string; data: CustomerUpdate }>
|
||||
) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<CustomerResponse, ApiError, { tenantId: string; customerId: string; data: CustomerUpdate }>({
|
||||
mutationFn: ({ tenantId, customerId, data }) => OrdersService.updateCustomer(tenantId, customerId, data),
|
||||
onSuccess: (data, variables) => {
|
||||
// Update the specific customer in cache
|
||||
queryClient.setQueryData(
|
||||
ordersKeys.customer(variables.tenantId, variables.customerId),
|
||||
data
|
||||
);
|
||||
|
||||
// Invalidate customers list for this tenant
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersKeys.customers(),
|
||||
predicate: (query) => {
|
||||
const queryKey = query.queryKey as string[];
|
||||
return queryKey.includes('list') &&
|
||||
JSON.stringify(queryKey).includes(variables.tenantId);
|
||||
},
|
||||
});
|
||||
},
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
// ===== Utility Functions =====
|
||||
|
||||
export const useInvalidateOrders = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return {
|
||||
invalidateAllOrders: (tenantId?: string) => {
|
||||
if (tenantId) {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersKeys.all,
|
||||
predicate: (query) => {
|
||||
return JSON.stringify(query.queryKey).includes(tenantId);
|
||||
},
|
||||
});
|
||||
} else {
|
||||
queryClient.invalidateQueries({ queryKey: ordersKeys.all });
|
||||
}
|
||||
},
|
||||
invalidateOrdersList: (tenantId: string) => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersKeys.orders(),
|
||||
predicate: (query) => {
|
||||
const queryKey = query.queryKey as string[];
|
||||
return queryKey.includes('list') &&
|
||||
JSON.stringify(queryKey).includes(tenantId);
|
||||
},
|
||||
});
|
||||
},
|
||||
invalidateCustomersList: (tenantId: string) => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersKeys.customers(),
|
||||
predicate: (query) => {
|
||||
const queryKey = query.queryKey as string[];
|
||||
return queryKey.includes('list') &&
|
||||
JSON.stringify(queryKey).includes(tenantId);
|
||||
},
|
||||
});
|
||||
},
|
||||
invalidateDashboard: (tenantId: string) => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersKeys.dashboard(tenantId),
|
||||
});
|
||||
},
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user