/* eslint-disable @typescript-eslint/no-explicit-any */ import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; import { fetchAuthSession, getCurrentUser } from "aws-amplify/auth"; export interface Project { projectId: string; name: string; description?: string; startDate?: string; endDate?: string; } export enum Priority { Urgent = "Urgent", High = "High", Medium = "Medium", Low = "Low", Backlog = "Backlog", } export enum Status { ToDo = "To Do", InProgress = "In Progress", TestReview = "Test/Review", Done = "Done", } export interface User { userId?: string; username: string; email: string; profilePictureUrl?: string; cognitoId?: string; teamId?: string; } export interface Attachment { attachmentId: string; fileURL: string; fileName: string; taskId: string; uploadedById: string; } export interface Task { taskId: string; title: string; description?: string; status?: Status; priority?: Priority; tags?: string; startDate?: string; dueDate?: string; points?: number; projectId: string; authorUserId?: string; assignedUserId?: string; author?: User; assignee?: User; comments?: Comment[]; attachments?: Attachment[]; } export interface SearchResults { tasks?: Task[]; projects?: Project[]; users?: User[]; } export interface Team { teamId: string; teamName: string; productOwnerUserId?: string; projectManagerUserId?: string; } export const api = createApi({ baseQuery: fetchBaseQuery({ baseUrl: process.env.NEXT_PUBLIC_API_BASE_URL, prepareHeaders: async (headers) => { const session = await fetchAuthSession(); const { accessToken } = session.tokens ?? {}; if (accessToken) { headers.set("Authorization", `Bearer ${accessToken}`); } return headers; }, }), reducerPath: "api", tagTypes: ["Projects", "Tasks", "Users", "Teams"], endpoints: (build) => ({ getAuthUser: build.query({ queryFn: async (_, _queryApi, _extraoptions, fetchWithBQ) => { try { const user = await getCurrentUser(); const session = await fetchAuthSession(); if (!session) throw new Error("No session found"); const { userSub } = session; const userDetailsResponse = await fetchWithBQ(`users/${userSub}`); const userDetails = userDetailsResponse.data as User; return { data: { user, userSub, userDetails } }; } catch (error: any) { return { error: error.message || "Could not fetch user data" }; } }, }), getProjects: build.query({ query: () => "projects", providesTags: ["Projects"], }), createProject: build.mutation>({ query: (project) => ({ url: "projects", method: "POST", body: project, }), invalidatesTags: ["Projects"], }), getTasks: build.query({ query: ({ projectId }) => `tasks?projectId=${projectId}`, providesTags: (result) => result ? result.map(({ taskId }) => ({ type: "Tasks" as const, taskId })) : [{ type: "Tasks" as const }], }), getTasksByUser: build.query({ query: (userId) => `tasks/user/${userId}`, providesTags: (result, error, userId) => result ? result.map(({ taskId }) => ({ type: "Tasks", taskId })) : [{ type: "Tasks", taskId: userId }], }), createTask: build.mutation>({ query: (task) => ({ url: "tasks", method: "POST", body: task, }), invalidatesTags: ["Tasks"], }), updateTaskStatus: build.mutation({ query: ({ taskId, status }) => ({ url: `tasks/${taskId}/status`, method: "PATCH", body: { status }, }), invalidatesTags: (result, error, { taskId }) => [ { type: "Tasks", id: taskId }, ], }), getUsers: build.query({ query: () => "users", providesTags: ["Users"], }), getTeams: build.query({ query: () => "teams", providesTags: ["Teams"], }), search: build.query({ query: (query) => `search?query=${query}`, }), }), }); export const { useGetAuthUserQuery, useGetProjectsQuery, useCreateProjectMutation, useGetTasksQuery, useCreateTaskMutation, useUpdateTaskStatusMutation, useSearchQuery, useGetUsersQuery, useGetTeamsQuery, useGetTasksByUserQuery, } = api;