From 2884996c796f3714df1832d3f4780de8378ebc9d Mon Sep 17 00:00:00 2001 From: IrohDW Date: Fri, 4 Oct 2024 14:06:02 -0600 Subject: [PATCH] Refactored Forum Modal to use custom hooks. --- src/pages/Forum/Components/ActionBar.tsx | 2 +- src/pages/Forum/Components/ModalButton.tsx | 2 +- .../ForumModal-State.ts} | 81 ++++++++++++-- .../Forum/{ => CreateForum}/ForumModal.tsx | 101 ++++++------------ .../CreateForum/GroupPermissions-State.ts | 41 +++++++ .../GroupPermissions.tsx} | 48 ++------- src/pages/Forum/Forum.tsx | 4 +- src/utils/QortalRequests.ts | 2 +- 8 files changed, 158 insertions(+), 123 deletions(-) rename src/pages/Forum/{ForumModal-Data.ts => CreateForum/ForumModal-State.ts} (59%) rename src/pages/Forum/{ => CreateForum}/ForumModal.tsx (64%) create mode 100644 src/pages/Forum/CreateForum/GroupPermissions-State.ts rename src/pages/Forum/{GroupPermissionsForm.tsx => CreateForum/GroupPermissions.tsx} (69%) diff --git a/src/pages/Forum/Components/ActionBar.tsx b/src/pages/Forum/Components/ActionBar.tsx index fb00bbc..ed9a2bd 100644 --- a/src/pages/Forum/Components/ActionBar.tsx +++ b/src/pages/Forum/Components/ActionBar.tsx @@ -9,7 +9,7 @@ import { ComposeP, InstanceContainer, } from "../../Home/Home-styles"; -import { ForumData, ForumModal } from "../ForumModal"; +import { ForumData, ForumModal } from "../CreateForum/ForumModal"; export const forums = signal([]); export const resetForumIndexes = (forums: Signal) => { diff --git a/src/pages/Forum/Components/ModalButton.tsx b/src/pages/Forum/Components/ModalButton.tsx index 21af72f..65c0f5d 100644 --- a/src/pages/Forum/Components/ModalButton.tsx +++ b/src/pages/Forum/Components/ModalButton.tsx @@ -18,7 +18,7 @@ import { NewMessageSendButton, NewMessageSendP, } from "../../Home/Home-styles"; -import { publishForum } from "../ForumModal-Data"; +import { publishForum } from "../CreateForum/ForumModal-State"; export interface ModalButtonProps { onSubmit: () => Promise; diff --git a/src/pages/Forum/ForumModal-Data.ts b/src/pages/Forum/CreateForum/ForumModal-State.ts similarity index 59% rename from src/pages/Forum/ForumModal-Data.ts rename to src/pages/Forum/CreateForum/ForumModal-State.ts index 36847de..4dd4038 100644 --- a/src/pages/Forum/ForumModal-Data.ts +++ b/src/pages/Forum/CreateForum/ForumModal-State.ts @@ -1,11 +1,80 @@ -import { FORUMS_ID } from "../../constants/Identifiers"; -import { setNotification } from "../../state/features/notificationsSlice"; -import { store } from "../../state/store"; -import { getGroup } from "../../utils/QortalRequests"; -import { objectToBase64 } from "../../utils/toBase64"; +import { Signal, useComputed, useSignal } from "@preact/signals-react"; +import { useSignals } from "@preact/signals-react/runtime"; +import { useEffect } from "react"; +import { FORUMS_ID } from "../../../constants/Identifiers"; +import { setNotification } from "../../../state/features/notificationsSlice"; +import { store } from "../../../state/store"; +import { getGroup } from "../../../utils/QortalRequests"; +import { objectToBase64 } from "../../../utils/toBase64"; +import { resetForumIndexes } from "../Components/ActionBar"; import { ForumData } from "./ForumModal"; -import { Group } from "./GroupPermissionsForm"; +import { Group } from "./GroupPermissions"; +export const useForumModalState = (forumData: Signal) => { + useSignals(); + const tempData = useSignal([]); + const selectedForumIndex = useSignal(0); + const selectedForum = useComputed(() => { + return tempData.value[selectedForumIndex.value]; + }); + + const initializeTempData = () => { + tempData.value = + forumData.value.length === 0 + ? [emptyForum] + : deepCopyArray(forumData.value); + selectedForumIndex.value = 0; + }; + + useEffect(() => { + initializeTempData(); + }, [forumData.value]); + + const addForum = () => { + const newForum = { ...emptyForum }; + newForum.listIndex = tempData.value.length; + tempData.value = [...tempData.value, newForum]; + selectedForumIndex.value = newForum.listIndex; + }; + + const removeForum = () => { + if (tempData.value.length <= 1) { + tempData.value = [{ ...emptyForum }]; + selectedForumIndex.value = 0; + } else { + tempData.value = tempData.value.filter( + (group, index) => index !== selectedForumIndex.value + ); + + if (selectedForumIndex.value > 0) selectedForumIndex.value -= 1; + else selectedForumIndex.value = 0; + } + resetForumIndexes(tempData); + }; + + const updateForums = () => { + tempData.value = [...tempData.value]; + }; + + return { + tempData, + selectedForumIndex, + selectedForum, + addForum, + removeForum, + updateForums, + initializeTempData, + }; +}; + +const emptyForum: ForumData = { + title: "", + encryption: "None", + groups: [], + descriptionHTML: "", + descriptionText: "", + listIndex: 0, +}; const getGroupsData = async (groups: Group[]) => { const groupPromises = groups.map(group => getGroup(group.id)); return await Promise.all(groupPromises); diff --git a/src/pages/Forum/ForumModal.tsx b/src/pages/Forum/CreateForum/ForumModal.tsx similarity index 64% rename from src/pages/Forum/ForumModal.tsx rename to src/pages/Forum/CreateForum/ForumModal.tsx index 20f5752..aec2661 100644 --- a/src/pages/Forum/ForumModal.tsx +++ b/src/pages/Forum/CreateForum/ForumModal.tsx @@ -8,18 +8,23 @@ import { import { useSignals } from "@preact/signals-react/runtime"; import React, { useEffect } from "react"; import { useSelector } from "react-redux"; -import { SelectField } from "../../components/common/SelectField"; -import { Spacer } from "../../components/common/Spacer"; -import { TextEditor } from "../../components/common/TextEditor/TextEditor"; -import { useTestIdentifiers } from "../../constants/Identifiers"; -import { appOwner } from "../../constants/Misc"; -import { RootState } from "../../state/store"; -import { NewMessageInputRow } from "../Home/Home-styles"; -import { resetForumIndexes } from "./Components/ActionBar"; -import { ModalButton } from "./Components/ModalButton"; -import { QmailTextField } from "./Components/QmailTextField"; -import { deepCopyArray, forumToString, publishForum } from "./ForumModal-Data"; -import { Group, GroupPermissionsForm } from "./GroupPermissionsForm"; +import { SelectField } from "../../../components/common/SelectField"; +import { Spacer } from "../../../components/common/Spacer"; +import { TextEditor } from "../../../components/common/TextEditor/TextEditor"; +import { useTestIdentifiers } from "../../../constants/Identifiers"; +import { appOwner } from "../../../constants/Misc"; +import { RootState } from "../../../state/store"; +import { NewMessageInputRow } from "../../Home/Home-styles"; +import { resetForumIndexes } from "../Components/ActionBar"; +import { ModalButton } from "../Components/ModalButton"; +import { QmailTextField } from "../Components/QmailTextField"; +import { + deepCopyArray, + forumToString, + publishForum, + useForumModalState, +} from "./ForumModal-State"; +import { Group, GroupPermissions } from "./GroupPermissions"; export type EncryptionType = "None" | "Group" | "GroupAdmin" | ""; export interface ForumData { @@ -45,64 +50,18 @@ interface NewForumModalProps { } export const ForumModal = ({ forumData }: NewForumModalProps) => { - useSignals(); - - const tempData = useSignal([]); - - const emptyForum: ForumData = { - title: "", - encryption: "None", - groups: [], - descriptionHTML: "", - descriptionText: "", - listIndex: 0, - }; - const { user } = useSelector((state: RootState) => state.auth); const isRenderModal = user?.name === appOwner || useTestIdentifiers; - const selectedForumIndex = useSignal(0); - const selectedForum = useComputed(() => { - return tempData.value[selectedForumIndex.value]; - }); - - const initializeTempData = () => { - tempData.value = - forumData.value.length === 0 - ? [emptyForum] - : deepCopyArray(forumData.value); - selectedForumIndex.value = 0; - }; - - useEffect(() => { - initializeTempData(); - }, [forumData.value]); - - const addForum = () => { - const newForum = { ...emptyForum }; - newForum.listIndex = tempData.value.length; - tempData.value = [...tempData.value, newForum]; - selectedForumIndex.value = newForum.listIndex; - }; - - const removeForum = () => { - if (tempData.value.length <= 1) { - tempData.value = [{ ...emptyForum }]; - selectedForumIndex.value = 0; - } else { - tempData.value = tempData.value.filter( - (group, index) => index !== selectedForumIndex.value - ); - - if (selectedForumIndex.value > 0) selectedForumIndex.value -= 1; - else selectedForumIndex.value = 0; - } - resetForumIndexes(tempData); - }; - - const updateForums = () => { - tempData.value = [...tempData.value]; - }; + const { + tempData, + selectedForumIndex, + selectedForum, + addForum, + removeForum, + updateForums, + initializeTempData, + } = useForumModalState(forumData); return ( { onClose={() => initializeTempData()} onSubmit={async () => { updateForums(); - const pub = await publishForum(tempData.value); + const isPublished = await publishForum(tempData.value); - if (pub) forumData.value = tempData.value; - return pub; + if (isPublished) forumData.value = tempData.value; + return isPublished; }} modalLabel={"Manage Forums"} buttonLabel={"Publish Forums"} @@ -189,7 +148,7 @@ export const ForumModal = ({ forumData }: NewForumModalProps) => { }} /> - { tempData.value[selectedForumIndex.value].groups = g; diff --git a/src/pages/Forum/CreateForum/GroupPermissions-State.ts b/src/pages/Forum/CreateForum/GroupPermissions-State.ts new file mode 100644 index 0000000..6fc1be0 --- /dev/null +++ b/src/pages/Forum/CreateForum/GroupPermissions-State.ts @@ -0,0 +1,41 @@ +import { useSignal } from "@preact/signals-react"; +import { useSignals } from "@preact/signals-react/runtime"; +import { useEffect } from "react"; +import { Group } from "./GroupPermissions"; + +export const useGroupPermissionsState = ( + initialGroups?: Group[], + afterChange?: (g: Group[]) => void +) => { + useSignals(); + const newGroup = { + id: "", + permissions: "Read", + } as Group; + const groups = useSignal(initialGroups || [newGroup]); + + useEffect(() => { + if (initialGroups) + groups.value = initialGroups?.length > 0 ? initialGroups : [newGroup]; + }, [initialGroups]); + + const addGroup = () => { + groups.value = [...groups.value, newGroup]; + if (afterChange) afterChange(groups.value); + }; + + const removeGroup = (groupIndex: number) => { + if (groups.value.length > 1) + groups.value = groups.value.filter( + (group, index) => index !== groupIndex + ); + else groups.value = [newGroup]; + if (afterChange) afterChange(groups.value); + }; + + const updateGroups = () => { + if (afterChange) afterChange(groups.value); + }; + + return { groups, addGroup, removeGroup, updateGroups }; +}; diff --git a/src/pages/Forum/GroupPermissionsForm.tsx b/src/pages/Forum/CreateForum/GroupPermissions.tsx similarity index 69% rename from src/pages/Forum/GroupPermissionsForm.tsx rename to src/pages/Forum/CreateForum/GroupPermissions.tsx index cf3ccf1..30e15a1 100644 --- a/src/pages/Forum/GroupPermissionsForm.tsx +++ b/src/pages/Forum/CreateForum/GroupPermissions.tsx @@ -2,14 +2,12 @@ import AddIcon from "@mui/icons-material/Add"; import RemoveIcon from "@mui/icons-material/Remove"; import { Box, IconButton } from "@mui/material"; import { styled } from "@mui/material/styles"; -import { Signal, useSignal } from "@preact/signals-react"; -import { useSignals } from "@preact/signals-react/runtime"; -import React, { useEffect } from "react"; import ShortUniqueId from "short-unique-id"; -import { SelectField } from "../../components/common/SelectField"; -import { NewMessageInputRow } from "../Home/Home-styles"; -import { QmailTextField } from "./Components/QmailTextField"; +import { SelectField } from "../../../components/common/SelectField"; +import { NewMessageInputRow } from "../../Home/Home-styles"; +import { QmailTextField } from "../Components/QmailTextField"; import { GroupPermissionType } from "./ForumModal"; +import { useGroupPermissionsState } from "./GroupPermissions-State"; export interface Group { id: string; @@ -19,47 +17,15 @@ export interface GroupPermissionsFormProps { initialGroups?: Group[]; afterChange?: (g: Group[]) => void; } -export const GroupPermissionsForm = ({ +export const GroupPermissions = ({ initialGroups, afterChange, }: GroupPermissionsFormProps) => { - useSignals(); - - const newGroup = { - id: "", - permissions: "Read", - } as Group; - const groups = useSignal(initialGroups || [newGroup]); - - useEffect(() => { - if (initialGroups) - groups.value = initialGroups?.length > 0 ? initialGroups : [newGroup]; - }, [initialGroups]); + const { groups, addGroup, removeGroup, updateGroups } = + useGroupPermissionsState(initialGroups, afterChange); const uid = new ShortUniqueId(); - const addGroup = () => { - groups.value = [...groups.value, newGroup]; - if (afterChange) afterChange(groups.value); - }; - - const removeGroup = (groupIndex: number) => { - if (groups.value.length > 1) - groups.value = groups.value.filter( - (group, index) => index !== groupIndex - ); - else groups.value = [newGroup]; - if (afterChange) afterChange(groups.value); - }; - - const updateGroups = () => { - if (afterChange) afterChange(groups.value); - }; - const buttonStyle = { - width: "70px", - height: "70px", - }; - const StyledIconButton = styled(IconButton)(` width: 60px; height: 60px; diff --git a/src/pages/Forum/Forum.tsx b/src/pages/Forum/Forum.tsx index 0a10bc0..158bff4 100644 --- a/src/pages/Forum/Forum.tsx +++ b/src/pages/Forum/Forum.tsx @@ -9,8 +9,8 @@ import { InstanceContainer, } from "../Home/Home-styles"; import { GroupMail } from "../Mail/GroupMail"; -import { Group } from "./GroupPermissionsForm"; -import { EncryptionType, ForumData } from "./ForumModal"; +import { Group } from "./CreateForum/GroupPermissions"; +import { EncryptionType, ForumData } from "./CreateForum/ForumModal"; export const Forum = ({ title, diff --git a/src/utils/QortalRequests.ts b/src/utils/QortalRequests.ts index f46bda1..b27768a 100644 --- a/src/utils/QortalRequests.ts +++ b/src/utils/QortalRequests.ts @@ -1,6 +1,6 @@ import { FORUMS_ID } from "../constants/Identifiers"; import { appOwner } from "../constants/Misc"; -import { ForumData } from "../pages/Forum/ForumModal"; +import { ForumData } from "../pages/Forum/CreateForum/ForumModal"; export interface GroupData { groupId: number;