복구
삭제
diff --git a/src/constants/queryKeys/index.ts b/src/constants/queryKeys/index.ts
index b00893bb..1bb348dc 100644
--- a/src/constants/queryKeys/index.ts
+++ b/src/constants/queryKeys/index.ts
@@ -1 +1,2 @@
+export { trashQueries } from "@/constants/queryKeys/trash.queryKey";
export { userQueries } from "@/constants/queryKeys/user.queryKey";
diff --git a/src/constants/queryKeys/trash.queryKey.ts b/src/constants/queryKeys/trash.queryKey.ts
new file mode 100644
index 00000000..22720e2b
--- /dev/null
+++ b/src/constants/queryKeys/trash.queryKey.ts
@@ -0,0 +1,36 @@
+import { infiniteQueryOptions } from "@tanstack/react-query";
+
+import {
+ getPersonalTrashList,
+ getTeamTrashList,
+} from "@/features/trash/api/trash.api";
+
+import { STALE_TIME } from "../staleTime";
+
+const SIZE = 20;
+
+export const trashQueries = {
+ all: ["trash"] as const,
+
+ personalTrashList: () =>
+ infiniteQueryOptions({
+ queryKey: [...trashQueries.all, "personal"],
+ initialPageParam: 0,
+ queryFn: ({ pageParam }: { pageParam: number }) =>
+ getPersonalTrashList({ page: pageParam, size: SIZE }),
+ getNextPageParam: (lastPage, _, lastPageParam) =>
+ lastPage.page < lastPage.totalPages - 1 ? lastPageParam + 1 : undefined,
+ staleTime: STALE_TIME.MEDIUM,
+ }),
+
+ teamTrashList: (teamId: number) =>
+ infiniteQueryOptions({
+ queryKey: [...trashQueries.all, "team", teamId],
+ initialPageParam: 0,
+ queryFn: ({ pageParam }: { pageParam: number }) =>
+ getTeamTrashList(teamId, { page: pageParam, size: SIZE }),
+ getNextPageParam: (lastPage, _, lastPageParam) =>
+ lastPage.page < lastPage.totalPages - 1 ? lastPageParam + 1 : undefined,
+ staleTime: STALE_TIME.MEDIUM,
+ }),
+};
diff --git a/src/features/trash/api/trash.api.ts b/src/features/trash/api/trash.api.ts
new file mode 100644
index 00000000..af163972
--- /dev/null
+++ b/src/features/trash/api/trash.api.ts
@@ -0,0 +1,43 @@
+import { apiClient } from "@/lib/api/client";
+import { ApiResponse } from "@/lib/api/types";
+
+import { TrashActionParam, TrashListData } from "../types/trash.types";
+
+export async function deleteTrash(data: TrashActionParam) {
+ const res = await apiClient.delete
>("/api/trash", {
+ body: data,
+ });
+ return res.data;
+}
+
+export async function restoreTrash(data: TrashActionParam) {
+ const res = await apiClient.post>(
+ "/api/trash/restore",
+ data,
+ );
+ return res.data;
+}
+
+export async function getPersonalTrashList(data: {
+ page?: number;
+ size?: number;
+}) {
+ const res = await apiClient.get>(
+ "/api/trash/personal",
+ { params: data },
+ );
+
+ return res.data;
+}
+
+export async function getTeamTrashList(
+ teamId: number,
+ data: { page?: number; size?: number },
+) {
+ const res = await apiClient.get>(
+ `/api/trash/teams/${teamId}`,
+ { params: data },
+ );
+
+ return res.data;
+}
diff --git a/src/features/trash/hooks/useDeleteTrashMutation/index.ts b/src/features/trash/hooks/useDeleteTrashMutation/index.ts
new file mode 100644
index 00000000..ecc435fc
--- /dev/null
+++ b/src/features/trash/hooks/useDeleteTrashMutation/index.ts
@@ -0,0 +1 @@
+export { useDeleteTrashMutation } from "./useDeleteTrashMutation";
diff --git a/src/features/trash/hooks/useDeleteTrashMutation/useDeleteTrashMutation.ts b/src/features/trash/hooks/useDeleteTrashMutation/useDeleteTrashMutation.ts
new file mode 100644
index 00000000..8392a5e5
--- /dev/null
+++ b/src/features/trash/hooks/useDeleteTrashMutation/useDeleteTrashMutation.ts
@@ -0,0 +1,29 @@
+import { useMutation, useQueryClient } from "@tanstack/react-query";
+
+import { deleteTrash } from "@/features/trash/api/trash.api";
+import { TrashActionParam } from "@/features/trash/types/trash.types";
+import { useToast } from "@/hooks/useToast";
+import { ApiError } from "@/lib/api/types";
+
+export const useDeleteTrashMutation = () => {
+ const queryClient = useQueryClient();
+ const { toast } = useToast();
+
+ return useMutation({
+ mutationFn: (data: TrashActionParam) => deleteTrash(data),
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ["trash"] });
+ queryClient.invalidateQueries({ queryKey: ["personal", "goals"] });
+ queryClient.invalidateQueries({ queryKey: ["teams", "all"] });
+ queryClient.invalidateQueries({ queryKey: ["todo"] });
+ toast({ title: "삭제되었습니다", variant: "success" });
+ },
+ onError: (error: ApiError) => {
+ toast({
+ title: "삭제에 실패했습니다",
+ description: error.message,
+ variant: "error",
+ });
+ },
+ });
+};
diff --git a/src/features/trash/hooks/useRestoreTrashMutation/index.ts b/src/features/trash/hooks/useRestoreTrashMutation/index.ts
new file mode 100644
index 00000000..f9c6affa
--- /dev/null
+++ b/src/features/trash/hooks/useRestoreTrashMutation/index.ts
@@ -0,0 +1 @@
+export { useRestoreTrashMutation } from "./useRestoreTrashMutation";
diff --git a/src/features/trash/hooks/useRestoreTrashMutation/useRestoreTrashMutation.ts b/src/features/trash/hooks/useRestoreTrashMutation/useRestoreTrashMutation.ts
new file mode 100644
index 00000000..4d30fc25
--- /dev/null
+++ b/src/features/trash/hooks/useRestoreTrashMutation/useRestoreTrashMutation.ts
@@ -0,0 +1,30 @@
+import { useMutation, useQueryClient } from "@tanstack/react-query";
+
+import { restoreTrash } from "@/features/trash/api/trash.api";
+import { TrashActionParam } from "@/features/trash/types/trash.types";
+import { useToast } from "@/hooks/useToast";
+import { ApiError } from "@/lib/api/types";
+
+export const useRestoreTrashMutation = () => {
+ const queryClient = useQueryClient();
+ const { toast } = useToast();
+
+ return useMutation({
+ mutationFn: (data: TrashActionParam) => restoreTrash(data),
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ["trash"] });
+ queryClient.invalidateQueries({ queryKey: ["personal", "goals"] });
+ queryClient.invalidateQueries({ queryKey: ["teams", "all"] });
+ queryClient.invalidateQueries({ queryKey: ["todo"] });
+
+ toast({ title: "복구되었습니다", variant: "success" });
+ },
+ onError: (error: ApiError) => {
+ toast({
+ title: "복구에 실패했습니다",
+ description: error.message,
+ variant: "error",
+ });
+ },
+ });
+};
diff --git a/src/features/trash/types/trash.types.ts b/src/features/trash/types/trash.types.ts
new file mode 100644
index 00000000..d275a9b7
--- /dev/null
+++ b/src/features/trash/types/trash.types.ts
@@ -0,0 +1,21 @@
+export interface TrashItemData {
+ itemType: "GOAL" | "TODO";
+ id: number;
+ deleteAt: string;
+ teamName: string;
+ goalName: string;
+ todoTitle: string;
+}
+
+export interface TrashListData {
+ content: TrashItemData[];
+ page: number;
+ size: number;
+ totalElements: number;
+ totalPages: number;
+}
+
+export interface TrashActionParam {
+ goalIds: number[];
+ todoIds: number[];
+}