"use client"; import { ActionButton } from "@/components/ui/action-button"; import { ButtonWithTooltip } from "@/components/ui/button"; import { toast } from "@/components/ui/sonner"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { useSession } from "@/lib/auth/client"; import { useTranslation } from "@/lib/i18n/client"; import { useMutation, useQueryClient, useSuspenseQuery, } from "@tanstack/react-query"; import { Check, KeyRound, Pencil, Trash, UserPlus, X } from "lucide-react"; import { useTRPC } from "@karakeep/shared-react/trpc"; import ActionConfirmingDialog from "../ui/action-confirming-dialog"; import AddUserDialog from "./AddUserDialog"; import { AdminCard } from "./AdminCard"; import ResetPasswordDialog from "./ResetPasswordDialog"; import UpdateUserDialog from "./UpdateUserDialog"; function toHumanReadableSize(size: number) { const sizes = ["Bytes", "KB", "MB", "GB", "TB"]; if (size === 0) return "0 Bytes"; const i = Math.floor(Math.log(size) / Math.log(1024)); return (size / Math.pow(1024, i)).toFixed(2) + " " + sizes[i]; } export default function UsersSection() { const api = useTRPC(); const queryClient = useQueryClient(); const { t } = useTranslation(); const { data: session } = useSession(); const { data: { users }, } = useSuspenseQuery(api.users.list.queryOptions()); const { data: userStats } = useSuspenseQuery( api.admin.userStats.queryOptions(), ); const { mutateAsync: deleteUser, isPending: isDeletionPending } = useMutation( api.users.delete.mutationOptions({ onSuccess: () => { toast({ description: "User deleted", }); queryClient.invalidateQueries(api.users.list.pathFilter()); }, onError: (e) => { toast({ variant: "destructive", description: `Something went wrong: ${e.message}`, }); }, }), ); return (
{t("admin.users_list.users_list")}
{t("common.name")} {t("common.email")} {t("admin.users_list.num_bookmarks")} {t("admin.users_list.asset_sizes")} {t("common.role")} {t("admin.users_list.local_user")} {t("common.actions")} {users.map((u) => ( {u.name} {u.email} {userStats[u.id].numBookmarks} /{" "} {u.bookmarkQuota ?? t("admin.users_list.unlimited")} {toHumanReadableSize(userStats[u.id].assetSizes)} /{" "} {u.storageQuota ? toHumanReadableSize(u.storageQuota) : t("admin.users_list.unlimited")} {u.role && t(`common.roles.${u.role}`)} {u.localUser ? : } ( { await deleteUser({ userId: u.id }); setDialogOpen(false); }} > Delete )} > ))}
); }