feat: add account deletion functionality with cascade delete for work… (#33)
* feat: add account deletion functionality with cascade delete for workspace relations * fix: add cascade delete to workspace user foreign key constraints * fix: change onDelete action to set null for user references in schema * feat: tweak design --------- Co-authored-by: Henry <henry_ball@hotmail.co.uk> Co-authored-by: Henry <30578846+hjball@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
import { authClient } from "@kan/auth/client";
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
|
||||
import Button from "~/components/Button";
|
||||
import { useModal } from "~/providers/modal";
|
||||
import { usePopup } from "~/providers/popup";
|
||||
import { api } from "~/utils/api";
|
||||
|
||||
export function DeleteAccountConfirmation() {
|
||||
const { closeModal } = useModal();
|
||||
const { showPopup } = usePopup();
|
||||
const router = useRouter();
|
||||
|
||||
const utils = api.useUtils();
|
||||
|
||||
const [isAcknowledgmentChecked, setIsAcknowledgmentChecked] = useState(false);
|
||||
|
||||
const deleteAccountMutation = useMutation({
|
||||
mutationFn: () => authClient.deleteUser(),
|
||||
onSuccess: async () => {
|
||||
closeModal();
|
||||
showPopup({
|
||||
header: "Account deleted",
|
||||
message: "Your account has been deleted.",
|
||||
icon: "success",
|
||||
});
|
||||
|
||||
utils.invalidate();
|
||||
|
||||
router.push("/");
|
||||
},
|
||||
onError: () => {
|
||||
closeModal();
|
||||
showPopup({
|
||||
header: "Error deleting account",
|
||||
message: "Please try again later, or contact customer support.",
|
||||
icon: "error",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const handleDeleteAccount = () => {
|
||||
deleteAccountMutation.mutate();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="p-5">
|
||||
<div className="flex w-full flex-col justify-between pb-4">
|
||||
<h2 className="text-md pb-4 font-medium text-neutral-900 dark:text-dark-1000">
|
||||
{`Are you sure you want to delete your account?`}
|
||||
</h2>
|
||||
<p className="mb-4 text-sm text-light-900 dark:text-dark-900">
|
||||
Keep in mind that this action is irreversible.
|
||||
</p>
|
||||
<p className="text-sm text-light-900 dark:text-dark-900">
|
||||
This will result in the permanent deletion of all data associated with
|
||||
your account.
|
||||
</p>
|
||||
</div>
|
||||
<div className="relative flex items-start">
|
||||
<div className="flex h-6 items-center">
|
||||
<input
|
||||
id="acknowledgment"
|
||||
name="acknowledgment"
|
||||
type="checkbox"
|
||||
aria-describedby="acknowledgment-description"
|
||||
className="mt-2 h-[14px] w-[14px] rounded border-gray-300 bg-transparent text-indigo-600 focus:shadow-none focus:ring-0 focus:ring-offset-0"
|
||||
checked={isAcknowledgmentChecked}
|
||||
onChange={() =>
|
||||
setIsAcknowledgmentChecked(!isAcknowledgmentChecked)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className="ml-3 text-sm leading-6">
|
||||
<p
|
||||
id="comments-description"
|
||||
className="text-light-900 dark:text-dark-1000"
|
||||
>
|
||||
I acknowledge that all of my account data will be permanently
|
||||
deleted and want to proceed.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5 flex justify-end space-x-2 sm:mt-6">
|
||||
<Button variant="secondary" onClick={() => closeModal()}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
variant="danger"
|
||||
onClick={handleDeleteAccount}
|
||||
disabled={!isAcknowledgmentChecked}
|
||||
isLoading={deleteAccountMutation.isPending}
|
||||
>
|
||||
Delete account
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import { api } from "~/utils/api";
|
||||
import Avatar from "./components/Avatar";
|
||||
import CreateAPIKeyForm from "./components/CreateAPIKeyForm";
|
||||
import { CustomURLConfirmation } from "./components/CustomURLConfirmation";
|
||||
import { DeleteAccountConfirmation } from "./components/DeleteAccountConfirmation";
|
||||
import { DeleteWorkspaceConfirmation } from "./components/DeleteWorkspaceConfirmation";
|
||||
import UpdateDisplayNameForm from "./components/UpdateDisplayNameForm";
|
||||
import UpdateWorkspaceDescriptionForm from "./components/UpdateWorkspaceDescriptionForm";
|
||||
@@ -127,20 +128,40 @@ export default function SettingsPage() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="border-t border-light-300 dark:border-dark-300">
|
||||
<h2 className="mt-8 text-[14px] text-neutral-900 dark:text-dark-1000">
|
||||
<div className="mb-8 border-t border-light-300 dark:border-dark-300">
|
||||
<h2 className="mb-4 mt-8 text-[14px] text-neutral-900 dark:text-dark-1000">
|
||||
Delete workspace
|
||||
</h2>
|
||||
<p className="mb-8 mt-2 text-sm text-neutral-500 dark:text-dark-900">
|
||||
Once you delete your workspace, there is no going back. Please
|
||||
be certain.
|
||||
<p className="mb-8 text-sm text-neutral-500 dark:text-dark-900">
|
||||
Once you delete your workspace, there is no going back. This
|
||||
action cannot be undone.
|
||||
</p>
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={() => openModal("DELETE_WORKSPACE")}
|
||||
>
|
||||
Delete workspace
|
||||
</Button>
|
||||
<div className="mt-4">
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => openModal("DELETE_WORKSPACE")}
|
||||
>
|
||||
Delete workspace
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mb-8 border-t border-light-300 dark:border-dark-300">
|
||||
<h2 className="mb-4 mt-8 text-[14px] text-neutral-900 dark:text-dark-1000">
|
||||
Delete account
|
||||
</h2>
|
||||
<p className="mb-8 text-sm text-neutral-500 dark:text-dark-900">
|
||||
Once you delete your account, there is no going back. This
|
||||
action cannot be undone.
|
||||
</p>
|
||||
<div className="mt-4">
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => openModal("DELETE_ACCOUNT")}
|
||||
>
|
||||
Delete account
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -152,6 +173,9 @@ export default function SettingsPage() {
|
||||
{modalContentType === "UPDATE_WORKSPACE_URL" && (
|
||||
<CustomURLConfirmation workspacePublicId={workspace.publicId} />
|
||||
)}
|
||||
{modalContentType === "DELETE_ACCOUNT" && (
|
||||
<DeleteAccountConfirmation />
|
||||
)}
|
||||
</Modal>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user