improved admin and events tables
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import { apiCall } from "@/lib";
|
||||
import { User } from "@/Zustand";
|
||||
import zustand, { User } from "@/Zustand";
|
||||
import {
|
||||
Button,
|
||||
ButtonGroup,
|
||||
Checkbox,
|
||||
Table,
|
||||
TableBody,
|
||||
@@ -12,14 +13,17 @@ import {
|
||||
Tooltip,
|
||||
} from "@heroui/react";
|
||||
import { useAsyncList } from "@react-stately/data";
|
||||
import { FormEvent, useState } from "react";
|
||||
import { useState } from "react";
|
||||
import AddUser from "./AddUser";
|
||||
import { AddLarge, Edit } from "@carbon/icons-react";
|
||||
import { AddLarge, Edit, TrashCan } from "@carbon/icons-react";
|
||||
import EditUser from "./EditUser";
|
||||
import DeleteConfirmation from "@/components/DeleteConfirmation";
|
||||
|
||||
export default function Users() {
|
||||
const [showAddUser, setShowAddUser] = useState(false);
|
||||
const [editUser, setEditUser] = useState<User | undefined>();
|
||||
const [deleteUser, setDeleteUser] = useState<User | undefined>();
|
||||
const loggedInUser = zustand((state) => state.user);
|
||||
|
||||
const users = useAsyncList<User>({
|
||||
async load() {
|
||||
@@ -64,23 +68,22 @@ export default function Users() {
|
||||
},
|
||||
});
|
||||
|
||||
// send an addUser request to the backend then reload the table
|
||||
async function addUser(e: FormEvent<HTMLFormElement>) {
|
||||
const data = Object.fromEntries(new FormData(e.currentTarget));
|
||||
async function sendDeleteUser(userName: User["userName"] | undefined) {
|
||||
if (!!userName) {
|
||||
const result = await apiCall("DELETE", "users", {
|
||||
userName,
|
||||
});
|
||||
|
||||
const result = await apiCall("POST", "users", undefined, {
|
||||
...data,
|
||||
admin: data.admin === "admin",
|
||||
});
|
||||
|
||||
if (result.ok) {
|
||||
users.reload();
|
||||
if (result.ok) {
|
||||
users.reload();
|
||||
setDeleteUser(undefined);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// content above the user-tabel
|
||||
const topContent = (
|
||||
<>
|
||||
<div>
|
||||
<Button
|
||||
color="primary"
|
||||
startContent={<AddLarge />}
|
||||
@@ -88,7 +91,7 @@ export default function Users() {
|
||||
>
|
||||
Add User
|
||||
</Button>
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
@@ -101,6 +104,13 @@ export default function Users() {
|
||||
topContent={topContent}
|
||||
sortDescriptor={users.sortDescriptor}
|
||||
onSortChange={users.sort}
|
||||
topContentPlacement="outside"
|
||||
classNames={{
|
||||
wrapper: "bg-accent-4",
|
||||
tr: "even:bg-accent-5 ",
|
||||
th: "font-subheadline text-xl text-accent-1 bg-transparent ",
|
||||
thead: "[&>tr]:first:!shadow-border",
|
||||
}}
|
||||
>
|
||||
<TableHeader>
|
||||
<TableColumn allowsSorting key="userName">
|
||||
@@ -119,16 +129,34 @@ export default function Users() {
|
||||
<Checkbox isSelected={user.admin} />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Button
|
||||
isIconOnly
|
||||
variant="light"
|
||||
size="sm"
|
||||
onPress={() => setEditUser(user)}
|
||||
>
|
||||
<Tooltip content="Edit user">
|
||||
<Edit />
|
||||
</Tooltip>
|
||||
</Button>
|
||||
<ButtonGroup>
|
||||
<Button
|
||||
isIconOnly
|
||||
variant="light"
|
||||
size="sm"
|
||||
onPress={() => setEditUser(user)}
|
||||
isDisabled={
|
||||
user.userName === "admin" &&
|
||||
loggedInUser?.userName !== "admin"
|
||||
}
|
||||
>
|
||||
<Tooltip content="Edit user">
|
||||
<Edit />
|
||||
</Tooltip>
|
||||
</Button>
|
||||
<Button
|
||||
isIconOnly
|
||||
variant="light"
|
||||
size="sm"
|
||||
color="danger"
|
||||
isDisabled={["admin", loggedInUser?.userName].includes(
|
||||
user.userName,
|
||||
)}
|
||||
onPress={() => setDeleteUser(user)}
|
||||
>
|
||||
<TrashCan />
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
@@ -138,11 +166,14 @@ export default function Users() {
|
||||
<AddUser
|
||||
isOpen={showAddUser}
|
||||
onOpenChange={setShowAddUser}
|
||||
onSubmit={(e) => void addUser(e)}
|
||||
onSuccess={() => {
|
||||
setShowAddUser(false);
|
||||
users.reload();
|
||||
}}
|
||||
/>
|
||||
<EditUser
|
||||
isOpen={editUser !== undefined}
|
||||
user={editUser}
|
||||
value={editUser}
|
||||
onOpenChange={(isOpen) =>
|
||||
!isOpen ? setEditUser(undefined) : undefined
|
||||
}
|
||||
@@ -151,6 +182,16 @@ export default function Users() {
|
||||
setEditUser(undefined);
|
||||
}}
|
||||
/>
|
||||
|
||||
<DeleteConfirmation
|
||||
isOpen={!!deleteUser}
|
||||
onOpenChange={(isOpen) => (!isOpen ? setDeleteUser(undefined) : null)}
|
||||
onDelete={() => sendDeleteUser(deleteUser?.userName)}
|
||||
itemName="User"
|
||||
>
|
||||
{" "}
|
||||
The user <span>{deleteUser?.userName}</span> will be deleted.
|
||||
</DeleteConfirmation>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user