import { Button, Dropdown, Input, Menu, MenuButton, MenuItem, Radio, RadioGroup } from "@mui/joy"; import { sortBy } from "lodash-es"; import { MoreVerticalIcon } from "lucide-react"; import React, { useEffect, useState } from "react"; import { toast } from "react-hot-toast"; import { userServiceClient } from "@/grpcweb"; import useCurrentUser from "@/hooks/useCurrentUser"; import { stringifyUserRole, useUserStore } from "@/store/v1"; import { RowStatus } from "@/types/proto/api/v1/common"; import { User, User_Role } from "@/types/proto/api/v1/user_service"; import { useTranslate } from "@/utils/i18n"; import showChangeMemberPasswordDialog from "../ChangeMemberPasswordDialog"; interface State { creatingUser: User; } const MemberSection = () => { const t = useTranslate(); const currentUser = useCurrentUser(); const userStore = useUserStore(); const [state, setState] = useState({ creatingUser: User.fromPartial({ username: "", password: "", role: User_Role.USER, }), }); const [users, setUsers] = useState([]); const sortedUsers = sortBy(users, "id"); useEffect(() => { fetchUsers(); }, []); const fetchUsers = async () => { const users = await userStore.fetchUsers(); setUsers(users); }; const handleUsernameInputChange = (event: React.ChangeEvent) => { setState({ ...state, creatingUser: { ...state.creatingUser, username: event.target.value, }, }); }; const handlePasswordInputChange = (event: React.ChangeEvent) => { setState({ ...state, creatingUser: { ...state.creatingUser, password: event.target.value, }, }); }; const handleUserRoleInputChange = (event: React.ChangeEvent) => { setState({ ...state, creatingUser: { ...state.creatingUser, role: event.target.value as User_Role, }, }); }; const handleCreateUserBtnClick = async () => { if (state.creatingUser.username === "" || state.creatingUser.password === "") { toast.error(t("message.fill-all")); return; } try { await userServiceClient.createUser({ user: { username: state.creatingUser.username, password: state.creatingUser.password, role: state.creatingUser.role, }, }); } catch (error: any) { toast.error(error.details); } await fetchUsers(); setState({ ...state, creatingUser: User.fromPartial({ username: "", password: "", role: User_Role.USER, }), }); }; const handleChangePasswordClick = (user: User) => { showChangeMemberPasswordDialog(user); }; const handleArchiveUserClick = async (user: User) => { const confirmed = window.confirm(t("setting.member-section.archive-warning", { username: user.nickname })); if (confirmed) { await userServiceClient.updateUser({ user: { name: user.name, rowStatus: RowStatus.ARCHIVED, }, updateMask: ["row_status"], }); fetchUsers(); } }; const handleRestoreUserClick = async (user: User) => { await userServiceClient.updateUser({ user: { name: user.name, rowStatus: RowStatus.ACTIVE, }, updateMask: ["row_status"], }); fetchUsers(); }; const handleDeleteUserClick = async (user: User) => { const confirmed = window.confirm(t("setting.member-section.delete-warning", { username: user.nickname })); if (confirmed) { await userStore.deleteUser(user.name); fetchUsers(); } }; return (

{t("setting.member-section.create-a-member")}

{t("common.username")}
{t("common.password")}
{t("common.role")}
{t("setting.member-list")}
{sortedUsers.map((user) => ( ))}
ID {t("common.role")} {t("common.username")} {t("common.nickname")} {t("common.email")}
{user.id} {stringifyUserRole(user.role)} {user.username} {user.rowStatus === RowStatus.ARCHIVED && "(Archived)"} {user.nickname} {user.email} {currentUser?.id === user.id ? ( {t("common.yourself")} ) : ( handleChangePasswordClick(user)}> {t("setting.account-section.change-password")} {user.rowStatus === RowStatus.ACTIVE ? ( handleArchiveUserClick(user)}>{t("setting.member-section.archive-member")} ) : ( <> handleRestoreUserClick(user)}>{t("common.restore")} handleDeleteUserClick(user)}>{t("setting.member-section.delete-member")} )} )}
); }; export default MemberSection;