2024-04-04 11:26:39 +02:00
|
|
|
import { useEffect, useState } from "react";
|
2024-03-21 03:37:37 +01:00
|
|
|
import Button from "./Button";
|
2024-04-04 11:26:39 +02:00
|
|
|
import AddMember, { AddMemberInfo } from "./AddMember";
|
|
|
|
import GetUsersInProject, { ProjectMember } from "./GetUsersInProject";
|
|
|
|
import GetAllUsers from "./GetAllUsers";
|
2024-04-11 00:34:27 +02:00
|
|
|
import InputField from "./InputField";
|
2024-03-21 03:37:37 +01:00
|
|
|
|
|
|
|
/**
|
2024-03-28 01:33:03 +01:00
|
|
|
* Provides UI for adding a member to a project.
|
|
|
|
* @returns {JSX.Element} - Returns the component UI for adding a member
|
2024-03-21 03:37:37 +01:00
|
|
|
*/
|
2024-04-02 13:14:08 +02:00
|
|
|
function AddUserToProject(props: { projectName: string }): JSX.Element {
|
2024-04-04 11:26:39 +02:00
|
|
|
const [names, setNames] = useState<string[]>([]);
|
2024-03-21 03:37:37 +01:00
|
|
|
const [users, setUsers] = useState<string[]>([]);
|
2024-04-04 11:26:39 +02:00
|
|
|
const [usersProj, setUsersProj] = useState<ProjectMember[]>([]);
|
2024-04-11 00:34:27 +02:00
|
|
|
const [search, setSearch] = useState("");
|
2024-04-04 11:26:39 +02:00
|
|
|
|
|
|
|
// Gets all users and project members for filtering
|
2024-03-21 03:37:37 +01:00
|
|
|
GetAllUsers({ setUsersProp: setUsers });
|
2024-04-04 11:26:39 +02:00
|
|
|
GetUsersInProject({
|
|
|
|
setUsersProp: setUsersProj,
|
|
|
|
projectName: props.projectName,
|
|
|
|
});
|
|
|
|
/*
|
|
|
|
* Filters the members from users so that users who are already
|
|
|
|
* members are not shown
|
|
|
|
*/
|
|
|
|
useEffect(() => {
|
|
|
|
setUsers((prevUsers) => {
|
|
|
|
const filteredUsers = prevUsers.filter(
|
|
|
|
(user) =>
|
|
|
|
!usersProj.some((projectUser) => projectUser.Username === user),
|
|
|
|
);
|
|
|
|
return filteredUsers;
|
|
|
|
});
|
|
|
|
}, [usersProj]);
|
|
|
|
|
|
|
|
// Attempts to add all of the selected users to the project
|
|
|
|
const handleAddClick = async (): Promise<void> => {
|
2024-04-11 00:34:27 +02:00
|
|
|
if (names.length === 0) {
|
2024-04-04 11:26:39 +02:00
|
|
|
alert("You have to choose at least one user to add");
|
2024-04-11 00:34:27 +02:00
|
|
|
return;
|
|
|
|
}
|
2024-04-04 11:26:39 +02:00
|
|
|
for (const name of names) {
|
|
|
|
const newMember: AddMemberInfo = {
|
|
|
|
userName: name,
|
|
|
|
projectName: props.projectName,
|
|
|
|
};
|
|
|
|
await AddMember({ memberToAdd: newMember });
|
|
|
|
}
|
|
|
|
setNames([]);
|
|
|
|
location.reload();
|
|
|
|
};
|
2024-03-21 03:37:37 +01:00
|
|
|
|
2024-04-04 11:26:39 +02:00
|
|
|
// Updates the names that have been selected
|
|
|
|
const handleUserClick = (user: string): void => {
|
|
|
|
setNames((prevNames): string[] => {
|
|
|
|
if (!prevNames.includes(user)) {
|
|
|
|
return [...prevNames, user];
|
|
|
|
}
|
|
|
|
return prevNames.filter((name) => name !== user);
|
|
|
|
});
|
2024-03-21 03:37:37 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
2024-04-11 00:34:27 +02:00
|
|
|
<div className="border-4 border-black bg-white flex flex-col items-center py-10 px-20 rounded-3xl content-center overflow-auto">
|
2024-04-04 11:26:39 +02:00
|
|
|
<h1 className="text-center font-bold text-[36px] pb-10">
|
|
|
|
{props.projectName}
|
|
|
|
</h1>
|
|
|
|
<p className="p-1 text-center font-bold text-[26px]">
|
|
|
|
Choose users to add:
|
2024-03-28 01:33:03 +01:00
|
|
|
</p>
|
2024-04-11 00:34:27 +02:00
|
|
|
|
|
|
|
<div>
|
|
|
|
<InputField
|
|
|
|
placeholder={"Search users"}
|
|
|
|
type={"Text"}
|
|
|
|
value={search}
|
|
|
|
onChange={(e) => {
|
|
|
|
setSearch(e.target.value);
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
<ul className="font-medium space-y-2 border-2 border-black mt-2 px-2 pb-2 rounded-2xl text-center overflow-auto h-[26vh] w-[34vh]">
|
2024-03-28 01:33:03 +01:00
|
|
|
<div></div>
|
2024-04-11 00:34:27 +02:00
|
|
|
{users
|
|
|
|
.filter((user) => {
|
|
|
|
return search.toLowerCase() === ""
|
|
|
|
? user
|
|
|
|
: user.toLowerCase().includes(search.toLowerCase());
|
|
|
|
})
|
|
|
|
.map((user) => (
|
|
|
|
<li
|
|
|
|
className={
|
|
|
|
names.includes(user)
|
|
|
|
? "items-start p-1 border-2 border-transparent rounded-full bg-orange-500 transition-all hover:bg-orange-600 text-white hover:cursor-pointer ring-2 ring-black"
|
|
|
|
: "items-start p-1 border-2 border-black rounded-full bg-orange-200 hover:bg-orange-400 transition-all hover:text-white hover:cursor-pointer"
|
|
|
|
}
|
|
|
|
key={user}
|
|
|
|
value={user}
|
|
|
|
onClick={() => {
|
|
|
|
handleUserClick(user);
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
<span>{user}</span>
|
|
|
|
</li>
|
|
|
|
))}
|
2024-03-28 01:33:03 +01:00
|
|
|
</ul>
|
|
|
|
</div>
|
2024-04-04 11:26:39 +02:00
|
|
|
<p className="pt-10 pb-5 underline text-center font-bold text-[18px]">
|
|
|
|
Number of users to be added: {names.length}
|
|
|
|
</p>
|
|
|
|
<div className="space-x-10 items-center">
|
2024-03-28 01:33:03 +01:00
|
|
|
<Button
|
|
|
|
text="Add"
|
|
|
|
onClick={(): void => {
|
2024-04-04 11:26:39 +02:00
|
|
|
void handleAddClick();
|
2024-03-28 01:33:03 +01:00
|
|
|
}}
|
2024-04-04 11:26:39 +02:00
|
|
|
type="button"
|
2024-03-28 01:33:03 +01:00
|
|
|
/>
|
2024-03-21 03:37:37 +01:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
export default AddUserToProject;
|