From 8b2fc884bf96de9e451b40d2e48ac634a248383f Mon Sep 17 00:00:00 2001 From: Mikkel RINGAUD Date: Fri, 22 Apr 2022 15:13:05 +0200 Subject: [PATCH] refactor: Wrote a CardEditor to prevent writing Cards twice --- src/components/ProjectEditor/CardEditor.tsx | 194 ++++++++++++++++++ .../ProjectEditor/LaunchpadEditor.tsx | 166 ++++++--------- .../ProjectEditor/LaunchpadPageEditor.tsx | 153 ++------------ src/components/ProjectEditor/index.tsx | 10 +- 4 files changed, 286 insertions(+), 237 deletions(-) create mode 100644 src/components/ProjectEditor/CardEditor.tsx diff --git a/src/components/ProjectEditor/CardEditor.tsx b/src/components/ProjectEditor/CardEditor.tsx new file mode 100644 index 0000000..1eb244e --- /dev/null +++ b/src/components/ProjectEditor/CardEditor.tsx @@ -0,0 +1,194 @@ +import type { ProjectData, ProjectDataSample } from "@/types/Project"; +import type { ChangeEvent } from "react"; + +// Stores +import { useUnsavedProjectStore } from "@/stores/unsaved_project"; + +// Components +import Select from "@/components/Select"; +import Input from "@/components/Input"; +import { Fragment } from "react"; + +// Icons +import { + HiOutlinePlus, + HiOutlineTrash, + HiArrowDown, + HiArrowUp +} from "react-icons/hi"; + +interface CardEditorProps { + handleSelection: (evt: ChangeEvent) => void; + selectorItems: + | ProjectData["launchpads"][number]["pages"] + | ProjectData["launchpads"] + ; + + type: "launchpad" | "page"; + launchpad: ProjectData["launchpads"][number] & { id: number } | null; + + target: + | ProjectData["launchpads"][number] & { id: number } | null + | ProjectData["launchpads"][number]["pages"][number] & { id: number } | null + + addToSelector: () => void, + removeFromSelector: () => void, + + upItem: () => void, + downItem: () => void, + + children: React.ReactNode +} + +export default function CardEditor ({ + handleSelection, + selectorItems, + + type, + launchpad, + target, + + addToSelector, + removeFromSelector, + + upItem, + downItem, + + children +}: CardEditorProps) { + const { data, setData } = useUnsavedProjectStore(); + if (!data) return

Loading...

; + + return ( +
+
+
+ + + +
+ + {children} + +
+ {target + ? ( + + {target.id !== 0 && ( + + )} + + + + {launchpad && target.id !== ((type === "launchpad" ? data.launchpads : launchpad.pages).length - 1) && ( + + )} + + ) + : ( +

+ No {type} selected +

+ ) + } +
+ + {launchpad && target && ( + { + const data_copy = { ...data }; + + if (type === "launchpad") { + data_copy.launchpads[target.id].name = evt.target.value; + } + else if (type === "page") { + data_copy.launchpads[launchpad.id].pages[target.id].name = evt.target.value; + } + else return; + + setData(data_copy); + }} + /> + )} +
+
+ ); +} diff --git a/src/components/ProjectEditor/LaunchpadEditor.tsx b/src/components/ProjectEditor/LaunchpadEditor.tsx index d34295d..a2e564e 100644 --- a/src/components/ProjectEditor/LaunchpadEditor.tsx +++ b/src/components/ProjectEditor/LaunchpadEditor.tsx @@ -9,14 +9,10 @@ import { useUnsavedProjectStore } from "@/stores/unsaved_project"; // Components import Launchpad from "@/components/Launchpad"; -import Select from "@/components/Select"; -import Input from "@/components/Input"; -import { Fragment } from "react"; - -// Icons -import { HiOutlinePlus, HiOutlineTrash } from "react-icons/hi"; +import CardEditor from "./CardEditor"; interface LaunchpadEditorProps { + setCurrentLaunchpadSelected: (id: number) => void; handleLaunchpadSelection: (evt: ChangeEvent) => void, launchpad: ProjectData["launchpads"][number] & { id: number } | null, sample: ProjectDataSample & { id: number } | null, @@ -28,6 +24,7 @@ interface LaunchpadEditorProps { } export default function LaunchpadEditor ({ + setCurrentLaunchpadSelected, handleLaunchpadSelection, launchpad, sample, @@ -60,100 +57,69 @@ export default function LaunchpadEditor ({ const { data, setData } = useUnsavedProjectStore(); if (!data) return

Loading...

