Merge branch 'frontend' into gruppDM

This commit is contained in:
Davenludd 2024-04-04 20:10:57 +02:00
commit 544383809b
14 changed files with 346 additions and 138 deletions

View file

@ -17,6 +17,7 @@ type Database interface {
AddUser(username string, password string) error AddUser(username string, password string) error
CheckUser(username string, password string) bool CheckUser(username string, password string) bool
RemoveUser(username string) error RemoveUser(username string) error
RemoveUserFromProject(username string, projectname string) error
PromoteToAdmin(username string) error PromoteToAdmin(username string) error
GetUserId(username string) (int, error) GetUserId(username string) (int, error)
AddProject(name string, description string, username string) error AddProject(name string, description string, username string) error
@ -43,6 +44,7 @@ type Database interface {
GetProjectTimes(projectName string) (map[string]int, error) GetProjectTimes(projectName string) (map[string]int, error)
UpdateWeeklyReport(projectName string, userName string, week int, developmentTime int, meetingTime int, adminTime int, ownWorkTime int, studyTime int, testingTime int) error UpdateWeeklyReport(projectName string, userName string, week int, developmentTime int, meetingTime int, adminTime int, ownWorkTime int, studyTime int, testingTime int) error
RemoveProject(projectname string) error RemoveProject(projectname string) error
GetUserName(id int) (string, error)
} }
// This struct is a wrapper type that holds the database connection // This struct is a wrapper type that holds the database connection
@ -86,6 +88,10 @@ const isProjectManagerQuery = `SELECT COUNT(*) > 0 FROM user_roles
JOIN projects ON user_roles.project_id = projects.id JOIN projects ON user_roles.project_id = projects.id
WHERE users.username = ? AND projects.name = ? AND user_roles.p_role = 'project_manager'` WHERE users.username = ? AND projects.name = ? AND user_roles.p_role = 'project_manager'`
const removeUserFromProjectQuery = `DELETE FROM user_roles
WHERE user_id = (SELECT id FROM users WHERE username = ?)
AND project_id = (SELECT id FROM projects WHERE name = ?)`
// DbConnect connects to the database // DbConnect connects to the database
func DbConnect(dbpath string) Database { func DbConnect(dbpath string) Database {
// Open the database // Open the database
@ -147,6 +153,11 @@ func (d *Db) AddUserToProject(username string, projectname string, role string)
return err return err
} }
func (d *Db) RemoveUserFromProject(username string, projectname string) error {
_, err := d.Exec(removeUserFromProjectQuery, username, projectname)
return err
}
// ChangeUserRole changes the role of a user within a project. // ChangeUserRole changes the role of a user within a project.
func (d *Db) ChangeUserRole(username string, projectname string, role string) error { func (d *Db) ChangeUserRole(username string, projectname string, role string) error {
// Execute the SQL query to change the user's role // Execute the SQL query to change the user's role
@ -601,3 +612,9 @@ func (d *Db) RemoveProject(projectname string) error {
_, err := d.Exec("DELETE FROM projects WHERE name = ?", projectname) _, err := d.Exec("DELETE FROM projects WHERE name = ?", projectname)
return err return err
} }
func (d *Db) GetUserName(id int) (string, error) {
var username string
err := d.Get(&username, "SELECT username FROM users WHERE id = ?", id)
return username, err
}

View file

@ -0,0 +1,40 @@
package projects
import (
db "ttime/internal/database"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/log"
"github.com/golang-jwt/jwt/v5"
)
func RemoveUserFromProject(c *fiber.Ctx) error {
user := c.Locals("user").(*jwt.Token)
claims := user.Claims.(jwt.MapClaims)
pm_name := claims["name"].(string)
project := c.Params("projectName")
username := c.Query("userName")
// Check if the user is a project manager
isPM, err := db.GetDb(c).IsProjectManager(pm_name, project)
if err != nil {
log.Info("Error checking if user is project manager:", err)
return c.Status(500).SendString(err.Error())
}
if !isPM {
log.Info("User: ", pm_name, " is not a project manager in project: ", project)
return c.Status(403).SendString("User is not a project manager")
}
// Remove the user from the project
if err = db.GetDb(c).RemoveUserFromProject(username, project); err != nil {
log.Info("Error removing user from project:", err)
return c.Status(500).SendString(err.Error())
}
// Return success message
log.Info("User : ", username, " removed from project: ", project)
return c.SendStatus(fiber.StatusOK)
}

View file

@ -0,0 +1,32 @@
package users
import (
"strconv"
db "ttime/internal/database"
"github.com/gofiber/fiber/v2"
)
// Return the username of a user given their user id
func GetUserName(c *fiber.Ctx) error {
// Check the query params for userId
user_id_string := c.Query("userId")
if user_id_string == "" {
return c.Status(400).SendString("Missing user id")
}
// Convert to int
user_id, err := strconv.Atoi(user_id_string)
if err != nil {
return c.Status(400).SendString("Invalid user id")
}
// Get the username from the database
username, err := db.GetDb(c).GetUserName(user_id)
if err != nil {
return c.Status(500).SendString(err.Error())
}
// Send the nuclear launch codes to north korea
return c.JSON(fiber.Map{"username": username})
}

View file

@ -103,6 +103,7 @@ func main() {
// userGroup := api.Group("/user") // Not currently in use // userGroup := api.Group("/user") // Not currently in use
api.Get("/users/all", users.ListAllUsers) api.Get("/users/all", users.ListAllUsers)
api.Get("/project/getAllUsers", users.GetAllUsersProject) api.Get("/project/getAllUsers", users.GetAllUsersProject)
api.Get("/username", users.GetUserName)
api.Post("/login", users.Login) api.Post("/login", users.Login)
api.Post("/register", users.Register) api.Post("/register", users.Register)
api.Post("/loginrenew", users.LoginRenew) api.Post("/loginrenew", users.LoginRenew)
@ -121,6 +122,7 @@ func main() {
api.Post("/ProjectRoleChange", projects.ProjectRoleChange) api.Post("/ProjectRoleChange", projects.ProjectRoleChange)
api.Put("/promoteToPm/:projectName", projects.PromoteToPm) api.Put("/promoteToPm/:projectName", projects.PromoteToPm)
api.Put("/addUserToProject/:projectName", projects.AddUserToProjectHandler) api.Put("/addUserToProject/:projectName", projects.AddUserToProjectHandler)
api.Delete("/removeUserFromProject/:projectName", projects.RemoveUserFromProject)
api.Delete("/removeProject/:projectName", projects.RemoveProject) api.Delete("/removeProject/:projectName", projects.RemoveProject)
api.Delete("/project/:projectID", projects.DeleteProject) api.Delete("/project/:projectID", projects.DeleteProject)

View file

@ -1,4 +1,4 @@
import { NewProjMember } from "../Components/AddMember"; import { AddMemberInfo } from "../Components/AddMember";
import { ProjectRoleChange } from "../Components/ChangeRole"; import { ProjectRoleChange } from "../Components/ChangeRole";
import { projectTimes } from "../Components/GetProjectTimes"; import { projectTimes } from "../Components/GetProjectTimes";
import { ProjectMember } from "../Components/GetUsersInProject"; import { ProjectMember } from "../Components/GetUsersInProject";
@ -197,7 +197,13 @@ interface API {
): Promise<APIResponse<void>>; ): Promise<APIResponse<void>>;
addUserToProject( addUserToProject(
user: NewProjMember, addMemberInfo: AddMemberInfo,
token: string,
): Promise<APIResponse<void>>;
removeUserFromProject(
user: string,
project: string,
token: string, token: string,
): Promise<APIResponse<void>>; ): Promise<APIResponse<void>>;
@ -227,6 +233,12 @@ interface API {
projectName: string, projectName: string,
token: string, token: string,
): Promise<APIResponse<string>>; ): Promise<APIResponse<string>>;
/**
* Get the username from the id
* @param {number} id The id of the user
* @param {string} token Your token
*/
getUsername(id: number, token: string): Promise<APIResponse<string>>;
} }
/** An instance of the API */ /** An instance of the API */
@ -336,18 +348,20 @@ export const api: API = {
}, },
async addUserToProject( async addUserToProject(
user: NewProjMember, addMemberInfo: AddMemberInfo,
token: string, token: string,
): Promise<APIResponse<void>> { ): Promise<APIResponse<void>> {
try { try {
const response = await fetch("/api/addUserToProject", { const response = await fetch(
`/api/addUserToProject/${addMemberInfo.projectName}/?userName=${addMemberInfo.userName}`,
{
method: "PUT", method: "PUT",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
Authorization: "Bearer " + token, Authorization: "Bearer " + token,
}, },
body: JSON.stringify(user), },
}); );
if (!response.ok) { if (!response.ok) {
return { success: false, message: "Failed to add member" }; return { success: false, message: "Failed to add member" };
@ -359,6 +373,31 @@ export const api: API = {
} }
}, },
async removeUserFromProject(
user: string,
project: string,
token: string,
): Promise<APIResponse<void>> {
try {
const response = await fetch(
`/api/removeUserFromProject/${project}?userName=${user}`,
{
method: "DELETE",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token,
},
},
);
if (!response.ok) {
return { success: false, message: "Failed to remove member" };
}
} catch (e) {
return { success: false, message: "Failed to remove member" };
}
return { success: true, message: "Removed member" };
},
async renewToken(token: string): Promise<APIResponse<string>> { async renewToken(token: string): Promise<APIResponse<string>> {
try { try {
const response = await fetch("/api/loginrenew", { const response = await fetch("/api/loginrenew", {
@ -837,4 +876,25 @@ export const api: API = {
} }
return { success: true, message: "User promoted to project manager" }; return { success: true, message: "User promoted to project manager" };
}, },
async getUsername(id: number, token: string): Promise<APIResponse<string>> {
try {
const response = await fetch(`/api/username?userId=${id}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token,
},
});
if (!response.ok) {
return { success: false, message: "Failed to get username" };
} else {
const data = (await response.json()) as string;
return { success: true, data };
}
} catch (e) {
return { success: false, message: "Failed to get username" };
}
},
}; };

View file

@ -1,44 +1,35 @@
import { APIResponse, api } from "../API/API"; import { api } from "../API/API";
export interface NewProjMember { export interface AddMemberInfo {
username: string; userName: string;
role: string; projectName: string;
projectname: string;
} }
/** /**
* Tries to add a member to a project * Tries to add a member to a project
* @param {Object} props - A NewProjMember * @param {AddMemberInfo} props.membertoAdd - Contains user's name and project's name
* @returns {boolean} True if added, false if not * @returns {Promise<void>}
*/ */
function AddMember(props: { memberToAdd: NewProjMember }): boolean { async function AddMember(props: { memberToAdd: AddMemberInfo }): Promise<void> {
let added = false; if (props.memberToAdd.userName === "") {
if ( alert("You must choose at least one user to add");
props.memberToAdd.username === "" || return;
props.memberToAdd.role === "" ||
props.memberToAdd.projectname === ""
) {
alert("All fields must be filled before adding");
return added;
} }
api try {
.addUserToProject( const response = await api.addUserToProject(
props.memberToAdd, props.memberToAdd,
localStorage.getItem("accessToken") ?? "", localStorage.getItem("accessToken") ?? "",
) );
.then((response: APIResponse<void>) => {
if (response.success) { if (response.success) {
alert("Member added"); alert(`[${props.memberToAdd.userName}] added`);
added = true;
} else { } else {
alert("Member not added"); alert(`[${props.memberToAdd.userName}] not added`);
console.error(response.message); console.error(response.message);
} }
}) } catch (error) {
.catch((error) => { alert(`[${props.memberToAdd.userName}] not added`);
console.error("An error occurred during member add:", error); console.error("An error occurred during member add:", error);
}); }
return added;
} }
export default AddMember; export default AddMember;

View file

@ -1,37 +1,10 @@
import { useState } from "react"; import { useState } from "react";
import { APIResponse, api } from "../API/API"; import { api } from "../API/API";
import { NewProject } from "../Types/goTypes"; import { NewProject } from "../Types/goTypes";
import InputField from "./InputField"; import InputField from "./InputField";
import Logo from "../assets/Logo.svg"; import Logo from "../assets/Logo.svg";
import Button from "./Button"; import Button from "./Button";
/**
* Tries to add a project to the system
* @param {Object} props - Project name and description
* @returns {boolean} True if created, false if not
*/
function CreateProject(props: { name: string; description: string }): void {
const project: NewProject = {
name: props.name,
description: props.description,
};
api
.createProject(project, localStorage.getItem("accessToken") ?? "")
.then((response: APIResponse<void>) => {
if (response.success) {
alert("Project added!");
} else {
alert("Project NOT added!");
console.error(response.message);
}
})
.catch((error) => {
alert("Project NOT added!");
console.error("An error occurred during creation:", error);
});
}
/** /**
* Provides UI for adding a project to the system. * Provides UI for adding a project to the system.
* @returns {JSX.Element} - Returns the component UI for adding a project * @returns {JSX.Element} - Returns the component UI for adding a project
@ -40,6 +13,33 @@ function AddProject(): JSX.Element {
const [name, setName] = useState(""); const [name, setName] = useState("");
const [description, setDescription] = useState(""); const [description, setDescription] = useState("");
/**
* Tries to add a project to the system
*/
const handleCreateProject = async (): Promise<void> => {
const project: NewProject = {
name: name.replace(/ /g, ""),
description: description.trim(),
};
try {
const response = await api.createProject(
project,
localStorage.getItem("accessToken") ?? "",
);
if (response.success) {
alert(`${project.name} added!`);
setDescription("");
setName("");
} else {
alert("Project not added, name could be taken");
console.error(response.message);
}
} catch (error) {
alert("Project not added");
console.error(error);
}
};
return ( return (
<div className="flex flex-col h-fit w-screen items-center justify-center"> <div className="flex flex-col h-fit w-screen items-center justify-center">
<div className="border-4 border-black bg-white flex flex-col items-center justify-center h-fit w-fit rounded-3xl content-center pl-20 pr-20"> <div className="border-4 border-black bg-white flex flex-col items-center justify-center h-fit w-fit rounded-3xl content-center pl-20 pr-20">
@ -47,10 +47,7 @@ function AddProject(): JSX.Element {
className="bg-white rounded px-8 pt-6 pb-8 mb-4 items-center justify-center flex flex-col w-fit h-fit" className="bg-white rounded px-8 pt-6 pb-8 mb-4 items-center justify-center flex flex-col w-fit h-fit"
onSubmit={(e) => { onSubmit={(e) => {
e.preventDefault(); e.preventDefault();
CreateProject({ void handleCreateProject();
name: name,
description: description,
});
}} }}
> >
<img <img

View file

@ -1,71 +1,86 @@
import { useState } from "react"; import { useEffect, useState } from "react";
import Button from "./Button"; import Button from "./Button";
import GetAllUsers from "./GetAllUsers"; import AddMember, { AddMemberInfo } from "./AddMember";
import AddMember, { NewProjMember } from "./AddMember";
import BackButton from "./BackButton"; import BackButton from "./BackButton";
import GetUsersInProject, { ProjectMember } from "./GetUsersInProject";
import GetAllUsers from "./GetAllUsers";
/** /**
* Provides UI for adding a member to a project. * Provides UI for adding a member to a project.
* @returns {JSX.Element} - Returns the component UI for adding a member * @returns {JSX.Element} - Returns the component UI for adding a member
*/ */
function AddUserToProject(props: { projectName: string }): JSX.Element { function AddUserToProject(props: { projectName: string }): JSX.Element {
const [name, setName] = useState(""); const [names, setNames] = useState<string[]>([]);
const [users, setUsers] = useState<string[]>([]); const [users, setUsers] = useState<string[]>([]);
const [role, setRole] = useState(""); const [usersProj, setUsersProj] = useState<ProjectMember[]>([]);
GetAllUsers({ setUsersProp: setUsers });
const handleClick = (): boolean => { // Gets all users and project members for filtering
const newMember: NewProjMember = { GetAllUsers({ setUsersProp: setUsers });
username: name, GetUsersInProject({
projectname: props.projectName, setUsersProp: setUsersProj,
role: role, 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)
alert("You have to choose at least one user to add");
for (const name of names) {
const newMember: AddMemberInfo = {
userName: name,
projectName: props.projectName,
}; };
return AddMember({ memberToAdd: newMember }); await AddMember({ memberToAdd: newMember });
}
setNames([]);
location.reload();
};
// 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);
});
}; };
return ( return (
<div className="border-4 border-black bg-white flex flex-col items-center justify-center rounded-3xl content-center pl-20 pr-20 h-[75vh] w-[50vh]"> <div className="border-4 border-black bg-white flex flex-col items-center pt-10 rounded-3xl content-center pl-20 pr-20 h-[63vh] w-[50] overflow-auto">
<p className="pb-4 mb-2 text-center font-bold text-[18px]"> <h1 className="text-center font-bold text-[36px] pb-10">
User chosen: [{name}] {props.projectName}
</h1>
<p className="p-1 text-center font-bold text-[26px]">
Choose users to add:
</p> </p>
<p className="pb-4 mb-2 text-center font-bold text-[18px]"> <div className="border-2 border-black pl-2 pr-2 pb-2 rounded-xl text-center overflow-auto h-[26vh] w-[26vh]">
Role chosen: [{role}]
</p>
<p className="pb-4 mb-2 text-center font-bold text-[18px]">
Project chosen: [{props.projectName}]
</p>
<p className="p-1">Choose role:</p>
<div className="border-2 border-black p-2 rounded-xl text-center h-[10h] w-[16] overflow-auto">
<ul className="text-center items-center font-medium space-y-2">
<li
className="h-[10] w-[14] items-start px-2 py-1 border-2 border-black rounded-full bg-orange-200 hover:bg-orange-600 hover:text-slate-100 hover:cursor-pointer"
onClick={() => {
setRole("member");
}}
>
{"Member"}
</li>
<li
className="h-[10] w-[14] items-start px-2 py-1 border-2 border-black rounded-full bg-orange-200 hover:bg-orange-600 hover:text-slate-100 hover:cursor-pointer"
onClick={() => {
setRole("project_manager");
}}
>
{"Project manager"}
</li>
</ul>
</div>
<p className="p-1">Choose user:</p>
<div className="border-2 border-black p-2 rounded-xl text-center overflow-scroll h-[26vh] w-[26vh]">
<ul className="text-center font-medium space-y-2"> <ul className="text-center font-medium space-y-2">
<div></div> <div></div>
{users.map((user) => ( {users.map((user) => (
<li <li
className="items-start p-1 border-2 border-black rounded-full bg-orange-200 hover:bg-orange-600 hover:text-slate-100 hover:cursor-pointer" className={
names.includes(user)
? "items-start p-1 border-2 border-transparent rounded-full bg-orange-500 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 hover:text-slate-100 hover:cursor-pointer"
}
key={user} key={user}
value={user} value={user}
onClick={() => { onClick={() => {
setName(user); handleUserClick(user);
}} }}
> >
<span>{user}</span> <span>{user}</span>
@ -73,13 +88,16 @@ function AddUserToProject(props: { projectName: string }): JSX.Element {
))} ))}
</ul> </ul>
</div> </div>
<div className="flex space-x-5 items-center justify-between"> <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 <Button
text="Add" text="Add"
onClick={(): void => { onClick={(): void => {
handleClick(); void handleAddClick();
}} }}
type="submit" type="button"
/> />
<BackButton /> <BackButton />
</div> </div>

View file

@ -2,7 +2,7 @@ import { useState } from "react";
import Button from "./Button"; import Button from "./Button";
import ChangeRole, { ProjectRoleChange } from "./ChangeRole"; import ChangeRole, { ProjectRoleChange } from "./ChangeRole";
export default function ChangeRoles(props: { export default function ChangeRoleView(props: {
projectName: string; projectName: string;
username: string; username: string;
}): JSX.Element { }): JSX.Element {

View file

@ -2,8 +2,11 @@ import { APIResponse, api } from "../API/API";
import { StrNameChange } from "../Types/goTypes"; import { StrNameChange } from "../Types/goTypes";
function ChangeUsername(props: { nameChange: StrNameChange }): void { function ChangeUsername(props: { nameChange: StrNameChange }): void {
if (props.nameChange.newName === "") { if (
alert("You have to select a new name"); props.nameChange.newName === "" ||
props.nameChange.newName === props.nameChange.prevName
) {
alert("You have to give a new name\n\nName not changed");
return; return;
} }
api api
@ -13,7 +16,7 @@ function ChangeUsername(props: { nameChange: StrNameChange }): void {
alert("Name changed successfully"); alert("Name changed successfully");
location.reload(); location.reload();
} else { } else {
alert("Name not changed"); alert("Name not changed, name could be taken");
console.error(response.message); console.error(response.message);
} }
}) })

View file

@ -1,8 +1,8 @@
import Button from "./Button"; import Button from "./Button";
import DeleteUser from "./DeleteUser";
import UserProjectListAdmin from "./UserProjectListAdmin"; import UserProjectListAdmin from "./UserProjectListAdmin";
import { useState } from "react"; import { useState } from "react";
import ChangeRoleView from "./ChangeRoleView"; import ChangeRoleView from "./ChangeRoleView";
import RemoveUserFromProj from "./RemoveUserFromProj";
function MemberInfoModal(props: { function MemberInfoModal(props: {
projectName: string; projectName: string;
@ -20,7 +20,7 @@ function MemberInfoModal(props: {
}; };
return ( return (
<div <div
className="fixed inset-0 bg-black bg-opacity-30 backdrop-blur-sm className="fixed inset-10 bg-opacity-30 backdrop-blur-sm
flex justify-center items-center" flex justify-center items-center"
> >
<div className="border-4 border-black bg-white rounded-lg text-center flex flex-col"> <div className="border-4 border-black bg-white rounded-lg text-center flex flex-col">
@ -42,13 +42,16 @@ function MemberInfoModal(props: {
<UserProjectListAdmin username={props.username} /> <UserProjectListAdmin username={props.username} />
<div className="items-center space-x-6"> <div className="items-center space-x-6">
<Button <Button
text={"Delete"} text={"Remove"}
onClick={function (): void { onClick={function (): void {
if ( if (
window.confirm("Are you sure you want to delete this user?") window.confirm(
"Are you sure you want to remove this user from the project?",
)
) { ) {
DeleteUser({ RemoveUserFromProj({
usernameToDelete: props.username, userToRemove: props.username,
projectName: props.projectName,
}); });
} }
}} }}

View file

@ -15,17 +15,21 @@ export default function Register(): JSX.Element {
const [errMessage, setErrMessage] = useState<string>(); const [errMessage, setErrMessage] = useState<string>();
const handleRegister = async (): Promise<void> => { const handleRegister = async (): Promise<void> => {
if (username === "" || password === "") {
alert("Must provide username and password");
return;
}
const newUser: NewUser = { const newUser: NewUser = {
username: username ?? "", username: username?.replace(/ /g, "") ?? "",
password: password ?? "", password: password ?? "",
}; };
const response = await api.registerUser(newUser); const response = await api.registerUser(newUser);
if (response.success) { if (response.success) {
alert("User added!"); alert(`${newUser.username} added!`);
setPassword(""); setPassword("");
setUsername(""); setUsername("");
} else { } else {
alert("User not added"); alert("User not added, name could be taken");
setErrMessage(response.message ?? "Unknown error"); setErrMessage(response.message ?? "Unknown error");
console.error(errMessage); console.error(errMessage);
} }

View file

@ -0,0 +1,41 @@
import { api, APIResponse } from "../API/API";
/**
* Removes a user from a project
* @param {string} props.usernameToDelete - The username of user to remove
* @param {string} props.projectName - Project to remove user from
* @returns {void}
* @example
* const exampleUsername = "user";
* const exampleProjectName "project";
* RemoveUserFromProj({ userToRemove: exampleUsername, projectName: exampleProjectName });
*/
export default function RemoveUserFromProj(props: {
userToRemove: string;
projectName: string;
}): void {
if (props.userToRemove === localStorage.getItem("username")) {
alert("Cannot remove yourself");
return;
}
api
.removeUserFromProject(
props.userToRemove,
props.projectName,
localStorage.getItem("accessToken") ?? "",
)
.then((response: APIResponse<void>) => {
if (response.success) {
alert(`${props.userToRemove} has been removed!`);
location.reload();
} else {
alert(`${props.userToRemove} has not been removed due to an error`);
console.error(response.message);
}
})
.catch((error) => {
alert(`${props.userToRemove} has not been removed due to an error`);
console.error("An error occurred during deletion:", error);
});
}

View file

@ -28,7 +28,7 @@ function UserInfoModal(props: {
const handleClickChangeName = (): void => { const handleClickChangeName = (): void => {
const nameChange: StrNameChange = { const nameChange: StrNameChange = {
prevName: props.username, prevName: props.username,
newName: newUsername, newName: newUsername.replace(/ /g, ""),
}; };
ChangeUsername({ nameChange: nameChange }); ChangeUsername({ nameChange: nameChange });
}; };