diff options
| author | Mohamed Bassem <me@mbassem.com> | 2025-07-10 19:34:31 +0000 |
|---|---|---|
| committer | Mohamed Bassem <me@mbassem.com> | 2025-07-10 20:45:45 +0000 |
| commit | 333d1610fad10e70759545f223959503288a02c6 (patch) | |
| tree | 3354a21d4fa3b4dc75d03ba5f940bd3c213078fd /apps/web/components/admin/UserList.tsx | |
| parent | 93049e864ae6d281b60c23dee868bca3f585dd4a (diff) | |
| download | karakeep-333d1610fad10e70759545f223959503288a02c6.tar.zst | |
feat: Add invite user support
Diffstat (limited to 'apps/web/components/admin/UserList.tsx')
| -rw-r--r-- | apps/web/components/admin/UserList.tsx | 214 |
1 files changed, 112 insertions, 102 deletions
diff --git a/apps/web/components/admin/UserList.tsx b/apps/web/components/admin/UserList.tsx index 2dd86277..3313fe60 100644 --- a/apps/web/components/admin/UserList.tsx +++ b/apps/web/components/admin/UserList.tsx @@ -19,6 +19,8 @@ import { useSession } from "next-auth/react"; import ActionConfirmingDialog from "../ui/action-confirming-dialog"; import AddUserDialog from "./AddUserDialog"; +import { AdminCard } from "./AdminCard"; +import InvitesList from "./InvitesList"; import ResetPasswordDialog from "./ResetPasswordDialog"; import UpdateUserDialog from "./UpdateUserDialog"; @@ -57,110 +59,118 @@ export default function UsersSection() { return ( <div className="flex flex-col gap-4"> - <div className="mb-2 flex items-center justify-between text-xl font-medium"> - <span>{t("admin.users_list.users_list")}</span> - <AddUserDialog> - <ButtonWithTooltip tooltip="Create User" variant="outline"> - <UserPlus size={16} /> - </ButtonWithTooltip> - </AddUserDialog> - </div> + <AdminCard> + <div className="flex flex-col gap-4"> + <div className="mb-2 flex items-center justify-between text-xl font-medium"> + <span>{t("admin.users_list.users_list")}</span> + <AddUserDialog> + <ButtonWithTooltip tooltip="Create User" variant="outline"> + <UserPlus size={16} /> + </ButtonWithTooltip> + </AddUserDialog> + </div> - <Table> - <TableHeader className="bg-gray-200"> - <TableHead>{t("common.name")}</TableHead> - <TableHead>{t("common.email")}</TableHead> - <TableHead>{t("admin.users_list.num_bookmarks")}</TableHead> - <TableHead>{t("common.quota")}</TableHead> - <TableHead>Storage Quota</TableHead> - <TableHead>{t("admin.users_list.asset_sizes")}</TableHead> - <TableHead>{t("common.role")}</TableHead> - <TableHead>{t("admin.users_list.local_user")}</TableHead> - <TableHead>{t("common.actions")}</TableHead> - </TableHeader> - <TableBody> - {users.users.map((u) => ( - <TableRow key={u.id}> - <TableCell className="py-1">{u.name}</TableCell> - <TableCell className="py-1">{u.email}</TableCell> - <TableCell className="py-1"> - {userStats[u.id].numBookmarks} - </TableCell> - <TableCell className="py-1"> - {u.bookmarkQuota ?? t("admin.users_list.unlimited")} - </TableCell> - <TableCell className="py-1"> - {u.storageQuota - ? toHumanReadableSize(u.storageQuota) - : t("admin.users_list.unlimited")} - </TableCell> - <TableCell className="py-1"> - {toHumanReadableSize(userStats[u.id].assetSizes)} - </TableCell> - <TableCell className="py-1"> - {u.role && t(`common.roles.${u.role}`)} - </TableCell> - <TableCell className="py-1"> - {u.localUser ? <Check /> : <X />} - </TableCell> - <TableCell className="flex gap-1 py-1"> - <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); - }} + <Table> + <TableHeader className="bg-gray-200"> + <TableHead>{t("common.name")}</TableHead> + <TableHead>{t("common.email")}</TableHead> + <TableHead>{t("admin.users_list.num_bookmarks")}</TableHead> + <TableHead>{t("common.quota")}</TableHead> + <TableHead>Storage Quota</TableHead> + <TableHead>{t("admin.users_list.asset_sizes")}</TableHead> + <TableHead>{t("common.role")}</TableHead> + <TableHead>{t("admin.users_list.local_user")}</TableHead> + <TableHead>{t("common.actions")}</TableHead> + </TableHeader> + <TableBody> + {users.users.map((u) => ( + <TableRow key={u.id}> + <TableCell className="py-1">{u.name}</TableCell> + <TableCell className="py-1">{u.email}</TableCell> + <TableCell className="py-1"> + {userStats[u.id].numBookmarks} + </TableCell> + <TableCell className="py-1"> + {u.bookmarkQuota ?? t("admin.users_list.unlimited")} + </TableCell> + <TableCell className="py-1"> + {u.storageQuota + ? toHumanReadableSize(u.storageQuota) + : t("admin.users_list.unlimited")} + </TableCell> + <TableCell className="py-1"> + {toHumanReadableSize(userStats[u.id].assetSizes)} + </TableCell> + <TableCell className="py-1"> + {u.role && t(`common.roles.${u.role}`)} + </TableCell> + <TableCell className="py-1"> + {u.localUser ? <Check /> : <X />} + </TableCell> + <TableCell className="flex gap-1 py-1"> + <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> + )} > - Delete - </ActionButton> - )} - > - <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")} - variant="outline" - disabled={session!.user.id == u.id || !u.localUser} - > - <KeyRound size={16} color="red" /> - </ButtonWithTooltip> - </ResetPasswordDialog> - <UpdateUserDialog - userId={u.id} - currentRole={u.role!} - currentQuota={u.bookmarkQuota} - currentStorageQuota={u.storageQuota} - > - <ButtonWithTooltip - tooltip="Edit User" - variant="outline" - disabled={session!.user.id == u.id} - > - <Pencil size={16} color="red" /> - </ButtonWithTooltip> - </UpdateUserDialog> - </TableCell> - </TableRow> - ))} - </TableBody> - </Table> + <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")} + variant="outline" + disabled={session!.user.id == u.id || !u.localUser} + > + <KeyRound size={16} color="red" /> + </ButtonWithTooltip> + </ResetPasswordDialog> + <UpdateUserDialog + userId={u.id} + currentRole={u.role!} + currentQuota={u.bookmarkQuota} + currentStorageQuota={u.storageQuota} + > + <ButtonWithTooltip + tooltip="Edit User" + variant="outline" + disabled={session!.user.id == u.id} + > + <Pencil size={16} color="red" /> + </ButtonWithTooltip> + </UpdateUserDialog> + </TableCell> + </TableRow> + ))} + </TableBody> + </Table> + </div> + </AdminCard> + + <AdminCard> + <InvitesList /> + </AdminCard> </div> ); } |
