diff --git a/frontend/src/components/domain/recipes/RecipeWizard/RecipeIngredientsStep.tsx b/frontend/src/components/domain/recipes/RecipeWizard/RecipeIngredientsStep.tsx new file mode 100644 index 00000000..3ad1d37d --- /dev/null +++ b/frontend/src/components/domain/recipes/RecipeWizard/RecipeIngredientsStep.tsx @@ -0,0 +1,212 @@ +import React from 'react'; +import { Package, Plus, Trash2 } from 'lucide-react'; +import type { WizardStepProps } from '../../../ui/WizardModal/WizardModal'; +import type { RecipeCreate, RecipeIngredientCreate, MeasurementUnit } from '../../../../api/types/recipes'; + +interface RecipeIngredientsStepProps extends WizardStepProps { + recipeData: Partial; + onUpdate: (data: Partial) => void; + availableIngredients: Array<{ value: string; label: string }>; + unitOptions: Array<{ value: MeasurementUnit; label: string }>; +} + +export const RecipeIngredientsStep: React.FC = ({ + recipeData, + onUpdate, + onNext, + onBack, + availableIngredients, + unitOptions +}) => { + const ingredients = recipeData.ingredients || []; + + const addIngredient = () => { + const newIngredient: RecipeIngredientCreate = { + ingredient_id: '', + quantity: 1, + unit: 'grams' as MeasurementUnit, + ingredient_order: ingredients.length + 1, + is_optional: false + }; + onUpdate({ ...recipeData, ingredients: [...ingredients, newIngredient] }); + }; + + const removeIngredient = (index: number) => { + if (ingredients.length > 1) { + const updated = ingredients.filter((_, i) => i !== index); + onUpdate({ ...recipeData, ingredients: updated }); + } + }; + + const updateIngredient = (index: number, field: keyof RecipeIngredientCreate, value: any) => { + const updated = ingredients.map((ing, i) => + i === index ? { ...ing, [field]: value } : ing + ); + onUpdate({ ...recipeData, ingredients: updated }); + }; + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + onNext(); + }; + + // Validation: at least one ingredient with valid data + const isValid = + ingredients.length > 0 && + ingredients.some((ing) => ing.ingredient_id && ing.ingredient_id.trim() !== '' && ing.quantity > 0); + + return ( +
+ {/* Header */} +
+
+ +
+
+

+ Ingredientes +

+

+ Agrega los ingredientes necesarios para esta receta +

+
+ +
+ + {/* Ingredients List */} +
+ {ingredients.length === 0 ? ( +
+ +

+ No hay ingredientes agregados +

+ +
+ ) : ( + ingredients.map((ingredient, index) => ( +
+ {/* Header */} +
+ + Ingrediente #{index + 1} + + +
+ + {/* Fields */} +
+ {/* Ingredient Selection */} +
+ + +
+ +
+ {/* Quantity */} +
+ + updateIngredient(index, 'quantity', parseFloat(e.target.value) || 0)} + className="w-full px-3 py-2 border border-[var(--border-secondary)] rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)] bg-[var(--bg-primary)] text-[var(--text-primary)] text-sm" + min="0" + step="0.1" + required + /> +
+ + {/* Unit */} +
+ + +
+ + {/* Optional Checkbox */} +
+ +
+
+
+
+ )) + )} +
+ + {/* Validation Message */} + {!isValid && ingredients.length > 0 && ( +
+

+ ⚠️ Atención: Asegúrate de seleccionar al menos un ingrediente con cantidad válida. +

+
+ )} + + {/* Hidden submit button for form handling */} +