Add production APIs to frontend
This commit is contained in:
243
frontend/src/api/hooks/production.ts
Normal file
243
frontend/src/api/hooks/production.ts
Normal file
@@ -0,0 +1,243 @@
|
||||
/**
|
||||
* Production React Query hooks
|
||||
*/
|
||||
import { useMutation, useQuery, useQueryClient, UseQueryOptions, UseMutationOptions } from '@tanstack/react-query';
|
||||
import { productionService } from '../services/production';
|
||||
import type {
|
||||
ProductionBatchCreate,
|
||||
ProductionBatchStatusUpdate,
|
||||
ProductionBatchResponse,
|
||||
ProductionBatchListResponse,
|
||||
ProductionDashboardSummary,
|
||||
DailyProductionRequirements,
|
||||
ProductionScheduleData,
|
||||
ProductionCapacityStatus,
|
||||
ProductionRequirements,
|
||||
ProductionYieldMetrics,
|
||||
} from '../types/production';
|
||||
import { ApiError } from '../client';
|
||||
|
||||
// Query Keys
|
||||
export const productionKeys = {
|
||||
all: ['production'] as const,
|
||||
tenant: (tenantId: string) => [...productionKeys.all, tenantId] as const,
|
||||
dashboard: (tenantId: string) => [...productionKeys.tenant(tenantId), 'dashboard'] as const,
|
||||
dailyRequirements: (tenantId: string, date?: string) =>
|
||||
[...productionKeys.tenant(tenantId), 'daily-requirements', date] as const,
|
||||
requirements: (tenantId: string, date?: string) =>
|
||||
[...productionKeys.tenant(tenantId), 'requirements', date] as const,
|
||||
batches: (tenantId: string) => [...productionKeys.tenant(tenantId), 'batches'] as const,
|
||||
activeBatches: (tenantId: string) => [...productionKeys.batches(tenantId), 'active'] as const,
|
||||
batch: (tenantId: string, batchId: string) =>
|
||||
[...productionKeys.batches(tenantId), batchId] as const,
|
||||
schedule: (tenantId: string, startDate?: string, endDate?: string) =>
|
||||
[...productionKeys.tenant(tenantId), 'schedule', startDate, endDate] as const,
|
||||
capacity: (tenantId: string, date?: string) =>
|
||||
[...productionKeys.tenant(tenantId), 'capacity', date] as const,
|
||||
yieldMetrics: (tenantId: string, startDate: string, endDate: string) =>
|
||||
[...productionKeys.tenant(tenantId), 'yield-metrics', startDate, endDate] as const,
|
||||
} as const;
|
||||
|
||||
// Dashboard Queries
|
||||
export const useProductionDashboard = (
|
||||
tenantId: string,
|
||||
options?: Omit<UseQueryOptions<ProductionDashboardSummary, ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<ProductionDashboardSummary, ApiError>({
|
||||
queryKey: productionKeys.dashboard(tenantId),
|
||||
queryFn: () => productionService.getDashboardSummary(tenantId),
|
||||
enabled: !!tenantId,
|
||||
staleTime: 30 * 1000, // 30 seconds
|
||||
refetchInterval: 60 * 1000, // 1 minute
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
export const useDailyProductionRequirements = (
|
||||
tenantId: string,
|
||||
date?: string,
|
||||
options?: Omit<UseQueryOptions<DailyProductionRequirements, ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<DailyProductionRequirements, ApiError>({
|
||||
queryKey: productionKeys.dailyRequirements(tenantId, date),
|
||||
queryFn: () => productionService.getDailyRequirements(tenantId, date),
|
||||
enabled: !!tenantId,
|
||||
staleTime: 5 * 60 * 1000, // 5 minutes
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
export const useProductionRequirements = (
|
||||
tenantId: string,
|
||||
date?: string,
|
||||
options?: Omit<UseQueryOptions<ProductionRequirements, ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<ProductionRequirements, ApiError>({
|
||||
queryKey: productionKeys.requirements(tenantId, date),
|
||||
queryFn: () => productionService.getProductionRequirements(tenantId, date),
|
||||
enabled: !!tenantId,
|
||||
staleTime: 5 * 60 * 1000, // 5 minutes
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
// Batch Queries
|
||||
export const useActiveBatches = (
|
||||
tenantId: string,
|
||||
options?: Omit<UseQueryOptions<ProductionBatchListResponse, ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<ProductionBatchListResponse, ApiError>({
|
||||
queryKey: productionKeys.activeBatches(tenantId),
|
||||
queryFn: () => productionService.getActiveBatches(tenantId),
|
||||
enabled: !!tenantId,
|
||||
staleTime: 30 * 1000, // 30 seconds
|
||||
refetchInterval: 60 * 1000, // 1 minute
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
export const useBatchDetails = (
|
||||
tenantId: string,
|
||||
batchId: string,
|
||||
options?: Omit<UseQueryOptions<ProductionBatchResponse, ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<ProductionBatchResponse, ApiError>({
|
||||
queryKey: productionKeys.batch(tenantId, batchId),
|
||||
queryFn: () => productionService.getBatchDetails(tenantId, batchId),
|
||||
enabled: !!tenantId && !!batchId,
|
||||
staleTime: 30 * 1000, // 30 seconds
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
// Schedule and Capacity Queries
|
||||
export const useProductionSchedule = (
|
||||
tenantId: string,
|
||||
startDate?: string,
|
||||
endDate?: string,
|
||||
options?: Omit<UseQueryOptions<ProductionScheduleData, ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<ProductionScheduleData, ApiError>({
|
||||
queryKey: productionKeys.schedule(tenantId, startDate, endDate),
|
||||
queryFn: () => productionService.getProductionSchedule(tenantId, startDate, endDate),
|
||||
enabled: !!tenantId,
|
||||
staleTime: 5 * 60 * 1000, // 5 minutes
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
export const useCapacityStatus = (
|
||||
tenantId: string,
|
||||
date?: string,
|
||||
options?: Omit<UseQueryOptions<ProductionCapacityStatus, ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<ProductionCapacityStatus, ApiError>({
|
||||
queryKey: productionKeys.capacity(tenantId, date),
|
||||
queryFn: () => productionService.getCapacityStatus(tenantId, date),
|
||||
enabled: !!tenantId,
|
||||
staleTime: 5 * 60 * 1000, // 5 minutes
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
export const useYieldMetrics = (
|
||||
tenantId: string,
|
||||
startDate: string,
|
||||
endDate: string,
|
||||
options?: Omit<UseQueryOptions<ProductionYieldMetrics, ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<ProductionYieldMetrics, ApiError>({
|
||||
queryKey: productionKeys.yieldMetrics(tenantId, startDate, endDate),
|
||||
queryFn: () => productionService.getYieldMetrics(tenantId, startDate, endDate),
|
||||
enabled: !!tenantId && !!startDate && !!endDate,
|
||||
staleTime: 15 * 60 * 1000, // 15 minutes (metrics are less frequently changing)
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
// Mutations
|
||||
export const useCreateProductionBatch = (
|
||||
options?: UseMutationOptions<ProductionBatchResponse, ApiError, { tenantId: string; batchData: ProductionBatchCreate }>
|
||||
) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<ProductionBatchResponse, ApiError, { tenantId: string; batchData: ProductionBatchCreate }>({
|
||||
mutationFn: ({ tenantId, batchData }) => productionService.createProductionBatch(tenantId, batchData),
|
||||
onSuccess: (data, { tenantId }) => {
|
||||
// Invalidate active batches to refresh the list
|
||||
queryClient.invalidateQueries({ queryKey: productionKeys.activeBatches(tenantId) });
|
||||
// Invalidate dashboard to update summary
|
||||
queryClient.invalidateQueries({ queryKey: productionKeys.dashboard(tenantId) });
|
||||
// Cache the new batch details
|
||||
queryClient.setQueryData(productionKeys.batch(tenantId, data.id), data);
|
||||
},
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
export const useUpdateBatchStatus = (
|
||||
options?: UseMutationOptions<
|
||||
ProductionBatchResponse,
|
||||
ApiError,
|
||||
{ tenantId: string; batchId: string; statusUpdate: ProductionBatchStatusUpdate }
|
||||
>
|
||||
) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<
|
||||
ProductionBatchResponse,
|
||||
ApiError,
|
||||
{ tenantId: string; batchId: string; statusUpdate: ProductionBatchStatusUpdate }
|
||||
>({
|
||||
mutationFn: ({ tenantId, batchId, statusUpdate }) =>
|
||||
productionService.updateBatchStatus(tenantId, batchId, statusUpdate),
|
||||
onSuccess: (data, { tenantId, batchId }) => {
|
||||
// Update the specific batch data
|
||||
queryClient.setQueryData(productionKeys.batch(tenantId, batchId), data);
|
||||
// Invalidate active batches to refresh the list
|
||||
queryClient.invalidateQueries({ queryKey: productionKeys.activeBatches(tenantId) });
|
||||
// Invalidate dashboard to update summary
|
||||
queryClient.invalidateQueries({ queryKey: productionKeys.dashboard(tenantId) });
|
||||
},
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
// Helper hooks for common use cases
|
||||
export const useProductionDashboardData = (tenantId: string) => {
|
||||
const dashboard = useProductionDashboard(tenantId);
|
||||
const activeBatches = useActiveBatches(tenantId);
|
||||
const dailyRequirements = useDailyProductionRequirements(tenantId);
|
||||
|
||||
return {
|
||||
dashboard: dashboard.data,
|
||||
activeBatches: activeBatches.data,
|
||||
dailyRequirements: dailyRequirements.data,
|
||||
isLoading: dashboard.isLoading || activeBatches.isLoading || dailyRequirements.isLoading,
|
||||
error: dashboard.error || activeBatches.error || dailyRequirements.error,
|
||||
refetch: () => {
|
||||
dashboard.refetch();
|
||||
activeBatches.refetch();
|
||||
dailyRequirements.refetch();
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const useProductionPlanningData = (tenantId: string, date?: string) => {
|
||||
const schedule = useProductionSchedule(tenantId);
|
||||
const capacity = useCapacityStatus(tenantId, date);
|
||||
const requirements = useProductionRequirements(tenantId, date);
|
||||
|
||||
return {
|
||||
schedule: schedule.data,
|
||||
capacity: capacity.data,
|
||||
requirements: requirements.data,
|
||||
isLoading: schedule.isLoading || capacity.isLoading || requirements.isLoading,
|
||||
error: schedule.error || capacity.error || requirements.error,
|
||||
refetch: () => {
|
||||
schedule.refetch();
|
||||
capacity.refetch();
|
||||
requirements.refetch();
|
||||
},
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user