From 2eb956e97e18bcb97fdc6ebd7a2c6828902c038e Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com> Date: Mon, 21 Aug 2023 11:44:59 +0530 Subject: [PATCH] refactor: project and workspace delete modals (#1915) --- .../project/delete-project-modal.tsx | 117 ++++++++--------- apps/app/components/ui/input/index.tsx | 4 +- apps/app/components/ui/input/types.d.ts | 2 +- .../workspace/delete-workspace-modal.tsx | 123 ++++++++++-------- 4 files changed, 124 insertions(+), 122 deletions(-) diff --git a/apps/app/components/project/delete-project-modal.tsx b/apps/app/components/project/delete-project-modal.tsx index 8edca368e..5b271d99d 100644 --- a/apps/app/components/project/delete-project-modal.tsx +++ b/apps/app/components/project/delete-project-modal.tsx @@ -1,9 +1,11 @@ -import React, { useEffect, useState } from "react"; +import React from "react"; import { useRouter } from "next/router"; import { mutate } from "swr"; +// react-hook-form +import { Controller, useForm } from "react-hook-form"; // headless ui import { Dialog, Transition } from "@headlessui/react"; // services @@ -27,6 +29,11 @@ type TConfirmProjectDeletionProps = { user: ICurrentUserResponse | undefined; }; +const defaultValues = { + projectName: "", + confirmDelete: "", +}; + export const DeleteProjectModal: React.FC = ({ isOpen, data, @@ -34,51 +41,41 @@ export const DeleteProjectModal: React.FC = ({ onSuccess, user, }) => { - const [isDeleteLoading, setIsDeleteLoading] = useState(false); - const [confirmProjectName, setConfirmProjectName] = useState(""); - const [confirmDeleteMyProject, setConfirmDeleteMyProject] = useState(false); - const [selectedProject, setSelectedProject] = useState(null); - const router = useRouter(); const { workspaceSlug } = router.query; const { setToastAlert } = useToast(); - const canDelete = confirmProjectName === data?.name && confirmDeleteMyProject; + const { + control, + formState: { isSubmitting }, + handleSubmit, + reset, + watch, + } = useForm({ defaultValues }); - useEffect(() => { - if (data) setSelectedProject(data); - else { - const timer = setTimeout(() => { - setSelectedProject(null); - clearTimeout(timer); - }, 300); - } - }, [data]); + const canDelete = + watch("projectName") === data?.name && watch("confirmDelete") === "delete my project"; const handleClose = () => { - setIsDeleteLoading(false); - const timer = setTimeout(() => { - setConfirmProjectName(""); - setConfirmDeleteMyProject(false); + reset(defaultValues); clearTimeout(timer); }, 350); + onClose(); }; - const handleDeletion = async () => { + const onSubmit = async () => { if (!data || !workspaceSlug || !canDelete) return; - setIsDeleteLoading(true); - await projectService - .deleteProject(workspaceSlug as string, data.id, user) + .deleteProject(workspaceSlug.toString(), data.id, user) .then(() => { handleClose(); mutate( - PROJECTS_LIST(workspaceSlug as string, { is_favorite: "all" }), + PROJECTS_LIST(workspaceSlug.toString(), { is_favorite: "all" }), (prevData) => prevData?.filter((project: IProject) => project.id !== data.id), false ); @@ -91,8 +88,7 @@ export const DeleteProjectModal: React.FC = ({ title: "Error!", message: "Something went wrong. Please try again later.", }) - ) - .finally(() => setIsDeleteLoading(false)); + ); }; return ( @@ -122,7 +118,7 @@ export const DeleteProjectModal: React.FC = ({ leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" > -
+
= ({

Are you sure you want to delete project{" "} - {selectedProject?.name}? - All of the data related to the project will be permanently removed. This - action cannot be undone + {data?.name}? All of the + data related to the project will be permanently removed. This action cannot be + undone

Enter the project name{" "} - - {selectedProject?.name} - {" "} - to continue: + {data?.name} to + continue:

- { - setConfirmProjectName(e.target.value); - }} + ( + + )} />
@@ -167,31 +164,27 @@ export const DeleteProjectModal: React.FC = ({ delete my project{" "} below:

- { - if (e.target.value === "delete my project") { - setConfirmDeleteMyProject(true); - } else { - setConfirmDeleteMyProject(false); - } - }} - name="typeDelete" + ( + + )} />
Cancel - - {isDeleteLoading ? "Deleting..." : "Delete Project"} + + {isSubmitting ? "Deleting..." : "Delete Project"}
-
+
diff --git a/apps/app/components/ui/input/index.tsx b/apps/app/components/ui/input/index.tsx index d00d1386f..867712a29 100644 --- a/apps/app/components/ui/input/index.tsx +++ b/apps/app/components/ui/input/index.tsx @@ -29,9 +29,9 @@ export const Input: React.FC = ({ type={type} id={id} value={value} - {...(register && register(name, validations))} + {...(register && register(name ?? "", validations))} onChange={(e) => { - register && register(name).onChange(e); + register && register(name ?? "").onChange(e); onChange && onChange(e); }} className={`block rounded-md bg-transparent text-sm focus:outline-none placeholder-custom-text-400 ${ diff --git a/apps/app/components/ui/input/types.d.ts b/apps/app/components/ui/input/types.d.ts index 8207006df..77a48b4b9 100644 --- a/apps/app/components/ui/input/types.d.ts +++ b/apps/app/components/ui/input/types.d.ts @@ -3,7 +3,7 @@ import type { UseFormRegister, RegisterOptions } from "react-hook-form"; export interface Props extends React.ComponentPropsWithoutRef<"input"> { label?: string; - name: string; + name?: string; value?: string | number | readonly string[]; mode?: "primary" | "transparent" | "trueTransparent" | "secondary" | "disabled"; register?: UseFormRegister; diff --git a/apps/app/components/workspace/delete-workspace-modal.tsx b/apps/app/components/workspace/delete-workspace-modal.tsx index b896a87e7..7ba8c0eff 100644 --- a/apps/app/components/workspace/delete-workspace-modal.tsx +++ b/apps/app/components/workspace/delete-workspace-modal.tsx @@ -1,9 +1,11 @@ -import React, { useEffect, useState } from "react"; +import React from "react"; import { useRouter } from "next/router"; import { mutate } from "swr"; +// react-hook-form +import { Controller, useForm } from "react-hook-form"; // headless ui import { Dialog, Transition } from "@headlessui/react"; // services @@ -26,57 +28,63 @@ type Props = { user: ICurrentUserResponse | undefined; }; +const defaultValues = { + workspaceName: "", + confirmDelete: "", +}; + export const DeleteWorkspaceModal: React.FC = ({ isOpen, data, onClose, user }) => { - const [isDeleteLoading, setIsDeleteLoading] = useState(false); - - const [confirmWorkspaceName, setConfirmWorkspaceName] = useState(""); - const [confirmDeleteMyWorkspace, setConfirmDeleteMyWorkspace] = useState(false); - - const [selectedWorkspace, setSelectedWorkspace] = useState(null); - const router = useRouter(); + const { setToastAlert } = useToast(); - useEffect(() => { - if (data) setSelectedWorkspace(data); - else { - const timer = setTimeout(() => { - setSelectedWorkspace(null); - clearTimeout(timer); - }, 350); - } - }, [data]); + const { + control, + formState: { isSubmitting }, + handleSubmit, + reset, + watch, + } = useForm({ defaultValues }); - const canDelete = confirmWorkspaceName === data?.name && confirmDeleteMyWorkspace; + const canDelete = + watch("workspaceName") === data?.name && watch("confirmDelete") === "delete my workspace"; const handleClose = () => { - setIsDeleteLoading(false); - setConfirmWorkspaceName(""); - setConfirmDeleteMyWorkspace(false); + const timer = setTimeout(() => { + reset(defaultValues); + clearTimeout(timer); + }, 350); + onClose(); }; - const handleDeletion = async () => { - setIsDeleteLoading(true); + const onSubmit = async () => { if (!data || !canDelete) return; + await workspaceService .deleteWorkspace(data.slug, user) .then(() => { handleClose(); + router.push("/"); + mutate(USER_WORKSPACES, (prevData) => prevData?.filter((workspace) => workspace.id !== data.id) ); + setToastAlert({ type: "success", - message: "Workspace deleted successfully", - title: "Success", + title: "Success!", + message: "Workspace deleted successfully.", }); }) - .catch((error) => { - console.log(error); - setIsDeleteLoading(false); - }); + .catch(() => + setToastAlert({ + type: "error", + title: "Error!", + message: "Something went wrong. Please try again later.", + }) + ); }; return ( @@ -106,7 +114,7 @@ export const DeleteWorkspaceModal: React.FC = ({ isOpen, data, onClose, u leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" > -
+
= ({ isOpen, data, onClose, u

Enter the workspace name{" "} - - {selectedWorkspace?.name} - {" "} - to continue: + {data?.name} to + continue:

- { - setConfirmWorkspaceName(e.target.value); - }} + ( + + )} />
@@ -154,28 +163,28 @@ export const DeleteWorkspaceModal: React.FC = ({ isOpen, data, onClose, u delete my workspace{" "} below:

- { - if (e.target.value === "delete my workspace") { - setConfirmDeleteMyWorkspace(true); - } else { - setConfirmDeleteMyWorkspace(false); - } - }} - name="typeDelete" + ( + + )} />
Cancel - - {isDeleteLoading ? "Deleting..." : "Delete Workspace"} + + {isSubmitting ? "Deleting..." : "Delete Workspace"}
-
+