Add component for ingredient group list item

This commit is contained in:
araemer 2025-10-25 08:35:06 +02:00
parent 7c01ed5894
commit 4290b02ca7
3 changed files with 79 additions and 30 deletions

View file

@ -73,10 +73,6 @@
@apply list-disc pl-6 mb-6;
}
.ingredient-group-card {
@apply pb-4 border-b border-gray-400;
}
/* containers */
.circular-container {
@apply flex-shrink-0 w-7 h-7 rounded-full bg-blue-300 text-white flex items-center justify-center shadow-sm;

View file

@ -1,34 +1,45 @@
/**
* Editor for ingredient groups
*/
import type {IngredientModel} from "../../models/IngredientModel"
import type {IngredientGroupModel} from "../../models/IngredientGroupModel"
import Button from "../basics/Button"
import {IngredientListEditor} from "./IngredientListEditor"
import {Plus} from "lucide-react"
import {ButtonType} from "../basics/BasicButtonDefinitions"
import IngredientGroupListItem from "./IngredientGroupListItem.tsx";
type IngredientGroupListEditorProps = {
ingredientGroupList: IngredientGroupModel[]
onChange: (ingredientGroupList: IngredientGroupModel[]) => void
}
/**
* Editor for ingredient groups
* @param ingredientGroupList List model containing ingredient groups
* @param onChange Method to call on change
*/
export function IngredientGroupListEditor({ingredientGroupList, onChange}: IngredientGroupListEditorProps) {
/**
* Update a member of the ingredient group list
* @param index Index of the ingredient group to change
* @param field Field name to change
* @param value New value
*/
const handleUpdate = (index: number, field: keyof IngredientGroupModel, value: string | IngredientModel[]) => {
const updated = ingredientGroupList.map((ingGrp, i) =>
i === index ? {...ingGrp, [field]: value} : ingGrp
)
onChange(updated)
}
const updateIngredientList = (index: number, ingredientList: IngredientModel[]) => {
handleUpdate(index, "ingredientList", ingredientList)
}
/**
* Add a new ingredient group to the list
*/
const handleAdd = () => {
onChange([...ingredientGroupList, {title: "", ingredientList: []}])
}
/**
* Remove an ingredient group from the list
* @param index Index of the group to remove
*/
const handleRemove = (index: number) => {
onChange(ingredientGroupList.filter((_, i) => i !== index))
}
@ -37,24 +48,12 @@ export function IngredientGroupListEditor({ingredientGroupList, onChange}: Ingre
<h2>Zutaten</h2>
<div>
{ingredientGroupList.map((ingGrp, index) => (
<div key={index} className="ingredient-group-card mb-4">
<div className="horizontal-input-group columns-2">
<input
placeholder="Titel (Optional)"
value={ingGrp.title}
onChange={e => handleUpdate(index, "title", e.target.value)}
<IngredientGroupListItem
index={index}
ingredientGroupModel={ingGrp}
handleUpdate={handleUpdate}
handleRemove={handleRemove}
/>
<Button
onClick={() => handleRemove(index)}
text={"Gruppe entfernen"}
buttonType={ButtonType.DarkButton}
/>
</div>
<IngredientListEditor
ingredients={ingGrp.ingredientList}
onChange={list => updateIngredientList(index, list)}
/>
</div>
))}
</div>
<Button

View file

@ -0,0 +1,54 @@
import Button from "../basics/Button.tsx";
import {ButtonType} from "../basics/BasicButtonDefinitions.ts";
import {IngredientListEditor} from "./IngredientListEditor.tsx";
import type {IngredientGroupModel} from "../../models/IngredientGroupModel.ts";
import type {IngredientModel} from "../../models/IngredientModel.ts";
type IngredientGroupListItemProps = {
/** The list item's index */
index: number
/** Model containing data for ingredient group */
ingredientGroupModel: IngredientGroupModel
/** Model containing data for ingredient group */
handleUpdate(index: number, field: keyof IngredientGroupModel, value: string | IngredientModel[]): void
/** Method for removing group */
handleRemove(index: number): void
}
/**
* List item representing an ingredient group
* @param index The list item's index
* @param ingredientGroupModel Model containing data for ingredient group
* @param handleUpdate Model containing data for ingredient group
* @param handleRemove Method for removing group
*/
export default function IngredientGroupListItem({
index,
ingredientGroupModel,
handleUpdate,
handleRemove
}: IngredientGroupListItemProps) {
const updateIngredientList = (index: number, ingredientList: IngredientModel[]) => {
handleUpdate(index, "ingredientList", ingredientList)
}
return (
<div key={index} className="pb-4 border-b border-gray-400 mb-4">
<div className="horizontal-input-group columns-2">
<input
placeholder="Titel (Optional)"
value={ingredientGroupModel.title}
onChange={e => handleUpdate(index, "title", e.target.value)}
/>
<Button
onClick={() => handleRemove(index)}
text={"Gruppe entfernen"}
buttonType={ButtonType.DarkButton}
/>
</div>
<IngredientListEditor
ingredients={ingredientGroupModel.ingredientList}
onChange={list => updateIngredientList(index, list)}
/>
</div>
)
}