import { NewWeeklyReport, NewUser, User, Project, NewProject, UserProjectMember, WeeklyReport, StrNameChange, NewProjMember, } from "../Types/goTypes"; /** * Response object returned by API methods. */ export interface APIResponse { /** Indicates whether the API call was successful */ success: boolean; /** Optional message providing additional information or error description */ message?: string; /** Optional data returned by the API method */ data?: T; } /** * Interface defining methods that an instance of the API must implement. */ interface API { /** * Register a new user * @param {NewUser} user The user object to be registered * @returns {Promise>} A promise containing the API response with the user data. */ registerUser(user: NewUser): Promise>; /** * Removes a user. * @param {string} username The username of the user to be removed. * @param {string} token The authentication token. * @returns {Promise>} A promise containing the API response with the removed user data. */ removeUser(username: string, token: string): Promise>; /** * Check if user is project manager. * @param {string} username The username of the user. * @param {string} projectName The name of the project. * @param {string} token The authentication token. * @returns {Promise>} A promise containing the API response indicating if the user is a project manager. */ checkIfProjectManager( projectName: string, token: string, ): Promise>; /** Logs in a user with the provided credentials. * @param {NewUser} NewUser The user object containing username and password. * @returns {Promise>} A promise resolving to an API response with a token. */ login(NewUser: NewUser): Promise>; /** * Renew the token * @param {string} token The current authentication token. * @returns {Promise>} A promise resolving to an API response with a renewed token. */ renewToken(token: string): Promise>; /** Promote user to admin */ /** Creates a new project. * @param {NewProject} project The project object containing name and description. * @param {string} token The authentication token. * @returns {Promise>} A promise resolving to an API response with the created project. */ createProject( project: NewProject, token: string, ): Promise>; /** Submits a weekly report * @param {NewWeeklyReport} weeklyReport The weekly report object. * @param {string} token The authentication token. * @returns {Promise>} A promise resolving to an API response with the submitted report. */ submitWeeklyReport( weeklyReport: NewWeeklyReport, token: string, ): Promise>; /** Gets a weekly report for a specific user, project and week * @param {string} projectName The name of the project. * @param {string} week The week number. * @param {string} token The authentication token. * @returns {Promise>} A promise resolving to an API response with the retrieved report. */ getWeeklyReport( projectName: string, week: string, token: string, ): Promise>; /** * Returns all the weekly reports for a user in a particular project * The username is derived from the token * @param {string} projectName The name of the project * @param {string} token The token of the user * @returns {APIResponse} A list of weekly reports */ getWeeklyReportsForUser( projectName: string, token: string, ): Promise>; /** Gets all the projects of a user * @param {string} token - The authentication token. * @returns {Promise>} A promise containing the API response with the user's projects. */ getUserProjects(token: string): Promise>; /** Gets a project by its id. * @param {number} id The id of the project to retrieve. * @returns {Promise>} A promise resolving to an API response containing the project data. */ getProject(id: number): Promise>; /** Gets a list of all users. * @param {string} token The authentication token of the requesting user. * @returns {Promise>} A promise resolving to an API response containing the list of users. */ getAllUsers(token: string): Promise>; /** Gets all users in a project from name*/ getAllUsersProject( projectName: string, token: string, ): Promise>; /** * Changes the username of a user in the database. * @param {StrNameChange} data The object containing the previous and new username. * @param {string} token The authentication token. * @returns {Promise>} A promise resolving to an API response. */ changeUserName( data: StrNameChange, token: string, ): Promise>; addUserToProject( user: NewProjMember, token: string, ): Promise>; removeProject( projectName: string, token: string, ): Promise>; } /** 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/${username}`, { method: "DELETE", headers: { "Content-Type": "application/json", Authorization: "Bearer " + token, }, body: JSON.stringify(username), }); if (!response.ok) { return { success: false, message: "Could not remove user" }; } else { return { success: true }; } } catch (e) { return { success: false, message: "Failed to remove user" }; } }, async checkIfProjectManager( projectName: string, token: string, ): Promise> { try { const response = await fetch( `/api/checkIfProjectManager/${projectName}`, { method: "GET", headers: { "Content-Type": "application/json", Authorization: "Bearer " + token, }, }, ); 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: "Failed to check if project manager" }; } }, 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 addUserToProject( user: NewProjMember, token: string, ): Promise> { try { const response = await fetch("/api/addUserToProject", { method: "PUT", headers: { "Content-Type": "application/json", Authorization: "Bearer " + token, }, body: JSON.stringify(user), }); if (!response.ok) { return { success: false, message: "Failed to add member" }; } else { return { success: true, message: "Added member" }; } } catch (e) { return { success: false, message: "Failed to add member" }; } }, 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.text(); return { success: true, message: data }; } catch (e) { return { success: false, message: "Failed to submit weekly report", }; } }, async getWeeklyReport( projectName: string, week: string, token: string, ): Promise> { try { const response = await fetch( `/api/getWeeklyReport?projectName=${projectName}&week=${week}`, { method: "GET", headers: { "Content-Type": "application/json", Authorization: "Bearer " + token, }, }, ); 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 getWeeklyReportsForUser( projectName: string, token: string, ): Promise> { try { const response = await fetch(`/api/getWeeklyReportsUser/${projectName}`, { method: "GET", headers: { "Content-Type": "application/json", Authorization: "Bearer " + token, }, }); if (!response.ok) { return { success: false, message: "Failed to get weekly reports for project: Response code " + response.status, }; } else { const data = (await response.json()) as WeeklyReport[]; return { success: true, data }; } } catch (e) { return { success: false, message: "Failed to get weekly reports for project, unknown error", }; } }, 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" }); } }, 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(), }; } }, async getAllUsers(token: string): Promise> { try { const response = await fetch("/api/users/all", { method: "GET", headers: { "Content-Type": "application/json", Authorization: "Bearer " + token, }, }); if (!response.ok) { return Promise.resolve({ success: false, message: "Failed to get users", }); } else { const data = (await response.json()) as string[]; return Promise.resolve({ success: true, data }); } } catch (e) { return Promise.resolve({ success: false, message: "API is not ok", }); } }, //Gets all users in a project async getAllUsersProject( projectName: string, token: string, ): Promise> { try { const response = await fetch(`/api/getUsersProject/${projectName}`, { method: "GET", headers: { "Content-Type": "application/json", Authorization: "Bearer " + token, }, }); if (!response.ok) { return Promise.resolve({ success: false, message: "Failed to get users", }); } else { const data = (await response.json()) as UserProjectMember[]; return Promise.resolve({ success: true, data }); } } catch (e) { return Promise.resolve({ success: false, message: "API is not ok", }); } }, async changeUserName( data: StrNameChange, token: string, ): Promise> { try { const response = await fetch("/api/changeUserName", { method: "PUT", headers: { "Content-Type": "application/json", Authorization: "Bearer " + token, }, body: JSON.stringify(data), }); if (!response.ok) { return { success: false, message: "Failed to change username" }; } else { return { success: true }; } } catch (e) { return { success: false, message: "Failed to change username" }; } }, async removeProject( projectName: string, token: string, ): Promise> { try { const response = await fetch(`/api/projectdelete/${projectName}`, { method: "DELETE", headers: { "Content-Type": "application/json", Authorization: "Bearer " + token, }, }); if (!response.ok) { return Promise.resolve({ success: false, message: "Failed to remove project", }); } else { const data = await response.text(); return Promise.resolve({ success: true, message: data }); } } catch (e) { return Promise.resolve({ success: false, message: "Failed to remove project", }); } }, };