diff --git a/src/pages/promiseDetail/PromiseDetailPage.tsx b/src/pages/promiseDetail/PromiseDetailPage.tsx index 16eb548e..d748cec7 100644 --- a/src/pages/promiseDetail/PromiseDetailPage.tsx +++ b/src/pages/promiseDetail/PromiseDetailPage.tsx @@ -21,6 +21,7 @@ import { import { extractMonthAndDay } from '@pages/promiseList/utils/extractMonthAndDay'; import { ModalRejectImg, ModalAcceptImg } from '@assets/svgs'; import Loading from '@components/commons/Loading'; +import ErrorPage from '@pages/errorPage/ErrorPage'; const PromiseDetail = () => { const location = useLocation(); @@ -29,8 +30,17 @@ const PromiseDetail = () => { const { tap, myNickname, appointmentId } = location.state; const userRole = 'SENIOR'; - const { juniorInfo, seniorInfo, timeList1, timeList2, timeList3, topic, personalTopic, isSuccess, isLoading } = - useGetPromiseDetail(appointmentId); + const { + juniorInfo, + seniorInfo, + timeList1, + timeList2, + timeList3, + topic, + personalTopic, + isLoading, + isError: getPromiseDetailError, + } = useGetPromiseDetail(appointmentId); // 기본뷰 / 거절뷰 const [viewType, setViewType] = useState('DEFAULT'); @@ -55,7 +65,11 @@ const PromiseDetail = () => { }; // 선배 약속 수락 - const { mutate: patchSeniorAccept } = usePatchSeniorAccept(() => handleModalOpen(true)); + const { + mutate: patchSeniorAccept, + isPending: isPatchSeniorAcceptPending, + isError: patchSeniorAcceptError, + } = usePatchSeniorAccept(() => handleModalOpen(true)); // 구글밋 링크 patch 콜백 함수 const handleSuccessCallback = (link: string) => { @@ -74,7 +88,11 @@ const PromiseDetail = () => { }; // 구글밋 링크 받아오기(post) 후 약속 수락 patch - const { mutate: postGoogleMeetLink } = usePostGoogleMeetLink((link) => { + const { + mutate: postGoogleMeetLink, + isPending: isPostGoogleMeetLinkPending, + isError: postGoogleMeetLinkError, + } = usePostGoogleMeetLink((link) => { handleSuccessCallback(link); }); @@ -95,7 +113,9 @@ const PromiseDetail = () => { }; // 선배 약속 거절 - const { mutate: patchSeniorReject } = usePatchSeniorReject(() => handleModalOpen(true)); + const { mutate: patchSeniorReject, isError: patchSeniorRejectError } = usePatchSeniorReject(() => + handleModalOpen(true) + ); const handleRejectBtn = () => { patchSeniorReject({ appointmentId: appointmentId, @@ -113,7 +133,15 @@ const PromiseDetail = () => { window.open(link, '_blank'); }; - useGetGoogleMeetLink(appointmentId, isEnterBtnClicked, handleClickEnterBtn); + const { isError: getGoogleMeetLinkError } = useGetGoogleMeetLink( + appointmentId, + isEnterBtnClicked, + handleClickEnterBtn + ); + + const handleBottomSheetOpen = () => { + setIsBottomSheetOpen(true); + }; const handleBottomSheetClose = () => { setIsBottomSheetOpen(false); @@ -127,16 +155,27 @@ const PromiseDetail = () => { const handleRejectDetailReason = (detailReason: string) => { setRejectDetail(detailReason); }; - // 훅을 조건문 밖에서 호출 + const countdown = useCountdown(timeList1?.date, timeList1?.startTime); const dateInfo = extractMonthAndDay(timeList1?.date + ''); - if (isLoading) { + if (tap === undefined || myNickname === undefined) { + navigate('/promiseList'); + } + + if (isLoading || isPatchSeniorAcceptPending || isPostGoogleMeetLinkPending) { return ; // 로딩 중일 때 표시 } - if (!isSuccess || !timeList1) { - return
데이터 없음
; // 데이터가 없을 때 표시 + if ( + getPromiseDetailError || + !timeList1 || + postGoogleMeetLinkError || + patchSeniorAcceptError || + patchSeniorRejectError || + getGoogleMeetLinkError + ) { + return ; } // 조건부로 훅의 결과를 처리 @@ -160,7 +199,13 @@ const PromiseDetail = () => { <>
+ navigate(`/promiseList`, { + state: { + prevTap: tap, + }, + }) + } title={viewType === 'DEFAULT' ? '자세히 보기' : '거절하기'} /> @@ -291,23 +336,13 @@ const PromiseDetail = () => { )} - {viewType === 'DECLINE' ? ( - - - - ) : ( - - - - )} + + {viewType === 'DECLINE' ? : } + { - // 라우터 이동할 때 location으로 약속id, 눌린 탭 상태값(pending, sheduled, ..) 받아와야함 const navigate = useNavigate(); const location = useLocation(); const { tap, myNickname, appointmentId, seniorId } = location.state; @@ -29,24 +28,39 @@ const PromiseDetailPageJunior = () => { navigate('/juniorPromise'); }; - useGetGoogleMeetLink(appointmentId, isEnterBtnClicked, handleClickEnterBtn); + const { isError: getGoogleMeetLinkError } = useGetGoogleMeetLink( + appointmentId, + isEnterBtnClicked, + handleClickEnterBtn + ); const handleSetIsDetailClicked = (type: boolean) => { setIsDetailClicked(type); }; - const { juniorInfo, seniorInfo, timeList1, topic, personalTopic, isSuccess, isLoading } = - useGetPromiseDetail(appointmentId); + const { + juniorInfo, + seniorInfo, + timeList1, + topic, + personalTopic, + isLoading, + isError: getPromiseDetailError, + } = useGetPromiseDetail(appointmentId); const countdown = useCountdown(timeList1?.date, timeList1?.startTime); const { diffText, diff } = countdown; + if (tap === undefined || myNickname === undefined || appointmentId === undefined || seniorId === undefined) { + navigate('/promiseList'); + } + if (isLoading) { - return ; // 로딩 중일 때 표시 + return ; } - if (!isSuccess || !timeList1) { + if (getPromiseDetailError || !timeList1 || getGoogleMeetLinkError) { return ; } diff --git a/src/pages/promiseDetail/apis/postGoogleMeetLink.ts b/src/pages/promiseDetail/apis/postGoogleMeetLink.ts index bdf3a785..8042a5ed 100644 --- a/src/pages/promiseDetail/apis/postGoogleMeetLink.ts +++ b/src/pages/promiseDetail/apis/postGoogleMeetLink.ts @@ -7,6 +7,6 @@ export const postGoogleMeetLink = async () => { // console.log(response.data.data.googleMeet); return response.data.data.googleMeet; } catch (err) { - console.log(err); + console.error('구글밋 회의실 개설 에러 ', err); } }; diff --git a/src/pages/promiseDetail/hooks/queries.ts b/src/pages/promiseDetail/hooks/queries.ts index c8af4821..98b6309f 100644 --- a/src/pages/promiseDetail/hooks/queries.ts +++ b/src/pages/promiseDetail/hooks/queries.ts @@ -18,7 +18,7 @@ export const usePatchSeniorReject = (onSuccessCallback?: () => void) => { const queryClient = useQueryClient(); const navigate = useNavigate(); - const { mutate, data } = useMutation({ + const { mutate, data, isError } = useMutation({ mutationKey: [QUERY_KEY_PROMISE_DETAIL.patchSeniorReject], mutationFn: ({ appointmentId, rejectReason, rejectDetail }: patchSeniorRejectRequestType) => patchSeniorReject({ appointmentId, rejectReason, rejectDetail }), @@ -34,12 +34,12 @@ export const usePatchSeniorReject = (onSuccessCallback?: () => void) => { }, }); - return { mutate, data }; + return { mutate, data, isError }; }; // 구글밋 링크 받기 export const usePostGoogleMeetLink = (onSuccessCallback?: (data: string) => void) => { - const { mutate, data } = useMutation({ + const { mutate, data, isPending, isError } = useMutation({ mutationKey: [QUERY_KEY_PROMISE_DETAIL.postGoogleMeetLink], mutationFn: postGoogleMeetLink, onSuccess: (data) => { @@ -49,7 +49,7 @@ export const usePostGoogleMeetLink = (onSuccessCallback?: (data: string) => void }, }); - return { mutate, data }; + return { mutate, data, isPending, isError }; }; // 선배 약속 수락 @@ -57,7 +57,7 @@ export const usePatchSeniorAccept = (onSuccessCallback?: () => void) => { const navigate = useNavigate(); const queryClient = useQueryClient(); - const { mutate, data } = useMutation({ + const { mutate, data, isPending, isError } = useMutation({ mutationKey: [QUERY_KEY_PROMISE_DETAIL.patchSeniorAccept], mutationFn: ({ appointmentId, googleMeetLink, timeList }: patchSeniorAcceptRequestType) => patchSeniorAccept({ appointmentId, googleMeetLink, timeList }), @@ -74,11 +74,11 @@ export const usePatchSeniorAccept = (onSuccessCallback?: () => void) => { }, }); - return { mutate, data }; + return { mutate, data, isPending, isError }; }; export const useGetPromiseDetail = (appointmentId: number) => { - const { data, isSuccess, isLoading } = useQuery({ + const { data, isSuccess, isLoading, isError } = useQuery({ queryKey: [QUERY_KEY_PROMISE_DETAIL.getPromiseDetail, appointmentId], queryFn: () => getPromiseDetail(appointmentId), }); @@ -116,5 +116,6 @@ export const useGetPromiseDetail = (appointmentId: number) => { personalTopic, isSuccess, isLoading, + isError }; }; diff --git a/src/pages/promiseList/PromiseListPage.tsx b/src/pages/promiseList/PromiseListPage.tsx index c9d3bd18..86736879 100644 --- a/src/pages/promiseList/PromiseListPage.tsx +++ b/src/pages/promiseList/PromiseListPage.tsx @@ -11,7 +11,6 @@ import { getRole } from '@utils/storage'; import ErrorPage from '@pages/errorPage/ErrorPage'; const PromiseListPage = () => { - // 유저가 선배일 경우 const userRole = getRole() + ''; const { myNickname, pending, scheduled, past, isLoading, isError } = useGetPromiseList(); diff --git a/src/pages/promiseList/components/ProfileContainer.tsx b/src/pages/promiseList/components/ProfileContainer.tsx index c0ffab0e..f20327e8 100644 --- a/src/pages/promiseList/components/ProfileContainer.tsx +++ b/src/pages/promiseList/components/ProfileContainer.tsx @@ -48,11 +48,14 @@ const ProfileContainer = (props: ProfileContainerPropType) => { // 상세 페이지 라우팅 const handleClickProfileContainer = (tap: string, userRole: string) => { + // [선배] 확정대기 - 약속 상세페이지 if (userRole === 'SENIOR' && tap === 'pending') { navigate('/promiseList/promiseDetail', { state: { tap: 'pending', myNickname: myNickname, appointmentId: profileCardData?.appointmentId }, }); } + + // [후배] 확정대기 - 약속 상세페이지 if (userRole === 'JUNIOR' && tap === 'pending') { navigate('/promiseList/promiseDetailJunior', { state: { @@ -64,12 +67,14 @@ const ProfileContainer = (props: ProfileContainerPropType) => { }); } + // [선배] 예정약속, 가장가까운약속 - 약속 상세페이지 if (userRole === 'SENIOR' && (tap === 'scheduled' || tap === 'default') && detail !== 'detail') { navigate('/promiseList/promiseDetail', { state: { tap: 'scheduled', myNickname: myNickname, appointmentId: profileCardData?.appointmentId }, }); } + // [후배] 예정약속, 가장가까운약속 - 약속 상세페이지 if (userRole === 'JUNIOR' && (tap === 'scheduled' || tap === 'default') && detail !== 'detail') { navigate('/promiseList/promiseDetailJunior', { state: { @@ -81,7 +86,7 @@ const ProfileContainer = (props: ProfileContainerPropType) => { }); } - // 실제 선배 아이디로 연결 필요 + // [후배] 약속 상세페이지 - 선배 상세페이지 if ( userRole === 'JUNIOR' && (tap === 'scheduled' || tap === 'default' || tap === 'pending') && diff --git a/src/pages/promiseList/components/PromiseTap.tsx b/src/pages/promiseList/components/PromiseTap.tsx index 286f0824..8ad48eee 100644 --- a/src/pages/promiseList/components/PromiseTap.tsx +++ b/src/pages/promiseList/components/PromiseTap.tsx @@ -17,11 +17,12 @@ interface PromiseTapPropType { const PromiseTap = (props: PromiseTapPropType) => { const location = useLocation(); const navigate = useNavigate(); - const [tap, setTap] = useState('pending'); - const { userRole, pending, scheduled, past, myNickname } = props; + const { userRole, pending, scheduled, past, myNickname } = props; const { prevTap } = location.state || {}; + const [tap, setTap] = useState('pending'); + useEffect(() => { if (prevTap && Object.keys(prevTap).length !== 0) { setTap(prevTap); diff --git a/src/pages/promiseList/components/RecentCard.tsx b/src/pages/promiseList/components/RecentCard.tsx index 86c117a6..de275f35 100644 --- a/src/pages/promiseList/components/RecentCard.tsx +++ b/src/pages/promiseList/components/RecentCard.tsx @@ -7,6 +7,7 @@ import PromiseTimerBtn from './PromiseTimerBtn'; import { profileCardDataType } from '../types/type'; import { useGetGoogleMeetLink } from '../hooks/queries'; import { useState } from 'react'; +import ErrorPage from '@pages/errorPage/ErrorPage'; interface RecentCardPropType { userRole: string; @@ -24,7 +25,11 @@ const RecentCard = (props: RecentCardPropType) => { setIsEnterBtnClicked(false); }; - useGetGoogleMeetLink(recentAppointment?.appointmentId, isEnterBtnClicked, handleClickEnterBtn); + const { isError: getGoogleMeetLinkError } = useGetGoogleMeetLink( + recentAppointment?.appointmentId, + isEnterBtnClicked, + handleClickEnterBtn + ); const handleClickUserGuide = () => { userRole === 'SENIOR' @@ -32,6 +37,10 @@ const RecentCard = (props: RecentCardPropType) => { : window.open('https://cumbersome-cactus-843.notion.site/d394be50d2b44a03878debd0e19bdb2f?pvs=4', '_blank'); }; + if (getGoogleMeetLinkError) { + return ; + } + return ( diff --git a/src/pages/promiseList/hooks/queries.ts b/src/pages/promiseList/hooks/queries.ts index 3b62ea49..eac51d63 100644 --- a/src/pages/promiseList/hooks/queries.ts +++ b/src/pages/promiseList/hooks/queries.ts @@ -13,7 +13,7 @@ export const useGetGoogleMeetLink = ( isEnterBtnClicked: boolean, onSuccessCallback?: (link: string) => void, ) => { - const { data, isSuccess } = useQuery({ + const { data, isSuccess, isError } = useQuery({ queryKey: [QUERY_KEY_PROMISE_LIST.getGoogleMeetLink, appointmentId, isEnterBtnClicked], queryFn: () => getGoogleMeetLink(appointmentId as number), enabled: !!isEnterBtnClicked && appointmentId !== undefined, @@ -28,7 +28,7 @@ export const useGetGoogleMeetLink = ( } }, [isSuccess, data]); - return { data, isSuccess }; + return { data, isSuccess, isError }; }; export const useGetPromiseList = () => {