New alert service

This commit is contained in:
Urtzi Alfaro
2025-12-05 20:07:01 +01:00
parent 1fe3a73549
commit 667e6e0404
393 changed files with 26002 additions and 61033 deletions

View File

@@ -28,9 +28,8 @@ export const IncompleteIngredientsAlert: React.FC = () => {
}
const handleViewIncomplete = () => {
// Navigate to inventory page
// TODO: In the future, this could pass a filter parameter to show only incomplete items
navigate('/app/operations/inventory');
// Navigate to inventory page with filter to show only incomplete items
navigate('/app/operations/inventory?filter=incomplete&needs_review=true');
};
return (

View File

@@ -12,6 +12,7 @@ import type { RecipeResponse } from '../../../api/types/recipes';
import { useTranslation } from 'react-i18next';
import { useRecipes } from '../../../api/hooks/recipes';
import { useIngredients } from '../../../api/hooks/inventory';
import { useEquipment } from '../../../api/hooks/equipment';
import { recipesService } from '../../../api/services/recipes';
import { useCurrentTenant } from '../../../stores/tenant.store';
import { statusColors } from '../../../styles/colors';
@@ -41,6 +42,7 @@ export const CreateProductionBatchModal: React.FC<CreateProductionBatchModalProp
// API Data
const { data: recipes = [], isLoading: recipesLoading } = useRecipes(tenantId);
const { data: ingredients = [], isLoading: ingredientsLoading } = useIngredients(tenantId);
const { data: equipmentData, isLoading: equipmentLoading } = useEquipment(tenantId, { is_active: true });
// Stage labels for display
const STAGE_LABELS: Record<ProcessStage, string> = {
@@ -91,6 +93,14 @@ export const CreateProductionBatchModal: React.FC<CreateProductionBatchModalProp
label: recipe.name
})), [recipes]);
const equipmentOptions = useMemo(() => {
if (!equipmentData?.equipment) return [];
return equipmentData.equipment.map(equip => ({
value: equip.id,
label: `${equip.name} (${equip.equipment_code || equip.id.substring(0, 8)})`
}));
}, [equipmentData]);
const handleSave = async (formData: Record<string, any>) => {
// Validate that end time is after start time
const startTime = new Date(formData.planned_start_time);
@@ -111,6 +121,11 @@ export const CreateProductionBatchModal: React.FC<CreateProductionBatchModalProp
? formData.staff_assigned.split(',').map((s: string) => s.trim()).filter((s: string) => s.length > 0)
: [];
// Convert equipment_used from comma-separated string to array
const equipmentArray = formData.equipment_used
? formData.equipment_used.split(',').map((e: string) => e.trim()).filter((e: string) => e.length > 0)
: [];
const batchData: ProductionBatchCreate = {
product_id: formData.product_id,
product_name: selectedProduct?.name || '',
@@ -126,7 +141,7 @@ export const CreateProductionBatchModal: React.FC<CreateProductionBatchModalProp
batch_number: formData.batch_number || '',
order_id: formData.order_id || '',
forecast_id: formData.forecast_id || '',
equipment_used: [], // TODO: Add equipment selection if needed
equipment_used: equipmentArray,
staff_assigned: staffArray,
station_id: formData.station_id || ''
};
@@ -271,6 +286,16 @@ export const CreateProductionBatchModal: React.FC<CreateProductionBatchModalProp
title: 'Recursos y Notas',
icon: Users,
fields: [
{
label: 'Equipos a Utilizar',
name: 'equipment_used',
type: 'text' as const,
placeholder: 'Separar IDs de equipos con comas (opcional)',
span: 2,
helpText: equipmentOptions.length > 0
? `Equipos disponibles: ${equipmentOptions.map(e => e.label).join(', ')}`
: 'No hay equipos activos disponibles'
},
{
label: 'Personal Asignado',
name: 'staff_assigned',
@@ -288,7 +313,7 @@ export const CreateProductionBatchModal: React.FC<CreateProductionBatchModalProp
}
]
}
], [productOptions, recipeOptions, t]);
], [productOptions, recipeOptions, equipmentOptions, t]);
// Quality Requirements Preview Component
const qualityRequirementsPreview = selectedRecipe && (