TTime/frontend/src/Components/AddUserToProject.tsx

126 lines
4 KiB
TypeScript
Raw Normal View History

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";
import InputField from "./InputField";
2024-03-21 03:37:37 +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[]>([]);
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> => {
if (names.length === 0) {
2024-04-04 11:26:39 +02:00
alert("You have to choose at least one user to add");
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 (
<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:
</p>
<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]">
<div></div>
{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>
))}
</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">
<Button
text="Add"
onClick={(): void => {
2024-04-04 11:26:39 +02:00
void handleAddClick();
}}
2024-04-04 11:26:39 +02:00
type="button"
/>
2024-03-21 03:37:37 +01:00
</div>
</div>
);
}
export default AddUserToProject;