import { Radio, RadioGroup } from "@mui/joy"; import { Button, Input } from "@usememos/mui"; import { sortBy } from "lodash-es"; import { MoreVerticalIcon } from "lucide-react"; import { observer } from "mobx-react-lite"; import React, { useEffect, useState } from "react"; import { toast } from "react-hot-toast"; import { userServiceClient } from "@/grpcweb"; import useCurrentUser from "@/hooks/useCurrentUser"; import { userStore } from "@/store/v2"; import { State } from "@/types/proto/api/v1/common"; import { User, User_Role } from "@/types/proto/api/v1/user_service"; import { useTranslate } from "@/utils/i18n"; import showCreateUserDialog from "../CreateUserDialog"; import { Popover, PopoverContent, PopoverTrigger } from "../ui/Popover"; interface LocalState { creatingUser: User; } const MemberSection = observer(() => { const t = useTranslate(); const currentUser = useCurrentUser(); 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 stringifyUserRole = (role: User_Role) => { if (role === User_Role.HOST) { return "Host"; } else if (role === User_Role.ADMIN) { return t("setting.member-section.admin"); } else { return t("setting.member-section.user"); } }; 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 handleArchiveUserClick = async (user: User) => { const confirmed = window.confirm(t("setting.member-section.archive-warning", { username: user.displayName })); if (confirmed) { await userServiceClient.updateUser({ user: { name: user.name, state: State.ARCHIVED, }, updateMask: ["state"], }); fetchUsers(); } }; const handleRestoreUserClick = async (user: User) => { await userServiceClient.updateUser({ user: { name: user.name, state: State.NORMAL, }, updateMask: ["state"], }); fetchUsers(); }; const handleDeleteUserClick = async (user: User) => { const confirmed = window.confirm(t("setting.member-section.delete-warning", { username: user.displayName })); 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) => ( ))}
{t("common.username")} {t("common.role")} {t("common.nickname")} {t("common.email")}
{user.username} {user.state === State.ARCHIVED && "(Archived)"} {stringifyUserRole(user.role)} {user.displayName} {user.email} {currentUser?.name === user.name ? ( {t("common.yourself")} ) : (
{user.state === State.NORMAL ? ( ) : ( <> )}
)}
); }); export default MemberSection;