Compare commits

...

29 commits

Author SHA1 Message Date
Peter KW
92119dd49e Added path + fixed import 2024-03-18 01:56:04 +01:00
Peter KW
8a2152395f Small fixes 2024-03-18 01:31:58 +01:00
Peter KW
516784c6bb Merge branch 'frontend' into gruppPP 2024-03-18 00:51:34 +01:00
Peter KW
4876038613 Merge remote-tracking branch 'origin/frontend' into gruppPP 2024-03-18 00:48:21 +01:00
Peter KW
f7b8ea7d97 Path fix 2024-03-18 00:46:04 +01:00
Peter KW
bd588048dd Import fix 2024-03-18 00:45:49 +01:00
Peter KW
070e9cc1e5 Link to button 2024-03-18 00:45:22 +01:00
Peter KW
844e94ed26 Small fixes to layout and added 2024-03-18 00:44:56 +01:00
Peter KW
0044b61ac8 Uses input field component instead now 2024-03-18 00:44:11 +01:00
Peter KW
3b49faec2d Import fix 2024-03-18 00:42:22 +01:00
Peter KW
8249678488 Using local storage for token 2024-03-18 00:42:05 +01:00
Peter KW
24e7e68ea0 Logout functionality 2024-03-18 00:41:46 +01:00
Peter KW
200da51633 AddProject component 2024-03-18 00:41:18 +01:00
Peter KW
d97516e0cd Added some paths again 2024-03-18 00:40:42 +01:00
al8763be
953c06212d API Changes 2024-03-18 00:22:32 +01:00
al8763be
7cc74866fc Merge branch 'dev' into frontend 2024-03-18 00:13:04 +01:00
al8763be
b45a20c9f5 Merge branch 'dev' into frontend 2024-03-18 00:06:20 +01:00
Imbus
741ad50ccf Merge branch 'dev' of github.com:imbus64/TTime into dev 2024-03-17 23:51:52 +01:00
dDogge
f6e4603603 Added handler for SignWeeklyReport named SignReport in handlers_report_related 2024-03-17 23:31:52 +01:00
Imbus
c487b47373 Merge branch 'BumBranch' of github.com:imbus64/TTime into BumBranch 2024-03-17 23:17:18 +01:00
Imbus
9070846b0b Fixing getWeeklyReport tests 2024-03-17 23:17:06 +01:00
al8763be
ff6af1d250 Merge branch 'dev' into BumBranch 2024-03-17 23:11:49 +01:00
al8763be
9f20d46fa6 Test for getWeeklyReport 2024-03-17 22:57:19 +01:00
Imbus
e012b6ff12 Error checking in register component, redirect to login if success 2024-03-17 22:48:38 +01:00
al8763be
c3ce25236f Full implementation of getWeeklyProject 2024-03-17 22:35:51 +01:00
al8763be
6823102b44 Deleted API test 2024-03-17 22:27:21 +01:00
al8763be
06c50e7a42 Merge branch 'frontend' into BumBranch 2024-03-17 22:20:48 +01:00
al8763be
7339a69bce getWeeklyReport 2024-03-17 22:20:34 +01:00
Peter KW
888256e9f6 Changed logincheck type and error clarification 2024-03-17 19:38:51 +01:00
16 changed files with 273 additions and 179 deletions

View file

