diff --git a/apps/web/src/apis/mentor/getMentorList.ts b/apps/web/src/apis/mentor/getMentorList.ts index 8e41e741..205f38bd 100644 --- a/apps/web/src/apis/mentor/getMentorList.ts +++ b/apps/web/src/apis/mentor/getMentorList.ts @@ -1,5 +1,6 @@ import { useInfiniteQuery, useQueryClient } from "@tanstack/react-query"; import type { AxiosError } from "axios"; +import { useCallback } from "react"; import { type MentorCardDetail, type MentorListResponse, MentorQueryKeys, mentorApi } from "./api"; interface UseGetMentorListRequest { @@ -24,14 +25,17 @@ const useGetMentorList = ({ region = "" }: UseGetMentorListRequest = {}) => { export const usePrefetchMentorList = () => { const queryClient = useQueryClient(); - const prefetchMentorList = (region: string) => { - queryClient.prefetchInfiniteQuery({ - queryKey: [MentorQueryKeys.mentorList, region], - queryFn: ({ pageParam = 0 }) => mentorApi.getMentorList(region, pageParam as number), - initialPageParam: 0, - staleTime: 1000 * 60 * 5, - }); - }; + const prefetchMentorList = useCallback( + (region: string) => { + queryClient.prefetchInfiniteQuery({ + queryKey: [MentorQueryKeys.mentorList, region], + queryFn: ({ pageParam = 0 }) => mentorApi.getMentorList(region, pageParam as number), + initialPageParam: 0, + staleTime: 1000 * 60 * 5, + }); + }, + [queryClient], + ); return { prefetchMentorList }; }; diff --git a/apps/web/src/app/mentor/_ui/MentorClient/_ui/MenteePageTabs/index.tsx b/apps/web/src/app/mentor/_ui/MentorClient/_ui/MenteePageTabs/index.tsx index 6a3cd55c..093c7a37 100644 --- a/apps/web/src/app/mentor/_ui/MentorClient/_ui/MenteePageTabs/index.tsx +++ b/apps/web/src/app/mentor/_ui/MentorClient/_ui/MenteePageTabs/index.tsx @@ -10,15 +10,19 @@ import TabSelector from "@/components/ui/TabSelector"; import { IconDirectionRight } from "@/public/svgs/mentor"; import { VerifyStatus } from "@/types/mentee"; import { MenteeTab } from "@/types/mentor"; +import { MentorChatCardsSkeleton } from "../../../MentorPageSkeleton"; const MenteePageTabs = () => { // api - const { data: mentoList = [] } = useGetChatRooms(); - const { data: menteeWaitingMentoringList = [] } = useGetMenteeMentoringList(VerifyStatus.PENDING); + const { data: mentoList = [], isPending: isMentoListPending } = useGetChatRooms(); + const { data: menteeWaitingMentoringList = [], isPending: isWaitingListPending } = useGetMenteeMentoringList( + VerifyStatus.PENDING, + ); // state const [selectedTab, setSelectedTab] = useState(MenteeTab.MY_MENTOR); const tabs = [MenteeTab.MY_MENTOR, MenteeTab.MY_APPLIED]; + const isCurrentTabPending = selectedTab === MenteeTab.MY_MENTOR ? isMentoListPending : isWaitingListPending; // 현재 탭에 따라 보여줄 데이터의 길이 const currentDataLength = selectedTab === MenteeTab.MY_MENTOR ? mentoList.length : menteeWaitingMentoringList.length; @@ -51,13 +55,16 @@ const MenteePageTabs = () => { )} - {currentDataLength === 0 && ( + {isCurrentTabPending ? ( + + ) : currentDataLength === 0 ? ( - )} + ) : null} - {selectedTab === MenteeTab.MY_MENTOR && + {!isCurrentTabPending && + selectedTab === MenteeTab.MY_MENTOR && mentoList.slice(0, 2).map((mentor) => ( { /> ))} - {selectedTab === MenteeTab.MY_APPLIED && + {!isCurrentTabPending && + selectedTab === MenteeTab.MY_APPLIED && menteeWaitingMentoringList .slice(0, 2) .map((mentor) => ( diff --git a/apps/web/src/app/mentor/_ui/MentorClient/_ui/MentorFindSection/index.tsx b/apps/web/src/app/mentor/_ui/MentorClient/_ui/MentorFindSection/index.tsx index ec91d6e0..2d3ff354 100644 --- a/apps/web/src/app/mentor/_ui/MentorClient/_ui/MentorFindSection/index.tsx +++ b/apps/web/src/app/mentor/_ui/MentorClient/_ui/MentorFindSection/index.tsx @@ -7,6 +7,7 @@ import EmptySdwBCards from "@/components/ui/EmptySdwBCards"; import FloatingUpBtn from "@/components/ui/FloatingUpBtn"; import { FilterTab } from "@/types/mentor"; import useInfinityScroll from "@/utils/useInfinityScroll"; +import { MentorCardListSkeleton } from "../../../MentorPageSkeleton"; import usePrefetchMentorFindTab from "./_hooks/usePrefetchMentorFindTab"; import useSelectedTab from "./_hooks/useSelectedTab"; @@ -17,6 +18,7 @@ const MentorFindSection = () => { data: mentorList = [], fetchNextPage, hasNextPage, + isPending, } = useGetMentorList({ region: selectedTab !== FilterTab.ALL ? selectedTab : "", }); @@ -44,12 +46,14 @@ const MentorFindSection = () => { {/* 멘토 리스트 */}
- {mentorList.length === 0 ? ( + {isPending ? ( + + ) : mentorList.length === 0 ? ( ) : ( - mentorList.map((mentor) => ( + mentorList.map((mentor, index) => ( diff --git a/apps/web/src/app/mentor/_ui/MentorClient/_ui/MentorPage/_ui/ApplicantListSection/index.tsx b/apps/web/src/app/mentor/_ui/MentorClient/_ui/MentorPage/_ui/ApplicantListSection/index.tsx index f834796e..55475d3d 100644 --- a/apps/web/src/app/mentor/_ui/MentorClient/_ui/MentorPage/_ui/ApplicantListSection/index.tsx +++ b/apps/web/src/app/mentor/_ui/MentorClient/_ui/MentorPage/_ui/ApplicantListSection/index.tsx @@ -3,14 +3,17 @@ import { useGetMentoringList } from "@/apis/mentor"; import MentorExpandChatCard from "@/components/mentor/MentorExpandChatCard"; import EmptySdwBCards from "@/components/ui/EmptySdwBCards"; import useInfinityScroll from "@/utils/useInfinityScroll"; +import { MentorApplicantListSkeleton } from "../../../../../MentorPageSkeleton"; const ApplicantListSection = () => { - const { data: mentoringApplicantList = [], fetchNextPage, hasNextPage } = useGetMentoringList({ size: 6 }); + const { data: mentoringApplicantList = [], fetchNextPage, hasNextPage, isPending } = useGetMentoringList({ size: 6 }); const { lastElementRef } = useInfinityScroll({ fetchNextPage, hasNextPage }); return ( <> - {mentoringApplicantList.length === 0 ? ( + {isPending ? ( + + ) : mentoringApplicantList.length === 0 ? ( ) : ( mentoringApplicantList.map((mentor, index) => ( diff --git a/apps/web/src/app/mentor/_ui/MentorClient/_ui/MentorPage/_ui/MyMentorSection/index.tsx b/apps/web/src/app/mentor/_ui/MentorClient/_ui/MentorPage/_ui/MyMentorSection/index.tsx index 77433fce..715480fd 100644 --- a/apps/web/src/app/mentor/_ui/MentorClient/_ui/MentorPage/_ui/MyMentorSection/index.tsx +++ b/apps/web/src/app/mentor/_ui/MentorClient/_ui/MentorPage/_ui/MyMentorSection/index.tsx @@ -2,9 +2,21 @@ import { useGetMentorMyProfile } from "@/apis/mentor"; import MentorCard from "@/components/mentor/MentorCard"; +import { MentorCardListSkeleton } from "../../../../../MentorPageSkeleton"; const MyMentorSection = () => { - const { data: myMentorProfile } = useGetMentorMyProfile(); + const { data: myMentorProfile, isPending } = useGetMentorMyProfile(); + + if (isPending) { + return ( + <> +

나의 멘토 페이지

+
+ +
+ + ); + } if (!myMentorProfile) { return
멘토 프로필을 불러오는 중...
; diff --git a/apps/web/src/app/mentor/_ui/MentorClient/_ui/MentorPage/index.tsx b/apps/web/src/app/mentor/_ui/MentorClient/_ui/MentorPage/index.tsx index 0521b691..ca479694 100644 --- a/apps/web/src/app/mentor/_ui/MentorClient/_ui/MentorPage/index.tsx +++ b/apps/web/src/app/mentor/_ui/MentorClient/_ui/MentorPage/index.tsx @@ -9,6 +9,7 @@ import TabSelector from "@/components/ui/TabSelector"; import { IconDirectionRight } from "@/public/svgs/mentor"; import { MentorTab } from "@/types/mentor"; +import { MentorChatCardsSkeleton } from "../../../MentorPageSkeleton"; import ApplicantListSection from "./_ui/ApplicantListSection"; import MyMentorSection from "./_ui/MyMentorSection"; @@ -17,7 +18,7 @@ const MentorPage = () => { const isMyMenteeTab = selectedTab === MentorTab.MY_MENTEE; const tabs = [MentorTab.MY_MENTEE, MentorTab.APPLY_LIST]; - const { data: myMenteeList = [] } = useGetChatRooms(); + const { data: myMenteeList = [], isPending: isMyMenteeListPending } = useGetChatRooms(); return ( <> @@ -46,7 +47,9 @@ const MentorPage = () => { {isMyMenteeTab ? ( <> {/* 나의 멘티 */} - {myMenteeList.length === 0 ? ( + {isMyMenteeListPending ? ( + + ) : myMenteeList.length === 0 ? ( ) : ( myMenteeList.slice(0, 3).map((mentee) => { diff --git a/apps/web/src/app/mentor/_ui/MentorClient/index.tsx b/apps/web/src/app/mentor/_ui/MentorClient/index.tsx index 59dad579..2d44a936 100644 --- a/apps/web/src/app/mentor/_ui/MentorClient/index.tsx +++ b/apps/web/src/app/mentor/_ui/MentorClient/index.tsx @@ -7,6 +7,7 @@ import { useGetMyInfo } from "@/apis/MyPage"; import CloudSpinnerPage from "@/components/ui/CloudSpinnerPage"; import useAuthStore from "@/lib/zustand/useAuthStore"; import { UserRole } from "@/types/mentor"; +import MentorPageSkeleton from "../MentorPageSkeleton"; import MenteePage from "./_ui/MenteePage"; import MentorPage from "./_ui/MentorPage"; @@ -27,7 +28,7 @@ const MentorClient = () => { }, [isAuthResolving, isUnauthorized, isError, role, router]); if (isAuthResolving) { - return ; + return ; } if (isUnauthorized || (!isError && !role)) { diff --git a/apps/web/src/app/mentor/_ui/MentorPageSkeleton.tsx b/apps/web/src/app/mentor/_ui/MentorPageSkeleton.tsx new file mode 100644 index 00000000..ea7df6b1 --- /dev/null +++ b/apps/web/src/app/mentor/_ui/MentorPageSkeleton.tsx @@ -0,0 +1,82 @@ +const MentorTabSkeleton = () => ( +