; + /** Remove `1` to the launchpad index. */ + const upLaunchpad = () => { + if (!launchpad) return; + const data_copy = { ...data }; + const launchpads_copy = [...data_copy.launchpads]; + const launchpad_copy = { ...launchpads_copy[launchpad.id] }; + const launchpad_id = launchpad.id; + + if (launchpad_id === 0) return; + + launchpads_copy[launchpad_id] = launchpads_copy[launchpad_id - 1]; + launchpads_copy[launchpad_id - 1] = launchpad_copy; + + data_copy.launchpads = launchpads_copy; + setData(data_copy); + + setCurrentLaunchpadSelected(launchpad_id - 1); + }; + + /** Add `1` to the launchpad index. */ + const downLaunchpad = () => { + if (!launchpad) return; + const data_copy = { ...data }; + const launchpads_copy = [...data_copy.launchpads]; + const launchpad_copy = { ...launchpads_copy[launchpad.id] }; + const launchpad_id = launchpad.id; + + if (launchpad_id === launchpads_copy.length - 1) return; + + launchpads_copy[launchpad_id] = launchpads_copy[launchpad_id + 1]; + launchpads_copy[launchpad_id + 1] = launchpad_copy; + + data_copy.launchpads = launchpads_copy; + setData(data_copy); + + setCurrentLaunchpadSelected(launchpad_id + 1); + }; + return ( -
-
-
- - - -
- - {launchpad && ( - null} - onPadDown={pad_id => handleLaunchpadClick(pad_id)} - /> - )} - -
- {launchpad - ? ( - - { - const data_copy = { ...data }; - data_copy.launchpads[launchpad.id].name = evt.target.value; - setData(data_copy); - }} - /> - - - - ) - : ( -

- No launchpad selected -

- ) - } -
-
-
+ + + {launchpad && ( + null} + onPadDown={pad_id => handleLaunchpadClick(pad_id)} + /> + )} + + ); } diff --git a/src/components/ProjectEditor/LaunchpadPageEditor.tsx b/src/components/ProjectEditor/LaunchpadPageEditor.tsx index 9c4873a..5e6eb7c 100644 --- a/src/components/ProjectEditor/LaunchpadPageEditor.tsx +++ b/src/components/ProjectEditor/LaunchpadPageEditor.tsx @@ -5,18 +5,7 @@ import logger from "@/utils/logger"; import { useUnsavedProjectStore } from "@/stores/unsaved_project"; -// Components -import Select from "@/components/Select"; -import Input from "@/components/Input"; -import { Fragment } from "react"; - -// Icons -import { - HiArrowDown, - HiArrowUp, - HiOutlinePlus, - HiOutlineTrash -} from "react-icons/hi"; +import CardEditor from "./CardEditor"; interface LaunchpadPageEditorProps { page: ProjectData["launchpads"][number]["pages"][number] & { id: number } | null, @@ -43,7 +32,7 @@ export default function LaunchpadPageEditor ({ const { data, setData } = useUnsavedProjectStore(); if (!data) return

Loading...

; - /** Remove 1 to the page index. */ + /** Remove `1` to the page index. */ const upLaunchpadPage = () => { if (!page) return; const data_copy = { ...data }; @@ -64,6 +53,7 @@ export default function LaunchpadPageEditor ({ setCurrentLaunchpadPageSelected(page_id - 1); }; + /** Add `1` to the page index. */ const downLaunchpadPage = () => { if (!page) return; const data_copy = { ...data }; @@ -85,125 +75,24 @@ export default function LaunchpadPageEditor ({ }; return ( -
-
-
- - - -
- -
- {page - ? ( - - {page.id !== 0 && ( - - )} - - - - {page.id !== (launchpad.pages.length - 1) && ( - - )} - - ) - : ( -

- No page selected -

- ) - } -
- - - {page && ( - { - const data_copy = { ...data }; - data_copy.launchpads[launchpad.id].pages[page.id].name = evt.target.value; - setData(data_copy); - }} - /> - )} + + +
+
-
+ ); } \ No newline at end of file diff --git a/src/components/ProjectEditor/index.tsx b/src/components/ProjectEditor/index.tsx index 6d55a64..3adc4eb 100644 --- a/src/components/ProjectEditor/index.tsx +++ b/src/components/ProjectEditor/index.tsx @@ -151,19 +151,19 @@ export default function ProjectEditor () { setCurrentPadSelected(pad_id); }; - // Short-hands for the current launchpad and page. - // We append the current index in the objects to avoid - // having to always re-use `(currentLaunchpadSelected !== null)`, etc... + /** Short-hand for `currentLaunchpadSelected` with data. */ const launchpad = (typeof currentLaunchpadSelected !== "undefined") ? { ...data.launchpads[currentLaunchpadSelected], id: currentLaunchpadSelected } : null; + /** Short-hand for `currentLaunchpadPageSelected` with data. */ const page = (launchpad && typeof currentLaunchpadPageSelected !== "undefined") ? { ...launchpad.pages[currentLaunchpadPageSelected], id: currentLaunchpadPageSelected } : null; - + + /** Short-hand for `currentPadSelected` with data. */ const sample = (launchpad && page && typeof currentPadSelected !== "undefined") ? { ...page.samples[currentPadSelected], id: currentPadSelected @@ -173,6 +173,7 @@ export default function ProjectEditor () {
{ - return (