Add production APIs to frontend

This commit is contained in:
Urtzi Alfaro
2025-09-10 08:00:50 +02:00
parent aff644d793
commit 44b789f523
4 changed files with 657 additions and 0 deletions

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