diff --git a/public/notPublic.png b/public/notPublic.png deleted file mode 100644 index 9ca6781d..00000000 Binary files a/public/notPublic.png and /dev/null differ diff --git a/public/threeAnimals.png b/public/threeAnimals.png new file mode 100644 index 00000000..5edc12c1 Binary files /dev/null and b/public/threeAnimals.png differ diff --git a/src/apis/axiosInstanceClient.ts b/src/apis/axiosInstanceClient.ts index d8e59c2c..3c350452 100644 --- a/src/apis/axiosInstanceClient.ts +++ b/src/apis/axiosInstanceClient.ts @@ -3,6 +3,7 @@ import { NETWORK } from '@/constants/api'; import { COOKIE_MAX_AGE } from '@/constants/cookie'; import { ErrorResponseData } from '@/types/apis/ErrorResponseData'; +import { alertAndLogin } from '@/utils/alertAndLogin'; import { checkIsTokenExpired } from '@/utils/checkIsTokenExpired'; import axios, { AxiosError, InternalAxiosRequestConfig } from 'axios'; import { getCookie, setCookie } from 'cookies-next'; @@ -43,7 +44,6 @@ axiosInstanceClient.interceptors.response.use( }, async (error: AxiosError) => { //TODO:에러네임, 쿠키 키 상수화 - if ( error.response && error.response.data && @@ -64,7 +64,6 @@ axiosInstanceClient.interceptors.response.use( accessToken, refreshToken, }); - //TODO: setCookie('auth', tokens, { maxAge: COOKIE_MAX_AGE }); if (error.config) { error.config.headers.Authorization = `Bearer ${tokens.accessToken}`; @@ -72,14 +71,23 @@ axiosInstanceClient.interceptors.response.use( return response; } } catch { - console.log('catched'); + console.log('재발행 에러, catched'); console.log(error); console.log(error.response.data.errorName); - alertAndLogin(); + console.log(error.response); + alertAndLogin( + '로그인 정보가 유효하지 않습니다. 다시 로그인 해주세요.', + ); return; } } else { - alertAndLogin(); + console.log('둘다 만료, catched'); + console.log(error); + console.log(error.response.data.errorName); + console.log(error.response); + alertAndLogin( + '로그인 정보가 유효하지 않습니다. 다시 로그인 해주세요.', + ); return; } } @@ -88,8 +96,3 @@ axiosInstanceClient.interceptors.response.use( return Promise.reject(error); }, ); - -const alertAndLogin = () => { - alert('로그인 정보가 유효하지 않습니다. 다시 로그인해주세요 '); - window.location.replace(`${process.env.NEXT_PUBLIC_REDIRECT_URL}?way=logout`); -}; diff --git a/src/app/(header)/plans/[planId]/_components/NotPublic/NotPublic.tsx b/src/app/(header)/plans/[planId]/_components/NotPublic/NotPublic.tsx index 5ee54472..d0690e3e 100644 --- a/src/app/(header)/plans/[planId]/_components/NotPublic/NotPublic.tsx +++ b/src/app/(header)/plans/[planId]/_components/NotPublic/NotPublic.tsx @@ -10,7 +10,7 @@ export default function NotPublic() { className="not-public__image" width={350} height={250} - src={'/notPublic.png'} + src={'/threeAnimals.png'} alt="not public page" /> diff --git a/src/app/(header)/plans/[planId]/_components/SearchingPlan/SearchingPlan.tsx b/src/app/(header)/plans/[planId]/_components/SearchingPlan/SearchingPlan.tsx new file mode 100644 index 00000000..b34b12b0 --- /dev/null +++ b/src/app/(header)/plans/[planId]/_components/SearchingPlan/SearchingPlan.tsx @@ -0,0 +1,18 @@ +import Image from 'next/image'; +import './index.scss'; + +export default function SearchingPlan() { + return ( +
+ searching-plan + +

계획 찾는 중.....

+
+ ); +} diff --git a/src/app/(header)/plans/[planId]/_components/SearchingPlan/index.scss b/src/app/(header)/plans/[planId]/_components/SearchingPlan/index.scss new file mode 100644 index 00000000..af92345c --- /dev/null +++ b/src/app/(header)/plans/[planId]/_components/SearchingPlan/index.scss @@ -0,0 +1,15 @@ +.searching-plan { + &__wrapper { + display: flex; + flex-direction: column; + align-items: center; + gap: 2rem; + margin: 4rem 0; + width: 100%; + } + &__image { + width: 100%; + max-width: 350px; + object-fit: contain; + } +} diff --git a/src/app/(header)/plans/[planId]/page.tsx b/src/app/(header)/plans/[planId]/page.tsx index d8c67ad7..0cb20e55 100644 --- a/src/app/(header)/plans/[planId]/page.tsx +++ b/src/app/(header)/plans/[planId]/page.tsx @@ -15,6 +15,7 @@ import { useRouter } from 'next/navigation'; import { useEffect, useState } from 'react'; import { useSetRecoilState } from 'recoil'; import NotPublic from './_components/NotPublic/NotPublic'; +import SearchingPlan from './_components/SearchingPlan/SearchingPlan'; import './index.scss'; export default function PlanIdPage({ params }: { params: { planId: string } }) { @@ -25,11 +26,22 @@ export default function PlanIdPage({ params }: { params: { planId: string } }) { const [currentURL, setCurrentURL] = useState(''); const { plan } = useGetPlanQuery(Number(planId), isLogin); const [isDeletePlanModalOpen, setIsDeletePlanModalOpen] = useState(false); + const [isClientSide, setIsClientSide] = useState(false); const { handleScroll, scrollableRef } = useScroll(); const { mutate: deletePlanAPI } = useDeletePlanMutation(); const setIsMyPlanStore = useSetRecoilState(isMyPlanStore); const isMyPlan = plan.writer.owner; - const isVisible = isMyPlan || plan.public; + + // isVisible이라는 변수는 isMyPlan 과 plan.public값에 의해서 정해진다. 하지만 서버에서는 둘 다 undefined이다 그러면 값이 undefined으로 falsy하다. + //그래서 초기html을 받으면 falsy한 html을 받느다. 서버와 클라이언트는 typeof window를 통해서 할 수 있다. + // 또 문제가 이 부분으로 인해 notPublic한 계획도 초기 렌더링시 계획이 보이게된다. 그럼 한번 더싼다. typeof window를 확인해서 + //undefined면 isLoading + useEffect(() => { + if (typeof window !== 'undefined') setIsClientSide(true); + return () => { + setIsClientSide(false); + }; + }, []); useEffect(() => { const current = window.location.href; @@ -56,6 +68,26 @@ export default function PlanIdPage({ params }: { params: { planId: string } }) { const handleOpenDeleteModal = () => { setIsDeletePlanModalOpen(true); }; + const createPageContent = () => { + if (isClientSide) { + if (isMyPlan || plan.public) { + return ( + + {isMyPlan && isSeason && ( +
+ 수정| + 삭제 +
+ )} +
+ ); + } else { + return ; + } + } else { + return ; + } + }; return ( <> @@ -73,18 +105,7 @@ export default function PlanIdPage({ params }: { params: { planId: string } }) { > 계획 - {isVisible ? ( - - {isMyPlan && isSeason && ( -
- 수정| - 삭제 -
- )} -
- ) : ( - - )} + {createPageContent()} {isMyPlan && (

공유하기

diff --git a/src/app/(headerless)/oauth/hooks/useOauthPage.ts b/src/app/(headerless)/oauth/hooks/useOauthPage.ts index 57ddd66f..157a5559 100644 --- a/src/app/(headerless)/oauth/hooks/useOauthPage.ts +++ b/src/app/(headerless)/oauth/hooks/useOauthPage.ts @@ -8,20 +8,18 @@ export default function useOauthPage() { const router = useRouter(); const searchParams = useSearchParams(); const way = searchParams.get('way'); + const code = searchParams.get('code'); useEffect(() => { - if (way === 'login') { - const code = searchParams.get('code'); + if (way === 'login' && code) { (async () => { - if (code) { - try { - const { data: tokens } = await postLogin(code); - setCookie('auth', tokens, { maxAge: COOKIE_MAX_AGE }); - window.location.replace('/home'); - } catch (error) { - alert('로그인에 실패했습니다. 잠시 후 시도해주세요'); - router.replace('/login'); - } + try { + const { data: tokens } = await postLogin(code); + setCookie('auth', tokens, { maxAge: COOKIE_MAX_AGE }); + window.location.replace('/home'); + } catch (error) { + alert('로그인에 실패했습니다. 잠시 후 시도해주세요'); + router.replace('/login'); } })(); } else if (way === 'logout') { @@ -30,7 +28,7 @@ export default function useOauthPage() { } else { router.replace('/'); } - }, [router, way, searchParams]); + }, [router, code, way]); return { way }; } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 75d5428b..9043f364 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -63,7 +63,6 @@ export default function RootLayout({ src="https://t1.kakaocdn.net/kakao_js_sdk/2.5.0/kakao.min.js" integrity="sha384-kYPsUbBPlktXsY6/oNHSUDZoTX6+YI51f63jCPEIPFP09ttByAdxd2mEjKuhdqn4" type="module" - strategy="lazyOnload" /> ); diff --git a/src/utils/alertAndLogin.ts b/src/utils/alertAndLogin.ts new file mode 100644 index 00000000..bc89c0b1 --- /dev/null +++ b/src/utils/alertAndLogin.ts @@ -0,0 +1,4 @@ +export const alertAndLogin = (text: string) => { + alert(text); + window.location.replace(`${process.env.NEXT_PUBLIC_REDIRECT_URL}?way=logout`); +};