diff --git a/src/app/(user-page)/my-meeting/_features/CardRightSection.tsx b/src/app/(user-page)/my-meeting/_features/CardRightSection.tsx index 0ee5998..b18cca1 100644 --- a/src/app/(user-page)/my-meeting/_features/CardRightSection.tsx +++ b/src/app/(user-page)/my-meeting/_features/CardRightSection.tsx @@ -7,9 +7,12 @@ import { useExpelMutation, useMemberStatusMutation, } from '@/hooks/mutations/useMyMeetingMutation'; +import { myMeetingKeys } from '@/hooks/queries/useMyMeetingQueries'; import { useBannerQueries } from '@/hooks/queries/useMyPageQueries'; +import { useQueryClient } from '@tanstack/react-query'; import Image from 'next/image'; import { useState } from 'react'; +import { getMyMeetingMemberProfile } from 'service/api/mymeeting'; import type { Member } from 'types/myMeeting'; import ModalProfile from './ModalProfile'; @@ -82,6 +85,23 @@ const CardRightSection = ({ setIsUserProfileModalOpen(true); }; + const queryClient = useQueryClient(); + + const handlePrefetchProfile = async (member: Member) => { + const queryKey = myMeetingKeys.memberProfile(meetingId, member.userId); + + // 캐시에 데이터가 있는지 확인 + const cachedData = queryClient.getQueryData(queryKey); + + if (!cachedData) { + await queryClient.prefetchQuery({ + queryKey, + queryFn: () => + getMyMeetingMemberProfile({ meetingId, userId: member.userId }), + }); + } + }; + // 프로필 보기 할 유저 const [selectedUser, setSelectedUser] = useState(null); @@ -124,6 +144,7 @@ const CardRightSection = ({ variant={'outline'} className="h-[40px] w-[93px]" onClick={(e) => handleOpenProfileModal(e, member)} + onMouseEnter={() => handlePrefetchProfile(member)} > 프로필보기 @@ -180,6 +201,7 @@ const CardRightSection = ({ setIsUserProfileModalOpen={setIsUserProfileModalOpen} setIsUserListModalOpen={setIsUserListModalOpen} currentUser={currentUser} + handlePrefetchProfile={handlePrefetchProfile} /> diff --git a/src/app/(user-page)/my-meeting/_features/ModalUserList.tsx b/src/app/(user-page)/my-meeting/_features/ModalUserList.tsx index d2890a9..f769542 100644 --- a/src/app/(user-page)/my-meeting/_features/ModalUserList.tsx +++ b/src/app/(user-page)/my-meeting/_features/ModalUserList.tsx @@ -14,6 +14,7 @@ const ModalUserList = ({ setSelectedUser, currentUser, className, + handlePrefetchProfile, }: { memberList: Member[]; setSelectedUser: Dispatch>; @@ -21,6 +22,7 @@ const ModalUserList = ({ setIsUserListModalOpen: Dispatch>; currentUser: IBanner; className?: string; + handlePrefetchProfile: (member: Member) => Promise; }) => { const handleProfileClick = (user: Member) => { setSelectedUser(user); @@ -55,6 +57,7 @@ const ModalUserList = ({ onClick={() => handleProfileClick(user)} variant="outline" size="sm" + onMouseEnter={() => handlePrefetchProfile(user)} > 프로필 보기 diff --git a/src/app/(user-page)/my-meeting/my/page.tsx b/src/app/(user-page)/my-meeting/my/page.tsx index b3944bf..69feb38 100644 --- a/src/app/(user-page)/my-meeting/my/page.tsx +++ b/src/app/(user-page)/my-meeting/my/page.tsx @@ -1,22 +1,56 @@ import NotYet from '@/components/common/NotYet'; +import { myMeetingKeys } from '@/hooks/queries/useMyMeetingQueries'; +import { QUERY_KEYS } from '@/hooks/queries/useMyPageQueries'; +import { + HydrationBoundary, + QueryClient, + dehydrate, +} from '@tanstack/react-query'; +import { getMyMeetingManage } from 'service/api/mymeeting'; +import { getBanner } from 'service/api/mypageProfile'; +import { Paginated } from 'types/meeting'; +import { IMyMeetingManage } from 'types/myMeeting'; import Created from '../_features/Created'; // import Joined from '../../components/Joined'; import Tab from '../_features/Tab'; -export default function Page({ +export default async function Page({ searchParams, }: { searchParams: { type: string }; }) { const type = searchParams?.type; + const queryClient = new QueryClient(); + + // 배너 + await queryClient.prefetchQuery({ + queryKey: QUERY_KEYS.banner(), + queryFn: () => getBanner(), + }); + + if (type === 'created') { + // 내가 만든 모임 리스트 prefetch + await queryClient.prefetchInfiniteQuery({ + queryKey: myMeetingKeys.manage(), + queryFn: ({ pageParam }) => getMyMeetingManage(pageParam), + getNextPageParam: (lastPage: Paginated) => + lastPage.nextCursor ?? false, + initialPageParam: 0, + }); + } else { + // 참여 중인 모임 prefetch + } + return (
- {type === 'created' ? : } + + {type === 'created' ? : } +
); } diff --git a/src/hooks/queries/useMyMeetingQueries.ts b/src/hooks/queries/useMyMeetingQueries.ts index 084975f..00f5ecf 100644 --- a/src/hooks/queries/useMyMeetingQueries.ts +++ b/src/hooks/queries/useMyMeetingQueries.ts @@ -3,6 +3,8 @@ import { getMyMeetingManage, getMyMeetingMemberProfile, } from 'service/api/mymeeting'; +import { Paginated } from 'types/meeting'; +import { IMyMeetingManage } from 'types/myMeeting'; export const myMeetingKeys = { all: ['mymeeting'] as const, @@ -19,7 +21,7 @@ export const useInfiniteMyMeetingManageQueries = () => { queryKey: myMeetingKeys.manage(), queryFn: ({ pageParam }) => getMyMeetingManage(pageParam), initialPageParam: 0, - getNextPageParam: (lastPage, pages) => { + getNextPageParam: (lastPage: Paginated, pages) => { console.log('[mutation] lastPage: ', lastPage); return lastPage.nextCursor ?? null; },