diff --git a/frontend/src/components/basics/MoveButtonControl.tsx b/frontend/src/components/basics/MoveButtonControl.tsx
new file mode 100644
index 0000000..a8b60b0
--- /dev/null
+++ b/frontend/src/components/basics/MoveButtonControl.tsx
@@ -0,0 +1,36 @@
+import Button from "./Button.tsx";
+import {ArrowDown, ArrowUp} from "lucide-react";
+import {ButtonType} from "./BasicButtonDefinitions.ts";
+
+type MoveButtonControlProps = {
+ isUpDisabled: boolean;
+ isDownDisabled: boolean;
+ onMoveUp(): void;
+ onMoveDown(): void;
+}
+
+/**
+ * Up and down buttons for reordering list items when not using drag & drop, e.g., on mobile devices.
+ * @param isUpDisabled Indicates whether the up button is enabled
+ * @param isDownDisabled Indicates whether the down button is enabled
+ * @param onMoveUp Method to call when move up is clicked
+ * @param onMoveDown Method to call when move down is clicked
+ */
+export function MoveButtonControl({isUpDisabled, isDownDisabled, onMoveUp, onMoveDown}: MoveButtonControlProps) {
+ return (
+
+
+ );
+}
\ No newline at end of file
diff --git a/frontend/src/components/recipes/InstructionStepListDesktopEditor.tsx b/frontend/src/components/recipes/InstructionStepListDesktopEditor.tsx
index da99ab3..e4cc784 100644
--- a/frontend/src/components/recipes/InstructionStepListDesktopEditor.tsx
+++ b/frontend/src/components/recipes/InstructionStepListDesktopEditor.tsx
@@ -1,7 +1,3 @@
-/**
- * Desktop editor using drag-and-drop via @dnd-kit
- */
-
import {closestCenter, DndContext, PointerSensor, useSensor, useSensors,} from "@dnd-kit/core";
import {arrayMove, SortableContext, verticalListSortingStrategy,} from "@dnd-kit/sortable";
import type {InstructionStepModel} from "../../models/InstructionStepModel";
@@ -16,10 +12,19 @@ type InstructionStepListDesktopEditorProps = {
onChange: (steps: InstructionStepModel[]) => void;
};
+/**
+ * Desktop editor using drag-and-drop via @dnd-kit
+ * @param instructionStepList List instruction step models
+ * @param onChange Method to call on any change to the list
+ * @constructor
+ */
export function InstructionStepListDesktopEditor({
instructionStepList,
onChange,
}: InstructionStepListDesktopEditorProps) {
+ /* Import methods for handling update of instruction steps as well as adding and removing steps.
+ * Those methods are shared by all versions of the instruction step editor, e.g., mobile and desktop.
+ */
const {handleUpdate, handleAdd, handleRemove} = instructionStepListEditorMethods(
instructionStepList,
onChange
@@ -27,6 +32,9 @@ export function InstructionStepListDesktopEditor({
const sensors = useSensors(useSensor(PointerSensor, {activationConstraint: {distance: 8}}));
+ /**
+ * Handle the drag end event and reorder list
+ */
const handleDragEnd = (event: any) => {
const {active, over} = event;
if (active.id !== over.id) {
diff --git a/frontend/src/components/recipes/InstructionStepListMobileEditor.tsx b/frontend/src/components/recipes/InstructionStepListMobileEditor.tsx
index c471842..e3977ce 100644
--- a/frontend/src/components/recipes/InstructionStepListMobileEditor.tsx
+++ b/frontend/src/components/recipes/InstructionStepListMobileEditor.tsx
@@ -1,7 +1,3 @@
-/**
- * Mobile editor using Up/Down buttons for reordering
- */
-
import {Plus} from "lucide-react";
import type {InstructionStepModel} from "../../models/InstructionStepModel";
import Button from "../basics/Button";
@@ -14,15 +10,28 @@ type InstructionStepListEditorMobileProps = {
onChange: (steps: InstructionStepModel[]) => void;
};
+/**
+ * Mobile editor using Up/Down buttons for reordering
+ * @param instructionStepList List instruction step models
+ * @param onChange Method to call on any change to the list
+ */
export function InstructionStepListMobileEditor({
instructionStepList,
onChange,
}: InstructionStepListEditorMobileProps) {
+ /* Import methods for handling update of instruction steps as well as adding and removing steps.
+ * Those methods are shared by all versions of the instruction step editor, e.g., mobile and desktop.
+ */
const {handleUpdate, handleAdd, handleRemove} = instructionStepListEditorMethods(
instructionStepList,
onChange
);
+ /**
+ * Move an instruction step either up or down in list.
+ * @param index Current index of the step to move
+ * @param direction Direction to move the step in. Either "up" or "down".
+ */
const moveStep = (index: number, direction: "up" | "down") => {
const newIndex = direction === "up" ? index - 1 : index + 1;
if (newIndex < 0 || newIndex >= instructionStepList.length) return;
@@ -35,11 +44,13 @@ export function InstructionStepListMobileEditor({
return (
Zubereitung
+
+ {/* Instruction list */}
{instructionStepList.map((step, index) => (
))}
+
+ {/* Button for adding an additional instruction step */}
void;
+ /**
+ * Method to call on updating the instruction step.
+ * @param index Index of the step to be updated.
+ * @param instructionText new instruction text
+ */
+ onUpdate: (index: number, instructionText: string) => void;
+ /**
+ * Method to call on removing the instruction step.
+ * @param index Index of the instruction step to be removed.
+ */
onRemove: (index: number) => void;
+ /** Indicates whether this is the first instruction step. Used to restrict movement. */
isFirst: boolean;
+ /** Indicates whether this is the last instruction step. Used to restrict movement. */
isLast: boolean;
};
+/**
+ * Numbered list item for instructions step list editor for mobile devices.
+ *
+ * Describes a single instruction step of a recipe. As drag & drop usually is a bit clumsy on
+ * mobile devices, the steps can be reordered with small up and down buttons below the step number.
+ * @param index Index of this instruction step
+ * @param stepModel Model containing the data for the current instruction step, e.g., instruction text.
+ * @param onMove Method to call on moving the instruction step.
+ * @param onUpdate Method to call on updating the instruction step.
+ * @param onRemove Method to call on removing the instruction step.
+ * @param isFirst Indicates whether this is the first instruction step. In this case, the step cannot be moved up.
+ * @param isLast Indicates whether this is the last instruction step. In this case, the step cannot be moved down.
+ */
export function InstructionStepMobileListItem({
index,
- step,
+ stepModel,
onMove,
onUpdate,
onRemove,
@@ -24,33 +56,27 @@ export function InstructionStepMobileListItem({
}: InstructionStepMobileListItemProps) {
return (
+ {/* Left column: Number of the instruction step and move controls */}
{index + 1}
-
- onMove(index, "up")}
- buttonType={ButtonType.TransparentButton}
- disabled={isFirst} // disable if first item
- />
- onMove(index, "down")}
- buttonType={ButtonType.TransparentButton}
- disabled={isLast} // disable if last item
- />
-