From 888256e9f6222abe1d6e97c1d4e54e961b59b89d Mon Sep 17 00:00:00 2001 From: Peter KW Date: Sun, 17 Mar 2024 19:38:51 +0100 Subject: [PATCH 01/21] Changed logincheck type and error clarification --- frontend/src/Components/LoginCheck.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/frontend/src/Components/LoginCheck.tsx b/frontend/src/Components/LoginCheck.tsx index 3658cbf..6a8a028 100644 --- a/frontend/src/Components/LoginCheck.tsx +++ b/frontend/src/Components/LoginCheck.tsx @@ -10,7 +10,7 @@ function LoginCheck(props: { username: string; password: string; setAuthority: Dispatch>; -}): number { +}): void { const user: NewUser = { username: props.username, password: props.password, @@ -42,14 +42,12 @@ function LoginCheck(props: { console.error("Token was undefined"); } } else { - console.error("Token could not be fetched"); + console.error("Token could not be fetched/No such user"); } }) .catch((error) => { console.error("An error occurred during login:", error); }); - - return 0; } export default LoginCheck; From 7339a69bceae1501e1cf2ea5c361cd10b498227c Mon Sep 17 00:00:00 2001 From: al8763be Date: Sun, 17 Mar 2024 22:20:34 +0100 Subject: [PATCH 02/21] getWeeklyReport --- frontend/src/API/API.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/frontend/src/API/API.ts b/frontend/src/API/API.ts index cfd5b61..95a7e02 100644 --- a/frontend/src/API/API.ts +++ b/frontend/src/API/API.ts @@ -20,6 +20,10 @@ interface API { registerUser(user: NewUser): Promise>; /** Remove a user */ removeUser(username: string, token: string): Promise>; + /** Login */ + login(NewUser: NewUser): Promise>; + /** Renew the token */ + renewToken(token: string): Promise>; /** Create a project */ createProject( project: NewProject, @@ -30,15 +34,16 @@ interface API { project: NewWeeklyReport, token: string, ): Promise>; - /** Renew the token */ - renewToken(token: string): Promise>; + /**Gets a weekly report*/ + getWeeklyReport( + projectName: string, + token: string, + ): Promise>; /** Gets all the projects of a user*/ getUserProjects( username: string, token: string, ): Promise>; - /** Login */ - login(NewUser: NewUser): Promise>; } // Export an instance of the API From 6823102b4421c4af3029aef161b92a5f3a89f46d Mon Sep 17 00:00:00 2001 From: al8763be Date: Sun, 17 Mar 2024 22:27:21 +0100 Subject: [PATCH 03/21] Deleted API test --- frontend/src/API/API.test.ts | 87 ------------------------------------ frontend/src/API/API.ts | 3 +- 2 files changed, 2 insertions(+), 88 deletions(-) delete mode 100644 frontend/src/API/API.test.ts diff --git a/frontend/src/API/API.test.ts b/frontend/src/API/API.test.ts deleted file mode 100644 index dbae706..0000000 --- a/frontend/src/API/API.test.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { describe, expect, test } from "@jest/globals"; -import { api } from "../API/API"; -import { NewUser, NewWeeklyReport } from "../Types/goTypes"; - -describe("API", () => { - test("registerUser", async () => { - const user: NewUser = { - username: "lol", // Add the username property - password: "lol", - }; - const response = await api.registerUser(user); - console.log(response.message); - expect(response.success).toBe(true); - expect(response.data).toHaveProperty("userId"); - }); - - test("createProject", async () => { - const project = { - name: "Project X", - description: "This is a test project", - }; - const token = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZG1pbiI6ZmFsc2UsImV4cCI6MTcxMDk0MDIwMywibmFtZSI6InJyZ3VtZHpwbWMifQ.V9NHoYMYV61t"; - - const response = await api.createProject(project, token); - console.log(response.message); - expect(response.success).toBe(true); - expect(response.data).toHaveProperty("projectId"); - }); - - test("renewToken", async () => { - const refreshToken = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZG1pbiI6ZmFsc2UsImV4cCI6MTcxMDk0MDIwMywibmFtZSI6InJyZ3VtZHpwbWMifQ.V9NHoYMYV61t"; - - const response = await api.renewToken(refreshToken); - console.log(response.message); - expect(response.success).toBe(true); - expect(response.data).toHaveProperty("accessToken"); - expect(response.data).toHaveProperty("refreshToken"); - }); - - test("getUserProjects", async () => { - const token = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZG1pbiI6ZmFsc2UsImV4cCI6MTcxMDk0MDIwMywibmFtZSI6InJyZ3VtZHpwbWMifQ.V9NHoYMYV61t"; - const username = "rrgumdzpmc"; - const response = await api.getUserProjects(username, token); - console.log(response.message); - expect(response.success).toBe(true); - expect(response.data).toHaveProperty("projects"); - }); - - test("submitWeeklyReport", async () => { - const report: NewWeeklyReport = { - projectName: "vtmosxssst", - week: 2, - developmentTime: 40, - meetingTime: 5, - adminTime: 2, - ownWorkTime: 10, - studyTime: 12, - testingTime: 41, - }; - const token = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZG1pbiI6ZmFsc2UsImV4cCI6MTcxMDk0MDIwMywibmFtZSI6InJyZ3VtZHpwbWMifQ.V9NHoYMYV61t"; - - const response = await api.submitWeeklyReport(report, token); - console.log(response.message); - expect(response.success).toBe(true); - expect(response.data).toHaveProperty( - "message", - "Report submitted successfully", - ); - }); - - test("login", async () => { - const user: NewUser = { - username: "rrgumdzpmc", // Add an empty string value for the username property - password: "always_same", - }; - - const response = await api.login(user); - console.log(response.message); - expect(response.success).toBe(true); - expect(response.data).toHaveProperty("accessToken"); - expect(response.data).toHaveProperty("refreshToken"); - }); -}); diff --git a/frontend/src/API/API.ts b/frontend/src/API/API.ts index 95a7e02..f6e5979 100644 --- a/frontend/src/API/API.ts +++ b/frontend/src/API/API.ts @@ -36,8 +36,9 @@ interface API { ): Promise>; /**Gets a weekly report*/ getWeeklyReport( + username: string, projectName: string, - token: string, + week: string, ): Promise>; /** Gets all the projects of a user*/ getUserProjects( From c3ce25236fa15083362b1eb5297a82516c4b9145 Mon Sep 17 00:00:00 2001 From: al8763be Date: Sun, 17 Mar 2024 22:35:51 +0100 Subject: [PATCH 04/21] Full implementation of getWeeklyProject --- frontend/src/API/API.ts | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/frontend/src/API/API.ts b/frontend/src/API/API.ts index f6e5979..32c5eb2 100644 --- a/frontend/src/API/API.ts +++ b/frontend/src/API/API.ts @@ -33,13 +33,14 @@ interface API { submitWeeklyReport( project: NewWeeklyReport, token: string, - ): Promise>; + ): Promise>; /**Gets a weekly report*/ getWeeklyReport( username: string, projectName: string, week: string, - ): Promise>; + token: string, + ): Promise>; /** Gets all the projects of a user*/ getUserProjects( username: string, @@ -169,9 +170,9 @@ export const api: API = { }, async submitWeeklyReport( - project: NewWeeklyReport, + weeklyReport: NewWeeklyReport, token: string, - ): Promise> { + ): Promise> { try { const response = await fetch("/api/submitWeeklyReport", { method: "POST", @@ -179,7 +180,7 @@ export const api: API = { "Content-Type": "application/json", Authorization: "Bearer " + token, }, - body: JSON.stringify(project), + body: JSON.stringify(weeklyReport), }); if (!response.ok) { @@ -189,7 +190,7 @@ export const api: API = { }; } - const data = (await response.json()) as Project; + const data = (await response.json()) as NewWeeklyReport; return { success: true, data }; } catch (e) { return { @@ -199,6 +200,33 @@ export const api: API = { } }, + async getWeeklyReport( + username: string, + projectName: string, + week: string, + token: string, + ): Promise> { + try { + const response = await fetch("/api/getWeeklyReport", { + method: "GET", + headers: { + "Content-Type": "application/json", + Authorization: "Bearer " + token, + }, + body: JSON.stringify({ username, projectName, week }), + }); + + if (!response.ok) { + return { success: false, message: "Failed to get weekly report" }; + } else { + const data = (await response.json()) as NewWeeklyReport; + return { success: true, data }; + } + } catch (e) { + return { success: false, message: "Failed to get weekly report" }; + } + }, + async login(NewUser: NewUser): Promise> { try { const response = await fetch("/api/login", { From e012b6ff1207b311948d45bf5e1589627f9830db Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Sun, 17 Mar 2024 22:48:38 +0100 Subject: [PATCH 05/21] Error checking in register component, redirect to login if success --- frontend/src/API/API.ts | 14 ++++++++++---- frontend/src/Components/Register.tsx | 21 +++++++++++++++++---- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/frontend/src/API/API.ts b/frontend/src/API/API.ts index 248ad37..9b11dba 100644 --- a/frontend/src/API/API.ts +++ b/frontend/src/API/API.ts @@ -37,13 +37,19 @@ export const api: API = { }); if (!response.ok) { - return { success: false, message: "Failed to register user" }; + return { + success: false, + message: "Failed to register user: " + response.status, + }; } else { - const data = (await response.json()) as User; - return { success: true, data }; + // const data = (await response.json()) as User; // The API does not currently return the user + return { success: true }; } } catch (e) { - return { success: false, message: "Failed to register user" }; + return { + success: false, + message: "Unknown error while registering user", + }; } }, diff --git a/frontend/src/Components/Register.tsx b/frontend/src/Components/Register.tsx index e4a3ba0..9e767ca 100644 --- a/frontend/src/Components/Register.tsx +++ b/frontend/src/Components/Register.tsx @@ -3,14 +3,26 @@ import { NewUser } from "../Types/Users"; import { api } from "../API/API"; import Logo from "../assets/Logo.svg"; import Button from "./Button"; +import { useNavigate } from "react-router-dom"; export default function Register(): JSX.Element { - const [username, setUsername] = useState(""); - const [password, setPassword] = useState(""); + const [username, setUsername] = useState(); + const [password, setPassword] = useState(); + const [errMessage, setErrMessage] = useState(); + + const nav = useNavigate(); const handleRegister = async (): Promise => { - const newUser: NewUser = { userName: username, password }; - await api.registerUser(newUser); // TODO: Handle errors + const newUser: NewUser = { + userName: username ?? "", + password: password ?? "", + }; + const response = await api.registerUser(newUser); + if (response.success) { + nav("/"); // Instantly navigate to the login page + } else { + setErrMessage(response.message ?? "Unknown error"); + } }; return ( @@ -67,6 +79,7 @@ export default function Register(): JSX.Element { }} /> + {errMessage &&

{errMessage}

}
+ +

