import { useState } from 'react' import { Dialog, Toast } from 'antd-mobile' import { projectApi } from '../../api/task.js' import { useAuth } from '../../auth/AuthContext.jsx' // 项目成员 (T-PJ-06/07, T-AS-06, T-PM-02) export default function ProjectMembers({ project, onClose, onChanged }) { const { user } = useAuth() const meId = user?.id const [members, setMembers] = useState(project.members || []) const [adding, setAdding] = useState(false) const [email, setEmail] = useState('') async function add() { const e = email.trim() if (!e) return try { await projectApi.addMember(project.id, { email: e }) setEmail('') setAdding(false) Toast.show({ content: '已添加' }) onChanged?.() onClose?.() } catch (err) { Toast.show({ content: err.message }) } } async function remove(m, isSelf) { const ok = await Dialog.confirm({ content: isSelf ? '退出该项目?退出后将不再可见。' : `移除成员「${m.name}」?`, confirmText: isSelf ? '退出' : '移除', }) if (!ok) return try { await projectApi.removeMember(project.id, m.userId) setMembers((prev) => prev.filter((x) => x.userId !== m.userId)) Toast.show({ content: isSelf ? '已退出' : '已移除' }) onChanged?.() if (isSelf) onClose?.() } catch (err) { Toast.show({ content: err.message }) } } return (
‹ {project.name}
{!project.isPersonal && ( setAdding(true)}>+ 添加 )}
{project.isPersonal ? '个人默认项目不可添加成员。' : '项目内所有成员权限均等、全读写;负责人与成员只是信息标记,不影响权限。'}
{members.map((m) => { const isOwner = m.userId === project.ownerId const isMe = m.userId === meId return (
{(m.name || '?').slice(0, 1)}
{m.name} {isMe && 我} {isOwner && 创建人} {isMe && !project.isPersonal && ( remove(m, true)}>退出 )} {!isMe && isOwner && —} {!isMe && !isOwner && !project.isPersonal && ( remove(m, false)}>移除 )}
) })}
成员被移出项目后,其担任的负责人 / 成员标记会保留历史并显示为「已退出」,不清空、不报错。
setEmail(e.target.value)} /> } actions={[ { key: 'c', text: '取消', onClick: () => setAdding(false) }, { key: 'ok', text: '添加', bold: true, onClick: add }, ]} onClose={() => setAdding(false)} />
) }