import { baseApi } from "@/store/api/baseApi"; import { Todo } from "@/store/models/Todo.model"; import { TodoStatus } from "@/constants/todoStatusEnum"; import { PriorityStatus } from "@/constants/priorityStatusEnum"; import { TableSortDirection } from "@/constants/tableSortDirectionEnum"; interface CreateTodoPayload { title: string; task: string; status: TodoStatus; priority: PriorityStatus; dueDate: Date; createdById: string; assigneeIds: string[]; } export interface TodosQueryParams { page?: number; limit?: number; search?: string; statuses?: TodoStatus[]; priorities?: PriorityStatus[]; sortBy?: "title" | "dueDate" | "status" | "priority" | "createdAt"; sortDir?: TableSortDirection; assigneeUserId?: string; teamOfManagerId?: string; } export interface PaginatedTodos { items: Todo[]; total: number; page: number; limit: number; } const normalizeSortDir = (dir?: TableSortDirection) => { return dir ? dir === TableSortDirection.DESCENDING ? "desc" : "asc" : undefined; }; const buildTodoParams = (params?: TodosQueryParams) => { if (!params) return {}; const { page, limit, search, statuses, priorities, sortBy, sortDir, assigneeUserId, teamOfManagerId, } = params; return { ...(page !== undefined && { page }), ...(limit !== undefined && { limit }), ...(search && { search }), ...(Array.isArray(statuses) && statuses.length && { statuses: statuses.join(","), }), ...(Array.isArray(priorities) && priorities.length && { priorities: priorities.join(","), }), ...(sortBy && { sortBy }), ...(sortDir && { sortDir: normalizeSortDir(sortDir) }), ...(assigneeUserId && { assigneeUserId }), ...(teamOfManagerId && { teamOfManagerId }), }; }; export const todosApi = baseApi.injectEndpoints({ overrideExisting: false, endpoints: (builder) => ({ getTodosByUser: builder.query({ query: (userId) => ({ url: `/todos/user/${userId}` }), providesTags: (result) => [ "Todos", ...(result ?? []).map(({ id }) => ({ type: "Todos", id } as const)), ], }), getTodos: builder.query({ query: (params) => ({ url: "/todos", params: buildTodoParams(params) }), providesTags: (result, _error, _arg) => [ "Todos", ...(result?.items ?? []).map( ({ id }) => ({ type: "Todos", id } as const) ), ], }), createTodo: builder.mutation({ query: (data) => ({ url: "/todos", method: "POST", body: data, }), invalidatesTags: ["Todos"], }), updateTodo: builder.mutation>({ query: (todo) => ({ url: `/todos/${todo.id}`, method: "PUT", body: todo, }), invalidatesTags: ["Todos"], }), deleteTodo: builder.mutation({ query: (id) => ({ url: `/todos/${id}`, method: "DELETE", }), invalidatesTags: ["Todos"], }), }), }); export const { useGetTodosByUserQuery, useGetTodosQuery, useCreateTodoMutation, useUpdateTodoMutation, useDeleteTodoMutation, } = todosApi;