+ + + ); +} + +export default AddProject; From 24e7e68ea01549e51f9aa9d175ca136340b9c5da Mon Sep 17 00:00:00 2001 From: Peter KW Date: Mon, 18 Mar 2024 00:41:46 +0100 Subject: [PATCH 12/21] Logout functionality --- frontend/src/Components/Header.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/Components/Header.tsx b/frontend/src/Components/Header.tsx index ba0a939..7a1e8ba 100644 --- a/frontend/src/Components/Header.tsx +++ b/frontend/src/Components/Header.tsx @@ -5,7 +5,7 @@ function Header({ username }: { username: string }): JSX.Element { const [isOpen, setIsOpen] = useState(false); const handleLogout = (): void => { - // Add any logout logic here + localStorage.clear(); }; return ( From 8249678488403cebc2fec756df5327af0a620a94 Mon Sep 17 00:00:00 2001 From: Peter KW Date: Mon, 18 Mar 2024 00:42:05 +0100 Subject: [PATCH 13/21] Using local storage for token --- frontend/src/Components/LoginCheck.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontend/src/Components/LoginCheck.tsx b/frontend/src/Components/LoginCheck.tsx index 6a8a028..786a96c 100644 --- a/frontend/src/Components/LoginCheck.tsx +++ b/frontend/src/Components/LoginCheck.tsx @@ -15,12 +15,16 @@ function LoginCheck(props: { username: props.username, password: props.password, }; + + localStorage.clear(); + api .login(user) .then((response: APIResponse) => { if (response.success) { if (response.data !== undefined) { const token = response.data; + localStorage.setItem("accessToken", token); //TODO: change so that it checks for user type (admin, user, pm) instead if (token !== "" && props.username === "admin") { props.setAuthority((prevAuth) => { From 3b49faec2d6f52561cbeec2f86cbd8ca0f6c00c9 Mon Sep 17 00:00:00 2001 From: Peter KW Date: Mon, 18 Mar 2024 00:42:22 +0100 Subject: [PATCH 14/21] Import fix --- frontend/src/Components/ProjectListUser.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/Components/ProjectListUser.tsx b/frontend/src/Components/ProjectListUser.tsx index 0502159..96eeaff 100644 --- a/frontend/src/Components/ProjectListUser.tsx +++ b/frontend/src/Components/ProjectListUser.tsx @@ -1,5 +1,5 @@ import { Link } from "react-router-dom"; -import { Project } from "../Types/Project"; +import { Project } from "../Types/goTypes"; /** * The props for the ProjectsProps component From 0044b61ac8233c1309a446542d46e71a2358000d Mon Sep 17 00:00:00 2001 From: Peter KW Date: Mon, 18 Mar 2024 00:44:11 +0100 Subject: [PATCH 15/21] Uses input field component instead now --- frontend/src/Components/Register.tsx | 31 +++------------------------- 1 file changed, 3 insertions(+), 28 deletions(-) diff --git a/frontend/src/Components/Register.tsx b/frontend/src/Components/Register.tsx index 0c0fcd0..3b17890 100644 --- a/frontend/src/Components/Register.tsx +++ b/frontend/src/Components/Register.tsx @@ -1,41 +1,16 @@ import { useState } from "react"; -import { NewUser } from "../Types/Users"; +import { NewUser } from "../Types/goTypes"; import { api } from "../API/API"; import Logo from "../assets/Logo.svg"; import Button from "./Button"; - -function InputField(props: { - label: string; - type: string; - value: string; - onChange: (e: React.ChangeEvent) => void; -}): JSX.Element { - return ( -
- - -
- ); -} +import InputField from "./InputField"; export default function Register(): JSX.Element { const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const handleRegister = async (): Promise => { - const newUser: NewUser = { userName: username, password }; + const newUser: NewUser = { username: username, password }; await api.registerUser(newUser); // TODO: Handle errors }; From 844e94ed2624ad932fba166f9517068852d49cca Mon Sep 17 00:00:00 2001 From: Peter KW Date: Mon, 18 Mar 2024 00:44:56 +0100 Subject: [PATCH 16/21] Small fixes to layout and added --- .../src/Pages/AdminPages/AdminAddProject.tsx | 20 ++++--------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/frontend/src/Pages/AdminPages/AdminAddProject.tsx b/frontend/src/Pages/AdminPages/AdminAddProject.tsx index 2922400..6df8851 100644 --- a/frontend/src/Pages/AdminPages/AdminAddProject.tsx +++ b/frontend/src/Pages/AdminPages/AdminAddProject.tsx @@ -1,25 +1,13 @@ +import AddProject from "../../Components/AddProject"; +import BackButton from "../../Components/BackButton"; import BasicWindow from "../../Components/BasicWindow"; -import Button from "../../Components/Button"; function AdminAddProject(): JSX.Element { - const content = <>; + const content = ; const buttons = ( <> -