diff --git a/src/apis/gathering-list/query/use-get-gathering-mine-list.ts b/src/apis/gathering-list/query/use-get-gathering-mine-list.ts index bbd16ae1..c04097fb 100644 --- a/src/apis/gathering-list/query/use-get-gathering-mine-list.ts +++ b/src/apis/gathering-list/query/use-get-gathering-mine-list.ts @@ -1,10 +1,13 @@ import queryKeys from "@/apis/query-keys"; import { GetGatheringMineListRequest } from "@/types/gathering-list"; -import { useInfiniteQuery, useQuery } from "@tanstack/react-query"; +import { + useSuspenseInfiniteQuery, + useSuspenseQuery, +} from "@tanstack/react-query"; import { getGatheringMineList } from "../gathering-list.api"; const useGetGatheringMineList = (params: GetGatheringMineListRequest) => { - return useQuery({ + return useSuspenseQuery({ queryKey: queryKeys.gatheringList.mine(params), queryFn: () => getGatheringMineList(params), }); @@ -13,7 +16,7 @@ const useGetGatheringMineList = (params: GetGatheringMineListRequest) => { const useGetGatheringMineListInfinite = ( params: Omit ) => { - return useInfiniteQuery({ + return useSuspenseInfiniteQuery({ queryKey: queryKeys.gatheringList.mineInfinite({ ...params, page: 0 }), queryFn: ({ pageParam }) => getGatheringMineList({ ...params, page: pageParam }), diff --git a/src/apis/user/query/use-get-user-info-suspense.ts b/src/apis/user/query/use-get-user-info-suspense.ts new file mode 100644 index 00000000..64d6a9d4 --- /dev/null +++ b/src/apis/user/query/use-get-user-info-suspense.ts @@ -0,0 +1,21 @@ +import queryKeys from "@/apis/query-keys"; +import { useSuspenseQuery } from "@tanstack/react-query"; +import { getUserInfo } from "../user.api"; + +const useGetUserInfoSuspense = () => { + return useSuspenseQuery({ + queryKey: queryKeys.user.all, + queryFn: getUserInfo, + retry: false, + staleTime: 1000 * 60 * 5, + select: (response) => ({ + ...response, + profileImageUrl: response.profileImageUrl + ? `${response.profileImageUrl}?date=${Date.now()}` + : "", + }), + structuralSharing: false, + }); +}; + +export default useGetUserInfoSuspense; diff --git a/src/app/(root)/(main)/my-page/page.tsx b/src/app/(root)/(main)/my-page/page.tsx index ba14dc7e..234baf51 100644 --- a/src/app/(root)/(main)/my-page/page.tsx +++ b/src/app/(root)/(main)/my-page/page.tsx @@ -1,10 +1,26 @@ -import { Gatherings, UserProfile } from "@/components/section"; +import { GatheringListSkeleton, UserProfile } from "@/components/section"; +import UserProfileSkeleton from "@/components/section/fallback/user-profile-skeleton"; +import { + HostGatherings, + MemberGatherings, +} from "@/components/section/user/gatherings"; +import { Suspense } from "react"; const MyPage = () => { return (
- - + }> + + + +
+ }> + + + }> + + +
); }; diff --git a/src/components/section/fallback/auth-status-skeleton.tsx b/src/components/section/fallback/auth-status-skeleton.tsx new file mode 100644 index 00000000..358ad4f4 --- /dev/null +++ b/src/components/section/fallback/auth-status-skeleton.tsx @@ -0,0 +1,7 @@ +const AuthStatusSkeleton = () => { + return ( +
+ ); +}; + +export default AuthStatusSkeleton; diff --git a/src/components/section/fallback/gathering-list-skeleton.tsx b/src/components/section/fallback/gathering-list-skeleton.tsx index c316f1f2..b99dc77e 100644 --- a/src/components/section/fallback/gathering-list-skeleton.tsx +++ b/src/components/section/fallback/gathering-list-skeleton.tsx @@ -1,4 +1,4 @@ -const GatheringListSkeleton = () => { +const GatheringListSkeleton = ({ subTitle = true }: { subTitle?: boolean }) => { const skeletonCards = Array.from({ length: 4 }, (_, index) => (
  • @@ -7,13 +7,13 @@ const GatheringListSkeleton = () => { {/* 본문 */}
    {/* 모임 명 */} -
    +
    {/* 카테고리 뱃지 및 인원 수 */}
    {/* 카테고리 뱃지 */} -
    +
    {/* 인원 수 */} -
    +
    @@ -26,7 +26,9 @@ const GatheringListSkeleton = () => {
    -
    + {subTitle && ( +
    + )}
    diff --git a/src/components/section/fallback/user-profile-skeleton.tsx b/src/components/section/fallback/user-profile-skeleton.tsx new file mode 100644 index 00000000..1aaea390 --- /dev/null +++ b/src/components/section/fallback/user-profile-skeleton.tsx @@ -0,0 +1,23 @@ +const UserProfileSkeleton = () => { + return ( +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + ); +}; + +export default UserProfileSkeleton; diff --git a/src/components/section/user/gatherings.tsx b/src/components/section/user/gatherings.tsx index fd395cc4..4c67ec90 100644 --- a/src/components/section/user/gatherings.tsx +++ b/src/components/section/user/gatherings.tsx @@ -3,45 +3,46 @@ import { useGetGatheringMineList } from "@/apis/gathering-list/query/use-get-gathering-mine-list"; import GatheringList from "../gathering/list/gathering-list"; -const Gatherings = () => { - const { - data: hostGathering, - isPending: isHostLoading, - isError: isHostError, - } = useGetGatheringMineList({ +const HostGatherings = () => { + const { data: hostGathering } = useGetGatheringMineList({ role: "HOST", size: 10, page: 0, }); - const { - data: memberGathering, - isPending: isMemberLoading, - isError: isMemberError, - } = useGetGatheringMineList({ + return ( + + ); +}; + +const MemberGatherings = () => { + const { data: memberGathering } = useGetGatheringMineList({ role: "MEMBER", size: 10, page: 0, }); - if (isHostLoading || isMemberLoading) return
    Loading...
    ; - - if (isHostError || isMemberError) return
    Error
    ; + return ( + + ); +}; +const Gatherings = () => { return (
    - - + +
    ); }; export default Gatherings; +export { HostGatherings, MemberGatherings }; diff --git a/src/components/section/user/user-profile.tsx b/src/components/section/user/user-profile.tsx index df06f7a8..99157d58 100644 --- a/src/components/section/user/user-profile.tsx +++ b/src/components/section/user/user-profile.tsx @@ -1,16 +1,13 @@ "use client"; -import useGetUserInfo from "@/apis/user/query/use-get-user-info"; +import useGetUserInfoSuspense from "@/apis/user/query/use-get-user-info-suspense"; import { PasswordEditModal, Profile, ProfileEditModal } from "@/components/ui"; const UserProfile = () => { - const { data, isPending, isError } = useGetUserInfo(); - - if (isPending) return
    Loading...
    ; - if (isError) return
    Error
    ; + const { data } = useGetUserInfoSuspense(); return (
    -
    +
    { />
    - + {data.nickname} diff --git a/src/components/ui/button/auth-status-button.tsx b/src/components/ui/button/auth-status-button.tsx index d08b2a94..821dbcbf 100644 --- a/src/components/ui/button/auth-status-button.tsx +++ b/src/components/ui/button/auth-status-button.tsx @@ -1,6 +1,7 @@ "use client"; import useSignOut from "@/apis/auth/mutation/use-sign-out"; import useGetUserInfo from "@/apis/user/query/use-get-user-info"; +import AuthStatusSkeleton from "@/components/section/fallback/auth-status-skeleton"; import { Button, Dropdown, Profile } from "@/components/ui"; import { useAuthStore } from "@/store/auth-store"; import { cn } from "@/utils/cn"; @@ -17,30 +18,30 @@ const AuthStatusButton = ({ className }: AuthStatusButtonProps) => { const isSignedIn = useAuthStore((state) => state.authStatus); if (isSignedIn) { - return ( - user && ( - - } - items={[ - { - text: "마이페이지", - onClick: () => router.push("/my-page"), - }, - { - text: "로그아웃", - onClick: signOut, - }, - ]} - itemClassName="hover:text-gray-neutral-700 text-gray-neutral-500 justify-center" - contentAlign="end" - /> - ) + return user ? ( + + } + items={[ + { + text: "마이페이지", + onClick: () => router.push("/my-page"), + }, + { + text: "로그아웃", + onClick: signOut, + }, + ]} + itemClassName="hover:text-gray-neutral-700 text-gray-neutral-500 justify-center" + contentAlign="end" + /> + ) : ( + ); } else { return (