From eb11cdae2d7588fb2f812b3222d6d87f2cbbe66c Mon Sep 17 00:00:00 2001 From: Katja Lutz Date: Wed, 22 Jun 2022 21:50:00 +0200 Subject: [PATCH] feat: implement Positions settings component --- src/components/Settings/Positions.tsx | 413 ++++++++++++++++++++++++++ 1 file changed, 413 insertions(+) create mode 100644 src/components/Settings/Positions.tsx diff --git a/src/components/Settings/Positions.tsx b/src/components/Settings/Positions.tsx new file mode 100644 index 0000000..6783335 --- /dev/null +++ b/src/components/Settings/Positions.tsx @@ -0,0 +1,413 @@ +import { + JSX, + Component, + For, + useContext, + startTransition, + Show, + splitProps, +} from "solid-js"; +import { produce, unwrap } from "solid-js/store"; +import { autoAnimate } from "~/directives/autoAnimate"; +import { sortable } from "~/directives/sortable"; +import { + LocalStoreContext, + Position, + POSITION_TYPE_AGILE, + POSITION_TYPE_QUANTITY, + StoreContext, + UiStoreContext, +} from "~/stores"; +import AddIcon from "~icons/carbon/add-filled"; +import DeleteIcon from "~icons/carbon/trash-can"; +import DragVerticalIcon from "~icons/carbon/drag-vertical"; +import PositionSettingsIcon from "~icons/carbon/settings-adjust"; +import { Checkbox, TextArea, TextInput } from "../Form"; +import { parseOptionalFloat } from "~/util"; +import { MarkdownHelpLabel } from "../Markdown"; + +export const PositionsSettings: Component = () => { + const [state, setState] = useContext(StoreContext)!; + const [uiState, setUiState] = useContext(UiStoreContext)!; + + autoAnimate; + sortable; + + const AddPositionButton: Component<{ idx?: number }> = (props) => ( + + ); + + return ( + <> +
{ + setState( + "positions", + produce((positions: any[]) => { + const oldIndex = evt.oldIndex; + const newIndex = evt.newIndex; + let item = positions[oldIndex]; + positions.splice(oldIndex, 1); + positions.splice(newIndex, 0, unwrap(item)); + }) + ); + }, + }} + > + + {(position, idx) => { + let nameInputRef: HTMLInputElement = undefined!; + let positionNumberInputRef: HTMLInputElement = undefined!; + let onEnterKeyClose: JSX.EventHandler< + HTMLInputElement, + KeyboardEvent + > = (e) => { + if (e.code !== "Enter") { + return; + } + + setUiState("selectedPosition", undefined); + }; + + const AgileDropdown: Component< + { selected: number } & JSX.HTMLAttributes + > = (p) => { + const [props, rest] = splitProps(p, ["selected", "class"]); + return ( + + ); + }; + + return ( +
+
+
+ +
+
+
+
+
+
+
{ + await startTransition(function () { + setUiState("selectedPosition", position.id); + }); + if (positionNumberInputRef) { + positionNumberInputRef.focus(); + } + }} + > + {position.number || idx() + 1} +
+
{ + await startTransition(function () { + setUiState("selectedPosition", position.id); + }); + if (nameInputRef) { + nameInputRef.focus(); + } + }} + > + {position.name} +
+
+
+ + + +
+
+
+
+
+ + +
+ { + setState( + "positions", + idx(), + "quantity", + parseFloat(e.currentTarget.value) || 0 + ); + }} + /> +
+
+ + + setState( + "positions", + idx(), + "agilePointsMin", + parseInt(e.currentTarget.value) + ) + } + selected={position.agilePointsMin || 0} + /> + + setState( + "positions", + idx(), + "agilePointsMax", + parseInt(e.currentTarget.value) + ) + } + selected={position.agilePointsMax || 0} + /> + +
+
+ { + setState( + "positions", + idx(), + "itemPrice", + parseOptionalFloat(e.currentTarget.value) + ); + }} + /> +
+ +
+ { + setState( + "positions", + idx(), + "name", + e.currentTarget.value + ); + }} + /> +
+
+ { + setState( + "positions", + idx(), + "number", + e.currentTarget.value + ); + }} + /> +
+
+ + setState( + "positions", + idx(), + "fixedDiscountPrice", + parseOptionalFloat(e.currentTarget.value) + ) + } + /> +
+
+