add confirm button for dangerous admin actions
This commit is contained in:
parent
8b42377453
commit
f66c35a225
@ -1,4 +1,6 @@
|
|||||||
|
import { ExclamationCircleIcon } from "@heroicons/react/24/solid";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
const AdminActionBody = ({
|
const AdminActionBody = ({
|
||||||
label,
|
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 (
|
||||||
|
<AdminActionButton
|
||||||
|
symbol={<ExclamationCircleIcon className="w-4 animate-ping" />}
|
||||||
|
label={`Confirm ${label}`}
|
||||||
|
onClick={onConfirm}
|
||||||
|
type={type}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AdminActionButton
|
||||||
|
symbol={symbol}
|
||||||
|
label={label}
|
||||||
|
onClick={() => {
|
||||||
|
setConfirmView(true);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const AdminActionButton = ({
|
const AdminActionButton = ({
|
||||||
label,
|
label,
|
||||||
onClick,
|
onClick,
|
||||||
@ -65,4 +114,4 @@ const AdminActionButton = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export { AdminActionLink, AdminActionButton };
|
export { AdminActionLink, AdminActionButton, AdminActionConfirmButton };
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
import { XCircleIcon } from "@heroicons/react/20/solid";
|
import { XCircleIcon } from "@heroicons/react/20/solid";
|
||||||
import { AdminBarLayout } from "~/components/admin/ControlBar";
|
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 Image from "next/image";
|
||||||
import {
|
import {
|
||||||
ResourceForm,
|
ResourceForm,
|
||||||
@ -87,11 +90,15 @@ const EditResourcePage = () => {
|
|||||||
onSubmit(formMethods.getValues());
|
onSubmit(formMethods.getValues());
|
||||||
}}
|
}}
|
||||||
/>,
|
/>,
|
||||||
<AdminActionLink
|
<AdminActionConfirmButton
|
||||||
key="cancel"
|
key="cancel"
|
||||||
symbol={<XCircleIcon className="w-4" />}
|
symbol={<XCircleIcon className="w-4" />}
|
||||||
label="Cancel"
|
label="Cancel"
|
||||||
href={`/resources/${data.id}`}
|
onConfirm={() => {
|
||||||
|
router.push(`/resources/${data.id}`).catch((error) => {
|
||||||
|
console.error(error);
|
||||||
|
});
|
||||||
|
}}
|
||||||
/>,
|
/>,
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
|
@ -6,10 +6,14 @@ import { type AuditoryResource, type PlatformLink } from "@prisma/client";
|
|||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { AdminBarLayout } from "~/components/admin/ControlBar";
|
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 { useRouter } from "next/router";
|
||||||
import { HeaderFooterLayout } from "~/layouts/HeaderFooterLayout";
|
import { HeaderFooterLayout } from "~/layouts/HeaderFooterLayout";
|
||||||
import { QueryWaitWrapper } from "~/components/LoadingWrapper";
|
import { QueryWaitWrapper } from "~/components/LoadingWrapper";
|
||||||
|
import { TrashIcon } from "@heroicons/react/24/outline";
|
||||||
|
|
||||||
export const PlatformLinkButton = ({
|
export const PlatformLinkButton = ({
|
||||||
platformLink,
|
platformLink,
|
||||||
@ -122,13 +126,23 @@ const ResourceViewPage = () => {
|
|||||||
return (
|
return (
|
||||||
<HeaderFooterLayout>
|
<HeaderFooterLayout>
|
||||||
<AdminBarLayout
|
<AdminBarLayout
|
||||||
actions={
|
actions={[
|
||||||
<AdminActionLink
|
<AdminActionLink
|
||||||
|
key="edit"
|
||||||
symbol={<PencilSquareIcon className="w-4" />}
|
symbol={<PencilSquareIcon className="w-4" />}
|
||||||
label="Edit Page"
|
label="Edit Page"
|
||||||
href={`${router.asPath}/edit`}
|
href={`${router.asPath}/edit`}
|
||||||
/>
|
/>,
|
||||||
}
|
<AdminActionConfirmButton
|
||||||
|
key="delete"
|
||||||
|
label="Delete"
|
||||||
|
symbol={<TrashIcon className="w-4" />}
|
||||||
|
onConfirm={() => {
|
||||||
|
// todo
|
||||||
|
console.log("deleting");
|
||||||
|
}}
|
||||||
|
/>,
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
<div className="mb-12">
|
<div className="mb-12">
|
||||||
<QueryWaitWrapper query={resourceQuery} Render={ConditionalView} />
|
<QueryWaitWrapper query={resourceQuery} Render={ConditionalView} />
|
||||||
|
@ -7,7 +7,10 @@ import {
|
|||||||
type UseFormReturn,
|
type UseFormReturn,
|
||||||
} from "react-hook-form";
|
} from "react-hook-form";
|
||||||
import { AdminBarLayout } from "~/components/admin/ControlBar";
|
import { AdminBarLayout } from "~/components/admin/ControlBar";
|
||||||
import { AdminActionButton, AdminActionLink } from "~/components/admin/common";
|
import {
|
||||||
|
AdminActionButton,
|
||||||
|
AdminActionConfirmButton,
|
||||||
|
} from "~/components/admin/common";
|
||||||
import {
|
import {
|
||||||
type ResourceCreateInput,
|
type ResourceCreateInput,
|
||||||
ResourceForm,
|
ResourceForm,
|
||||||
@ -55,11 +58,15 @@ const EditResourcePage = () => {
|
|||||||
.catch((error) => console.error(error));
|
.catch((error) => console.error(error));
|
||||||
}}
|
}}
|
||||||
/>,
|
/>,
|
||||||
<AdminActionLink
|
<AdminActionConfirmButton
|
||||||
key="cancel"
|
key="cancel"
|
||||||
symbol={<XCircleIcon className="w-4" />}
|
symbol={<XCircleIcon className="w-4" />}
|
||||||
label="Cancel"
|
label="Cancel"
|
||||||
href={`/resources`}
|
onConfirm={() => {
|
||||||
|
router.push("/resources").catch((error) => {
|
||||||
|
console.error(error);
|
||||||
|
});
|
||||||
|
}}
|
||||||
/>,
|
/>,
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user