@ -16,6 +16,7 @@ type GlobalState interface {
GetUserProjects(c *fiber.Ctx) error // To get all projects GetUserProjects(c *fiber.Ctx) error // To get all projects
SubmitWeeklyReport(c *fiber.Ctx) error SubmitWeeklyReport(c *fiber.Ctx) error
GetWeeklyReport(c *fiber.Ctx) error GetWeeklyReport(c *fiber.Ctx) error
SignReport(c *fiber.Ctx) error
// GetProject(c *fiber.Ctx) error // To get a specific project // GetProject(c *fiber.Ctx) error // To get a specific project
// UpdateProject(c *fiber.Ctx) error // To update a project // UpdateProject(c *fiber.Ctx) error // To update a project
// DeleteProject(c *fiber.Ctx) error // To delete a project // DeleteProject(c *fiber.Ctx) error // To delete a project

View file

@ -37,13 +37,16 @@ func (gs *GState) SubmitWeeklyReport(c *fiber.Ctx) error {
// Handler for retrieving weekly report // Handler for retrieving weekly report
func (gs *GState) GetWeeklyReport(c *fiber.Ctx) error { func (gs *GState) GetWeeklyReport(c *fiber.Ctx) error {
// Extract the necessary parameters from the request // Extract the necessary parameters from the request
println("GetWeeklyReport")
user := c.Locals("user").(*jwt.Token) user := c.Locals("user").(*jwt.Token)
claims := user.Claims.(jwt.MapClaims) claims := user.Claims.(jwt.MapClaims)
username := claims["name"].(string) username := claims["name"].(string)
// Extract project name and week from query parameters // Extract project name and week from query parameters
projectName := c.Query("projectName") projectName := c.Query("projectName")
println(projectName)
week := c.Query("week") week := c.Query("week")
println(week)
// Convert week to integer // Convert week to integer
weekInt, err := strconv.Atoi(week) weekInt, err := strconv.Atoi(week)
@ -60,3 +63,31 @@ func (gs *GState) GetWeeklyReport(c *fiber.Ctx) error {
// Return the retrieved weekly report // Return the retrieved weekly report
return c.JSON(report) return c.JSON(report)
} }
func (gs *GState) SignReport(c *fiber.Ctx) error {
// Extract the necessary parameters from the token
user := c.Locals("user").(*jwt.Token)
claims := user.Claims.(jwt.MapClaims)
managerUsername := claims["name"].(string)
// Extract the report ID and project manager ID from request parameters
reportID, err := strconv.Atoi(c.Params("reportId"))
if err != nil {
return c.Status(400).SendString("Invalid report ID")
}
// Call the database function to get the project manager ID
managerID, err := gs.Db.GetUserId(managerUsername)
if err != nil {
return c.Status(500).SendString("Failed to get project manager ID")
}
// Call the database function to sign the weekly report
err = gs.Db.SignWeeklyReport(reportID, managerID)
if err != nil {
return c.Status(500).SendString("Failed to sign the weekly report: " + err.Error())
}
// Return success response
return c.Status(200).SendString("Weekly report signed successfully")
}

View file

@ -78,6 +78,7 @@ func main() {
server.Post("/api/loginrenew", gs.LoginRenew) server.Post("/api/loginrenew", gs.LoginRenew)
server.Delete("/api/userdelete/:username", gs.UserDelete) // Perhaps just use POST to avoid headaches server.Delete("/api/userdelete/:username", gs.UserDelete) // Perhaps just use POST to avoid headaches
server.Post("/api/project", gs.CreateProject) server.Post("/api/project", gs.CreateProject)
server.Get("/api/getWeeklyReport", gs.GetWeeklyReport)
// Announce the port we are listening on and start the server // Announce the port we are listening on and start the server
err = server.Listen(fmt.Sprintf(":%d", conf.Port)) err = server.Listen(fmt.Sprintf(":%d", conf.Port))

View file

@ -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");
});
});

View file

