added validation of recipes to editor

This commit is contained in:
Anika Raemer 2025-09-07 17:35:05 +02:00
parent 69b7920f23
commit 37057f19f1

View file

@ -14,11 +14,47 @@ type RecipeEditorProps = {
* ingredients (with amount, unit, name), instructions, and image URL.
*/
export default function RecipeEditor({ recipe, onSave, onCancel }: RecipeEditorProps) {
/** draft of the new recipe */
const [draft, setDraft] = useState<Recipe>(recipe)
/** Error list */
const [errors, setErrors] = useState<{ title?: boolean; ingredients?: boolean }>({})
/**
* Update ingredients
* @param ingredients new ingredients
*/
const updateIngredients = (ingredients: Ingredient[]) => {
setDraft({ ...draft, ingredients })
}
/**
* Validate recipe
* @returns Information on the errors the validation encountered
*/
const validate = () => {
const newErrors: { title?: boolean; ingredients?: boolean } = {}
// each recipe requires a title
if (!draft.title.trim()) {
newErrors.title = true
}
// the incredient list must not be empty
// @todo enhance validation and visualization of ingredient errors
if (!draft.ingredients || draft.ingredients.length === 0) {
newErrors.ingredients = true
}
setErrors(newErrors)
return Object.keys(newErrors).length === 0
}
/** Handles saving and ensures that the draft is only saved if valid */
const handleSave = (draft: Recipe) => {
if (validate()) {
onSave(draft)
}
}
// ensure that there is a recipe and show error otherwise
if (!recipe) return <div>Oops, there's no recipe in RecipeEditor...</div>
// @todo add handling of images
return (
@ -30,7 +66,7 @@ export default function RecipeEditor({ recipe, onSave, onCancel }: RecipeEditorP
{/* Title */}
<h3 className="subsection-heading">Title</h3>
<input
className="input-field"
className={`input-field ${errors.title ? "border-red-500" : ""}`}
placeholder="Title"
value={draft.title}
onChange={e => setDraft({ ...draft, title: e.target.value })}
@ -61,11 +97,13 @@ export default function RecipeEditor({ recipe, onSave, onCancel }: RecipeEditorP
}}
/>
</div>
{/* Ingredient List */}
{/* Ingredient List - @todo better visualization of errors! */}
<div className={errors.ingredients ? "border border-red-500 rounded p-2" : ""}>
<IngredientListEditor
ingredients={draft.ingredients}
onChange={updateIngredients}
/>
</div>
<h3 className="subsection-heading">Instructions</h3>
{/* Instructions */}
@ -80,7 +118,7 @@ export default function RecipeEditor({ recipe, onSave, onCancel }: RecipeEditorP
{/* Save Button */}
<button
className="primary-button"
onClick={() => onSave(draft)}
onClick={() => handleSave(draft)}
>
Save
</button>