import { useState } from "react"; import { useRouter } from "next/router"; import Link from "next/link"; import { observer } from "mobx-react-lite"; // mobx store import { useMobxStore } from "lib/mobx/store-provider"; // hooks import useToast from "hooks/use-toast"; // components import { ConfirmProjectMemberRemove } from "components/project"; // ui import { CustomSelect, Tooltip } from "@plane/ui"; // icons import { ChevronDown, Dot, XCircle } from "lucide-react"; // constants import { ROLE } from "constants/workspace"; // types import { IProjectMember, TUserProjectRole } from "types"; type Props = { member: IProjectMember; }; export const ProjectMemberListItem: React.FC = observer((props) => { const { member } = props; // states const [removeMemberModal, setRemoveMemberModal] = useState(false); // router const router = useRouter(); const { workspaceSlug, projectId } = router.query; // store const { user: { currentUser, currentProjectMemberInfo, currentProjectRole, leaveProject }, projectMember: { removeMemberFromProject, updateMember }, } = useMobxStore(); // hooks const { setToastAlert } = useToast(); // derived values const isAdmin = currentProjectRole === 20; const memberDetails = member.member; const handleRemove = async () => { if (!workspaceSlug || !projectId) return; if (memberDetails.id === currentUser?.id) { await leaveProject(workspaceSlug.toString(), projectId.toString()) .then(() => router.push(`/${workspaceSlug}/projects`)) .catch((err) => setToastAlert({ type: "error", title: "Error", message: err?.error || "Something went wrong. Please try again.", }) ); } else await removeMemberFromProject(workspaceSlug.toString(), projectId.toString(), member.id).catch((err) => setToastAlert({ type: "error", title: "Error", message: err?.error || "Something went wrong. Please try again.", }) ); }; return ( <> setRemoveMemberModal(false)} data={member.member} onSubmit={handleRemove} />
{memberDetails.avatar && memberDetails.avatar !== "" ? ( {memberDetails.display_name ) : ( {(memberDetails.display_name ?? memberDetails.email ?? "?")[0]} )}
{memberDetails.first_name} {memberDetails.last_name}

{memberDetails.display_name}

{isAdmin && ( <>

{memberDetails.email}

)}
{ROLE[member.role as keyof typeof ROLE]} {memberDetails.id !== currentProjectMemberInfo?.id && ( )}
} value={member.role} onChange={(value: TUserProjectRole | undefined) => { if (!workspaceSlug || !projectId) return; updateMember(workspaceSlug.toString(), projectId.toString(), member.id, { role: value, }).catch((err) => { const error = err.error; const errorString = Array.isArray(error) ? error[0] : error; setToastAlert({ type: "error", title: "Error!", message: errorString ?? "An error occurred while updating member role. Please try again.", }); }); }} disabled={ memberDetails.id === currentUser?.id || !member.member || (currentProjectRole && currentProjectRole !== 20 && currentProjectRole < member.role) } placement="bottom-end" > {Object.keys(ROLE).map((key) => { if (currentProjectRole && currentProjectRole !== 20 && currentProjectRole < parseInt(key)) return null; return ( <>{ROLE[parseInt(key) as keyof typeof ROLE]} ); })} {isAdmin && ( )}
); });