aboutsummaryrefslogtreecommitdiffstats
path: root/apps/web
diff options
context:
space:
mode:
authorDeepanshu Saini <76242952+deepanshu2711@users.noreply.github.com>2025-06-21 19:01:45 +0530
committerGitHub <noreply@github.com>2025-06-21 14:31:45 +0100
commit0f4c616230f570b2323fbc473e6f857b36abd5ba (patch)
treed84f675985ba7a68b2b1c69c6eff9fa16bc052c9 /apps/web
parent426beff15aad0c164e81996b3f6754fdc6ecfc29 (diff)
downloadkarakeep-0f4c616230f570b2323fbc473e6f857b36abd5ba.tar.zst
feat(admin): add confirmation dialog for user deletion (#1648) (#1649)
* feat(admin): add confirmation dialog for user deletion (#1648) * No need to manage dialog state --------- Co-authored-by: Mohamed Bassem <me@mbassem.com>
Diffstat (limited to 'apps/web')
-rw-r--r--apps/web/components/admin/UserList.tsx41
-rw-r--r--apps/web/lib/i18n/locales/en/translation.json1
2 files changed, 32 insertions, 10 deletions
diff --git a/apps/web/components/admin/UserList.tsx b/apps/web/components/admin/UserList.tsx
index 3dfcaad1..c32c13e3 100644
--- a/apps/web/components/admin/UserList.tsx
+++ b/apps/web/components/admin/UserList.tsx
@@ -1,6 +1,6 @@
"use client";
-import { ActionButtonWithTooltip } from "@/components/ui/action-button";
+import { ActionButton } from "@/components/ui/action-button";
import { ButtonWithTooltip } from "@/components/ui/button";
import LoadingSpinner from "@/components/ui/spinner";
import {
@@ -17,6 +17,7 @@ import { api } from "@/lib/trpc";
import { Check, KeyRound, Pencil, Trash, UserPlus, X } from "lucide-react";
import { useSession } from "next-auth/react";
+import ActionConfirmingDialog from "../ui/action-confirming-dialog";
import AddUserDialog from "./AddUserDialog";
import ChangeRoleDialog from "./ChangeRoleDialog";
import ResetPasswordDialog from "./ResetPasswordDialog";
@@ -34,7 +35,7 @@ export default function UsersSection() {
const invalidateUserList = api.useUtils().users.list.invalidate;
const { data: users } = api.users.list.useQuery();
const { data: userStats } = api.admin.userStats.useQuery();
- const { mutate: deleteUser, isPending: isDeletionPending } =
+ const { mutateAsync: deleteUser, isPending: isDeletionPending } =
api.users.delete.useMutation({
onSuccess: () => {
toast({
@@ -93,15 +94,35 @@ export default function UsersSection() {
{u.localUser ? <Check /> : <X />}
</TableCell>
<TableCell className="flex gap-1 py-1">
- <ActionButtonWithTooltip
- tooltip={t("admin.users_list.delete_user")}
- variant="outline"
- onClick={() => deleteUser({ userId: u.id })}
- loading={isDeletionPending}
- disabled={session!.user.id == u.id}
+ <ActionConfirmingDialog
+ title={t("admin.users_list.delete_user")}
+ description={t(
+ "admin.users_list.delete_user_confirm_description",
+ {
+ name: u.name ?? "this user",
+ },
+ )}
+ actionButton={(setDialogOpen) => (
+ <ActionButton
+ variant="destructive"
+ loading={isDeletionPending}
+ onClick={async () => {
+ await deleteUser({ userId: u.id });
+ setDialogOpen(false);
+ }}
+ >
+ Delete
+ </ActionButton>
+ )}
>
- <Trash size={16} color="red" />
- </ActionButtonWithTooltip>
+ <ButtonWithTooltip
+ tooltip={t("admin.users_list.delete_user")}
+ variant="outline"
+ disabled={session!.user.id == u.id}
+ >
+ <Trash size={16} color="red" />
+ </ButtonWithTooltip>
+ </ActionConfirmingDialog>
<ResetPasswordDialog userId={u.id}>
<ButtonWithTooltip
tooltip={t("admin.users_list.reset_password")}
diff --git a/apps/web/lib/i18n/locales/en/translation.json b/apps/web/lib/i18n/locales/en/translation.json
index 3ad4a25e..1801788e 100644
--- a/apps/web/lib/i18n/locales/en/translation.json
+++ b/apps/web/lib/i18n/locales/en/translation.json
@@ -275,6 +275,7 @@
"change_role": "Change Role",
"reset_password": "Reset Password",
"delete_user": "Delete User",
+ "delete_user_confirm_description": "Are you sure you want to delete user \"{{name}}\"?",
"num_bookmarks": "Num Bookmarks",
"asset_sizes": "Asset Sizes",
"local_user": "Local User",