diff --git a/web/src/components/forms/IngredientItem.tsx b/web/src/components/forms/IngredientItem.tsx new file mode 100644 index 0000000..5a83c3e --- /dev/null +++ b/web/src/components/forms/IngredientItem.tsx @@ -0,0 +1,17 @@ +import type { RecipeIngredient } from "../../types/recipe"; + +interface IngredientItemProps { + ingredient: RecipeIngredient; + onChange: (id: string, name: string) => void; +} + +export default function IngredientItem({ ingredient, onChange }: IngredientItemProps) { + return ( + onChange(ingredient.Id, e.target.value)} + placeholder="Ingredient name" + /> + ); +} diff --git a/web/src/components/forms/IngredientList.tsx b/web/src/components/forms/IngredientList.tsx new file mode 100644 index 0000000..160506b --- /dev/null +++ b/web/src/components/forms/IngredientList.tsx @@ -0,0 +1,59 @@ +import type { Dispatch, SetStateAction } from "react"; +import { type IngredientId, type IngredientsById, type RecipeIngredient, type RecipeIngredientSection, type SectionsById } from "../../types/recipe"; +import IngredientSectionElement from "./IngredientSectionElement"; +import { Reorder } from "motion/react"; + + +interface IngredientListProps { +} + +export default function IngredientList({ sectionOrder, setSectionOrder, sectionsById, ingredientsById, setIngredientsById }: IngredientListProps) { + const handleIngredientChange = ( + ingredientId: IngredientId, + field: "Name" | "Amount" | "Unit", + value: string + ) => { + setIngredientsById(prev => { + const ing = prev[ingredientId]; + if (!ing) return prev; + + const updated: RecipeIngredient = { + ...ing, + [field]: + field === "Amount" + ? (value === "" ? 0 : Number(value)) + : value, + }; + + // If nothing changed, keep same reference + if (updated === ing) return prev; + + return { ...prev, [ingredientId]: updated }; + }); + }; + + return ( + <> + + {sectionOrder.map(sectionId => { + const section = sectionsById[sectionId]; + console.log("@section", section); + return ( + + + + + ) + })} + + + ); +} diff --git a/web/src/components/forms/IngredientSection.tsx b/web/src/components/forms/IngredientSection.tsx new file mode 100644 index 0000000..522a8a4 --- /dev/null +++ b/web/src/components/forms/IngredientSection.tsx @@ -0,0 +1,36 @@ +import type { DragControls } from "motion/react"; +import type { RecipeIngredientSection } from "../../types/recipe"; +import DeleteIconSmall from "../icons/DeleteIconSmall"; +import DragIconSmall from "../icons/DragIconSmall"; + +interface IngredientSectionProps { + section: RecipeIngredientSection; + onChange: (id: string, name: string) => void; + index: number; + controls: DragControls; +}; + +export default function IngredientSection({ section, onChange, index, controls }: IngredientSectionProps) { + return ( +
+

Group:

+ onChange(section.Id, e.target.value)} + placeholder="Section title" + className="mx-2 px-2 py-1 border border-gray-300 flex-grow rounded-sm" + /> + +
+ +
controls.start(e)}> + +
+ +
+
+ ); +} diff --git a/web/src/components/forms/InstructionElement.tsx b/web/src/components/forms/InstructionElement.tsx index 933ca95..919143f 100644 --- a/web/src/components/forms/InstructionElement.tsx +++ b/web/src/components/forms/InstructionElement.tsx @@ -1,10 +1,11 @@ import { useEffect, useState, type ChangeEvent } from "react"; -import type { Instruction } from "../../pages/Create"; +import type { RecipeInstruction } from "../../types/recipe"; import { Reorder, useDragControls } from "motion/react"; import DragIconSmall from "../icons/DragIconSmall"; +import DeleteIconSmall from "../icons/DeleteIconSmall"; interface InstructionElementProps { - instruction: Instruction; + instruction: RecipeInstruction; index: number; allowDelete: boolean; onChange: (id: string, value: string) => void; @@ -22,13 +23,13 @@ export default function InstructionElement({ instruction, index, allowDelete, on // No need to set many times if (!dirty) setDirty(true); - onChange(instruction.id, e.target.value); + onChange(instruction.Id, e.target.value); } // EFFECTS useEffect(() => { if (dirty) - setValid(instruction.content !== ""); + setValid(instruction.Content !== ""); }, [dirty, instruction]); return ( @@ -44,7 +45,7 @@ export default function InstructionElement({ instruction, index, allowDelete, on