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 }