Add component for ingredient group list item
This commit is contained in:
parent
7c01ed5894
commit
4290b02ca7
3 changed files with 79 additions and 30 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)}
|
||||
/>
|
||||
<Button
|
||||
onClick={() => handleRemove(index)}
|
||||
text={"Gruppe entfernen"}
|
||||
buttonType={ButtonType.DarkButton}
|
||||
/>
|
||||
</div>
|
||||
<IngredientListEditor
|
||||
ingredients={ingGrp.ingredientList}
|
||||
onChange={list => updateIngredientList(index, list)}
|
||||
/>
|
||||
</div>
|
||||
<IngredientGroupListItem
|
||||
index={index}
|
||||
ingredientGroupModel={ingGrp}
|
||||
handleUpdate={handleUpdate}
|
||||
handleRemove={handleRemove}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<Button
|
||||
|
|
|
|||
54
frontend/src/components/recipes/IngredientGroupListItem.tsx
Normal file
54
frontend/src/components/recipes/IngredientGroupListItem.tsx
Normal 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>
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue