From 05545f6f886d45c198af23fd0e4a1d0ce693886b Mon Sep 17 00:00:00 2001 From: Davenludd Date: Fri, 29 Mar 2024 17:53:37 +0100 Subject: [PATCH 01/32] Minor fixes --- frontend/src/Components/DisplayUserProjects.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/src/Components/DisplayUserProjects.tsx b/frontend/src/Components/DisplayUserProjects.tsx index 29e4bcb..494e6b0 100644 --- a/frontend/src/Components/DisplayUserProjects.tsx +++ b/frontend/src/Components/DisplayUserProjects.tsx @@ -25,8 +25,9 @@ function DisplayUserProject(): JSX.Element { const handleProjectClick = async (projectName: string): Promise => { const token = localStorage.getItem("accessToken") ?? ""; const response = await api.checkIfProjectManager(projectName, token); + console.log(response.data); if (response.success) { - if (response.data) { + if (response.data === true) { navigate(`/PMProjectPage/${projectName}`); } else { navigate(`/project/${projectName}`); From c1f49915baff3271ded8d5b33bf8f57b52715db7 Mon Sep 17 00:00:00 2001 From: Davenludd Date: Fri, 29 Mar 2024 18:29:38 +0100 Subject: [PATCH 02/32] Refactor signReport method signature --- frontend/src/API/API.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/frontend/src/API/API.ts b/frontend/src/API/API.ts index 886c957..0a85e70 100644 --- a/frontend/src/API/API.ts +++ b/frontend/src/API/API.ts @@ -161,10 +161,7 @@ interface API { * @param {number} reportId The id of the report to sign * @param {string} token The authentication token */ - signReport( - reportId: number, - token: string, - ): Promise>; + signReport(reportId: number, token: string): Promise>; } /** An instance of the API */ @@ -615,5 +612,5 @@ export const api: API = { } catch (e) { return { success: false, message: "Failed to sign report" }; } - } + }, }; From 8b6462abee3e7e615578d7f24e37187f14a82c44 Mon Sep 17 00:00:00 2001 From: Peter KW Date: Fri, 29 Mar 2024 20:19:22 +0100 Subject: [PATCH 03/32] Changed so that username is required to get projects, so that you can get another user's projects (for admin stuff) --- .../handlers/projects/GetUserProject.go | 11 +++++----- backend/main.go | 2 +- .../src/Components/DisplayUserProjects.tsx | 20 +++++-------------- 3 files changed, 12 insertions(+), 21 deletions(-) diff --git a/backend/internal/handlers/projects/GetUserProject.go b/backend/internal/handlers/projects/GetUserProject.go index 99ed63b..6c80515 100644 --- a/backend/internal/handlers/projects/GetUserProject.go +++ b/backend/internal/handlers/projects/GetUserProject.go @@ -4,15 +4,16 @@ import ( db "ttime/internal/database" "github.com/gofiber/fiber/v2" - "github.com/golang-jwt/jwt/v5" + "github.com/gofiber/fiber/v2/log" ) // GetUserProjects returns all projects that the user is a member of func GetUserProjects(c *fiber.Ctx) error { - // First we get the username from the token - user := c.Locals("user").(*jwt.Token) - claims := user.Claims.(jwt.MapClaims) - username := claims["name"].(string) + username := c.Params("username") + if username == "" { + log.Info("No username provided") + return c.Status(400).SendString("No username provided") + } // Then dip into the database to get the projects projects, err := db.GetDb(c).GetProjectsForUser(username) diff --git a/backend/main.go b/backend/main.go index cf58280..e4cffae 100644 --- a/backend/main.go +++ b/backend/main.go @@ -112,7 +112,7 @@ func main() { // All project related routes // projectGroup := api.Group("/project") // Not currently in use - api.Get("/getUserProjects", projects.GetUserProjects) + api.Get("/getUserProjects/:username", projects.GetUserProjects) api.Get("/project/:projectId", projects.GetProject) api.Get("/checkIfProjectManager/:projectName", projects.IsProjectManagerHandler) api.Get("/getUsersProject/:projectName", projects.ListAllUsersProject) diff --git a/frontend/src/Components/DisplayUserProjects.tsx b/frontend/src/Components/DisplayUserProjects.tsx index 92ba84f..3df2936 100644 --- a/frontend/src/Components/DisplayUserProjects.tsx +++ b/frontend/src/Components/DisplayUserProjects.tsx @@ -2,6 +2,7 @@ import { useState } from "react"; import { Project } from "../Types/goTypes"; import { useNavigate } from "react-router-dom"; import GetProjects from "./GetProjects"; +import { api } from "../API/API"; /** * Renders a component that displays the projects a user is a part of and links to the projects start-page. @@ -11,16 +12,10 @@ function DisplayUserProject(): JSX.Element { const [projects, setProjects] = useState([]); const navigate = useNavigate(); - const getProjects = async (): Promise => { - const token = localStorage.getItem("accessToken") ?? ""; - const response = await api.getUserProjects(token); - console.log(response); - if (response.success) { - setProjects(response.data ?? []); - } else { - console.error(response.message); - } - }; + GetProjects({ + setProjectsProp: setProjects, + username: localStorage.getItem("username") ?? "", + }); const handleProjectClick = async (projectName: string): Promise => { const token = localStorage.getItem("accessToken") ?? ""; @@ -37,11 +32,6 @@ function DisplayUserProject(): JSX.Element { } }; - // Call getProjects when the component mounts - useEffect(() => { - void getProjects(); - }, []); - return ( <>

Your Projects

From 5f42fa7818ad4919dbdfcba12c3189b98eb6ac25 Mon Sep 17 00:00:00 2001 From: Peter KW Date: Sun, 31 Mar 2024 20:54:00 +0200 Subject: [PATCH 04/32] Fixed types and imports of types --- frontend/src/API/API.ts | 21 ++++++++----------- frontend/src/Components/AddMember.tsx | 9 ++++++-- frontend/src/Components/AddUserToProject.tsx | 3 +-- frontend/src/Components/GetUsersInProject.tsx | 10 ++++++--- frontend/src/Components/ProjectInfoModal.tsx | 5 ++--- 5 files changed, 26 insertions(+), 22 deletions(-) diff --git a/frontend/src/API/API.ts b/frontend/src/API/API.ts index e7de646..f0b024b 100644 --- a/frontend/src/API/API.ts +++ b/frontend/src/API/API.ts @@ -1,13 +1,13 @@ +import { NewProjMember } from "../Components/AddMember"; +import { ProjectMember } from "../Components/GetUsersInProject"; import { NewWeeklyReport, NewUser, User, Project, NewProject, - UserProjectMember, WeeklyReport, StrNameChange, - NewProjMember, } from "../Types/goTypes"; /** @@ -137,7 +137,7 @@ interface API { getAllUsersProject( projectName: string, token: string, - ): Promise>; + ): Promise>; /** * Changes the username of a user in the database. * @param {StrNameChange} data The object containing the previous and new username. @@ -151,7 +151,7 @@ interface API { addUserToProject( user: NewProjMember, token: string, - ): Promise>; + ): Promise>; removeProject( projectName: string, @@ -165,10 +165,7 @@ interface API { * @param {number} reportId The id of the report to sign * @param {string} token The authentication token */ - signReport( - reportId: number, - token: string, - ): Promise>; + signReport(reportId: number, token: string): Promise>; } /** An instance of the API */ @@ -281,7 +278,7 @@ export const api: API = { async addUserToProject( user: NewProjMember, token: string, - ): Promise> { + ): Promise> { try { const response = await fetch("/api/addUserToProject", { method: "PUT", @@ -520,7 +517,7 @@ export const api: API = { async getAllUsersProject( projectName: string, token: string, - ): Promise> { + ): Promise> { try { const response = await fetch(`/api/getUsersProject/${projectName}`, { method: "GET", @@ -536,7 +533,7 @@ export const api: API = { message: "Failed to get users", }); } else { - const data = (await response.json()) as UserProjectMember[]; + const data = (await response.json()) as ProjectMember[]; return Promise.resolve({ success: true, data }); } } catch (e) { @@ -622,5 +619,5 @@ export const api: API = { } catch (e) { return { success: false, message: "Failed to sign report" }; } - } + }, }; diff --git a/frontend/src/Components/AddMember.tsx b/frontend/src/Components/AddMember.tsx index d29be68..194afe8 100644 --- a/frontend/src/Components/AddMember.tsx +++ b/frontend/src/Components/AddMember.tsx @@ -1,5 +1,10 @@ import { APIResponse, api } from "../API/API"; -import { NewProjMember } from "../Types/goTypes"; + +export interface NewProjMember { + username: string; + role: string; + projectname: string; +} /** * Tries to add a member to a project @@ -21,7 +26,7 @@ function AddMember(props: { memberToAdd: NewProjMember }): boolean { props.memberToAdd, localStorage.getItem("accessToken") ?? "", ) - .then((response: APIResponse) => { + .then((response: APIResponse) => { if (response.success) { alert("Member added"); added = true; diff --git a/frontend/src/Components/AddUserToProject.tsx b/frontend/src/Components/AddUserToProject.tsx index 9f4439b..2f5e6af 100644 --- a/frontend/src/Components/AddUserToProject.tsx +++ b/frontend/src/Components/AddUserToProject.tsx @@ -1,8 +1,7 @@ import { useState } from "react"; -import { NewProjMember } from "../Types/goTypes"; import Button from "./Button"; import GetAllUsers from "./GetAllUsers"; -import AddMember from "./AddMember"; +import AddMember, { NewProjMember } from "./AddMember"; import BackButton from "./BackButton"; /** diff --git a/frontend/src/Components/GetUsersInProject.tsx b/frontend/src/Components/GetUsersInProject.tsx index acdd965..a682d3f 100644 --- a/frontend/src/Components/GetUsersInProject.tsx +++ b/frontend/src/Components/GetUsersInProject.tsx @@ -1,7 +1,11 @@ import { Dispatch, useEffect } from "react"; -import { UserProjectMember } from "../Types/goTypes"; import { api } from "../API/API"; +export interface ProjectMember { + Username: string; + UserRole: string; +} + /** * Gets all projects that user is a member of * @param props - A setStateAction for the array you want to put projects in @@ -12,9 +16,9 @@ import { api } from "../API/API"; */ function GetUsersInProject(props: { projectName: string; - setUsersProp: Dispatch>; + setUsersProp: Dispatch>; }): void { - const setUsers: Dispatch> = + const setUsers: Dispatch> = props.setUsersProp; useEffect(() => { const fetchUsers = async (): Promise => { diff --git a/frontend/src/Components/ProjectInfoModal.tsx b/frontend/src/Components/ProjectInfoModal.tsx index 3075b19..27d4e6e 100644 --- a/frontend/src/Components/ProjectInfoModal.tsx +++ b/frontend/src/Components/ProjectInfoModal.tsx @@ -1,7 +1,6 @@ import { useState } from "react"; import Button from "./Button"; -import { UserProjectMember } from "../Types/goTypes"; -import GetUsersInProject from "./GetUsersInProject"; +import GetUsersInProject, { ProjectMember } from "./GetUsersInProject"; import { Link } from "react-router-dom"; function ProjectInfoModal(props: { @@ -10,7 +9,7 @@ function ProjectInfoModal(props: { onClose: () => void; onClick: (username: string) => void; }): JSX.Element { - const [users, setUsers] = useState([]); + const [users, setUsers] = useState([]); GetUsersInProject({ projectName: props.projectname, setUsersProp: setUsers }); if (!props.isVisible) return <>; From 0c8a394f7416e0f35ee275cd2b5a952ca6de0722 Mon Sep 17 00:00:00 2001 From: Peter KW Date: Sun, 31 Mar 2024 20:56:08 +0200 Subject: [PATCH 05/32] Small fix so that it uses component for getting users in a proj --- frontend/src/Components/ProjectMembers.tsx | 30 +++++----------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/frontend/src/Components/ProjectMembers.tsx b/frontend/src/Components/ProjectMembers.tsx index 60ffcd9..52e8559 100644 --- a/frontend/src/Components/ProjectMembers.tsx +++ b/frontend/src/Components/ProjectMembers.tsx @@ -1,31 +1,15 @@ -import { useEffect, useState } from "react"; +import { useState } from "react"; import { Link, useParams } from "react-router-dom"; -import { api } from "../API/API"; -import { UserProjectMember } from "../Types/goTypes"; +import GetUsersInProject, { ProjectMember } from "./GetUsersInProject"; function ProjectMembers(): JSX.Element { const { projectName } = useParams(); - const [projectMembers, setProjectMembers] = useState([]); + const [projectMembers, setProjectMembers] = useState([]); - useEffect(() => { - const getProjectMembers = async (): Promise => { - const token = localStorage.getItem("accessToken") ?? ""; - const response = await api.getAllUsersProject(projectName ?? "", token); - console.log(response); - if (response.success) { - setProjectMembers(response.data ?? []); - } else { - console.error(response.message); - } - }; - - void getProjectMembers(); - }, [projectName]); - - interface ProjectMember { - Username: string; - UserRole: string; - } + GetUsersInProject({ + projectName: projectName ?? "", + setUsersProp: setProjectMembers, + }); return ( <> From e7911574be07bc1ffd0be7271480220c096ea926 Mon Sep 17 00:00:00 2001 From: Peter KW Date: Sun, 31 Mar 2024 20:56:40 +0200 Subject: [PATCH 06/32] Removed unused files --- .../AdminPages/AdminProjectManageMembers.tsx | 23 ------------- .../src/Pages/AdminPages/AdminProjectPage.tsx | 33 ------------------- .../AdminPages/AdminProjectViewMemberInfo.tsx | 23 ------------- .../Pages/AdminPages/AdminViewUserInfo.tsx | 28 ---------------- 4 files changed, 107 deletions(-) delete mode 100644 frontend/src/Pages/AdminPages/AdminProjectManageMembers.tsx delete mode 100644 frontend/src/Pages/AdminPages/AdminProjectPage.tsx delete mode 100644 frontend/src/Pages/AdminPages/AdminProjectViewMemberInfo.tsx delete mode 100644 frontend/src/Pages/AdminPages/AdminViewUserInfo.tsx diff --git a/frontend/src/Pages/AdminPages/AdminProjectManageMembers.tsx b/frontend/src/Pages/AdminPages/AdminProjectManageMembers.tsx deleted file mode 100644 index 7d06a46..0000000 --- a/frontend/src/Pages/AdminPages/AdminProjectManageMembers.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import BackButton from "../../Components/BackButton"; -import BasicWindow from "../../Components/BasicWindow"; -import Button from "../../Components/Button"; - -function AdminProjectManageMembers(): JSX.Element { - const content = <>; - - const buttons = ( - <> - - - ); } export default ChangeUsername; From 3981190c7a61ef5c1b925e896e5ba80aca27d675 Mon Sep 17 00:00:00 2001 From: Peter KW Date: Mon, 1 Apr 2024 02:16:06 +0200 Subject: [PATCH 13/32] Can now change username in this modal + moved some stuff to a separate modal --- frontend/src/Components/UserInfoModal.tsx | 73 ++++++++++++++++------- 1 file changed, 52 insertions(+), 21 deletions(-) diff --git a/frontend/src/Components/UserInfoModal.tsx b/frontend/src/Components/UserInfoModal.tsx index 9d8dc11..7888c6b 100644 --- a/frontend/src/Components/UserInfoModal.tsx +++ b/frontend/src/Components/UserInfoModal.tsx @@ -1,34 +1,38 @@ -import { Link } from "react-router-dom"; import Button from "./Button"; import DeleteUser from "./DeleteUser"; import UserProjectListAdmin from "./UserProjectListAdmin"; +import { useState } from "react"; +import InputField from "./InputField"; +import ChangeUsername from "./ChangeUsername"; +import { StrNameChange } from "../Types/goTypes"; function UserInfoModal(props: { isVisible: boolean; - manageMember: boolean; username: string; onClose: () => void; - onDelete: (username: string) => void; }): JSX.Element { - if (!props.isVisible) return <>; - const ManageUserOrMember = (check: boolean): JSX.Element => { - if (check) { - return ( - -

- (Change Role) -

- - ); + const [showInput, setShowInput] = useState(false); + const [newUsername, setNewUsername] = useState(""); + if (!props.isVisible) { + return <>; + } + + const handleChangeNameView = (): void => { + if (showInput) { + setShowInput(false); + } else { + setShowInput(true); } - return ( - -

- (Change Username) -

- - ); }; + + const handleClickChangeName = (): void => { + const nameChange: StrNameChange = { + prevName: props.username, + newName: newUsername, + }; + ChangeUsername({ nameChange: nameChange }); + }; + return (

{props.username}

- {ManageUserOrMember(props.manageMember)} +

+ (Change Username) +

+ {showInput && ( +
+ +
+ )}

Member of these projects: @@ -62,6 +91,8 @@ function UserInfoModal(props: {

+
+ + ); +} + +export default MemberInfoModal; From 58deef400a9d448059bad1dfb75fea9fdd9b4d1e Mon Sep 17 00:00:00 2001 From: Peter KW Date: Mon, 1 Apr 2024 02:17:02 +0200 Subject: [PATCH 15/32] Removed unused code --- frontend/src/Components/ProjectListAdmin.tsx | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/frontend/src/Components/ProjectListAdmin.tsx b/frontend/src/Components/ProjectListAdmin.tsx index f25ee47..7305ea4 100644 --- a/frontend/src/Components/ProjectListAdmin.tsx +++ b/frontend/src/Components/ProjectListAdmin.tsx @@ -1,7 +1,7 @@ import { useState } from "react"; import { NewProject } from "../Types/goTypes"; import ProjectInfoModal from "./ProjectInfoModal"; -import UserInfoModal from "./UserInfoModal"; +import MemberInfoModal from "./MemberInfoModal"; /** * A list of projects for admin manage projects page, that sets an onClick @@ -51,13 +51,8 @@ export function ProjectListAdmin(props: { isVisible={projectModalVisible} projectname={projectname} /> - { - return; - }} isVisible={userModalVisible} username={username} /> From dc98fb510e896259169b658b0453c60ceb9627f6 Mon Sep 17 00:00:00 2001 From: Peter KW Date: Mon, 1 Apr 2024 02:17:57 +0200 Subject: [PATCH 16/32] Clears username+password fields on successful register --- frontend/src/Components/Register.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/src/Components/Register.tsx b/frontend/src/Components/Register.tsx index 6192637..8a22806 100644 --- a/frontend/src/Components/Register.tsx +++ b/frontend/src/Components/Register.tsx @@ -22,6 +22,8 @@ export default function Register(): JSX.Element { const response = await api.registerUser(newUser); if (response.success) { alert("User added!"); + setPassword(""); + setUsername(""); } else { alert("User not added"); setErrMessage(response.message ?? "Unknown error"); From 1212b3c5efb301e895edee48e08a5063afdcf06c Mon Sep 17 00:00:00 2001 From: Peter KW Date: Mon, 1 Apr 2024 02:20:48 +0200 Subject: [PATCH 17/32] Removed some stuff --- frontend/src/Components/UserListAdmin.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/frontend/src/Components/UserListAdmin.tsx b/frontend/src/Components/UserListAdmin.tsx index c08b05c..76cae9f 100644 --- a/frontend/src/Components/UserListAdmin.tsx +++ b/frontend/src/Components/UserListAdmin.tsx @@ -1,6 +1,5 @@ import { useState } from "react"; import UserInfoModal from "./UserInfoModal"; -import DeleteUser from "./DeleteUser"; /** * A list of users for admin manage users page, that sets an onClick @@ -30,9 +29,7 @@ export function UserListAdmin(props: { users: string[] }): JSX.Element { return ( <> DeleteUser} isVisible={modalVisible} username={username} /> From f3466854c7e0664d4e4045f6617c8382589c2089 Mon Sep 17 00:00:00 2001 From: Peter KW Date: Mon, 1 Apr 2024 02:24:26 +0200 Subject: [PATCH 18/32] Removed unused pages and paths to them in main --- .../Pages/AdminPages/AdminChangeUsername.tsx | 28 ------------------- .../AdminPages/AdminProjectChangeUserRole.tsx | 23 --------------- frontend/src/main.tsx | 11 -------- 3 files changed, 62 deletions(-) delete mode 100644 frontend/src/Pages/AdminPages/AdminChangeUsername.tsx delete mode 100644 frontend/src/Pages/AdminPages/AdminProjectChangeUserRole.tsx diff --git a/frontend/src/Pages/AdminPages/AdminChangeUsername.tsx b/frontend/src/Pages/AdminPages/AdminChangeUsername.tsx deleted file mode 100644 index b130fae..0000000 --- a/frontend/src/Pages/AdminPages/AdminChangeUsername.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import BackButton from "../../Components/BackButton"; -import BasicWindow from "../../Components/BasicWindow"; -import Button from "../../Components/Button"; -import ChangeUsername from "../../Components/ChangeUsername"; - -function AdminChangeUsername(): JSX.Element { - const content = ( - <> - - - ); - - const buttons = ( - <> -