From 62b5317fb1531c27943b7808597ed56da016f2a2 Mon Sep 17 00:00:00 2001 From: gimdogyun Date: Mon, 25 Mar 2024 14:16:53 +0900 Subject: [PATCH 1/3] feat : NeedAuth & NeedLogin Component MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - NeedAuth : 특정 권한이 없을 시 메인으로 리다이렉팅 - NeedLogin : 로그인 상태가 아닐 시 로그인으로 리다이렉팅 - #888 --- src/components/NeedAuth/NeedAuth.tsx | 27 +++++++++++++++++++++++++++ src/components/NeedAuth/NeedLogin.tsx | 25 +++++++++++++++++++++++++ src/hooks/useCheckAuth.ts | 6 +++++- 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 src/components/NeedAuth/NeedAuth.tsx create mode 100644 src/components/NeedAuth/NeedLogin.tsx diff --git a/src/components/NeedAuth/NeedAuth.tsx b/src/components/NeedAuth/NeedAuth.tsx new file mode 100644 index 000000000..4bf802a38 --- /dev/null +++ b/src/components/NeedAuth/NeedAuth.tsx @@ -0,0 +1,27 @@ +import { useEffect } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { Role } from '@api/dto'; +import useCheckAuth from '@hooks/useCheckAuth'; + +interface NeedLoginProps { + children: JSX.Element; + roles: Role[]; +} + +const NeedAuth = ({ children, roles }: NeedLoginProps) => { + const { checkIncludeOneOfAuths } = useCheckAuth(); + const navigate = useNavigate(); + + useEffect(() => { + if (!checkIncludeOneOfAuths(roles)) { + navigate('/'); + } + }, [checkIncludeOneOfAuths(roles)]); + + if (checkIncludeOneOfAuths(roles)) { + return children; + } + return null; +}; + +export default NeedAuth; diff --git a/src/components/NeedAuth/NeedLogin.tsx b/src/components/NeedAuth/NeedLogin.tsx new file mode 100644 index 000000000..999f755ca --- /dev/null +++ b/src/components/NeedAuth/NeedLogin.tsx @@ -0,0 +1,25 @@ +import { useEffect } from 'react'; +import { useNavigate } from 'react-router-dom'; +import useCheckAuth from '@hooks/useCheckAuth'; + +interface NeedLoginProps { + children: JSX.Element; +} + +const NeedLogin = ({ children }: NeedLoginProps) => { + const { checkLogin } = useCheckAuth(); + const navigate = useNavigate(); + + useEffect(() => { + if (!checkLogin()) { + navigate('/login'); + } + }, [checkLogin()]); + + if (checkLogin()) { + return children; + } + return null; +}; + +export default NeedLogin; diff --git a/src/hooks/useCheckAuth.ts b/src/hooks/useCheckAuth.ts index 7eb5076e1..1b00a7ed7 100644 --- a/src/hooks/useCheckAuth.ts +++ b/src/hooks/useCheckAuth.ts @@ -6,6 +6,10 @@ import memberState from '@recoil/member.recoil'; const useCheckAuth = () => { const member: MemberInfo | null = useRecoilValue(memberState); + const checkLogin = useMemo(() => { + return () => member !== null; + }, [member]); + const checkAuth = useMemo(() => { return (requiredRole: Role) => member?.memberJobs?.includes(requiredRole); }, [member]); @@ -16,7 +20,7 @@ const useCheckAuth = () => { const checkIsMyId = (id: number) => member?.memberId === id; - return { checkAuth, checkIncludeOneOfAuths, checkIsMyId }; + return { checkLogin, checkAuth, checkIncludeOneOfAuths, checkIsMyId }; }; export default useCheckAuth; From 39d48440685e737668d5b34f808f961811ec1f70 Mon Sep 17 00:00:00 2001 From: gimdogyun Date: Mon, 25 Mar 2024 14:33:37 +0900 Subject: [PATCH 2/3] =?UTF-8?q?feat=20:=20=EA=B6=8C=ED=95=9C=EC=9D=B4=20?= =?UTF-8?q?=EC=97=86=EC=9D=84=20=EC=8B=9C=20ConfirmModal=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - #888 --- src/components/NeedAuth/NeedAuth.tsx | 17 ++++++++++------- src/components/NeedAuth/NeedLogin.tsx | 17 ++++++++++------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/components/NeedAuth/NeedAuth.tsx b/src/components/NeedAuth/NeedAuth.tsx index 4bf802a38..3b4df861f 100644 --- a/src/components/NeedAuth/NeedAuth.tsx +++ b/src/components/NeedAuth/NeedAuth.tsx @@ -1,7 +1,8 @@ -import { useEffect } from 'react'; +import React from 'react'; import { useNavigate } from 'react-router-dom'; import { Role } from '@api/dto'; import useCheckAuth from '@hooks/useCheckAuth'; +import ConfirmModal from '@components/Modal/ConfirmModal'; interface NeedLoginProps { children: JSX.Element; @@ -12,16 +13,18 @@ const NeedAuth = ({ children, roles }: NeedLoginProps) => { const { checkIncludeOneOfAuths } = useCheckAuth(); const navigate = useNavigate(); - useEffect(() => { - if (!checkIncludeOneOfAuths(roles)) { - navigate('/'); - } - }, [checkIncludeOneOfAuths(roles)]); + const onClose = () => { + navigate('/'); + }; if (checkIncludeOneOfAuths(roles)) { return children; } - return null; + return ( + +

