({ isDialogOpen, setIsDialogOpen })
| 4 | import { useSearchParams } from "react-router-dom"; |
| 5 | |
| 6 | const AddProjectMember = ({ isDialogOpen, setIsDialogOpen }) => { |
| 7 | |
| 8 | const [searchParams] = useSearchParams(); |
| 9 | |
| 10 | const id = searchParams.get('id'); |
| 11 | |
| 12 | const currentWorkspace = useSelector((state) => state.workspace?.currentWorkspace || null); |
| 13 | |
| 14 | const project = currentWorkspace?.projects.find((p) => p.id === id); |
| 15 | const projectMembersEmails = project?.members.map((member) => member.user.email); |
| 16 | |
| 17 | const [email, setEmail] = useState(''); |
| 18 | const [isAdding, setIsAdding] = useState(false); |
| 19 | |
| 20 | const handleSubmit = async (e) => { |
| 21 | e.preventDefault(); |
| 22 | |
| 23 | }; |
| 24 | |
| 25 | if (!isDialogOpen) return null; |
| 26 | |
| 27 | return ( |
| 28 | <div className="fixed inset-0 bg-black/20 dark:bg-black/50 backdrop-blur flex items-center justify-center z-50"> |
| 29 | <div className="bg-white dark:bg-zinc-950 border border-zinc-300 dark:border-zinc-800 rounded-xl p-6 w-full max-w-md text-zinc-900 dark:text-zinc-200"> |
| 30 | {/* Header */} |
| 31 | <div className="mb-4"> |
| 32 | <h2 className="text-xl font-bold flex items-center gap-2"> |
| 33 | <UserPlus className="size-5 text-zinc-900 dark:text-zinc-200" /> Add Member to Project |
| 34 | </h2> |
| 35 | {currentWorkspace && ( |
| 36 | <p className="text-sm text-zinc-700 dark:text-zinc-400"> |
| 37 | Adding to Project: <span className="text-blue-600 dark:text-blue-400">{project.name}</span> |
| 38 | </p> |
| 39 | )} |
| 40 | </div> |
| 41 | |
| 42 | {/* Form */} |
| 43 | <form onSubmit={handleSubmit} className="space-y-4"> |
| 44 | {/* Email */} |
| 45 | <div className="space-y-2"> |
| 46 | <label htmlFor="email" className="text-sm font-medium text-zinc-900 dark:text-zinc-200"> |
| 47 | Email Address |
| 48 | </label> |
| 49 | <div className="relative"> |
| 50 | <Mail className="absolute left-3 top-1/2 -translate-y-1/2 text-zinc-500 dark:text-zinc-400 w-4 h-4" /> |
| 51 | {/* List All non project members from current workspace */} |
| 52 | <select value={email} onChange={(e) => setEmail(e.target.value)} className="pl-10 mt-1 w-full rounded border border-zinc-300 dark:border-zinc-700 dark:bg-zinc-900 text-zinc-900 dark:text-zinc-200 text-sm placeholder-zinc-400 dark:placeholder-zinc-500 py-2 focus:outline-none focus:border-blue-500" required > |
| 53 | <option value="">Select a member</option> |
| 54 | {currentWorkspace?.members |
| 55 | .filter((member) => !projectMembersEmails.includes(member.user.email)) |
| 56 | .map((member) => ( |
| 57 | <option key={member.user.id} value={member.user.email}> {member.user.email} </option> |
| 58 | ))} |
| 59 | </select> |
| 60 | </div> |
| 61 | </div> |
| 62 | |
| 63 | {/* Footer */} |
nothing calls this directly
no outgoing calls
no test coverage detected