Improve the frontend and fix TODOs

This commit is contained in:
Urtzi Alfaro
2025-10-24 13:05:04 +02:00
parent 07c33fa578
commit 61376b7a9f
100 changed files with 8284 additions and 3419 deletions

View File

@@ -196,10 +196,24 @@ export const useStockMovements = (
offset: number = 0,
options?: Omit<UseQueryOptions<StockMovementResponse[], ApiError>, 'queryKey' | 'queryFn'>
) => {
// Validate UUID format if ingredientId is provided
const isValidUUID = (uuid?: string): boolean => {
if (!uuid) return true; // undefined/null is valid (means no filter)
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
return uuidRegex.test(uuid);
};
const validIngredientId = ingredientId && isValidUUID(ingredientId) ? ingredientId : undefined;
// Log warning if ingredient ID is invalid
if (ingredientId && !isValidUUID(ingredientId)) {
console.warn('[useStockMovements] Invalid ingredient ID format:', ingredientId);
}
return useQuery<StockMovementResponse[], ApiError>({
queryKey: inventoryKeys.stock.movements(tenantId, ingredientId),
queryFn: () => inventoryService.getStockMovements(tenantId, ingredientId, limit, offset),
enabled: !!tenantId,
queryKey: inventoryKeys.stock.movements(tenantId, validIngredientId),
queryFn: () => inventoryService.getStockMovements(tenantId, validIngredientId, limit, offset),
enabled: !!tenantId && (!ingredientId || isValidUUID(ingredientId)),
staleTime: 1 * 60 * 1000, // 1 minute
...options,
});

View File

@@ -230,7 +230,7 @@ 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,
@@ -243,4 +243,40 @@ export const useProductionPlanningData = (tenantId: string, date?: string) => {
requirements.refetch();
},
};
};
// ===== Scheduler Mutations =====
/**
* Hook to trigger production scheduler manually (for development/testing)
*/
export const useTriggerProductionScheduler = (
options?: UseMutationOptions<
{ success: boolean; message: string; tenant_id: string },
ApiError,
string
>
) => {
const queryClient = useQueryClient();
return useMutation<
{ success: boolean; message: string; tenant_id: string },
ApiError,
string
>({
mutationFn: (tenantId: string) => productionService.triggerProductionScheduler(tenantId),
onSuccess: (_, tenantId) => {
// Invalidate all production queries for this tenant
queryClient.invalidateQueries({
queryKey: productionKeys.dashboard(tenantId),
});
queryClient.invalidateQueries({
queryKey: productionKeys.batches(tenantId),
});
queryClient.invalidateQueries({
queryKey: productionKeys.activeBatches(tenantId),
});
},
...options,
});
};

View File

@@ -12,6 +12,7 @@ import {
TenantStatistics,
TenantSearchParams,
TenantNearbyParams,
AddMemberWithUserCreate,
} from '../types/tenant';
import { ApiError } from '../client';
@@ -247,16 +248,16 @@ export const useUpdateModelStatus = (
export const useAddTeamMember = (
options?: UseMutationOptions<
TenantMemberResponse,
ApiError,
TenantMemberResponse,
ApiError,
{ tenantId: string; userId: string; role: string }
>
) => {
const queryClient = useQueryClient();
return useMutation<
TenantMemberResponse,
ApiError,
TenantMemberResponse,
ApiError,
{ tenantId: string; userId: string; role: string }
>({
mutationFn: ({ tenantId, userId, role }) => tenantService.addTeamMember(tenantId, userId, role),
@@ -268,6 +269,30 @@ export const useAddTeamMember = (
});
};
export const useAddTeamMemberWithUserCreation = (
options?: UseMutationOptions<
TenantMemberResponse,
ApiError,
{ tenantId: string; memberData: AddMemberWithUserCreate }
>
) => {
const queryClient = useQueryClient();
return useMutation<
TenantMemberResponse,
ApiError,
{ tenantId: string; memberData: AddMemberWithUserCreate }
>({
mutationFn: ({ tenantId, memberData }) =>
tenantService.addTeamMemberWithUserCreation(tenantId, memberData),
onSuccess: (data, { tenantId }) => {
// Invalidate team members query
queryClient.invalidateQueries({ queryKey: tenantKeys.members(tenantId) });
},
...options,
});
};
export const useUpdateMemberRole = (
options?: UseMutationOptions<
TenantMemberResponse,