From f66c35a225de33711c1887d883bcab96ff88669e Mon Sep 17 00:00:00 2001 From: Brandon Egger Date: Tue, 5 Sep 2023 20:27:33 -0500 Subject: [PATCH] add confirm button for dangerous admin actions --- src/components/admin/common.tsx | 51 +++++++++++++++++++++++++++++- src/pages/resources/[id]/edit.tsx | 13 ++++++-- src/pages/resources/[id]/index.tsx | 22 ++++++++++--- src/pages/resources/create.tsx | 13 ++++++-- 4 files changed, 88 insertions(+), 11 deletions(-) diff --git a/src/components/admin/common.tsx b/src/components/admin/common.tsx index 0f8abd3..71beaa8 100644 --- a/src/components/admin/common.tsx +++ b/src/components/admin/common.tsx @@ -1,4 +1,6 @@ +import { ExclamationCircleIcon } from "@heroicons/react/24/solid"; import Link from "next/link"; +import { useEffect, useState } from "react"; const AdminActionBody = ({ label, @@ -38,6 +40,53 @@ const AdminActionLink = ({ ); }; +const AdminActionConfirmButton = ({ + label, + onConfirm, + symbol, + type = "button", +}: { + label: string; + onConfirm?: () => void; + symbol: JSX.Element | undefined; + type?: HTMLButtonElement["type"]; +}) => { + const [isConfirmView, setConfirmView] = useState(false); + + useEffect(() => { + if (!isConfirmView) { + return; + } + + setTimeout(() => { + if (isConfirmView) { + setConfirmView(false); + } + }, 5000); + }, [isConfirmView]); + + if (isConfirmView) { + return ( + } + label={`Confirm ${label}`} + onClick={onConfirm} + type={type} + /> + ); + } + + return ( + { + setConfirmView(true); + }} + /> + ); +}; + const AdminActionButton = ({ label, onClick, @@ -65,4 +114,4 @@ const AdminActionButton = ({ ); }; -export { AdminActionLink, AdminActionButton }; +export { AdminActionLink, AdminActionButton, AdminActionConfirmButton }; diff --git a/src/pages/resources/[id]/edit.tsx b/src/pages/resources/[id]/edit.tsx index 7641bc5..817d3b0 100644 --- a/src/pages/resources/[id]/edit.tsx +++ b/src/pages/resources/[id]/edit.tsx @@ -1,6 +1,9 @@ import { XCircleIcon } from "@heroicons/react/20/solid"; import { AdminBarLayout } from "~/components/admin/ControlBar"; -import { AdminActionButton, AdminActionLink } from "~/components/admin/common"; +import { + AdminActionButton, + AdminActionConfirmButton, +} from "~/components/admin/common"; import Image from "next/image"; import { ResourceForm, @@ -87,11 +90,15 @@ const EditResourcePage = () => { onSubmit(formMethods.getValues()); }} />, - } label="Cancel" - href={`/resources/${data.id}`} + onConfirm={() => { + router.push(`/resources/${data.id}`).catch((error) => { + console.error(error); + }); + }} />, ]} > diff --git a/src/pages/resources/[id]/index.tsx b/src/pages/resources/[id]/index.tsx index b4471ba..9770b1c 100644 --- a/src/pages/resources/[id]/index.tsx +++ b/src/pages/resources/[id]/index.tsx @@ -6,10 +6,14 @@ import { type AuditoryResource, type PlatformLink } from "@prisma/client"; import Image from "next/image"; import Link from "next/link"; import { AdminBarLayout } from "~/components/admin/ControlBar"; -import { AdminActionLink } from "~/components/admin/common"; +import { + AdminActionConfirmButton, + AdminActionLink, +} from "~/components/admin/common"; import { useRouter } from "next/router"; import { HeaderFooterLayout } from "~/layouts/HeaderFooterLayout"; import { QueryWaitWrapper } from "~/components/LoadingWrapper"; +import { TrashIcon } from "@heroicons/react/24/outline"; export const PlatformLinkButton = ({ platformLink, @@ -122,13 +126,23 @@ const ResourceViewPage = () => { return ( } label="Edit Page" href={`${router.asPath}/edit`} - /> - } + />, + } + onConfirm={() => { + // todo + console.log("deleting"); + }} + />, + ]} >
diff --git a/src/pages/resources/create.tsx b/src/pages/resources/create.tsx index 454d26a..0920379 100644 --- a/src/pages/resources/create.tsx +++ b/src/pages/resources/create.tsx @@ -7,7 +7,10 @@ import { type UseFormReturn, } from "react-hook-form"; import { AdminBarLayout } from "~/components/admin/ControlBar"; -import { AdminActionButton, AdminActionLink } from "~/components/admin/common"; +import { + AdminActionButton, + AdminActionConfirmButton, +} from "~/components/admin/common"; import { type ResourceCreateInput, ResourceForm, @@ -55,11 +58,15 @@ const EditResourcePage = () => { .catch((error) => console.error(error)); }} />, - } label="Cancel" - href={`/resources`} + onConfirm={() => { + router.push("/resources").catch((error) => { + console.error(error); + }); + }} />, ]} >