diff options
| author | Deepanshu Saini <76242952+deepanshu2711@users.noreply.github.com> | 2025-06-21 19:01:45 +0530 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-21 14:31:45 +0100 |
| commit | 0f4c616230f570b2323fbc473e6f857b36abd5ba (patch) | |
| tree | d84f675985ba7a68b2b1c69c6eff9fa16bc052c9 | |
| parent | 426beff15aad0c164e81996b3f6754fdc6ecfc29 (diff) | |
| download | karakeep-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>
| -rw-r--r-- | apps/web/components/admin/UserList.tsx | 41 | ||||
| -rw-r--r-- | apps/web/lib/i18n/locales/en/translation.json | 1 |
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", |
