diff --git a/src/entities/auth/api/myInfo.api.ts b/src/entities/auth/api/myInfo.api.ts index 09f74ebf..4ed68a4b 100644 --- a/src/entities/auth/api/myInfo.api.ts +++ b/src/entities/auth/api/myInfo.api.ts @@ -1,9 +1,10 @@ -import { UserProfile } from "@/entities/auth/types/auth.type"; +import { + UpdateProfileRequest, + UserProfile, +} from "@/entities/auth/types/auth.type"; import { apiClient } from "@/shared/lib/api/client"; import { ApiResponse } from "@/shared/lib/api/types"; -import { MyProfileFormData } from "../../../features/user/types/myProfile.type"; - export async function getMyInfo() { const res = await apiClient.get>("/api/users/me"); return res.data; @@ -19,7 +20,7 @@ export async function uploadProfileImage(file: File) { return res.data; } -export async function updateProfile(data: MyProfileFormData) { +export async function updateProfile(data: UpdateProfileRequest) { const res = await apiClient.put>("/api/users", data); return res.data; } diff --git a/src/entities/auth/index.ts b/src/entities/auth/index.ts new file mode 100644 index 00000000..2377854b --- /dev/null +++ b/src/entities/auth/index.ts @@ -0,0 +1,15 @@ +export { + deleteMe, + getMyInfo, + updateProfile, + uploadProfileImage, +} from "./api/myInfo.api"; +export { checkEmailDuplicate, signupMutationFn } from "./api/signup.api"; +export { userQueries } from "./query/user.queryKey"; +export type { + AuthFormType, + CheckEmailResponse, + SocialType, + UpdateProfileRequest, + UserProfile, +} from "./types/auth.type"; diff --git a/src/entities/auth/types/auth.type.ts b/src/entities/auth/types/auth.type.ts index 0e2c8990..7c9cd551 100644 --- a/src/entities/auth/types/auth.type.ts +++ b/src/entities/auth/types/auth.type.ts @@ -17,3 +17,9 @@ export type CheckEmailResponse = { data: { exists: boolean }; timestamp: string; }; + +export type UpdateProfileRequest = { + nickname: string; + currentPassword?: string | null; + password?: string | null; +}; diff --git a/src/features/trash/api/trash.api.ts b/src/entities/trash/api/trash.api.ts similarity index 100% rename from src/features/trash/api/trash.api.ts rename to src/entities/trash/api/trash.api.ts diff --git a/src/entities/trash/index.ts b/src/entities/trash/index.ts new file mode 100644 index 00000000..e5218045 --- /dev/null +++ b/src/entities/trash/index.ts @@ -0,0 +1,12 @@ +export { + deleteTrash, + getPersonalTrashList, + getTeamTrashList, + restoreTrash, +} from "./api/trash.api"; +export { trashQueries } from "./query/trash.queryKey"; +export type { + TrashActionParam, + TrashItemData, + TrashListData, +} from "./types/trash.types"; diff --git a/src/features/trash/trash.queryKey.ts b/src/entities/trash/query/trash.queryKey.ts similarity index 90% rename from src/features/trash/trash.queryKey.ts rename to src/entities/trash/query/trash.queryKey.ts index bc8ad887..94dc89bf 100644 --- a/src/features/trash/trash.queryKey.ts +++ b/src/entities/trash/query/trash.queryKey.ts @@ -3,9 +3,8 @@ import { infiniteQueryOptions } from "@tanstack/react-query"; import { getPersonalTrashList, getTeamTrashList, -} from "@/features/trash/api/trash.api"; - -import { STALE_TIME } from "../../shared/constants/query/staleTime"; +} from "@/entities/trash/api/trash.api"; +import { STALE_TIME } from "@/shared/constants/query/staleTime"; const SIZE = 20; diff --git a/src/features/trash/types/trash.types.ts b/src/entities/trash/types/trash.types.ts similarity index 100% rename from src/features/trash/types/trash.types.ts rename to src/entities/trash/types/trash.types.ts diff --git a/src/features/trash/hooks/useDeleteTrashMutation/index.ts b/src/features/trash/mutation/useDeleteTrashMutation/index.ts similarity index 100% rename from src/features/trash/hooks/useDeleteTrashMutation/index.ts rename to src/features/trash/mutation/useDeleteTrashMutation/index.ts diff --git a/src/features/trash/hooks/useDeleteTrashMutation/useDeleteTrashMutation.ts b/src/features/trash/mutation/useDeleteTrashMutation/useDeleteTrashMutation.ts similarity index 87% rename from src/features/trash/hooks/useDeleteTrashMutation/useDeleteTrashMutation.ts rename to src/features/trash/mutation/useDeleteTrashMutation/useDeleteTrashMutation.ts index e42de087..d1297b9a 100644 --- a/src/features/trash/hooks/useDeleteTrashMutation/useDeleteTrashMutation.ts +++ b/src/features/trash/mutation/useDeleteTrashMutation/useDeleteTrashMutation.ts @@ -1,7 +1,6 @@ import { useMutation, useQueryClient } from "@tanstack/react-query"; -import { deleteTrash } from "@/features/trash/api/trash.api"; -import { TrashActionParam } from "@/features/trash/types/trash.types"; +import { deleteTrash, TrashActionParam } from "@/entities/trash"; import { useToast } from "@/shared/hooks/useToast"; import { ApiError } from "@/shared/lib/api/types"; diff --git a/src/features/trash/hooks/useRestoreTrashMutation/index.ts b/src/features/trash/mutation/useRestoreTrashMutation/index.ts similarity index 100% rename from src/features/trash/hooks/useRestoreTrashMutation/index.ts rename to src/features/trash/mutation/useRestoreTrashMutation/index.ts diff --git a/src/features/trash/hooks/useRestoreTrashMutation/useRestoreTrashMutation.ts b/src/features/trash/mutation/useRestoreTrashMutation/useRestoreTrashMutation.ts similarity index 87% rename from src/features/trash/hooks/useRestoreTrashMutation/useRestoreTrashMutation.ts rename to src/features/trash/mutation/useRestoreTrashMutation/useRestoreTrashMutation.ts index 8ea57063..3596a03d 100644 --- a/src/features/trash/hooks/useRestoreTrashMutation/useRestoreTrashMutation.ts +++ b/src/features/trash/mutation/useRestoreTrashMutation/useRestoreTrashMutation.ts @@ -1,7 +1,6 @@ import { useMutation, useQueryClient } from "@tanstack/react-query"; -import { restoreTrash } from "@/features/trash/api/trash.api"; -import { TrashActionParam } from "@/features/trash/types/trash.types"; +import { restoreTrash, TrashActionParam } from "@/entities/trash"; import { useToast } from "@/shared/hooks/useToast"; import { ApiError } from "@/shared/lib/api/types"; diff --git a/src/features/user/hooks/useMyProfileForm/useMyProfileForm.ts b/src/features/user/hooks/useMyProfileForm/useMyProfileForm.ts index d2cc2f39..524ec986 100644 --- a/src/features/user/hooks/useMyProfileForm/useMyProfileForm.ts +++ b/src/features/user/hooks/useMyProfileForm/useMyProfileForm.ts @@ -6,7 +6,7 @@ import { myProfileSchema, } from "@/features/user/types/myProfile.type"; -import { useUpdateProfileMutation } from "../useUpdateProfileMutation"; +import { useUpdateProfileMutation } from "../../mutation/useUpdateProfileMutation"; export function useMyProfileForm(initialNickname: string) { const [values, setValues] = useState({ diff --git a/src/features/user/index.ts b/src/features/user/index.ts new file mode 100644 index 00000000..9afd9cf8 --- /dev/null +++ b/src/features/user/index.ts @@ -0,0 +1,4 @@ +export { useMyProfileForm } from "./hooks/useMyProfileForm"; +export { useDeleteMeMutation } from "./mutation/useDeleteMeMutation"; +export { useUpdateProfileMutation } from "./mutation/useUpdateProfileMutation"; +export { useUploadProfileImageMutation } from "./mutation/useUploadProfileImageMutation"; diff --git a/src/features/user/hooks/useDeleteMeMutation/index.ts b/src/features/user/mutation/useDeleteMeMutation/index.ts similarity index 100% rename from src/features/user/hooks/useDeleteMeMutation/index.ts rename to src/features/user/mutation/useDeleteMeMutation/index.ts diff --git a/src/features/user/hooks/useDeleteMeMutation/useDeleteMeMutation.ts b/src/features/user/mutation/useDeleteMeMutation/useDeleteMeMutation.ts similarity index 89% rename from src/features/user/hooks/useDeleteMeMutation/useDeleteMeMutation.ts rename to src/features/user/mutation/useDeleteMeMutation/useDeleteMeMutation.ts index 4e8744d7..d803545c 100644 --- a/src/features/user/hooks/useDeleteMeMutation/useDeleteMeMutation.ts +++ b/src/features/user/mutation/useDeleteMeMutation/useDeleteMeMutation.ts @@ -1,11 +1,10 @@ import { useMutation } from "@tanstack/react-query"; import { useRouter } from "next/navigation"; +import { deleteMe } from "@/entities/auth/api/myInfo.api"; import { logoutAction } from "@/features/auth/logout/actions/logoutAction"; import { useToast } from "@/shared/hooks/useToast"; -import { deleteMe } from "../../../../entities/auth/api/myInfo.api"; - export function useDeleteMeMutation() { const { toast } = useToast(); const router = useRouter(); diff --git a/src/features/user/hooks/useUpdateProfileMutation/index.ts b/src/features/user/mutation/useUpdateProfileMutation/index.ts similarity index 100% rename from src/features/user/hooks/useUpdateProfileMutation/index.ts rename to src/features/user/mutation/useUpdateProfileMutation/index.ts diff --git a/src/features/user/hooks/useUpdateProfileMutation/useUpdateProfileMutation.ts b/src/features/user/mutation/useUpdateProfileMutation/useUpdateProfileMutation.ts similarity index 100% rename from src/features/user/hooks/useUpdateProfileMutation/useUpdateProfileMutation.ts rename to src/features/user/mutation/useUpdateProfileMutation/useUpdateProfileMutation.ts diff --git a/src/features/user/hooks/useUploadProfileImageMutation/index.ts b/src/features/user/mutation/useUploadProfileImageMutation/index.ts similarity index 100% rename from src/features/user/hooks/useUploadProfileImageMutation/index.ts rename to src/features/user/mutation/useUploadProfileImageMutation/index.ts diff --git a/src/features/user/hooks/useUploadProfileImageMutation/useUploadProfileImageMutation.ts b/src/features/user/mutation/useUploadProfileImageMutation/useUploadProfileImageMutation.ts similarity index 100% rename from src/features/user/hooks/useUploadProfileImageMutation/useUploadProfileImageMutation.ts rename to src/features/user/mutation/useUploadProfileImageMutation/useUploadProfileImageMutation.ts diff --git a/src/widgets/my/MyProfileForm.tsx b/src/widgets/my/MyProfileForm.tsx index 59f517fd..a2fba52d 100644 --- a/src/widgets/my/MyProfileForm.tsx +++ b/src/widgets/my/MyProfileForm.tsx @@ -3,10 +3,9 @@ import { useSuspenseQuery } from "@tanstack/react-query"; import { useRouter } from "next/navigation"; import React from "react"; -import { userQueries } from "@/entities/auth/query/user.queryKey"; +import { userQueries } from "@/entities/auth"; import { logoutAction } from "@/features/auth/logout/actions/logoutAction"; -import { useDeleteMeMutation } from "@/features/user/hooks/useDeleteMeMutation/useDeleteMeMutation"; -import { useMyProfileForm } from "@/features/user/hooks/useMyProfileForm"; +import { useDeleteMeMutation, useMyProfileForm } from "@/features/user"; import { useOverlay } from "@/shared/hooks/useOverlay"; import Button from "@/shared/ui/Button/Button/Button"; import { Icon } from "@/shared/ui/Icon"; diff --git a/src/widgets/my/ProfileImageUploader.tsx b/src/widgets/my/ProfileImageUploader.tsx index 8869acba..ee3add77 100644 --- a/src/widgets/my/ProfileImageUploader.tsx +++ b/src/widgets/my/ProfileImageUploader.tsx @@ -1,7 +1,7 @@ "use client"; import React, { useRef } from "react"; -import { useUploadProfileImageMutation } from "@/features/user/hooks/useUploadProfileImageMutation"; +import { useUploadProfileImageMutation } from "@/features/user/mutation/useUploadProfileImageMutation"; import { useToast } from "@/shared/hooks/useToast"; import ActionButton from "../../shared/ui/Button/ActionButton/ActionButton"; diff --git a/src/widgets/trash/PersonalTrash/PersonalTrash.tsx b/src/widgets/trash/PersonalTrash/PersonalTrash.tsx index 774efb90..8a945506 100644 --- a/src/widgets/trash/PersonalTrash/PersonalTrash.tsx +++ b/src/widgets/trash/PersonalTrash/PersonalTrash.tsx @@ -1,5 +1,5 @@ "use client"; -import { trashQueries } from "@/features/trash/trash.queryKey"; +import { trashQueries } from "@/entities/trash"; import { useInfiniteScroll } from "@/shared/hooks/useInfiniteScroll"; import TrashEmpty from "@/widgets/trash/TrashEmpty"; import TrashList from "@/widgets/trash/TrashList"; diff --git a/src/widgets/trash/TeamTrash/TeamTrash.tsx b/src/widgets/trash/TeamTrash/TeamTrash.tsx index aa585af3..35e5ef1d 100644 --- a/src/widgets/trash/TeamTrash/TeamTrash.tsx +++ b/src/widgets/trash/TeamTrash/TeamTrash.tsx @@ -1,6 +1,6 @@ import React from "react"; -import { trashQueries } from "@/features/trash/trash.queryKey"; +import { trashQueries } from "@/entities/trash"; import { useInfiniteScroll } from "@/shared/hooks/useInfiniteScroll"; import TrashEmpty from "@/widgets/trash/TrashEmpty"; import TrashList from "@/widgets/trash/TrashList"; diff --git a/src/widgets/trash/TrashItem/TrashItem.tsx b/src/widgets/trash/TrashItem/TrashItem.tsx index 0de4f339..6d159369 100644 --- a/src/widgets/trash/TrashItem/TrashItem.tsx +++ b/src/widgets/trash/TrashItem/TrashItem.tsx @@ -1,12 +1,12 @@ import React from "react"; -import { TrashItemData } from "@/features/trash/types/trash.types"; +import { TrashItemData } from "@/entities/trash"; import { Icon } from "@/shared/ui/Icon"; import TrashBadge from "@/widgets/trash/TrashItem/TrashBadge"; interface TrashItemProps extends TrashItemData { isSelected: boolean; - onToggle: (id: number) => void; + onToggle: (key: string) => void; } function TrashItem({ isSelected, onToggle, ...item }: TrashItemProps) { @@ -16,7 +16,7 @@ function TrashItem({ isSelected, onToggle, ...item }: TrashItemProps) { onToggle(item.id)} + onClick={() => onToggle(`${item.itemType}-${item.id}`)} />
diff --git a/src/widgets/trash/TrashList/TrashList.tsx b/src/widgets/trash/TrashList/TrashList.tsx index 4af7543e..e4eee6a7 100644 --- a/src/widgets/trash/TrashList/TrashList.tsx +++ b/src/widgets/trash/TrashList/TrashList.tsx @@ -1,9 +1,9 @@ "use client"; import React, { useState } from "react"; -import { useDeleteTrashMutation } from "@/features/trash/hooks/useDeleteTrashMutation"; -import { useRestoreTrashMutation } from "@/features/trash/hooks/useRestoreTrashMutation"; -import { TrashItemData } from "@/features/trash/types/trash.types"; +import { TrashItemData } from "@/entities/trash"; +import { useDeleteTrashMutation } from "@/features/trash/mutation/useDeleteTrashMutation"; +import { useRestoreTrashMutation } from "@/features/trash/mutation/useRestoreTrashMutation"; import SoftButton from "@/shared/ui/Button/SoftButton"; import TrashItem from "../TrashItem"; @@ -15,30 +15,34 @@ interface TrashListProps { } function TrashList({ items, bottomRef, isFetchingNextPage }: TrashListProps) { - const [selectedIds, setSelectedIds] = useState>(new Set()); + const [selectedKeys, setSelectedKeys] = useState>(new Set()); const { mutate: restoreMutate, isPending: isRestore } = useRestoreTrashMutation(); const { mutate: deleteMutate, isPending: isDeleting } = useDeleteTrashMutation(); - const handleToggle = (id: number) => { - setSelectedIds((prev) => { + const getItemKey = (item: TrashItemData) => `${item.itemType}-${item.id}`; + + const handleToggle = (key: string) => { + setSelectedKeys((prev) => { const next = new Set(prev); - next.has(id) ? next.delete(id) : next.add(id); + next.has(key) ? next.delete(key) : next.add(key); return next; }); }; const handleSelectAll = () => { - if (selectedIds.size === items.length) { - setSelectedIds(new Set()); + if (selectedKeys.size === items.length) { + setSelectedKeys(new Set()); } else { - setSelectedIds(new Set(items.map((item) => item.id))); + setSelectedKeys(new Set(items.map(getItemKey))); } }; const getSelectedTrashItems = () => { - const selectedItems = items.filter((item) => selectedIds.has(item.id)); + const selectedItems = items.filter((item) => + selectedKeys.has(getItemKey(item)), + ); return { goalIds: selectedItems .filter((item) => item.itemType === "GOAL") @@ -50,13 +54,13 @@ function TrashList({ items, bottomRef, isFetchingNextPage }: TrashListProps) { }; const handleRestore = () => { restoreMutate(getSelectedTrashItems(), { - onSuccess: () => setSelectedIds(new Set()), + onSuccess: () => setSelectedKeys(new Set()), }); }; const handleDelete = () => { deleteMutate(getSelectedTrashItems(), { - onSuccess: () => setSelectedIds(new Set()), + onSuccess: () => setSelectedKeys(new Set()), }); }; @@ -65,8 +69,8 @@ function TrashList({ items, bottomRef, isFetchingNextPage }: TrashListProps) {
{items.map((item) => ( @@ -91,7 +95,7 @@ function TrashList({ items, bottomRef, isFetchingNextPage }: TrashListProps) { variant={"grayActive"} className="tablet:w-[90px] w-20 whitespace-nowrap" onClick={handleRestore} - disabled={selectedIds.size === 0 || isRestore || isDeleting} + disabled={selectedKeys.size === 0 || isRestore || isDeleting} > 복구 @@ -99,7 +103,7 @@ function TrashList({ items, bottomRef, isFetchingNextPage }: TrashListProps) { variant={"grayActive"} className="tablet:w-[90px] w-20 whitespace-nowrap" onClick={handleDelete} - disabled={selectedIds.size === 0 || isRestore || isDeleting} + disabled={selectedKeys.size === 0 || isRestore || isDeleting} > 삭제