Skip to content

Commit

Permalink
Merge pull request #2879 from metabrainz/dont-delete-my-stuff-ffs
Browse files Browse the repository at this point in the history
Show a confirmation modal before deletion
  • Loading branch information
MonkeyDo committed May 22, 2024
2 parents a914162 + 9a0249b commit 18e6eee
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 35 deletions.
78 changes: 78 additions & 0 deletions frontend/js/src/components/ConfirmationModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import NiceModal, { useModal } from "@ebay/nice-modal-react";
import * as React from "react";

type ConfirmationModalProps = {
body?: JSX.Element;
};

export default NiceModal.create((props: ConfirmationModalProps) => {
const modal = useModal();
const closeModal = React.useCallback(() => {
modal.hide();
document?.body?.classList?.remove("modal-open");
setTimeout(modal.remove, 200);
}, [modal]);

const { body } = props;

const onCancel = () => {
modal.reject();
closeModal();
};
const onConfirm = () => {
modal.resolve();
closeModal();
};

return (
<div
id="ConfirmationModal"
className={`modal fade ${modal.visible ? "in" : ""}`}
tabIndex={-1}
role="dialog"
aria-labelledby="confirmationModalLabel"
data-backdrop="static"
>
<div className="modal-dialog modal-sm" role="document">
<div className="modal-content">
<div className="modal-header">
<button
type="button"
className="close"
data-dismiss="modal"
aria-label="Close"
>
<span aria-hidden="true">&times;</span>
</button>
<h4 className="modal-title" id="confirmationModalLabel">
Confirm this action
</h4>
</div>

<div className="modal-body">
{body || <>Do you confirm this action?</>}
</div>

<div className="modal-footer">
<button
type="button"
className="btn btn-default"
data-dismiss="modal"
onClick={onCancel}
>
Cancel
</button>
<button
type="button"
className="btn btn-danger"
onClick={onConfirm}
data-dismiss="modal"
>
Confirm
</button>
</div>
</div>
</div>
</div>
);
});
59 changes: 36 additions & 23 deletions frontend/js/src/settings/delete-listens/DeleteListens.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,40 @@
import * as React from "react";

import { useLocation, Link, useNavigate } from "react-router-dom";
import { Link, useNavigate } from "react-router-dom";
import { toast } from "react-toastify";
import { Helmet } from "react-helmet";
import NiceModal from "@ebay/nice-modal-react";
import { isString } from "lodash";
import { ToastMsg } from "../../notifications/Notifications";
import GlobalAppContext from "../../utils/GlobalAppContext";
import ExportButtons from "../export/ExportButtons";
import ConfirmationModal from "../../components/ConfirmationModal";

export default function DeleteListens() {
const { currentUser } = React.useContext(GlobalAppContext);
const { name } = currentUser;
const location = useLocation();
const navigate = useNavigate();

// eslint-disable-next-line consistent-return
const deleteListens = async (e: React.FormEvent<HTMLFormElement>) => {
const deleteListens = async (e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();

try {
const confirmMessage = (
<>
<span className="text-danger">
You are about to delete all of your listens.
</span>
<br />
<b>This action cannot be undone.</b>
<br />
Are you certain you want to proceed?
</>
);
await NiceModal.show(ConfirmationModal, { body: confirmMessage });
} catch (error) {
toast.info("Canceled listen deletion");
return undefined;
}
try {
const response = await fetch("/settings/delete-listens/", {
method: "POST",
Expand All @@ -26,7 +44,9 @@ export default function DeleteListens() {
});
if (!response.ok) {
const errJson = await response.json();
throw errJson.message ?? "Error";
throw isString(errJson.error)
? errJson.error
: errJson.toString() || "Error";
}

toast.success(
Expand All @@ -46,14 +66,6 @@ export default function DeleteListens() {
message={
<>
Error while deleting listens for user {name}: {error.toString()}
<button
type="button"
onClick={() => {
navigate("/settings/");
}}
>
Back to setting
</button>
</>
}
/>
Expand Down Expand Up @@ -90,16 +102,17 @@ export default function DeleteListens() {
<ExportButtons feedback={false} />
<br />

<form onSubmit={deleteListens}>
<button
id="btn-delete-listens"
className="btn btn-danger btn-lg"
type="submit"
style={{ width: "250px" }}
>
Delete listens
</button>
</form>
<button
id="btn-delete-listens"
className="btn btn-danger btn-lg"
type="button"
style={{ width: "250px" }}
onClick={deleteListens}
data-toggle="modal"
data-target="#ConfirmationModal"
>
Delete listens
</button>
</>
);
}
43 changes: 31 additions & 12 deletions frontend/js/src/settings/delete/DeleteAccount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,36 @@ import * as React from "react";
import { redirect } from "react-router-dom";
import { toast } from "react-toastify";
import { Helmet } from "react-helmet";
import NiceModal from "@ebay/nice-modal-react";
import { ToastMsg } from "../../notifications/Notifications";
import GlobalAppContext from "../../utils/GlobalAppContext";
import ExportButtons from "../export/ExportButtons";
import ConfirmationModal from "../../components/ConfirmationModal";

export default function DeleteAccount() {
const { currentUser } = React.useContext(GlobalAppContext);
const { name } = currentUser;

// eslint-disable-next-line consistent-return
const deleteAccount = async (e: React.FormEvent<HTMLFormElement>) => {
const deleteAccount = async (e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();

try {
const confirmMessage = (
<>
<span className="text-danger">
You are about to delete your account.
</span>
<br />
<b>This action cannot be undone.</b>
<br />
Are you certain you want to proceed?
</>
);
await NiceModal.show(ConfirmationModal, { body: confirmMessage });
} catch (error) {
toast.info("Canceled account deletion");
return undefined;
}
try {
const response = await fetch("/settings/delete/", {
method: "POST",
Expand Down Expand Up @@ -61,16 +79,17 @@ export default function DeleteAccount() {
<ExportButtons />
<br />
<p className="text-brand text-danger">This cannot be undone!</p>
<form onSubmit={deleteAccount}>
<button
id="btn-delete-user"
className="btn btn-danger btn-lg"
type="submit"
style={{ width: "250px" }}
>
Delete account
</button>
</form>
<button
id="btn-delete-user"
className="btn btn-danger btn-lg"
type="button"
style={{ width: "250px" }}
onClick={deleteAccount}
data-toggle="modal"
data-target="#ConfirmationModal"
>
Delete account
</button>
</>
);
}

0 comments on commit 18e6eee

Please sign in to comment.