diff --git a/src/app/group/[groupId]/edit/page.tsx b/src/app/group/[groupId]/edit/page.tsx
index beb48496..607b6ac4 100644
--- a/src/app/group/[groupId]/edit/page.tsx
+++ b/src/app/group/[groupId]/edit/page.tsx
@@ -10,12 +10,10 @@ import {
import type { APIGroupDetail, APIEditBookGroup } from '@/types/group';
import { SERVICE_ERROR_MESSAGE } from '@/constants';
-import {
- checkAuthentication,
- isAxiosErrorWithCustomCode,
-} from '@/utils/helpers';
-
+import { isAxiosErrorWithCustomCode } from '@/utils/helpers';
import useToast from '@/v1/base/Toast/useToast';
+
+import withAuthRequired from '@/hocs/withAuthRequired';
import BookGroupEditDateForm from '@/v1/bookGroup/edit/BookGroupEditDateForm';
import BookGroupEditIntroduceForm from '@/v1/bookGroup/edit/BookGroupEditIntroduceForm';
import BookGroupEditTitleForm from '@/v1/bookGroup/edit/BookGroupEditTitleForm';
@@ -28,13 +26,15 @@ const BookGroupEditPage = ({
}) => {
const router = useRouter();
- const isAuthenticated = checkAuthentication();
-
const { data: bookGroupData } = useBookGroupEditCurrentInfo(groupId);
const { isOwner, title, description, maxMemberCount, startDate, endDate } =
bookGroupData;
- if (!isAuthenticated || !isOwner) {
+ /**
+ * @todo
+ * 401 페이지 만들기 (접근 권한이 없어요)
+ */
+ if (!isOwner) {
notFound();
}
@@ -99,4 +99,4 @@ const BookGroupEditPage = ({
);
};
-export default BookGroupEditPage;
+export default withAuthRequired(BookGroupEditPage);
diff --git a/src/app/group/[groupId]/join/page.tsx b/src/app/group/[groupId]/join/page.tsx
index 8750b3bc..08de9554 100644
--- a/src/app/group/[groupId]/join/page.tsx
+++ b/src/app/group/[groupId]/join/page.tsx
@@ -6,6 +6,8 @@ import { SubmitHandler, useForm } from 'react-hook-form';
import useJoinBookGroup from '@/hooks/group/useJoinBookGroup';
import SSRSafeSuspense from '@/components/SSRSafeSuspense';
+import withAuthRequired from '@/hocs/withAuthRequired';
+
import Loading from '@/v1/base/Loading';
import Input from '@/v1/base/Input';
import InputLength from '@/v1/base/InputLength';
@@ -36,6 +38,8 @@ const JoinBookGroupPage = ({
);
};
+export default withAuthRequired(JoinBookGroupPage);
+
const BookGroupJoinForm = ({ groupId }: { groupId: number }) => {
const router = useRouter();
const { isMember, hasPassword, question, joinBookGroup } =
@@ -100,5 +104,3 @@ const BookGroupJoinForm = ({ groupId }: { groupId: number }) => {
);
};
-
-export default JoinBookGroupPage;
diff --git a/src/app/group/create/page.tsx b/src/app/group/create/page.tsx
index 9151feea..da9a1401 100644
--- a/src/app/group/create/page.tsx
+++ b/src/app/group/create/page.tsx
@@ -1,7 +1,11 @@
+'use client';
+
+import withAuthRequired from '@/hocs/withAuthRequired';
+
import CreateBookGroupFunnel from '@/v1/bookGroup/create/CreateBookGroupFunnel';
const GroupCreateFunnelPage = () => {
return ;
};
-export default GroupCreateFunnelPage;
+export default withAuthRequired(GroupCreateFunnelPage);
diff --git a/src/app/profile/me/add/page.tsx b/src/app/profile/me/add/page.tsx
index 8cbfef82..ad62e746 100644
--- a/src/app/profile/me/add/page.tsx
+++ b/src/app/profile/me/add/page.tsx
@@ -4,8 +4,10 @@ import useAllJobQuery from '@/queries/job/useAllJobQuery';
import { checkAuthentication } from '@/utils/helpers';
-import AddJobProfile from '@/v1/profile/AddJobProfile';
import SSRSafeSuspense from '@/components/SSRSafeSuspense';
+import withAuthRequired from '@/hocs/withAuthRequired';
+
+import AddJobProfile from '@/v1/profile/AddJobProfile';
const AddJobProfilePage = () => {
return (
@@ -15,6 +17,8 @@ const AddJobProfilePage = () => {
);
};
+export default withAuthRequired(AddJobProfilePage);
+
const Contents = () => {
const isAuthenticated = checkAuthentication();
const allJobQuery = useAllJobQuery({ enabled: isAuthenticated });
@@ -23,5 +27,3 @@ const Contents = () => {
) : null;
};
-
-export default AddJobProfilePage;
diff --git a/src/app/profile/me/edit/page.tsx b/src/app/profile/me/edit/page.tsx
index 4016132d..970f2f7f 100644
--- a/src/app/profile/me/edit/page.tsx
+++ b/src/app/profile/me/edit/page.tsx
@@ -5,22 +5,22 @@ import useMyProfileQuery from '@/queries/user/useMyProfileQuery';
import { checkAuthentication } from '@/utils/helpers';
-import EditProfile from '@/v1/profile/EditProfile';
import SSRSafeSuspense from '@/components/SSRSafeSuspense';
+import withAuthRequired from '@/hocs/withAuthRequired';
-/**
- * @todo
- * Fallback UI 추가하기
- */
+import EditProfile from '@/v1/profile/EditProfile';
+import Loading from '@/v1/base/Loading';
const EditProfilePage = () => {
return (
-
+ }>
);
};
+export default withAuthRequired(EditProfilePage);
+
const Contents = () => {
const isAuthenticated = checkAuthentication();
const allJobQuery = useAllJobQuery({ enabled: isAuthenticated });
@@ -30,5 +30,3 @@ const Contents = () => {
) : null;
};
-
-export default EditProfilePage;
diff --git a/src/app/profile/me/group/page.tsx b/src/app/profile/me/group/page.tsx
index cde1a832..71358673 100644
--- a/src/app/profile/me/group/page.tsx
+++ b/src/app/profile/me/group/page.tsx
@@ -4,6 +4,8 @@ import useMyGroupsQuery from '@/queries/group/useMyGroupQuery';
import { checkAuthentication } from '@/utils/helpers';
import SSRSafeSuspense from '@/components/SSRSafeSuspense';
+import withAuthRequired from '@/hocs/withAuthRequired';
+
import BackButton from '@/v1/base/BackButton';
import TopNavigation from '@/v1/base/TopNavigation';
import DetailBookGroupCard from '@/v1/bookGroup/DetailBookGroupCard';
@@ -24,6 +26,8 @@ const UserGroupPage = () => {
);
};
+export default withAuthRequired(UserGroupPage);
+
const UserGroupContent = () => {
const isAuthenticated = checkAuthentication();
const { data } = useMyGroupsQuery({ enabled: isAuthenticated });
@@ -65,8 +69,6 @@ const UserGroupContent = () => {
);
};
-export default UserGroupPage;
-
const PageSkeleton = () => (
{Array.from({ length: 4 }).map((_, index) => (
diff --git a/src/hocs/withAuthRequired.tsx b/src/hocs/withAuthRequired.tsx
new file mode 100644
index 00000000..db655b3a
--- /dev/null
+++ b/src/hocs/withAuthRequired.tsx
@@ -0,0 +1,36 @@
+'use client';
+
+import { useRouter } from 'next/navigation';
+import { useEffect, useState } from 'react';
+
+import { checkAuthentication } from '@/utils/helpers';
+
+const withAuthRequired = (
+ WrappedComponent: React.ComponentType
+) => {
+ const Component = (props: P) => {
+ const router = useRouter();
+
+ const [isAuthenticated, setIsAuthenticated] = useState(false);
+
+ useEffect(() => {
+ const hasAccessToken = checkAuthentication();
+
+ if (!hasAccessToken) {
+ router.push('/login');
+ } else {
+ setIsAuthenticated(hasAccessToken);
+ }
+ }, [router]);
+
+ if (!isAuthenticated) {
+ return null;
+ } else {
+ return ;
+ }
+ };
+
+ return Component;
+};
+
+export default withAuthRequired;
diff --git a/src/v1/profile/group/ProfileGroupContainer.tsx b/src/v1/profile/group/ProfileGroupContainer.tsx
index d066fa50..cb033e86 100644
--- a/src/v1/profile/group/ProfileGroupContainer.tsx
+++ b/src/v1/profile/group/ProfileGroupContainer.tsx
@@ -1,6 +1,9 @@
import useMyGroupsQuery from '@/queries/group/useMyGroupQuery';
import useMyProfileQuery from '@/queries/user/useMyProfileQuery';
-import { APIUser } from '@/types/user';
+import type { APIUser } from '@/types/user';
+
+import { checkAuthentication } from '@/utils/helpers';
+
import ProfileGroupPresenter from './ProfileGroupPresenter';
const ProfileGroupContainer = ({
@@ -8,7 +11,9 @@ const ProfileGroupContainer = ({
}: {
userId: 'me' | APIUser['userId'];
}) => {
- const { data } = useMyGroupsQuery();
+ const isAuthenticated = checkAuthentication();
+
+ const { data } = useMyGroupsQuery({ enabled: isAuthenticated });
const {
data: { userId: myId },
} = useMyProfileQuery({ enabled: userId === 'me' });