접근 권한이 없습니다

+
+ ); }; export default NeedAuth; diff --git a/src/components/NeedAuth/NeedLogin.tsx b/src/components/NeedAuth/NeedLogin.tsx index 999f755ca..d8be796fb 100644 --- a/src/components/NeedAuth/NeedLogin.tsx +++ b/src/components/NeedAuth/NeedLogin.tsx @@ -1,6 +1,7 @@ -import { useEffect } from 'react'; +import React from 'react'; import { useNavigate } from 'react-router-dom'; import useCheckAuth from '@hooks/useCheckAuth'; +import ConfirmModal from '@components/Modal/ConfirmModal'; interface NeedLoginProps { children: JSX.Element; @@ -10,16 +11,18 @@ const NeedLogin = ({ children }: NeedLoginProps) => { const { checkLogin } = useCheckAuth(); const navigate = useNavigate(); - useEffect(() => { - if (!checkLogin()) { - navigate('/login'); - } - }, [checkLogin()]); + const onClose = () => { + navigate('/login'); + }; if (checkLogin()) { return children; } - return null; + return ( + +

로그인 후 이용해주세요

+
+ ); }; export default NeedLogin; From cae9db20d6d9d6e0c6cf4098a75060618aa2bee8 Mon Sep 17 00:00:00 2001 From: gimdogyun Date: Tue, 26 Mar 2024 15:18:04 +0900 Subject: [PATCH 3/3] =?UTF-8?q?feat=20:=20=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EB=B3=84=20=EA=B6=8C=ED=95=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - NeedAuth는 회장과 부회장은 무조건 허용하도록 수정 - #888 --- src/components/NeedAuth/NeedAuth.tsx | 6 +- src/router/useMainRouter.tsx | 86 +++++++++++++++++++++++----- 2 files changed, 75 insertions(+), 17 deletions(-) diff --git a/src/components/NeedAuth/NeedAuth.tsx b/src/components/NeedAuth/NeedAuth.tsx index 3b4df861f..60d7c1e03 100644 --- a/src/components/NeedAuth/NeedAuth.tsx +++ b/src/components/NeedAuth/NeedAuth.tsx @@ -6,10 +6,10 @@ import ConfirmModal from '@components/Modal/ConfirmModal'; interface NeedLoginProps { children: JSX.Element; - roles: Role[]; + roles?: Role[]; } -const NeedAuth = ({ children, roles }: NeedLoginProps) => { +const NeedAuth = ({ children, roles = [] }: NeedLoginProps) => { const { checkIncludeOneOfAuths } = useCheckAuth(); const navigate = useNavigate(); @@ -17,7 +17,7 @@ const NeedAuth = ({ children, roles }: NeedLoginProps) => { navigate('/'); }; - if (checkIncludeOneOfAuths(roles)) { + if (checkIncludeOneOfAuths([...roles, 'ROLE_회장', 'ROLE_부회장'])) { return children; } return ( diff --git a/src/router/useMainRouter.tsx b/src/router/useMainRouter.tsx index 945b38e84..8d4813f06 100644 --- a/src/router/useMainRouter.tsx +++ b/src/router/useMainRouter.tsx @@ -22,6 +22,8 @@ import SeminarAttend from '@pages/senimarAttend/SenimarAttend'; import FitContainer from '@components/Layout/Container/FitContainer'; import FullContainer from '@components/Layout/Container/FullContainer'; import MainLayout from '@components/Layout/MainLayout'; +import NeedAuth from '@components/NeedAuth/NeedAuth'; +import NeedLogin from '@components/NeedAuth/NeedLogin'; const useMainRouter = () => useRoutes([ @@ -54,7 +56,11 @@ const useMainRouter = () => }, { path: 'profile/:memberId/*', - element: , + element: ( + + + + ), }, ], }, @@ -66,7 +72,11 @@ const useMainRouter = () => children: [ { path: 'dutyManage', - element: , + element: ( + + + + ), }, /* { path: 'electionManage', @@ -74,19 +84,35 @@ const useMainRouter = () => }, */ { path: 'libraryManage/*', - element: , + element: ( + + + + ), }, { path: 'seminarManage', - element: , + element: ( + + + + ), }, { path: 'activeMemberManage', - element: , + element: ( + + + + ), }, { path: 'meritManage', - element: , + element: ( + + + + ), }, ], }, @@ -95,29 +121,53 @@ const useMainRouter = () => children: [ { path: ':categoryName', - element: , + element: ( + + + + ), }, { path: 'write/:categoryName', - element: , + element: ( + + + + ), }, { path: 'view/:postId', - element: , + element: ( + + + + ), }, ], }, { path: 'study', - element: , + element: ( + + + + ), }, { path: 'library', - element: , + element: ( + + + + ), }, { path: 'seminar', - element: , + element: ( + + + + ), }, /* { path: 'election', @@ -125,11 +175,19 @@ const useMainRouter = () => }, */ { path: 'rank', - element: , + element: ( + + + + ), }, { path: 'game', - element: , + element: ( + + + + ), }, /* { path: 'ctf',