Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[노철] - 비공개 계획 #399

Merged
merged 4 commits into from
Jan 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file removed public/notPublic.png
Binary file not shown.
Binary file added public/threeAnimals.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 13 additions & 10 deletions src/apis/axiosInstanceClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -43,7 +44,6 @@ axiosInstanceClient.interceptors.response.use(
},
async (error: AxiosError<ErrorResponseData>) => {
//TODO:에러네임, 쿠키 키 상수화

if (
error.response &&
error.response.data &&
Expand All @@ -64,22 +64,30 @@ axiosInstanceClient.interceptors.response.use(
accessToken,
refreshToken,
});
//TODO:
setCookie('auth', tokens, { maxAge: COOKIE_MAX_AGE });
if (error.config) {
error.config.headers.Authorization = `Bearer ${tokens.accessToken}`;
const response = await axiosInstanceClient.request(error.config);
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;
}
}
Expand All @@ -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`);
};
Original file line number Diff line number Diff line change
Expand Up @@ -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"
/>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Image from 'next/image';
import './index.scss';

export default function SearchingPlan() {
return (
<div className="searching-plan__wrapper">
<Image
className="searching-plan__image"
width={350}
height={250}
src={'/threeAnimals.png'}
alt="searching-plan"
/>

<h1 className="font-size-xl">계획 찾는 중..... </h1>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
47 changes: 34 additions & 13 deletions src/app/(header)/plans/[planId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 } }) {
Expand All @@ -25,11 +26,22 @@ export default function PlanIdPage({ params }: { params: { planId: string } }) {
const [currentURL, setCurrentURL] = useState<string>('');
const { plan } = useGetPlanQuery(Number(planId), isLogin);
const [isDeletePlanModalOpen, setIsDeletePlanModalOpen] = useState(false);
const [isClientSide, setIsClientSide] = useState<boolean>(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;
Expand All @@ -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 (
<ReadOnlyPlan isMine={isMyPlan} planData={{ ...plan }}>
{isMyPlan && isSeason && (
<div className="plan__header--buttons">
<Link href={`/plans/edit/${planId}`}>수정</Link>|
<span onClick={handleOpenDeleteModal}>삭제</span>
</div>
)}
</ReadOnlyPlan>
);
} else {
return <NotPublic />;
}
} else {
return <SearchingPlan />;
}
};

return (
<>
Expand All @@ -73,18 +105,7 @@ export default function PlanIdPage({ params }: { params: { planId: string } }) {
&gt;
<span>계획</span>
</div>
{isVisible ? (
<ReadOnlyPlan isMine={isMyPlan} planData={{ ...plan }}>
{isMyPlan && isSeason && (
<div className="plan__header--buttons">
<Link href={`/plans/edit/${planId}`}>수정</Link>|
<span onClick={handleOpenDeleteModal}>삭제</span>
</div>
)}
</ReadOnlyPlan>
) : (
<NotPublic />
)}
{createPageContent()}
{isMyPlan && (
<div className="plans-page--share">
<h2>공유하기</h2>
Expand Down
22 changes: 10 additions & 12 deletions src/app/(headerless)/oauth/hooks/useOauthPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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') {
Expand All @@ -30,7 +28,7 @@ export default function useOauthPage() {
} else {
router.replace('/');
}
}, [router, way, searchParams]);
}, [router, code, way]);

return { way };
}
1 change: 0 additions & 1 deletion src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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"
/>
</html>
);
Expand Down
4 changes: 4 additions & 0 deletions src/utils/alertAndLogin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const alertAndLogin = (text: string) => {
alert(text);
window.location.replace(`${process.env.NEXT_PUBLIC_REDIRECT_URL}?way=logout`);
};