import React, { useState, useEffect } from "react"; import { ListGroup, Row, Col, Dropdown, Spinner, Button, } from "react-bootstrap"; import OperationDialog from "../common/OperationDialog"; import { User, AuthUser } from "@/services/user"; import { getHttpUserClient, HttpUser } from "@/http/user"; const kModify = "modify"; const kDelete = "delete"; type TModify = typeof kModify; type TDelete = typeof kDelete; type ContextMenuItem = TModify | TDelete; interface UserCardProps { on: { [key in ContextMenuItem]: () => void }; user: User; } const UserItem: React.FC = ({ user, on }) => { return (
@{user.username + " "} {user.nickname}
{user.permissions.map((permission) => { return ( {permission + " "} ); })}
Manage Modify Delete
); }; interface DialogProps { open: boolean; close: () => void; token: string; data: TData; onSuccess: (data: TReturn) => void; } const CreateUserDialog: React.FC> = ({ open, close, token, onSuccess, }) => { return ( getHttpUserClient().createUser( { username, password, }, token ) } close={close} open={open} onSuccessAndClose={onSuccess} /> ); }; const UsernameLabel: React.FC = (props) => { return {props.children}; }; const UserDeleteDialog: React.FC> = ({ open, close, token, data: { username }, onSuccess }) => { return ( ( <> You are deleting user {username} ! )} onProcess={() => getHttpUserClient().delete(username, token)} onSuccessAndClose={onSuccess} /> ); }; const UserModifyDialog: React.FC> = ({ open, close, token, data: { oldUser }, onSuccess }) => { return ( ( <> You are change the password of user {oldUser.username} ! )} inputScheme={ [ { type: "text", label: "New Username", initValue: oldUser.username }, { type: "text", label: "New Password" }, { type: "text", label: "New Nickname", initValue: oldUser.nickname }, ] as const } onProcess={([username, password, nickname]) => getHttpUserClient().patch( oldUser.username, { username: username !== oldUser.username ? username : undefined, password: password !== "" ? password : undefined, nickname: nickname !== oldUser.nickname ? nickname : undefined, }, token ) } onSuccessAndClose={onSuccess} /> ); }; interface UserAdminProps { user: AuthUser; } const UserAdmin: React.FC = (props) => { type DialogInfo = | null | { type: "create"; } | { type: TModify; user: HttpUser; } | { type: TDelete; username: string }; const [users, setUsers] = useState(null); const [dialog, setDialog] = useState(null); const [usersVersion, setUsersVersion] = useState(0); const updateUsers = (): void => { setUsersVersion(usersVersion + 1); }; const token = props.user.token; useEffect(() => { let subscribe = true; void getHttpUserClient() .list() .then((us) => { if (subscribe) { setUsers(us); } }); return () => { subscribe = false; }; }, [usersVersion]); let dialogNode: React.ReactNode; if (dialog) { switch (dialog.type) { case "create": dialogNode = ( setDialog(null)} token={token} data={undefined} onSuccess={updateUsers} /> ); break; case "delete": dialogNode = ( setDialog(null)} token={token} data={{ username: dialog.username }} onSuccess={updateUsers} /> ); break; case kModify: dialogNode = ( setDialog(null)} token={token} data={{ oldUser: dialog.user }} onSuccess={updateUsers} /> ); break; } } if (users) { const userComponents = users.map((user) => { return ( { setDialog({ type: "modify", user, }); }, delete: () => { setDialog({ type: "delete", username: user.username, }); }, }} /> ); }); return ( <> {userComponents} {dialogNode} ); } else { return ; } }; export default UserAdmin;