diff --git a/src/components/auth/guard/PaymentAccessGuard.tsx b/src/components/auth/guard/PaymentAccessGuard.tsx
new file mode 100644
index 0000000..0337722
--- /dev/null
+++ b/src/components/auth/guard/PaymentAccessGuard.tsx
@@ -0,0 +1,58 @@
+import { useQuery } from '@tanstack/react-query';
+import memberApi from '@/apis/member/memberApi';
+import { useState, useEffect } from 'react';
+import { Outlet, useNavigate } from 'react-router-dom';
+import RoutePath from '@/routes/routePath';
+import { toast } from 'react-toastify';
+import LoadingSpinner from '@/components/common/LoadingSpinner';
+
+const PaymentAccessGuard = () => {
+ const [redirect, setRedirect] = useState(false);
+ const navigate = useNavigate();
+ const { data, isLoading } = useQuery({
+ queryKey: ['member'],
+ queryFn: memberApi.GET_DASHBOARD
+ });
+
+ useEffect(() => {
+ if (!data) return;
+
+ if (data.member.role !== 'ASSOCIATE') {
+ toast.error('준회원 조건을 충족해주세요.');
+ setRedirect(true);
+ }
+
+ if (!data.currentMembership) {
+ toast.error('정회원 지원 이후 학회비를 결제할 수 있어요.');
+ setRedirect(true);
+ }
+
+ if (!data.currentRecruitmentRound) {
+ toast.error('지금은 정회원 모집 기간이 아니에요.');
+ setRedirect(true);
+ }
+ }, []);
+
+ useEffect(() => {
+ if (redirect) {
+ navigate(RoutePath.Dashboard);
+ }
+ }, [redirect, navigate]);
+
+ if (isLoading) {
+ return ;
+ }
+
+ if (!data) return;
+
+ if (
+ data.member.role !== 'ASSOCIATE' ||
+ !data.currentRecruitmentRound ||
+ !data.currentMembership
+ ) {
+ navigate(RoutePath.Dashboard);
+ return null;
+ } else return ;
+};
+
+export default PaymentAccessGuard;
diff --git a/src/components/auth/guard/PaymentSuccessAccessGuard.tsx b/src/components/auth/guard/PaymentSuccessAccessGuard.tsx
new file mode 100644
index 0000000..d651bdc
--- /dev/null
+++ b/src/components/auth/guard/PaymentSuccessAccessGuard.tsx
@@ -0,0 +1,49 @@
+import { useQuery } from '@tanstack/react-query';
+import memberApi from '@/apis/member/memberApi';
+import { useState, useEffect } from 'react';
+import { Outlet, useNavigate } from 'react-router-dom';
+import RoutePath from '@/routes/routePath';
+import { toast } from 'react-toastify';
+import LoadingSpinner from '@/components/common/LoadingSpinner';
+
+const PaymentSuccessAccessGuard = () => {
+ const [redirect, setRedirect] = useState(false);
+ const navigate = useNavigate();
+ const { data, isLoading } = useQuery({
+ queryKey: ['member'],
+ queryFn: memberApi.GET_DASHBOARD
+ });
+
+ useEffect(() => {
+ if (!data) return;
+
+ if (data.member.role !== 'REGULAR') {
+ toast.error('토스페이먼츠 결제를 완료해주세요.');
+ setRedirect(true);
+ }
+
+ if (!data.currentRecruitmentRound) {
+ toast.error('지금은 정회원 모집 기간이 아니에요.');
+ setRedirect(true);
+ }
+ }, []);
+
+ useEffect(() => {
+ if (redirect) {
+ navigate(RoutePath.Dashboard);
+ }
+ }, [redirect, navigate]);
+
+ if (isLoading) {
+ return ;
+ }
+
+ if (!data) return;
+
+ if (data.member.role !== 'REGULAR' || !data.currentRecruitmentRound) {
+ navigate(RoutePath.Dashboard);
+ return null;
+ } else return ;
+};
+
+export default PaymentSuccessAccessGuard;
diff --git a/src/routes/index.tsx b/src/routes/index.tsx
index c946584..c04bfef 100644
--- a/src/routes/index.tsx
+++ b/src/routes/index.tsx
@@ -2,6 +2,7 @@ import App from '@/App';
import * as Sentry from '@sentry/react';
import RoutePath from '@/routes/routePath';
import { RouterProvider, createBrowserRouter } from 'react-router-dom';
+import PaymentSuccessAccessGuard from '@/components/auth/guard/PaymentSuccessAccessGuard';
import Layout from '@/components/layout/Layout';
import {
MypageAccessGuard,
@@ -31,6 +32,7 @@ import {
import { DicordConnect } from '@/pages/DiscordConnect';
import { DiscordGuide } from '@/pages/DiscordGuide';
import { Suspense } from 'react';
+import PaymentAccessGuard from '@/components/auth/guard/PaymentAccessGuard';
const sentryCreateBrowserRouter =
Sentry.wrapCreateBrowserRouter(createBrowserRouter);
@@ -122,15 +124,18 @@ const router = sentryCreateBrowserRouter([
},
{
path: RoutePath.PaymentsCheckout,
- element:
+ element: ,
+ children: [{ index: true, element: }]
},
{
path: RoutePath.PaymentsFail,
- element:
+ element: ,
+ children: [{ index: true, element: }]
},
{
path: RoutePath.PaymentsSuccess,
- element:
+ element: ,
+ children: [{ index: true, element: }]
},
// Todo: 404 Not found page
{ path: '*', element: not found page }