import { NewWeeklyReport, NewUser, User, Project, NewProject, WeeklyReport, } from "../Types/goTypes"; // This type of pattern should be hard to misuse export interface APIResponse { success: boolean; message?: string; data?: T; } // Note that all protected routes also require a token // Defines all the methods that an instance of the API must implement interface API { /** Register a new user */ registerUser(user: NewUser): Promise>; /** Remove a user */ removeUser(username: string, token: string): Promise>; /** Check if user is project manager */ checkIfProjectManager( username: string, projectName: string, token: string, ): Promise>; /** Login */ login(NewUser: NewUser): Promise>; /** Renew the token */ renewToken(token: string): Promise>; /** Promote user to admin */ /** Create a project */ createProject( project: NewProject, token: string, ): Promise>; /** Submit a weekly report */ submitWeeklyReport( project: NewWeeklyReport, token: string, ): Promise>; /**Gets a weekly report*/ getWeeklyReport( username: string, projectName: string, week: string, token: string, ): Promise>; getWeeklyReportsForProject( username: string, projectName: string, token: string, ): Promise>; /** Gets all the projects of a user*/ getUserProjects(token: string): Promise>; /** Gets a project from id*/ getProject(id: number): Promise>; } // Export an instance of the API export const api: API = { async registerUser(user: NewUser): Promise> { try { const response = await fetch("/api/register", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(user), }); if (!response.ok) { return { success: false, message: "Failed to register user: " + response.status, }; } else { // const data = (await response.json()) as User; // The API does not currently return the user return { success: true }; } } catch (e) { return { success: false, message: "Unknown error while registering user", }; } }, async removeUser( username: string, token: string, ): Promise> { try { const response = await fetch("/api/userdelete", { method: "POST", headers: { "Content-Type": "application/json", Authorization: "Bearer " + token, }, body: JSON.stringify(username), }); if (!response.ok) { return { success: false, message: "Failed to remove user" }; } else { const data = (await response.json()) as User; return { success: true, data }; } } catch (e) { return { success: false, message: "Failed to remove user" }; } }, async checkIfProjectManager( username: string, projectName: string, token: string, ): Promise> { try { const response = await fetch("/api/checkIfProjectManager", { method: "GET", headers: { "Content-Type": "application/json", Authorization: "Bearer " + token, }, body: JSON.stringify({ username, projectName }), }); if (!response.ok) { return { success: false, message: "Failed to check if project manager", }; } else { const data = (await response.json()) as boolean; return { success: true, data }; } } catch (e) { return { success: false, message: "fuck" }; } }, async createProject( project: NewProject, token: string, ): Promise> { try { const response = await fetch("/api/project", { method: "POST", headers: { "Content-Type": "application/json", Authorization: "Bearer " + token, }, body: JSON.stringify(project), }); if (!response.ok) { return { success: false, message: "Failed to create project" }; } else { const data = (await response.json()) as Project; return { success: true, data }; } } catch (e) { return { success: false, message: "Failed to create project" }; } }, async renewToken(token: string): Promise> { try { const response = await fetch("/api/loginrenew", { method: "POST", headers: { "Content-Type": "application/json", Authorization: "Bearer " + token, }, }); if (!response.ok) { return { success: false, message: "Failed to renew token" }; } else { const data = (await response.json()) as string; return { success: true, data }; } } catch (e) { return { success: false, message: "Failed to renew token" }; } }, async getUserProjects(token: string): Promise> { try { const response = await fetch("/api/getUserProjects", { method: "GET", headers: { "Content-Type": "application/json", Authorization: "Bearer " + token, }, }); if (!response.ok) { return Promise.resolve({ success: false, message: "Failed to get user projects", }); } else { const data = (await response.json()) as Project[]; return Promise.resolve({ success: true, data }); } } catch (e) { return Promise.resolve({ success: false, message: "API fucked", }); } }, async submitWeeklyReport( weeklyReport: NewWeeklyReport, token: string, ): Promise> { try { const response = await fetch("/api/submitWeeklyReport", { method: "POST", headers: { "Content-Type": "application/json", Authorization: "Bearer " + token, }, body: JSON.stringify(weeklyReport), }); if (!response.ok) { return { success: false, message: "Failed to submit weekly report", }; } const data = (await response.json()) as NewWeeklyReport; return { success: true, data }; } catch (e) { return { success: false, message: "Failed to submit weekly report", }; } }, 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 WeeklyReport; return { success: true, data }; } } catch (e) { return { success: false, message: "Failed to get weekly report" }; } }, async getWeeklyReportsForProject( username: string, projectName: string, token: string, ): Promise> { try { const response = await fetch("/api/getWeeklyReportsUser", { method: "GET", headers: { "Content-Type": "application/json", Authorization: "Bearer " + token, }, body: JSON.stringify({ username, projectName }), }); if (!response.ok) { return { success: false, message: "Failed to get weekly reports for project", }; } else { const data = (await response.json()) as WeeklyReport[]; return { success: true, data }; } } catch (e) { return { success: false, message: "fucked again", }; } }, async login(NewUser: NewUser): Promise> { try { const response = await fetch("/api/login", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(NewUser), }); if (!response.ok) { return { success: false, message: "Failed to login" }; } else { const data = (await response.json()) as { token: string }; // Update the type of 'data' return { success: true, data: data.token }; } } catch (e) { return Promise.resolve({ success: false, message: "Failed to login" }); } }, // Gets a projet by id, currently untested since we have no javascript-based tests async getProject(id: number): Promise> { try { const response = await fetch(`/api/project/${id}`, { method: "GET", }); if (!response.ok) { return { success: false, message: "Failed to get project: Response code " + response.status, }; } else { const data = (await response.json()) as Project; return { success: true, data }; } // The code below is garbage but satisfies the linter // This needs fixing, do not copy this pattern } catch (e: unknown) { return { success: false, message: "Failed to get project: " + (e as Error).toString(), }; } }, };