@ -20,25 +20,32 @@ interface API {
registerUser(user: NewUser): Promise<APIResponse<User>>; registerUser(user: NewUser): Promise<APIResponse<User>>;
/** Remove a user */ /** Remove a user */
removeUser(username: string, token: string): Promise<APIResponse<User>>; removeUser(username: string, token: string): Promise<APIResponse<User>>;
/** Login */
login(NewUser: NewUser): Promise<APIResponse<string>>;
/** Renew the token */
renewToken(token: string): Promise<APIResponse<string>>;
/** Create a project */ /** Create a project */
createProject( createProject(
project: NewProject, project: NewProject,
token: string, token: string,
): Promise<APIResponse<Project>>; ): Promise<APIResponse<Project>>;
/** Submit a weekly report */
submitWeeklyReport(
project: NewWeeklyReport,
token: string,
): Promise<APIResponse<Project>>;
/** Renew the token */
renewToken(token: string): Promise<APIResponse<string>>;
/** Gets all the projects of a user*/ /** Gets all the projects of a user*/
getUserProjects( getUserProjects(
username: string, username: string,
token: string, token: string,
): Promise<APIResponse<Project[]>>; ): Promise<APIResponse<Project[]>>;
/** Login */ /** Submit a weekly report */
login(NewUser: NewUser): Promise<APIResponse<string>>; submitWeeklyReport(
project: NewWeeklyReport,
token: string,
): Promise<APIResponse<NewWeeklyReport>>;
/**Gets a weekly report*/
getWeeklyReport(
username: string,
projectName: string,
week: string,
token: string,
): Promise<APIResponse<NewWeeklyReport>>;
} }
// Export an instance of the API // Export an instance of the API
@ -54,13 +61,19 @@ export const api: API = {
}); });
if (!response.ok) { if (!response.ok) {
return { success: false, message: "Failed to register user" }; return {
success: false,
message: "Failed to register user: " + response.status,
};
} else { } else {
const data = (await response.json()) as User; // const data = (await response.json()) as User; // The API does not currently return the user
return { success: true, data }; return { success: true };
} }
} catch (e) { } catch (e) {
return { success: false, message: "Failed to register user" }; return {
success: false,
message: "Unknown error while registering user",
};
} }
}, },
@ -163,9 +176,9 @@ export const api: API = {
}, },
async submitWeeklyReport( async submitWeeklyReport(
project: NewWeeklyReport, weeklyReport: NewWeeklyReport,
token: string, token: string,
): Promise<APIResponse<Project>> { ): Promise<APIResponse<NewWeeklyReport>> {
try { try {
const response = await fetch("/api/submitWeeklyReport", { const response = await fetch("/api/submitWeeklyReport", {
method: "POST", method: "POST",
@ -173,7 +186,7 @@ export const api: API = {
"Content-Type": "application/json", "Content-Type": "application/json",
Authorization: "Bearer " + token, Authorization: "Bearer " + token,
}, },
body: JSON.stringify(project), body: JSON.stringify(weeklyReport),
}); });
if (!response.ok) { if (!response.ok) {
@ -183,7 +196,7 @@ export const api: API = {
}; };
} }
const data = (await response.json()) as Project; const data = (await response.json()) as NewWeeklyReport;
return { success: true, data }; return { success: true, data };
} catch (e) { } catch (e) {
return { return {
@ -193,6 +206,33 @@ export const api: API = {
} }
}, },
async getWeeklyReport(
username: string,
projectName: string,
week: string,
token: string,
): Promise<APIResponse<NewWeeklyReport>> {
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<APIResponse<string>> { async login(NewUser: NewUser): Promise<APIResponse<string>> {
try { try {
const response = await fetch("/api/login", { const response = await fetch("/api/login", {

View file

@ -0,0 +1,94 @@
import { useState } from "react";
import { APIResponse, api } from "../API/API";
import { NewProject, Project } from "../Types/goTypes";
import InputField from "./InputField";
import Logo from "../assets/Logo.svg";
import Button from "./Button";
/**
* Tries to add a project to the system
* @param props - Project name and description
* @returns {boolean} True if created, false if not
*/
function CreateProject(props: { name: string; description: string }): boolean {
const project: NewProject = {
name: props.name,
description: props.description,
};
let created = false;
api
.createProject(project, localStorage.getItem("accessToken") ?? "")
.then((response: APIResponse<Project>) => {
if (response.success) {
created = true;
} else {
console.error(response.message);
}
})
.catch((error) => {
console.error("An error occurred during creation:", error);
});
return created;
}
/**
* Tries to add a project to the system
* @returns {JSX.Element} UI for project adding
*/
function AddProject(): JSX.Element {
const [name, setName] = useState("");
const [description, setDescription] = useState("");
return (
<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">
<form
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) => {
e.preventDefault();
CreateProject({ name: name, description: description });
}}
>
<img
src={Logo}
className="logo w-[7vw] mb-10 mt-10"
alt="TTIME Logo"
/>
<h3 className="pb-4 mb-2 text-center font-bold text-[18px]">
Create a new project
</h3>
<InputField
label="Name"
type="text"
value={name}
onChange={(e) => {
setName(e.target.value);
}}
/>
<InputField
label="Description"
type="text"
value={description}
onChange={(e) => {
setDescription(e.target.value);
}}
/>
<div className="flex items-center justify-between">
<Button
text="Create"
onClick={(): void => {
return;
}}
type="submit"
/>
</div>
</form>
<p className="text-center text-gray-500 text-xs"></p>
</div>
</div>
);
}
export default AddProject;

View file

@ -5,7 +5,7 @@ function Header({ username }: { username: string }): JSX.Element {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const handleLogout = (): void => { const handleLogout = (): void => {
// Add any logout logic here localStorage.clear();
}; };
return ( return (

View file

@ -10,17 +10,21 @@ function LoginCheck(props: {
username: string; username: string;
password: string; password: string;
setAuthority: Dispatch<SetStateAction<number>>; setAuthority: Dispatch<SetStateAction<number>>;
}): number { }): void {
const user: NewUser = { const user: NewUser = {
username: props.username, username: props.username,
password: props.password, password: props.password,
}; };
localStorage.clear();
api api
.login(user) .login(user)
.then((response: APIResponse<string>) => { .then((response: APIResponse<string>) => {
if (response.success) { if (response.success) {
if (response.data !== undefined) { if (response.data !== undefined) {
const token = response.data; const token = response.data;
localStorage.setItem("accessToken", token);
//TODO: change so that it checks for user type (admin, user, pm) instead //TODO: change so that it checks for user type (admin, user, pm) instead
if (token !== "" && props.username === "admin") { if (token !== "" && props.username === "admin") {
props.setAuthority((prevAuth) => { props.setAuthority((prevAuth) => {
@ -42,14 +46,12 @@ function LoginCheck(props: {
console.error("Token was undefined"); console.error("Token was undefined");
} }
} else { } else {
console.error("Token could not be fetched"); console.error("Token could not be fetched/No such user");
} }
}) })
.catch((error) => { .catch((error) => {
console.error("An error occurred during login:", error); console.error("An error occurred during login:", error);
}); });
return 0;
} }
export default LoginCheck; export default LoginCheck;

View file

@ -3,40 +3,27 @@ import { NewUser } from "../Types/goTypes";
import { api } from "../API/API"; import { api } from "../API/API";
import Logo from "../assets/Logo.svg"; import Logo from "../assets/Logo.svg";
import Button from "./Button"; import Button from "./Button";
import InputField from "./InputField";
function InputField(props: { import { useNavigate } from "react-router-dom";
label: string;
type: string;
value: string;
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
}): JSX.Element {
return (
<div className="mb-4">
<label
className="block text-gray-700 text-sm font-sans font-bold mb-2"
htmlFor={props.label}
>
{props.label}
</label>
<input
className="appearance-none border-2 border-black rounded-2xl w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
id={props.label}
type={props.type}
placeholder={props.label}
value={props.value}
onChange={props.onChange}
/>
</div>
);
}
export default function Register(): JSX.Element { export default function Register(): JSX.Element {
const [username, setUsername] = useState(""); const [username, setUsername] = useState<string>();
const [password, setPassword] = useState(""); const [password, setPassword] = useState<string>();
const [errMessage, setErrMessage] = useState<string>();
const nav = useNavigate();
const handleRegister = async (): Promise<void> => { const handleRegister = async (): Promise<void> => {
const newUser: NewUser = { username: username, password }; const newUser: NewUser = {
await api.registerUser(newUser); // TODO: Handle errors 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 ( return (

View file

@ -1,11 +1,11 @@
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { User } from "../Types/goTypes"; import { PublicUser } from "../Types/goTypes";
/** /**
* The props for the UserProps component * The props for the UserProps component
*/ */
interface UserProps { interface UserProps {
users: User[]; users: PublicUser[];
} }
/** /**
@ -23,7 +23,7 @@ export function UserListAdmin(props: UserProps): JSX.Element {
<div> <div>
<ul className="font-bold underline text-[30px] cursor-pointer padding"> <ul className="font-bold underline text-[30px] cursor-pointer padding">
{props.users.map((user) => ( {props.users.map((user) => (
<Link to="/admin-view-user" key={user.userId} state={user.username}> <Link to="/adminUserInfo" key={user.userId} state={user.username}>
<li className="pt-5" key={user.userId}> <li className="pt-5" key={user.userId}>
{user.username} {user.username}
</li> </li>

View file

@ -1,25 +1,13 @@
import AddProject from "../../Components/AddProject";
import BackButton from "../../Components/BackButton";
import BasicWindow from "../../Components/BasicWindow"; import BasicWindow from "../../Components/BasicWindow";
import Button from "../../Components/Button";
function AdminAddProject(): JSX.Element { function AdminAddProject(): JSX.Element {
const content = <></>; const content = <AddProject />;
const buttons = ( const buttons = (
<> <>
<Button <BackButton />
text="Finish"
onClick={(): void => {
return;
}}
type="button"
/>
<Button
text="Back"
onClick={(): void => {
return;
}}
type="button"
/>
</> </>
); );

View file

@ -1,3 +1,5 @@
import { Link } from "react-router-dom";
import BackButton from "../../Components/BackButton";
import BasicWindow from "../../Components/BasicWindow"; import BasicWindow from "../../Components/BasicWindow";
import Button from "../../Components/Button"; import Button from "../../Components/Button";
@ -6,6 +8,7 @@ function AdminManageProjects(): JSX.Element {
const buttons = ( const buttons = (
<> <>
<Link to="/addProject">
<Button <Button
text="Add Project" text="Add Project"
onClick={(): void => { onClick={(): void => {
@ -13,13 +16,8 @@ function AdminManageProjects(): JSX.Element {
}} }}
type="button" type="button"
/> />
<Button </Link>
text="Back" <BackButton />
onClick={(): void => {
return;
}}
type="button"
/>
</> </>
); );

View file

@ -2,14 +2,14 @@ import BasicWindow from "../../Components/BasicWindow";
import Button from "../../Components/Button"; import Button from "../../Components/Button";
import BackButton from "../../Components/BackButton"; import BackButton from "../../Components/BackButton";
import { UserListAdmin } from "../../Components/UserListAdmin"; import { UserListAdmin } from "../../Components/UserListAdmin";
import { User } from "../../Types/Users"; import { PublicUser } from "../../Types/goTypes";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
function AdminManageUsers(): JSX.Element { function AdminManageUsers(): JSX.Element {
//TODO: Change so that it reads users from database //TODO: Change so that it reads users from database
const users: User[] = []; const users: PublicUser[] = [];
for (let i = 1; i <= 20; i++) { for (let i = 1; i <= 20; i++) {
users.push({ id: i, userName: "Example User " + i }); users.push({ userId: "id" + i, username: "Example User " + i });
} }
const navigate = useNavigate(); const navigate = useNavigate();
@ -28,7 +28,7 @@ function AdminManageUsers(): JSX.Element {
<Button <Button
text="Add User" text="Add User"
onClick={(): void => { onClick={(): void => {
navigate("/admin-add-user"); navigate("/adminAddUser");
}} }}
type="button" type="button"
/> />

View file

@ -6,12 +6,12 @@ function AdminMenuPage(): JSX.Element {
<> <>
<h1 className="font-bold text-[30px] mb-[20px]">Administrator Menu</h1> <h1 className="font-bold text-[30px] mb-[20px]">Administrator Menu</h1>
<div className="border-4 border-black bg-white flex flex-col items-center justify-center min-h-[65vh] h-fit w-[50vw] rounded-3xl content-center overflow-scroll space-y-[10vh] p-[30px]"> <div className="border-4 border-black bg-white flex flex-col items-center justify-center min-h-[65vh] h-fit w-[50vw] rounded-3xl content-center overflow-scroll space-y-[10vh] p-[30px]">
<Link to="/admin-manage-users"> <Link to="/adminManageUser">
<h1 className="font-bold underline text-[30px] cursor-pointer"> <h1 className="font-bold underline text-[30px] cursor-pointer">
Manage Users Manage Users
</h1> </h1>
</Link> </Link>
<Link to="/admin-manage-projects"> <Link to="/adminManageProject">
<h1 className="font-bold underline text-[30px] cursor-pointer"> <h1 className="font-bold underline text-[30px] cursor-pointer">
Manage Projects Manage Projects
</h1> </h1>

View file

@ -5,6 +5,11 @@ import { createBrowserRouter, RouterProvider } from "react-router-dom";
import App from "./Pages/App"; import App from "./Pages/App";
import AdminMenuPage from "./Pages/AdminPages/AdminMenuPage"; import AdminMenuPage from "./Pages/AdminPages/AdminMenuPage";
import YourProjectsPage from "./Pages/YourProjectsPage"; import YourProjectsPage from "./Pages/YourProjectsPage";
import AdminAddProject from "./Pages/AdminPages/AdminAddProject";
import AdminManageProjects from "./Pages/AdminPages/AdminManageProjects";
import AdminManageUsers from "./Pages/AdminPages/AdminManageUsers";
import AdminAddUser from "./Pages/AdminPages/AdminAddUser";
import AdminViewUserInfo from "./Pages/AdminPages/AdminViewUserInfo";
// This is where the routes are mounted // This is where the routes are mounted
const router = createBrowserRouter([ const router = createBrowserRouter([
@ -20,6 +25,30 @@ const router = createBrowserRouter([
path: "/pm", path: "/pm",
element: <YourProjectsPage />, element: <YourProjectsPage />,
}, },
{
path: "/user",
element: <YourProjectsPage />,
},
{
path: "/addProject",
element: <AdminAddProject />,
},
{
path: "/adminAddUser",
element: <AdminAddUser />,
},
{
path: "/adminUserInfo",
element: <AdminViewUserInfo />,
},
{
path: "/adminManageProject",
element: <AdminManageProjects />,
},
{
path: "/adminManageUser",
element: <AdminManageUsers />,
},
]); ]);
// Semi-hacky way to get the root element // Semi-hacky way to get the root element

View file

@ -21,6 +21,7 @@ registerPath = base_url + "/api/register"
loginPath = base_url + "/api/login" loginPath = base_url + "/api/login"
addProjectPath = base_url + "/api/project" addProjectPath = base_url + "/api/project"
submitReportPath = base_url + "/api/submitReport" submitReportPath = base_url + "/api/submitReport"
getWeeklyReportPath = base_url + "/api/getWeeklyReport"
# Posts the username and password to the register endpoint # Posts the username and password to the register endpoint
@ -74,7 +75,7 @@ def test_submit_report():
response = requests.post( response = requests.post(
submitReportPath, submitReportPath,
json={ json={
"projectName": "report1", "projectName": projectName,
"week": 1, "week": 1,
"developmentTime": 10, "developmentTime": 10,
"meetingTime": 5, "meetingTime": 5,
@ -89,9 +90,18 @@ def test_submit_report():
assert response.status_code == 200, "Submit report failed" assert response.status_code == 200, "Submit report failed"
print("Submit report successful") print("Submit report successful")
def test_get_weekly_report():
token = login(username, "always_same").json()["token"]
response = requests.get(
getWeeklyReportPath,
headers={"Authorization": "Bearer " + token},
params={"username": username, "projectName": projectName , "week": 1}
)
print(response.text)
if __name__ == "__main__": if __name__ == "__main__":
test_create_user() test_create_user()
test_login() test_login()
test_add_project() test_add_project()
test_submit_report() test_submit_report()
test_get_weekly_report()