Add frontend order API

This commit is contained in:
Urtzi Alfaro
2025-09-09 08:30:06 +02:00
parent 5269a083b6
commit bc3d0ff90c
4 changed files with 844 additions and 0 deletions

View 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),
});
},
};
};