From 65bccc3b4b7fb6835b5551090bc7a50e4985881b Mon Sep 17 00:00:00 2001 From: bada308 <203190@jnu.ac.kr> Date: Sun, 24 Mar 2024 01:13:56 +0900 Subject: [PATCH 01/45] =?UTF-8?q?fix:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FE/src/app/(auth)/login/logging-in/page.tsx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/FE/src/app/(auth)/login/logging-in/page.tsx b/FE/src/app/(auth)/login/logging-in/page.tsx index bc1b1433..624e0d38 100644 --- a/FE/src/app/(auth)/login/logging-in/page.tsx +++ b/FE/src/app/(auth)/login/logging-in/page.tsx @@ -3,20 +3,21 @@ import { useSearchParams } from "next/navigation"; import { useEffect } from "react"; import LoadingSpinner from "@/components/common/LoadingSpinner"; -import { useSlackLoginMutation } from "@/hooks/query/useAuthQuery"; +// import { useSlackLoginMutation } from "@/hooks/query/useAuthQuery"; const LoginSlackCallbackPage = () => { const searchParams = useSearchParams(); const code = searchParams.get("code"); - const { mutate: loginSlack } = useSlackLoginMutation(); + // const { mutate: loginSlack } = useSlackLoginMutation(); useEffect(() => { if (code) { - loginSlack({ - code, - redirect_uri: process.env.NEXT_PUBLIC_SLACK_REDIRECT_URI, - }); + // loginSlack({ + // code, + // redirect_uri: process.env.NEXT_PUBLIC_SLACK_REDIRECT_URI, + // }); + console.log("code", code); } }, [code]); From f8e9bcbe33a33b3f1eac24b6696562c134eb7913 Mon Sep 17 00:00:00 2001 From: bada308 <203190@jnu.ac.kr> Date: Sun, 24 Mar 2024 01:22:39 +0900 Subject: [PATCH 02/45] =?UTF-8?q?fix:=20mutate=20=EC=9E=AC=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=20false=20=EC=84=A4=EC=A0=95=20&=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20=EA=B8=B0=EB=8A=A5=20=EB=B3=B5=EC=9B=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FE/src/app/(auth)/login/logging-in/page.tsx | 12 ++++++------ FE/src/utils/provider.tsx | 3 +++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/FE/src/app/(auth)/login/logging-in/page.tsx b/FE/src/app/(auth)/login/logging-in/page.tsx index 624e0d38..ec2f5223 100644 --- a/FE/src/app/(auth)/login/logging-in/page.tsx +++ b/FE/src/app/(auth)/login/logging-in/page.tsx @@ -3,20 +3,20 @@ import { useSearchParams } from "next/navigation"; import { useEffect } from "react"; import LoadingSpinner from "@/components/common/LoadingSpinner"; -// import { useSlackLoginMutation } from "@/hooks/query/useAuthQuery"; +import { useSlackLoginMutation } from "@/hooks/query/useAuthQuery"; const LoginSlackCallbackPage = () => { const searchParams = useSearchParams(); const code = searchParams.get("code"); - // const { mutate: loginSlack } = useSlackLoginMutation(); + const { mutate: loginSlack } = useSlackLoginMutation(); useEffect(() => { if (code) { - // loginSlack({ - // code, - // redirect_uri: process.env.NEXT_PUBLIC_SLACK_REDIRECT_URI, - // }); + loginSlack({ + code, + redirect_uri: process.env.NEXT_PUBLIC_SLACK_REDIRECT_URI, + }); console.log("code", code); } }, [code]); diff --git a/FE/src/utils/provider.tsx b/FE/src/utils/provider.tsx index 9786c4b3..b66bf957 100644 --- a/FE/src/utils/provider.tsx +++ b/FE/src/utils/provider.tsx @@ -12,6 +12,9 @@ const Provider = ({ children }: PropsWithChildren) => { retry: false, useErrorBoundary: true, }, + mutations: { + retry: false, + }, }, }); From 057d610c20e627f4361effd20743b0bce490ed86 Mon Sep 17 00:00:00 2001 From: bada308 <203190@jnu.ac.kr> Date: Sun, 24 Mar 2024 01:46:35 +0900 Subject: [PATCH 03/45] =?UTF-8?q?fix:=20=EB=B2=84=ED=8A=BC=20=ED=81=B4?= =?UTF-8?q?=EB=A6=AD=20=EC=8B=9C=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FE/src/app/(auth)/login/logging-in/page.tsx | 36 ++++++++++++++------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/FE/src/app/(auth)/login/logging-in/page.tsx b/FE/src/app/(auth)/login/logging-in/page.tsx index ec2f5223..48a19e19 100644 --- a/FE/src/app/(auth)/login/logging-in/page.tsx +++ b/FE/src/app/(auth)/login/logging-in/page.tsx @@ -1,7 +1,7 @@ "use client"; import { useSearchParams } from "next/navigation"; -import { useEffect } from "react"; +// import { useEffect } from "react"; import LoadingSpinner from "@/components/common/LoadingSpinner"; import { useSlackLoginMutation } from "@/hooks/query/useAuthQuery"; @@ -11,16 +11,30 @@ const LoginSlackCallbackPage = () => { const { mutate: loginSlack } = useSlackLoginMutation(); - useEffect(() => { - if (code) { - loginSlack({ - code, - redirect_uri: process.env.NEXT_PUBLIC_SLACK_REDIRECT_URI, - }); - console.log("code", code); - } - }, [code]); + // useEffect(() => { + // if (code) { + // loginSlack({ + // code, + // + // }); + // console.log("code", code); + // } + // }, [code]); - return ; + return ( + <> + + + + ); }; export default LoginSlackCallbackPage; From 47a70a2519c7f0733e35cf0e51d6c1f007870aa8 Mon Sep 17 00:00:00 2001 From: bada308 <203190@jnu.ac.kr> Date: Sun, 24 Mar 2024 14:39:03 +0900 Subject: [PATCH 04/45] =?UTF-8?q?fix:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FE/src/app/(auth)/login/logging-in/page.tsx | 35 ++++++--------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/FE/src/app/(auth)/login/logging-in/page.tsx b/FE/src/app/(auth)/login/logging-in/page.tsx index 48a19e19..bc1b1433 100644 --- a/FE/src/app/(auth)/login/logging-in/page.tsx +++ b/FE/src/app/(auth)/login/logging-in/page.tsx @@ -1,7 +1,7 @@ "use client"; import { useSearchParams } from "next/navigation"; -// import { useEffect } from "react"; +import { useEffect } from "react"; import LoadingSpinner from "@/components/common/LoadingSpinner"; import { useSlackLoginMutation } from "@/hooks/query/useAuthQuery"; @@ -11,30 +11,15 @@ const LoginSlackCallbackPage = () => { const { mutate: loginSlack } = useSlackLoginMutation(); - // useEffect(() => { - // if (code) { - // loginSlack({ - // code, - // - // }); - // console.log("code", code); - // } - // }, [code]); + useEffect(() => { + if (code) { + loginSlack({ + code, + redirect_uri: process.env.NEXT_PUBLIC_SLACK_REDIRECT_URI, + }); + } + }, [code]); - return ( - <> - - - - ); + return ; }; export default LoginSlackCallbackPage; From ed9cea2228959fba2b58c06c605b3103ed45a1eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Mon, 1 Apr 2024 22:51:18 +0900 Subject: [PATCH 05/45] =?UTF-8?q?fix:=20=20localstorage=EA=B0=92=EC=9D=84?= =?UTF-8?q?=20=EA=B0=80=EC=A0=B8=EC=98=A4=EC=A7=80=20=EB=AA=BB=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 서버단에서 실행시, window 객체가 준비되기 전에 요청하여 window 객체가 없는 버그 수정 토큰을 가져오기 전 window 객체가 준비되었는지 확인하는 로직 추가 #10 --- FE/src/apis/instance.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/FE/src/apis/instance.ts b/FE/src/apis/instance.ts index 74bc153e..70a8b913 100644 --- a/FE/src/apis/instance.ts +++ b/FE/src/apis/instance.ts @@ -19,6 +19,7 @@ const https = axios.create({ https.interceptors.request.use( async (config) => { + if (typeof window === "undefined") return config; const accessToken = localStorage.getItem("accessToken")?.replace(/"/g, ""); const tokenExpiration = localStorage.getItem("tokenExpiration"); From d1e5c47100d974c8bf2d284dc74558c3d03d3c40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Wed, 3 Apr 2024 11:23:54 +0900 Subject: [PATCH 06/45] =?UTF-8?q?rename:=20guest=20route=20group=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기존에 private에 있던 라우터 중 로그인 없이 접근 가능한 라우터를 guest 라우터 그룹을 생성해 따로 뺴둠 #9 --- .../{(private)/(program) => (guest)}/detail/[programId]/page.tsx | 0 FE/src/app/{(private)/(program) => (guest)}/detail/error.tsx | 0 FE/src/app/{(private)/(program) => (guest)}/detail/loading.tsx | 0 FE/src/app/{(private)/(program) => (guest)}/layout.tsx | 0 FE/src/app/{(private)/(program) => (guest)}/main/loading.tsx | 0 FE/src/app/{(private)/(program) => (guest)}/main/page.tsx | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename FE/src/app/{(private)/(program) => (guest)}/detail/[programId]/page.tsx (100%) rename FE/src/app/{(private)/(program) => (guest)}/detail/error.tsx (100%) rename FE/src/app/{(private)/(program) => (guest)}/detail/loading.tsx (100%) rename FE/src/app/{(private)/(program) => (guest)}/layout.tsx (100%) rename FE/src/app/{(private)/(program) => (guest)}/main/loading.tsx (100%) rename FE/src/app/{(private)/(program) => (guest)}/main/page.tsx (100%) diff --git a/FE/src/app/(private)/(program)/detail/[programId]/page.tsx b/FE/src/app/(guest)/detail/[programId]/page.tsx similarity index 100% rename from FE/src/app/(private)/(program)/detail/[programId]/page.tsx rename to FE/src/app/(guest)/detail/[programId]/page.tsx diff --git a/FE/src/app/(private)/(program)/detail/error.tsx b/FE/src/app/(guest)/detail/error.tsx similarity index 100% rename from FE/src/app/(private)/(program)/detail/error.tsx rename to FE/src/app/(guest)/detail/error.tsx diff --git a/FE/src/app/(private)/(program)/detail/loading.tsx b/FE/src/app/(guest)/detail/loading.tsx similarity index 100% rename from FE/src/app/(private)/(program)/detail/loading.tsx rename to FE/src/app/(guest)/detail/loading.tsx diff --git a/FE/src/app/(private)/(program)/layout.tsx b/FE/src/app/(guest)/layout.tsx similarity index 100% rename from FE/src/app/(private)/(program)/layout.tsx rename to FE/src/app/(guest)/layout.tsx diff --git a/FE/src/app/(private)/(program)/main/loading.tsx b/FE/src/app/(guest)/main/loading.tsx similarity index 100% rename from FE/src/app/(private)/(program)/main/loading.tsx rename to FE/src/app/(guest)/main/loading.tsx diff --git a/FE/src/app/(private)/(program)/main/page.tsx b/FE/src/app/(guest)/main/page.tsx similarity index 100% rename from FE/src/app/(private)/(program)/main/page.tsx rename to FE/src/app/(guest)/main/page.tsx From ab8156f0626f747231d0ce9e3e6312531dd6613f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Wed, 3 Apr 2024 11:31:50 +0900 Subject: [PATCH 07/45] =?UTF-8?q?feat:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=97=AC=EB=B6=80=EB=A5=BC=20=ED=99=95=EC=9D=B8=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EC=9C=A0=ED=8B=B8=20=ED=95=A8=EC=88=98=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 로그인 여부를 확인하는 유틸 함수 추가 #9 --- FE/src/utils/authWithStorage.ts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/FE/src/utils/authWithStorage.ts b/FE/src/utils/authWithStorage.ts index 4bbfc9bc..9274f4e8 100644 --- a/FE/src/utils/authWithStorage.ts +++ b/FE/src/utils/authWithStorage.ts @@ -21,3 +21,31 @@ export const deleteTokenInfo = () => { removeAccessToken(); removeTokenExpiration(); }; + +export const getAccessToken = () => { + return localStorage.getItem("accessToken"); +}; + +export const getTokenExpiration = () => { + return localStorage.getItem("tokenExpiration"); +}; + +export const CheckIsLoggedIn = () => { + const accessToken = getAccessToken(); + const tokenExpiration = getTokenExpiration(); + + if (!accessToken || !tokenExpiration) { + deleteTokenInfo(); + return false; + } + + const tokenExpirationDate = new Date(+tokenExpiration); + const now = new Date(); + + if (tokenExpirationDate < now) { + deleteTokenInfo(); + return false; + } + + return true; +}; From 61edd05957c8d0191f1a8add705cd432f934f1f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Wed, 3 Apr 2024 11:33:01 +0900 Subject: [PATCH 08/45] =?UTF-8?q?refactor:=20Auth.tsx=20=EC=9C=A0=ED=8B=B8?= =?UTF-8?q?=20=ED=95=A8=EC=88=98=20=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기존에 useEffect에서 토큰을 가져오던 로직을 따로 유틸 함수로 뺌 --- FE/src/components/common/validate/Auth.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/FE/src/components/common/validate/Auth.tsx b/FE/src/components/common/validate/Auth.tsx index 0f87d9d6..a6949310 100644 --- a/FE/src/components/common/validate/Auth.tsx +++ b/FE/src/components/common/validate/Auth.tsx @@ -3,15 +3,13 @@ import { useRouter } from "next/navigation"; import { useEffect } from "react"; import ROUTES from "@/constants/ROUTES"; -import { deleteTokenInfo } from "@/utils/authWithStorage"; +import { CheckIsLoggedIn, deleteTokenInfo } from "@/utils/authWithStorage"; const AuthValidate = () => { const router = useRouter(); useEffect(() => { - const accessToken = localStorage.getItem("accessToken"); - const tokenExpiration = localStorage.getItem("tokenExpiration"); - - if (!accessToken || !tokenExpiration) { + const isLoggedIn = CheckIsLoggedIn(); + if (!isLoggedIn) { deleteTokenInfo(); router.push(ROUTES.LOGIN); } From 9fb5d704c2a53e4de2210ac3ed9636d18e2b0412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Wed, 3 Apr 2024 11:49:35 +0900 Subject: [PATCH 09/45] =?UTF-8?q?feat:=20ui=EB=A1=9C=EC=A7=81=EC=9D=B4=20?= =?UTF-8?q?=EC=97=86=EB=8A=94=20validation=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=ED=9B=85=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ui로직 없이 로그인 여부만 확인 후 리다이렉트 시키는 컴포넌트를 훅으로 변경 #9 --- FE/src/app/(private)/layout.tsx | 10 +++------- .../programDetail/attendee/AttendeeInfo.container.tsx | 7 +++++++ .../validate/Auth.tsx => hooks/useAuthValidate.tsx} | 6 ++---- 3 files changed, 12 insertions(+), 11 deletions(-) rename FE/src/{components/common/validate/Auth.tsx => hooks/useAuthValidate.tsx} (84%) diff --git a/FE/src/app/(private)/layout.tsx b/FE/src/app/(private)/layout.tsx index b3876d21..3496d446 100644 --- a/FE/src/app/(private)/layout.tsx +++ b/FE/src/app/(private)/layout.tsx @@ -1,12 +1,8 @@ import { PropsWithChildren } from "react"; -import AuthValidate from "@/components/common/validate/Auth"; +import useAuthValidate from "@/hooks/useAuthValidate"; const PrivateLayout = ({ children }: PropsWithChildren) => { - return ( - <> - - {children} - - ); + useAuthValidate(); + return <>{children}; }; export default PrivateLayout; diff --git a/FE/src/components/programDetail/attendee/AttendeeInfo.container.tsx b/FE/src/components/programDetail/attendee/AttendeeInfo.container.tsx index 12c92ed5..2d6b4e2a 100644 --- a/FE/src/components/programDetail/attendee/AttendeeInfo.container.tsx +++ b/FE/src/components/programDetail/attendee/AttendeeInfo.container.tsx @@ -3,15 +3,22 @@ import { ErrorBoundary } from "react-error-boundary"; import AttendeeInfo from "./AttendeeInfo"; import ErrorFallback from "@/components/common/ErrorFallback"; +import { CheckIsLoggedIn } from "@/utils/authWithStorage"; interface AttendeeInfoContainerProps { programId: number; } const AttendeeInfoContainer = ({ programId }: AttendeeInfoContainerProps) => { + const isLoggedIn = CheckIsLoggedIn(); return (
+ {!isLoggedIn && ( +
+ 로그인이 필요한 페이지입니다. +
+ )} diff --git a/FE/src/components/common/validate/Auth.tsx b/FE/src/hooks/useAuthValidate.tsx similarity index 84% rename from FE/src/components/common/validate/Auth.tsx rename to FE/src/hooks/useAuthValidate.tsx index a6949310..8a262405 100644 --- a/FE/src/components/common/validate/Auth.tsx +++ b/FE/src/hooks/useAuthValidate.tsx @@ -5,7 +5,7 @@ import { useEffect } from "react"; import ROUTES from "@/constants/ROUTES"; import { CheckIsLoggedIn, deleteTokenInfo } from "@/utils/authWithStorage"; -const AuthValidate = () => { +const useAuthValidate = () => { const router = useRouter(); useEffect(() => { const isLoggedIn = CheckIsLoggedIn(); @@ -14,7 +14,5 @@ const AuthValidate = () => { router.push(ROUTES.LOGIN); } }, []); - - return <>; }; -export default AuthValidate; +export default useAuthValidate; From b240ca2abea4c718ada8032f5a221858a1af3f4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Wed, 3 Apr 2024 16:41:07 +0900 Subject: [PATCH 10/45] =?UTF-8?q?feat:=20tanstack=20devtool=20=EC=9D=98?= =?UTF-8?q?=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit devtool 추가 #9 --- FE/package.json | 1 + FE/pnpm-lock.yaml | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/FE/package.json b/FE/package.json index d07162d4..80eb256b 100644 --- a/FE/package.json +++ b/FE/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "@tanstack/react-query": "^4.35.7", + "@tanstack/react-query-devtools": "^5.28.14", "@types/qs": "^6.9.10", "@types/react-syntax-highlighter": "^15.5.11", "axios": "^1.6.2", diff --git a/FE/pnpm-lock.yaml b/FE/pnpm-lock.yaml index 12ca9281..e7b0f0c5 100644 --- a/FE/pnpm-lock.yaml +++ b/FE/pnpm-lock.yaml @@ -8,6 +8,9 @@ dependencies: '@tanstack/react-query': specifier: ^4.35.7 version: 4.35.7(react-dom@18.2.0)(react@18.2.0) + '@tanstack/react-query-devtools': + specifier: ^5.28.14 + version: 5.28.14(@tanstack/react-query@4.35.7)(react@18.2.0) '@types/qs': specifier: ^6.9.10 version: 6.9.10 @@ -371,6 +374,21 @@ packages: resolution: {integrity: sha512-PgDJtX75ubFS0WCYFM7DqEoJ4QbxU3S5OH3gJSI40xr7UVVax3/J4CM3XUMOTs+EOT5YGEfssi3tfRVGte4DEw==} dev: false + /@tanstack/query-devtools@5.28.10: + resolution: {integrity: sha512-5UN629fKa5/1K/2Pd26gaU7epxRrYiT1gy+V+pW5K6hnf1DeUKK3pANSb2eHKlecjIKIhTwyF7k9XdyE2gREvQ==} + dev: false + + /@tanstack/react-query-devtools@5.28.14(@tanstack/react-query@4.35.7)(react@18.2.0): + resolution: {integrity: sha512-4CrFBI1O5wibV1ZdGAnBMmTuc7SiShhxWubxRMyIloeEioxs3DQkFbouGBea5nexuwIxAkvhUB8khpPnNjhxMw==} + peerDependencies: + '@tanstack/react-query': ^5.28.14 + react: ^18.0.0 + dependencies: + '@tanstack/query-devtools': 5.28.10 + '@tanstack/react-query': 4.35.7(react-dom@18.2.0)(react@18.2.0) + react: 18.2.0 + dev: false + /@tanstack/react-query@4.35.7(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-0MankquP/6EOM2ATfEov6ViiKemey5uTbjGlFMX1xGotwNaqC76YKDMJdHumZupPbZcZPWAeoPGEHQmVKIKoOQ==} peerDependencies: From cc8b313f050a5b36dd942014f28c97bc3ff76335 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Wed, 3 Apr 2024 16:43:05 +0900 Subject: [PATCH 11/45] =?UTF-8?q?feat:=20devtool=20provider=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit devtool provider 적용 #9 --- FE/src/utils/provider.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FE/src/utils/provider.tsx b/FE/src/utils/provider.tsx index b66bf957..2115f7c6 100644 --- a/FE/src/utils/provider.tsx +++ b/FE/src/utils/provider.tsx @@ -1,6 +1,7 @@ "use client"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; import { PropsWithChildren } from "react"; import { ToastContainer } from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; @@ -27,6 +28,7 @@ const Provider = ({ children }: PropsWithChildren) => { pauseOnFocusLoss={false} /> {children} + ); }; From fcd23ca57fa0c9e85c18ac2ba9cf394c4bc12c0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Fri, 5 Apr 2024 15:49:20 +0900 Subject: [PATCH 12/45] =?UTF-8?q?feat:=20blur=20=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=EB=90=9C=20attendee=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit blur 처리된 attendee 컴포넌트 추가 --- FE/src/components/common/MemberList.tsx | 11 +++++--- .../programDetail/attendee/BluredAttedee.tsx | 25 +++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 FE/src/components/programDetail/attendee/BluredAttedee.tsx diff --git a/FE/src/components/common/MemberList.tsx b/FE/src/components/common/MemberList.tsx index 9ec65440..85b4aad3 100644 --- a/FE/src/components/common/MemberList.tsx +++ b/FE/src/components/common/MemberList.tsx @@ -2,11 +2,16 @@ import { SimpleMemberInfo } from "@/types/member"; interface MemberListProps { members: SimpleMemberInfo[]; + blur?: boolean; } -const MemberList = ({ members }: MemberListProps) => { +const MemberList = ({ members, blur = false }: MemberListProps) => { return ( -
+
{members.map((member) => ( ))} @@ -16,7 +21,7 @@ const MemberList = ({ members }: MemberListProps) => { const MemberListItem = ({ name }: Omit) => { return ( -
+
{name}
); diff --git a/FE/src/components/programDetail/attendee/BluredAttedee.tsx b/FE/src/components/programDetail/attendee/BluredAttedee.tsx new file mode 100644 index 00000000..6ebd367d --- /dev/null +++ b/FE/src/components/programDetail/attendee/BluredAttedee.tsx @@ -0,0 +1,25 @@ +import { attendStatuses } from "./AttendeeInfo.container"; +import AttendeeStatus from "./AttendeeStatus"; +import { MemberAttendStatusInfoDto } from "@/apis/dtos/member.dto"; +import MemberList from "@/components/common/MemberList"; + +const members: MemberAttendStatusInfoDto[] = [ + { + memberId: 1, + name: "김민수", + attendStatus: "attend", + }, +]; + +export default function BluredAttedee() { + return ( +
+ {attendStatuses.map((status) => ( +
+ + +
+ ))} +
+ ); +} From 17e031c7fc4f57b371cb3e3c5233ab00b5e2de07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Fri, 5 Apr 2024 15:50:36 +0900 Subject: [PATCH 13/45] =?UTF-8?q?refactor:=20=EB=B0=98=EB=B3=B5=EB=90=98?= =?UTF-8?q?=EB=8A=94=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=ED=98=B8?= =?UTF-8?q?=EC=B6=9C=EC=9D=84=20=EB=B0=98=EB=B3=B5=EB=AC=B8=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=B9=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 반복되는 컴포넌트 호출을 반복문으로 변경 #9 --- .../attendee/AttendeeInfo.container.tsx | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/FE/src/components/programDetail/attendee/AttendeeInfo.container.tsx b/FE/src/components/programDetail/attendee/AttendeeInfo.container.tsx index 2d6b4e2a..e6240e65 100644 --- a/FE/src/components/programDetail/attendee/AttendeeInfo.container.tsx +++ b/FE/src/components/programDetail/attendee/AttendeeInfo.container.tsx @@ -2,6 +2,7 @@ import { ErrorBoundary } from "react-error-boundary"; import AttendeeInfo from "./AttendeeInfo"; +import BluredAttedee from "./BluredAttedee"; import ErrorFallback from "@/components/common/ErrorFallback"; import { CheckIsLoggedIn } from "@/utils/authWithStorage"; @@ -9,20 +10,25 @@ interface AttendeeInfoContainerProps { programId: number; } +export const attendStatuses = [ + "attend", + "late", + "absent", + "nonResponse", +] as const; + const AttendeeInfoContainer = ({ programId }: AttendeeInfoContainerProps) => { const isLoggedIn = CheckIsLoggedIn(); return (
- {!isLoggedIn && ( -
- 로그인이 필요한 페이지입니다. -
+ {isLoggedIn ? ( + attendStatuses.map((status) => ( + + )) + ) : ( + )} - - - -
); From 182b0a70d18f0e1ad9160bc6ae3f28d4a4271246 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Fri, 5 Apr 2024 16:02:35 +0900 Subject: [PATCH 14/45] =?UTF-8?q?feat:=20=EB=B8=94=EB=9F=AC=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EB=AA=A9=20=EB=8D=B0=EC=9D=B4=ED=84=B0=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 블러처리 목 데이터 추가 #9 --- .../attendee/AttendeeInfo.container.tsx | 18 +++++---- .../programDetail/attendee/BluredAttedee.tsx | 40 ++++++++++++------- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/FE/src/components/programDetail/attendee/AttendeeInfo.container.tsx b/FE/src/components/programDetail/attendee/AttendeeInfo.container.tsx index e6240e65..eff4c5d0 100644 --- a/FE/src/components/programDetail/attendee/AttendeeInfo.container.tsx +++ b/FE/src/components/programDetail/attendee/AttendeeInfo.container.tsx @@ -22,13 +22,17 @@ const AttendeeInfoContainer = ({ programId }: AttendeeInfoContainerProps) => { return (
- {isLoggedIn ? ( - attendStatuses.map((status) => ( - - )) - ) : ( - - )} + {isLoggedIn + ? attendStatuses.map((status) => ( + + )) + : attendStatuses.map((status) => ( + + ))}
); diff --git a/FE/src/components/programDetail/attendee/BluredAttedee.tsx b/FE/src/components/programDetail/attendee/BluredAttedee.tsx index 6ebd367d..ee73847d 100644 --- a/FE/src/components/programDetail/attendee/BluredAttedee.tsx +++ b/FE/src/components/programDetail/attendee/BluredAttedee.tsx @@ -1,25 +1,35 @@ -import { attendStatuses } from "./AttendeeInfo.container"; import AttendeeStatus from "./AttendeeStatus"; import { MemberAttendStatusInfoDto } from "@/apis/dtos/member.dto"; import MemberList from "@/components/common/MemberList"; +import { AttendStatus } from "@/types/member"; -const members: MemberAttendStatusInfoDto[] = [ - { - memberId: 1, - name: "김민수", - attendStatus: "attend", - }, -]; +const mockMember: MemberAttendStatusInfoDto = { + memberId: 1, + name: "20기 박건규", + attendStatus: "attend", +}; -export default function BluredAttedee() { +interface BluredAttedeeProps { + status: AttendStatus; +} + +export default function BluredAttedee({ status }: BluredAttedeeProps) { + const population = + status === "attend" + ? 52 + : status === "late" + ? 3 + : status === "absent" + ? 1 + : 0; + const members = Array.from({ length: population }, (_, i) => ({ + ...mockMember, + memberId: i + 1, + })); return (
- {attendStatuses.map((status) => ( -
- - -
- ))} + +
); } From 5805f283efc53f5af125899245b9819df15bd945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Fri, 5 Apr 2024 16:28:47 +0900 Subject: [PATCH 15/45] =?UTF-8?q?feat:=20Auth=20=ED=99=95=EC=9D=B8=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=EC=9D=84=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 이전처럼 훅으로 로직 처리시 한 곳에서 일괄 처리가 불가능함 이를 layout에서 처리하기 위해서 컴포넌트로 구현 #9 --- FE/src/app/(private)/layout.tsx | 10 +++++++--- FE/src/components/common/validate/Auth.tsx | 22 ++++++++++++++++++++++ FE/src/hooks/useAuthValidate.tsx | 18 ------------------ 3 files changed, 29 insertions(+), 21 deletions(-) create mode 100644 FE/src/components/common/validate/Auth.tsx delete mode 100644 FE/src/hooks/useAuthValidate.tsx diff --git a/FE/src/app/(private)/layout.tsx b/FE/src/app/(private)/layout.tsx index 3496d446..b3876d21 100644 --- a/FE/src/app/(private)/layout.tsx +++ b/FE/src/app/(private)/layout.tsx @@ -1,8 +1,12 @@ import { PropsWithChildren } from "react"; -import useAuthValidate from "@/hooks/useAuthValidate"; +import AuthValidate from "@/components/common/validate/Auth"; const PrivateLayout = ({ children }: PropsWithChildren) => { - useAuthValidate(); - return <>{children}; + return ( + <> + + {children} + + ); }; export default PrivateLayout; diff --git a/FE/src/components/common/validate/Auth.tsx b/FE/src/components/common/validate/Auth.tsx new file mode 100644 index 00000000..0f87d9d6 --- /dev/null +++ b/FE/src/components/common/validate/Auth.tsx @@ -0,0 +1,22 @@ +"use client"; + +import { useRouter } from "next/navigation"; +import { useEffect } from "react"; +import ROUTES from "@/constants/ROUTES"; +import { deleteTokenInfo } from "@/utils/authWithStorage"; + +const AuthValidate = () => { + const router = useRouter(); + useEffect(() => { + const accessToken = localStorage.getItem("accessToken"); + const tokenExpiration = localStorage.getItem("tokenExpiration"); + + if (!accessToken || !tokenExpiration) { + deleteTokenInfo(); + router.push(ROUTES.LOGIN); + } + }, []); + + return <>; +}; +export default AuthValidate; diff --git a/FE/src/hooks/useAuthValidate.tsx b/FE/src/hooks/useAuthValidate.tsx deleted file mode 100644 index 8a262405..00000000 --- a/FE/src/hooks/useAuthValidate.tsx +++ /dev/null @@ -1,18 +0,0 @@ -"use client"; - -import { useRouter } from "next/navigation"; -import { useEffect } from "react"; -import ROUTES from "@/constants/ROUTES"; -import { CheckIsLoggedIn, deleteTokenInfo } from "@/utils/authWithStorage"; - -const useAuthValidate = () => { - const router = useRouter(); - useEffect(() => { - const isLoggedIn = CheckIsLoggedIn(); - if (!isLoggedIn) { - deleteTokenInfo(); - router.push(ROUTES.LOGIN); - } - }, []); -}; -export default useAuthValidate; From 6777b23484862449f57f0d28bf2e095872dd5891 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Fri, 5 Apr 2024 16:47:06 +0900 Subject: [PATCH 16/45] =?UTF-8?q?feat:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?= =?UTF-8?q?=EC=9D=B4=20=EB=90=98=EC=96=B4=EC=9E=88=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EC=9C=BC=EB=A9=B4=20=ED=97=A4=EB=8D=94=EC=97=90=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EB=B2=84=ED=8A=BC=20=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 로그인이 되어 있지 않다면 헤더에 유저 버튼 및 행사생성 버튼을 로그인 버튼으로 변경 #9 --- FE/src/components/common/header/Header.tsx | 14 +++++++++++-- .../common/header/LoginRedirectBtn.tsx | 20 +++++++++++++++++++ FE/src/components/common/header/Logo.tsx | 2 -- FE/src/components/common/header/UserBtn.tsx | 2 -- 4 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 FE/src/components/common/header/LoginRedirectBtn.tsx diff --git a/FE/src/components/common/header/Header.tsx b/FE/src/components/common/header/Header.tsx index 53c27539..585855e0 100644 --- a/FE/src/components/common/header/Header.tsx +++ b/FE/src/components/common/header/Header.tsx @@ -1,14 +1,24 @@ +"use client"; import CreateBtn from "./CreateBtn"; +import LoginRedirectBtn from "./LoginRedirectBtn"; import Logo from "./Logo"; import UserBtn from "./UserBtn"; +import { CheckIsLoggedIn } from "@/utils/authWithStorage"; const Header = () => { + const isLoggedIn = CheckIsLoggedIn(); return (
- - + {isLoggedIn ? ( + <> + + + + ) : ( + + )}
); diff --git a/FE/src/components/common/header/LoginRedirectBtn.tsx b/FE/src/components/common/header/LoginRedirectBtn.tsx new file mode 100644 index 00000000..06ff0a15 --- /dev/null +++ b/FE/src/components/common/header/LoginRedirectBtn.tsx @@ -0,0 +1,20 @@ +import Image from "next/image"; +import Link from "../Link"; +import ROUTES from "@/constants/ROUTES"; + +const LOGIN = "로그인 후 사용해주세요!"; + +export default function LoginRedirectBtn() { + return ( + + 로그인 버튼 + {LOGIN} + + ); +} diff --git a/FE/src/components/common/header/Logo.tsx b/FE/src/components/common/header/Logo.tsx index db45bdf3..e01fab4d 100644 --- a/FE/src/components/common/header/Logo.tsx +++ b/FE/src/components/common/header/Logo.tsx @@ -1,5 +1,3 @@ -"use client"; - import Image from "next/image"; import { usePathname, useRouter } from "next/navigation"; import ROUTES from "@/constants/ROUTES"; diff --git a/FE/src/components/common/header/UserBtn.tsx b/FE/src/components/common/header/UserBtn.tsx index ada937e9..921fc870 100644 --- a/FE/src/components/common/header/UserBtn.tsx +++ b/FE/src/components/common/header/UserBtn.tsx @@ -1,5 +1,3 @@ -"use client"; - import Image from "next/image"; import UserActiveModal from "./Modal/UserActiveModal"; import useModal from "@/hooks/useModal"; From a692b1450fa66f5a090e336ce387683f73d7fd64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Fri, 5 Apr 2024 20:21:30 +0900 Subject: [PATCH 17/45] =?UTF-8?q?feat:=20=EC=9C=A0=EC=A0=80=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=20=EB=AA=A8=EB=8B=AC=EC=9D=98=20=EC=83=81=ED=83=9C?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20=EB=B2=84=ED=8A=BC=EC=9D=84=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EB=B2=84=ED=8A=BC=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 유저 상태 모달의 상태 변경 버튼을 로그인 버튼으로 수정 #9 --- .../userAttendModal/LoginModal.tsx | 24 +++++++++++++++++++ .../UserAttendModal.container.tsx | 14 +++++++---- .../userAttendModal/UserAttendModal.tsx | 2 -- 3 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 FE/src/components/programDetail/userAttendModal/LoginModal.tsx diff --git a/FE/src/components/programDetail/userAttendModal/LoginModal.tsx b/FE/src/components/programDetail/userAttendModal/LoginModal.tsx new file mode 100644 index 00000000..d3f4a3bf --- /dev/null +++ b/FE/src/components/programDetail/userAttendModal/LoginModal.tsx @@ -0,0 +1,24 @@ +// import AttendToggleLabel from "./AttendToggleLabel"; +import Link from "next/link"; +import AttendStatusToggle from "@/components/common/attendStatusToggle/AttendStatusToggle"; +import StatusToggleItem from "@/components/common/attendStatusToggle/StatusToggleItem"; +import ROUTES from "@/constants/ROUTES"; + +export default function LoginModal() { + return ( +
+ + + +

로그인 후 사용해주세요!

+ {}} + /> +
+ ); +} diff --git a/FE/src/components/programDetail/userAttendModal/UserAttendModal.container.tsx b/FE/src/components/programDetail/userAttendModal/UserAttendModal.container.tsx index ee68ae12..f6f0bd28 100644 --- a/FE/src/components/programDetail/userAttendModal/UserAttendModal.container.tsx +++ b/FE/src/components/programDetail/userAttendModal/UserAttendModal.container.tsx @@ -3,10 +3,12 @@ import classNames from "classnames"; import Image from "next/image"; import { ErrorBoundary } from "react-error-boundary"; +import LoginModal from "./LoginModal"; import UserAttendModal from "./UserAttendModal"; import ErrorFallbackNoIcon from "@/components/common/ErrorFallbackNoIcon"; import useModal from "@/hooks/useModal"; import useOutsideRef from "@/hooks/useOutsideRef"; +import { CheckIsLoggedIn } from "@/utils/authWithStorage"; interface UserAttendModalProps { programId: number; @@ -15,6 +17,7 @@ interface UserAttendModalProps { const UserAttendModalContainer = ({ programId }: UserAttendModalProps) => { const { isOpen, openModal, closeModal } = useModal(); const modalRef = useOutsideRef(closeModal); + const isLoggedIn = CheckIsLoggedIn(); const modalStyle = classNames( "fixed left-0 z-10 flex h-60 w-full flex-col items-center gap-5 rounded-t-3xl border-t-2 bg-background shadow-2xl transition-all duration-500", @@ -26,7 +29,6 @@ const UserAttendModalContainer = ({ programId }: UserAttendModalProps) => { const handleOpenModal = (e: React.MouseEvent) => { e.stopPropagation(); - console.log("hi", isOpen); isOpen ? closeModal() : openModal(); }; @@ -46,9 +48,13 @@ const UserAttendModalContainer = ({ programId }: UserAttendModalProps) => { style={{ width: 38, height: 6 }} />
- - - + {isLoggedIn ? ( + + + + ) : ( + + )} ); }; diff --git a/FE/src/components/programDetail/userAttendModal/UserAttendModal.tsx b/FE/src/components/programDetail/userAttendModal/UserAttendModal.tsx index 3c48780b..ad1a8efb 100644 --- a/FE/src/components/programDetail/userAttendModal/UserAttendModal.tsx +++ b/FE/src/components/programDetail/userAttendModal/UserAttendModal.tsx @@ -1,5 +1,3 @@ -"use client"; - import { useQueryClient } from "@tanstack/react-query"; import AttendStatusModalLoader from "./AttendStatusModal.loader"; import AttendStatusView from "./AttendStatusView"; From 18977b212f1e6e727e24e58be0b96cb8997dbe93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Fri, 5 Apr 2024 21:09:36 +0900 Subject: [PATCH 18/45] =?UTF-8?q?feat:=20=EB=B9=84=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=EC=8B=9C=20main=20=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EB=8B=A4=EB=A5=B8=20api=EB=A1=9C=20?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=20=EB=B3=B4=EB=82=B4=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 비로그인시 main페이지에서 리스트를 불러오는 타 api로 요청 보내도록 수정 --- FE/src/apis/program.ts | 4 ++-- FE/src/constants/API.ts | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/FE/src/apis/program.ts b/FE/src/apis/program.ts index 562b6dac..b49414b8 100644 --- a/FE/src/apis/program.ts +++ b/FE/src/apis/program.ts @@ -23,7 +23,7 @@ export const getProgramById = async ( programId: number, ): Promise => { const { data } = await https({ - url: API.PROGRAM.DETAIL(programId), + url: API.PROGRAM.GUEST_DETAIL(programId), }); return new ProgramInfoDto(data?.data); }; @@ -46,7 +46,7 @@ export const getProgramList = async ({ page, }: GetProgramListRequest): Promise => { const { data } = await https({ - url: API.PROGRAM.LIST, + url: API.PROGRAM.GUEST_LIST, method: "GET", params: { category, diff --git a/FE/src/constants/API.ts b/FE/src/constants/API.ts index 6f04c50e..02cf4258 100644 --- a/FE/src/constants/API.ts +++ b/FE/src/constants/API.ts @@ -1,9 +1,11 @@ const PROGRAM = { LIST: "/programs", CREATE: "/programs", + GUEST_LIST: "/guest/programs", UPDATE: (programId: number) => `/programs/${programId}`, DELETE: (programId: number) => `/programs/${programId}`, DETAIL: (programId: number) => `/programs/${programId}`, + GUEST_DETAIL: (programId: number) => `/guest/programs/${programId}`, ACCESS_RIGHT: (programId: number) => `/programs/${programId}/accessRight`, }; From 7b3e5653a9197a332d8f86e361b07ff144e14bac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Fri, 5 Apr 2024 22:46:10 +0900 Subject: [PATCH 19/45] =?UTF-8?q?fix:=20localstorage=EC=97=90=20=EC=A0=91?= =?UTF-8?q?=EA=B7=BC=EB=B6=88=EA=B0=80=EB=8A=A5=20=EB=B9=8C=EB=93=9C=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit window가 준비되지 않은 시점에서 localstorage에 접근하여 생기는 빌드 버그 수정 useEffect를 사용해서 렌더링이 완료된 시점에서 접근하도록 수정 #9 --- FE/src/components/common/header/Header.tsx | 4 ++-- FE/src/hooks/useCheckIsLoggedIn.tsx | 10 ++++++++++ FE/src/utils/authWithStorage.ts | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 FE/src/hooks/useCheckIsLoggedIn.tsx diff --git a/FE/src/components/common/header/Header.tsx b/FE/src/components/common/header/Header.tsx index 585855e0..04ad1e7c 100644 --- a/FE/src/components/common/header/Header.tsx +++ b/FE/src/components/common/header/Header.tsx @@ -3,10 +3,10 @@ import CreateBtn from "./CreateBtn"; import LoginRedirectBtn from "./LoginRedirectBtn"; import Logo from "./Logo"; import UserBtn from "./UserBtn"; -import { CheckIsLoggedIn } from "@/utils/authWithStorage"; +import useCheckIsLoggedIn from "@/hooks/useCheckIsLoggedIn"; const Header = () => { - const isLoggedIn = CheckIsLoggedIn(); + const isLoggedIn = useCheckIsLoggedIn(); return (
diff --git a/FE/src/hooks/useCheckIsLoggedIn.tsx b/FE/src/hooks/useCheckIsLoggedIn.tsx new file mode 100644 index 00000000..3c46ea1a --- /dev/null +++ b/FE/src/hooks/useCheckIsLoggedIn.tsx @@ -0,0 +1,10 @@ +import { useEffect } from "react"; +import { CheckIsLoggedIn } from "@/utils/authWithStorage"; + +export default function useCheckIsLoggedIn() { + let isLoggedIn; + useEffect(() => { + isLoggedIn = CheckIsLoggedIn(); + }, []); + return isLoggedIn; +} diff --git a/FE/src/utils/authWithStorage.ts b/FE/src/utils/authWithStorage.ts index 9274f4e8..fecf8539 100644 --- a/FE/src/utils/authWithStorage.ts +++ b/FE/src/utils/authWithStorage.ts @@ -31,6 +31,7 @@ export const getTokenExpiration = () => { }; export const CheckIsLoggedIn = () => { + if (!window) return false; const accessToken = getAccessToken(); const tokenExpiration = getTokenExpiration(); @@ -46,6 +47,5 @@ export const CheckIsLoggedIn = () => { deleteTokenInfo(); return false; } - return true; }; From 6745859fff1cb848cee107f7fe904dda2eb595dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Fri, 5 Apr 2024 23:43:26 +0900 Subject: [PATCH 20/45] =?UTF-8?q?refactor:=20guest=20group=20=EC=9D=98=20l?= =?UTF-8?q?ayout=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit children을 ReactNode 타입으로 변경 props를 read-only로 변경 컴포넌트 이름을 GuestLayout으로 변경 #9 --- FE/src/app/(guest)/layout.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/FE/src/app/(guest)/layout.tsx b/FE/src/app/(guest)/layout.tsx index ebe8f27e..972949b5 100644 --- a/FE/src/app/(guest)/layout.tsx +++ b/FE/src/app/(guest)/layout.tsx @@ -1,7 +1,8 @@ -import { PropsWithChildren } from "react"; import Header from "@/components/common/header/Header"; -export default function ProgramLayout({ children }: PropsWithChildren) { +export default function GuestLayout({ + children, +}: Readonly<{ children: React.ReactNode }>) { return ( <>
From 8fb16b52e841f2cbee3462aa5e23d55c0aa01f2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Fri, 5 Apr 2024 23:57:29 +0900 Subject: [PATCH 21/45] =?UTF-8?q?fix:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=9D=B4=ED=9B=84=EC=97=90=EB=8F=84=20=ED=97=A4=EB=8D=94?= =?UTF-8?q?=EC=97=90=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EB=B2=84=ED=8A=BC?= =?UTF-8?q?=EC=9D=B4=20=EB=B3=B4=EC=9D=B4=EB=8A=94=20=EB=B2=84=EA=B7=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 로그인 이후에도 헤더에 로그인 버튼이 보이는 버그 수정 로그인 여부를 완전히 가져온 이후, 재랜더링이 되도록 수정 --- FE/src/components/common/header/Header.tsx | 35 ++++++++++++++-------- FE/src/hooks/useCheckIsLoggedIn.tsx | 10 ------- 2 files changed, 23 insertions(+), 22 deletions(-) delete mode 100644 FE/src/hooks/useCheckIsLoggedIn.tsx diff --git a/FE/src/components/common/header/Header.tsx b/FE/src/components/common/header/Header.tsx index 04ad1e7c..cdfc6b0e 100644 --- a/FE/src/components/common/header/Header.tsx +++ b/FE/src/components/common/header/Header.tsx @@ -1,25 +1,36 @@ "use client"; +import { useEffect, useState } from "react"; import CreateBtn from "./CreateBtn"; import LoginRedirectBtn from "./LoginRedirectBtn"; import Logo from "./Logo"; import UserBtn from "./UserBtn"; -import useCheckIsLoggedIn from "@/hooks/useCheckIsLoggedIn"; +import { CheckIsLoggedIn } from "@/utils/authWithStorage"; const Header = () => { - const isLoggedIn = useCheckIsLoggedIn(); + const [isLoggedIn, setIsLoggedIn] = useState(false); + const [isLoading, setIsLoading] = useState(true); + + useEffect(() => { + const isLoggedIn = CheckIsLoggedIn(); + setIsLoggedIn(isLoggedIn); + setIsLoading(false); + }, []); + return (
-
- {isLoggedIn ? ( - <> - - - - ) : ( - - )} -
+ {!isLoading && ( +
+ {isLoggedIn ? ( + <> + + + + ) : ( + + )} +
+ )}
); }; diff --git a/FE/src/hooks/useCheckIsLoggedIn.tsx b/FE/src/hooks/useCheckIsLoggedIn.tsx deleted file mode 100644 index 3c46ea1a..00000000 --- a/FE/src/hooks/useCheckIsLoggedIn.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { useEffect } from "react"; -import { CheckIsLoggedIn } from "@/utils/authWithStorage"; - -export default function useCheckIsLoggedIn() { - let isLoggedIn; - useEffect(() => { - isLoggedIn = CheckIsLoggedIn(); - }, []); - return isLoggedIn; -} From 52aa4457ec313696b4219cf43e2fecab883e58ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Wed, 10 Apr 2024 15:21:44 +0900 Subject: [PATCH 22/45] =?UTF-8?q?feat:=20=EB=A9=94=EC=8B=9C=EC=A7=80?= =?UTF-8?q?=EB=A5=BC=20=EB=B3=B4=EB=82=B4=EA=B8=B0=20=EC=9C=84=ED=95=9C=20?= =?UTF-8?q?api=20=EC=A3=BC=EC=86=8C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 메시지를 보내기 위한 api 주소추가 #15 --- FE/src/constants/API.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FE/src/constants/API.ts b/FE/src/constants/API.ts index 02cf4258..2349f8ed 100644 --- a/FE/src/constants/API.ts +++ b/FE/src/constants/API.ts @@ -7,6 +7,8 @@ const PROGRAM = { DETAIL: (programId: number) => `/programs/${programId}`, GUEST_DETAIL: (programId: number) => `/guest/programs/${programId}`, ACCESS_RIGHT: (programId: number) => `/programs/${programId}/accessRight`, + SEND_MESSAGE: (programId: number) => + `/programs/${programId}/slack/notification`, }; const MEMBER = { From 09db1edba77218a0f136cc5097829bd3b84b5dbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Wed, 10 Apr 2024 15:22:13 +0900 Subject: [PATCH 23/45] =?UTF-8?q?feat:=20=EB=A9=94=EC=8B=9C=EC=A7=80?= =?UTF-8?q?=EB=A5=BC=20=EB=B3=B4=EB=82=B4=EA=B8=B0=20=EC=9C=84=ED=95=9C=20?= =?UTF-8?q?api=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 슬랙 메시지를 보내기 위한 api 추가 #15 --- FE/src/apis/program.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/FE/src/apis/program.ts b/FE/src/apis/program.ts index b49414b8..8ba0246f 100644 --- a/FE/src/apis/program.ts +++ b/FE/src/apis/program.ts @@ -86,6 +86,19 @@ export interface PostProgramRequest members: { memberId: number }[]; } +export const sendMessage = async (programId: number) => { + const isConfirmed = confirm("메시지를 보내시겠습니까?"); + if (!isConfirmed) return; + + return await https({ + url: API.PROGRAM.SEND_MESSAGE(programId), + method: "POST", + data: { + programUrl: "https://econo.eeos.store/detail/" + programId, + }, + }); +}; + export const postProgram = async ( body: PostProgramRequest, ): Promise => { From 34a3f077a46a2da796393d1d3d8e3aa45b284939 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Wed, 10 Apr 2024 15:27:51 +0900 Subject: [PATCH 24/45] =?UTF-8?q?feat:=20api=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EB=A5=BC=20=EC=9C=84=ED=95=9C=20=EB=B2=84=ED=8A=BC=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 api 테스트를 위한 버튼 추가 #15 --- FE/src/apis/program.ts | 1 + FE/src/components/programDetail/program/ProgramInfo.tsx | 2 ++ 2 files changed, 3 insertions(+) diff --git a/FE/src/apis/program.ts b/FE/src/apis/program.ts index 8ba0246f..1056894b 100644 --- a/FE/src/apis/program.ts +++ b/FE/src/apis/program.ts @@ -87,6 +87,7 @@ export interface PostProgramRequest } export const sendMessage = async (programId: number) => { + if (!window) return; const isConfirmed = confirm("메시지를 보내시겠습니까?"); if (!isConfirmed) return; diff --git a/FE/src/components/programDetail/program/ProgramInfo.tsx b/FE/src/components/programDetail/program/ProgramInfo.tsx index 632832ad..affab1b4 100644 --- a/FE/src/components/programDetail/program/ProgramInfo.tsx +++ b/FE/src/components/programDetail/program/ProgramInfo.tsx @@ -3,6 +3,7 @@ import ProgramDetail from "./ProgramDetail"; import ProgramHeader from "./ProgramHeader"; import ProgramInfoLoader from "./ProgramInfo.loader"; +import { sendMessage } from "@/apis/program"; import { useGetProgramById } from "@/hooks/query/useProgramQuery"; interface ProgramInfoProps { @@ -21,6 +22,7 @@ const ProgramInfo = ({ programId }: ProgramInfoProps) => { return (
+
From 894a6f4c8b48ed5e3876d836b105ca07e2febe48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Thu, 11 Apr 2024 23:46:05 +0900 Subject: [PATCH 25/45] =?UTF-8?q?chore:=20=EC=A3=BC=EC=84=9D=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 임시 기능으로 추가한 버튼, 기능 구현 완료시 제거하도록 TODO 주석 추가 #15 --- FE/src/components/programDetail/program/ProgramInfo.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/FE/src/components/programDetail/program/ProgramInfo.tsx b/FE/src/components/programDetail/program/ProgramInfo.tsx index affab1b4..efbbaad3 100644 --- a/FE/src/components/programDetail/program/ProgramInfo.tsx +++ b/FE/src/components/programDetail/program/ProgramInfo.tsx @@ -3,7 +3,8 @@ import ProgramDetail from "./ProgramDetail"; import ProgramHeader from "./ProgramHeader"; import ProgramInfoLoader from "./ProgramInfo.loader"; -import { sendMessage } from "@/apis/program"; +// TODO: 기능 구현 이후 삭제하기 +import { sendSlackMessage } from "@/apis/program"; import { useGetProgramById } from "@/hooks/query/useProgramQuery"; interface ProgramInfoProps { @@ -22,7 +23,10 @@ const ProgramInfo = ({ programId }: ProgramInfoProps) => { return (
- + {/* TODO: 기능 구현 이후 삭제하기 */} +
From 37027abff9c39ef49026de252bb88c01ee86c934 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Thu, 11 Apr 2024 23:46:54 +0900 Subject: [PATCH 26/45] =?UTF-8?q?refactor:=20api=20=EB=AA=85=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 메시지 요청 api 이름 명시적으로 slack을 붙이도록 이름 변경 #15 --- FE/src/apis/program.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FE/src/apis/program.ts b/FE/src/apis/program.ts index 1056894b..c971c20c 100644 --- a/FE/src/apis/program.ts +++ b/FE/src/apis/program.ts @@ -86,7 +86,7 @@ export interface PostProgramRequest members: { memberId: number }[]; } -export const sendMessage = async (programId: number) => { +export const sendSlackMessage = async (programId: number) => { if (!window) return; const isConfirmed = confirm("메시지를 보내시겠습니까?"); if (!isConfirmed) return; From 97b85b479f105a40028dc78ad3f2b87ee2c55ea5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Fri, 12 Apr 2024 00:28:50 +0900 Subject: [PATCH 27/45] =?UTF-8?q?fix:=20window=EB=A5=BC=20=EA=B0=80?= =?UTF-8?q?=EC=A0=B8=EC=98=AC=20=EC=88=98=20=EC=9E=88=EB=8A=94=20=EC=97=AC?= =?UTF-8?q?=EB=B6=80=EB=A5=BC=20=ED=99=95=EC=9D=B8=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=EC=9D=B4=20=EC=A0=9C=EB=8C=80=EB=A1=9C=20?= =?UTF-8?q?=EB=8F=99=EC=9E=91=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8D=98=20?= =?UTF-8?q?=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit window의 typeof의 값을 확인함으로서 버그수정 #15 --- FE/src/utils/authWithStorage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FE/src/utils/authWithStorage.ts b/FE/src/utils/authWithStorage.ts index fecf8539..73e438c1 100644 --- a/FE/src/utils/authWithStorage.ts +++ b/FE/src/utils/authWithStorage.ts @@ -31,7 +31,7 @@ export const getTokenExpiration = () => { }; export const CheckIsLoggedIn = () => { - if (!window) return false; + if (typeof window !== "undefined") return false; const accessToken = getAccessToken(); const tokenExpiration = getTokenExpiration(); From 6923a2aea7e48d24241749beb53075ac9cee2aaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Fri, 12 Apr 2024 00:31:37 +0900 Subject: [PATCH 28/45] =?UTF-8?q?feat:=20=EA=B8=80=20=EC=9E=91=EC=84=B1?= =?UTF-8?q?=EC=8B=9C=20=EB=A9=94=EC=8B=9C=EC=A7=80=EB=A5=BC=20=EB=B3=B4?= =?UTF-8?q?=EB=82=BC=20=EC=88=98=20=EC=9E=88=EB=8F=84=EB=A1=9D=20api=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 글 작성이 올바르게 되었을 시 메시지를 보내는 요청을 하도록 개발 --- FE/src/apis/program.ts | 7 +++++-- FE/src/hooks/query/useProgramQuery.ts | 11 ++++++++--- FE/src/utils/authWithStorage.ts | 2 +- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/FE/src/apis/program.ts b/FE/src/apis/program.ts index c971c20c..8dc24999 100644 --- a/FE/src/apis/program.ts +++ b/FE/src/apis/program.ts @@ -95,9 +95,12 @@ export const sendSlackMessage = async (programId: number) => { url: API.PROGRAM.SEND_MESSAGE(programId), method: "POST", data: { - programUrl: "https://econo.eeos.store/detail/" + programId, + programUrl: + process.env.NEXT_PUBLIC_SLACK_MESSAGE_REQUEST_URL_PREFIX + programId, }, - }); + }) + .then(() => alert("메시지를 성공적으로 전송했습니다.")) + .catch(() => alert("메시지 전송에 실패했습니다.")); }; export const postProgram = async ( diff --git a/FE/src/hooks/query/useProgramQuery.ts b/FE/src/hooks/query/useProgramQuery.ts index d45bc985..59413eb2 100644 --- a/FE/src/hooks/query/useProgramQuery.ts +++ b/FE/src/hooks/query/useProgramQuery.ts @@ -10,6 +10,7 @@ import { getProgramList, patchProgram, postProgram, + sendSlackMessage, } from "@/apis/program"; import API from "@/constants/API"; import ROUTES from "@/constants/ROUTES"; @@ -26,10 +27,14 @@ export const useCreateProgram = ({ programData, formReset }: CreateProgram) => { return useMutation({ mutationKey: [API.PROGRAM.CREATE], - mutationFn: () => postProgram(programData), - onSettled: (data) => { + mutationFn: async () => { + const { programId } = await postProgram(programData); + await sendSlackMessage(programId); + return programId; + }, + onSuccess: (programId) => { formReset(); - data && router.replace(ROUTES.DETAIL(data?.programId)); + programId && router.replace(ROUTES.DETAIL(programId)); }, }); }; diff --git a/FE/src/utils/authWithStorage.ts b/FE/src/utils/authWithStorage.ts index 73e438c1..2fa269c9 100644 --- a/FE/src/utils/authWithStorage.ts +++ b/FE/src/utils/authWithStorage.ts @@ -31,7 +31,7 @@ export const getTokenExpiration = () => { }; export const CheckIsLoggedIn = () => { - if (typeof window !== "undefined") return false; + // if (typeof window !== "undefined") return false; const accessToken = getAccessToken(); const tokenExpiration = getTokenExpiration(); From 6c43a9312623f82a414f7ff10d537667cd6eae80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Fri, 12 Apr 2024 14:08:18 +0900 Subject: [PATCH 29/45] =?UTF-8?q?refactor:=20=EB=A9=94=EC=8B=9C=EC=A7=80?= =?UTF-8?q?=20=ED=83=9D=EC=8A=A4=ED=8A=B8=20=EC=83=81=EC=88=98=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 슬랙 알림 보낼지에 대한 메시지 상수화 --- FE/src/apis/program.ts | 19 ++++++++++++++----- FE/src/constants/MESSAGE.ts | 8 ++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/FE/src/apis/program.ts b/FE/src/apis/program.ts index 8dc24999..e88060db 100644 --- a/FE/src/apis/program.ts +++ b/FE/src/apis/program.ts @@ -86,10 +86,16 @@ export interface PostProgramRequest members: { memberId: number }[]; } -export const sendSlackMessage = async (programId: number) => { +export const sendSlackMessage = async ( + programId: number, + isRetry: boolean = false, +) => { if (!window) return; - const isConfirmed = confirm("메시지를 보내시겠습니까?"); - if (!isConfirmed) return; + + if (!isRetry) { + const isConfirmed = confirm(MESSAGE.SLACK_MESSAGE.CONFIRM); + if (!isConfirmed) return; + } return await https({ url: API.PROGRAM.SEND_MESSAGE(programId), @@ -99,8 +105,11 @@ export const sendSlackMessage = async (programId: number) => { process.env.NEXT_PUBLIC_SLACK_MESSAGE_REQUEST_URL_PREFIX + programId, }, }) - .then(() => alert("메시지를 성공적으로 전송했습니다.")) - .catch(() => alert("메시지 전송에 실패했습니다.")); + .then(() => alert(MESSAGE.SLACK_MESSAGE.SUCCESS)) + .catch(() => { + const retry = confirm(MESSAGE.SLACK_MESSAGE.FAIL); + if (retry) sendSlackMessage(programId); + }); }; export const postProgram = async ( diff --git a/FE/src/constants/MESSAGE.ts b/FE/src/constants/MESSAGE.ts index 2a275832..6dbee93e 100644 --- a/FE/src/constants/MESSAGE.ts +++ b/FE/src/constants/MESSAGE.ts @@ -41,6 +41,13 @@ const TEAM_BUILDING = { INCREATABLE: "진행중인 팀빌딩이 있어 팀빌딩을 생성할 수 없습니다.", }; +const SLACK_MESSAGE = { + CONFIRM: + "슬랙 알림을 보내시겠습니까? 슬랙 알림은 공지사항 채널에 전송됩니다.", + SUCCESS: "슬랙 알림이 성공적으로 보내졌습니다! 공지사항 채널을 확인해주세요", + FAIL: "알 수 없는 이유로 슬랙 알림 전송에 실패했습니다. 다시 시도하겠습니까?", +}; + Object.freeze(EDIT_DISABLED); Object.freeze(AUTH); Object.freeze(EDIT); @@ -59,4 +66,5 @@ export default { CONFIRM, TEAM_BUILDING, COMPLATE, + SLACK_MESSAGE, }; From cfeadadb1ad64bace42b8c9bf4892ba5ed361f5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Fri, 12 Apr 2024 14:09:38 +0900 Subject: [PATCH 30/45] =?UTF-8?q?feat:=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EC=9A=A9=20=EB=B2=84=ED=8A=BC=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 테스트용 버튼 제거 #15 --- FE/src/components/programDetail/program/ProgramInfo.tsx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/FE/src/components/programDetail/program/ProgramInfo.tsx b/FE/src/components/programDetail/program/ProgramInfo.tsx index efbbaad3..632832ad 100644 --- a/FE/src/components/programDetail/program/ProgramInfo.tsx +++ b/FE/src/components/programDetail/program/ProgramInfo.tsx @@ -3,8 +3,6 @@ import ProgramDetail from "./ProgramDetail"; import ProgramHeader from "./ProgramHeader"; import ProgramInfoLoader from "./ProgramInfo.loader"; -// TODO: 기능 구현 이후 삭제하기 -import { sendSlackMessage } from "@/apis/program"; import { useGetProgramById } from "@/hooks/query/useProgramQuery"; interface ProgramInfoProps { @@ -23,10 +21,6 @@ const ProgramInfo = ({ programId }: ProgramInfoProps) => { return (
- {/* TODO: 기능 구현 이후 삭제하기 */} -
From a6c77b2d1eaf48710e572617d064db092d577b96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Fri, 12 Apr 2024 15:51:16 +0900 Subject: [PATCH 31/45] =?UTF-8?q?feat:=20=EA=B2=B9=EC=B9=98=EB=8A=94=20ui?= =?UTF-8?q?=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EB=B6=84=EB=A6=AC?= =?UTF-8?q?=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 로그인 벼튼 ui 중복 사용으로 컴포넌트 분리 #18 --- .../components/login/ui/StyledLoginButton.tsx | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 FE/src/components/login/ui/StyledLoginButton.tsx diff --git a/FE/src/components/login/ui/StyledLoginButton.tsx b/FE/src/components/login/ui/StyledLoginButton.tsx new file mode 100644 index 00000000..21a5be66 --- /dev/null +++ b/FE/src/components/login/ui/StyledLoginButton.tsx @@ -0,0 +1,32 @@ +import classNames from "classnames"; +import Image from "next/image"; +import Link from "next/link"; + +const defaultStyle = "flex w-64 justify-center gap-4 rounded-3xl py-3"; + +const colors = { + slack: "bg-slack text-white text-paragraph", + guest: "bg-primary text-black text-paragraph", +}; + +interface StyledLoginButtonProps { + linkUrl: string; + buttonText: string; + imageUrl: string; + color: keyof typeof colors; +} + +export default function StyledLoginButton({ + linkUrl, + buttonText, + imageUrl, + color, +}: StyledLoginButtonProps) { + const buttonStyle = classNames(defaultStyle, colors[color]); + return ( + + 슬랙 로고 +

{buttonText}

+ + ); +} From 3aa3041e8ece5650a12872b938e3d52560426eca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Fri, 12 Apr 2024 15:52:14 +0900 Subject: [PATCH 32/45] =?UTF-8?q?feat:=20slack=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20=EB=B2=84=ED=8A=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit slack 로그인 버튼 수정 #18" --- FE/src/components/login/slack/LoginSection.tsx | 15 ++++++++++----- .../{LoginButton.tsx => SlackLoginButton.tsx} | 17 ++++++++--------- 2 files changed, 18 insertions(+), 14 deletions(-) rename FE/src/components/login/slack/{LoginButton.tsx => SlackLoginButton.tsx} (70%) diff --git a/FE/src/components/login/slack/LoginSection.tsx b/FE/src/components/login/slack/LoginSection.tsx index f239cc6d..87c3d941 100644 --- a/FE/src/components/login/slack/LoginSection.tsx +++ b/FE/src/components/login/slack/LoginSection.tsx @@ -1,12 +1,17 @@ -import SlackLoginButton from "./LoginButton"; +import React from "react"; -const SlackLoginSection = () => { +interface LoginSectionProps { + title: string; + loginBtnComponent: React.ReactNode; +} + +const LoginSection = ({ title, loginBtnComponent }: LoginSectionProps) => { return (
-

에코노베이션 슬랙으로 로그인

- +

{title}

+ {loginBtnComponent}
); }; -export default SlackLoginSection; +export default LoginSection; diff --git a/FE/src/components/login/slack/LoginButton.tsx b/FE/src/components/login/slack/SlackLoginButton.tsx similarity index 70% rename from FE/src/components/login/slack/LoginButton.tsx rename to FE/src/components/login/slack/SlackLoginButton.tsx index b7a29e8a..b1f4ad75 100644 --- a/FE/src/components/login/slack/LoginButton.tsx +++ b/FE/src/components/login/slack/SlackLoginButton.tsx @@ -1,9 +1,8 @@ "use client"; -import Image from "next/image"; -import Link from "next/link"; import { useSearchParams } from "next/navigation"; import { useEffect } from "react"; +import StyledLoginButton from "../ui/StyledLoginButton"; import { useSlackLoginMutation } from "@/hooks/query/useAuthQuery"; const SlackLoginButton = () => { @@ -24,13 +23,13 @@ const SlackLoginButton = () => { }, [code]); return ( - - 슬랙 로고 -

슬랙으로 로그인

- + ); }; + export default SlackLoginButton; From b04f0b1485b2269cbb82776aa0ac8bab8b3531d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Fri, 12 Apr 2024 15:53:01 +0900 Subject: [PATCH 33/45] =?UTF-8?q?feat:=20guest=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20=EB=B2=84=ED=8A=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit guest 로그인 버튼 추가 #18 --- FE/src/components/login/guest/GuestLoginButton.tsx | 12 ++++++++++++ FE/src/components/login/guest/GuestLoginSection.tsx | 12 ++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 FE/src/components/login/guest/GuestLoginButton.tsx create mode 100644 FE/src/components/login/guest/GuestLoginSection.tsx diff --git a/FE/src/components/login/guest/GuestLoginButton.tsx b/FE/src/components/login/guest/GuestLoginButton.tsx new file mode 100644 index 00000000..d91c433d --- /dev/null +++ b/FE/src/components/login/guest/GuestLoginButton.tsx @@ -0,0 +1,12 @@ +import StyledLoginButton from "../ui/StyledLoginButton"; + +export default function GuestLoginButton() { + return ( + + ); +} diff --git a/FE/src/components/login/guest/GuestLoginSection.tsx b/FE/src/components/login/guest/GuestLoginSection.tsx new file mode 100644 index 00000000..e898203f --- /dev/null +++ b/FE/src/components/login/guest/GuestLoginSection.tsx @@ -0,0 +1,12 @@ +import GuestLoginButton from "./GuestLoginButton"; + +const GuestLoginSection = ({ title }) => { + return ( +
+

{title}

+ +
+ ); +}; + +export default GuestLoginSection; From bb098949e38aa31b53e469d42b2da991807a62d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Fri, 12 Apr 2024 15:53:35 +0900 Subject: [PATCH 34/45] =?UTF-8?q?feat:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 로그인 버튼 적용 #18 --- FE/src/components/login/RightSection.tsx | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/FE/src/components/login/RightSection.tsx b/FE/src/components/login/RightSection.tsx index bcf030c1..baca876b 100644 --- a/FE/src/components/login/RightSection.tsx +++ b/FE/src/components/login/RightSection.tsx @@ -1,5 +1,7 @@ import Title from "../common/Title"; -import SlackLoginSection from "./slack/LoginSection"; +import GuestLoginButton from "./guest/GuestLoginButton"; +import LoginSection from "./slack/LoginSection"; +import SlackLoginButton from "./slack/SlackLoginButton"; const LoginRightSection = () => { return ( @@ -8,10 +10,15 @@ const LoginRightSection = () => { className="flex flex-col items-center justify-center gap-24" > - <SlackLoginSection /> + <LoginSection + title="에코노베이션 슬랙으로 로그인" + loginBtnComponent={<SlackLoginButton />} + /> + <LoginSection + title="게스트모드로 EEOS 둘러보기" + loginBtnComponent={<GuestLoginButton />} + /> </div> ); }; export default LoginRightSection; - -// From 5dc0216dcfde46dc32b6233277c30c01d777fa59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= <geongyu09@gmail.com> Date: Fri, 12 Apr 2024 15:54:28 +0900 Subject: [PATCH 35/45] =?UTF-8?q?feat:=20guest=20=EB=AA=A8=EB=93=9C=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=EC=97=90=20=EB=93=A4=EC=96=B4=EA=B0=88=20bla?= =?UTF-8?q?ck-company=20=EB=A1=9C=EA=B3=A0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit guest 모드 버튼에 들어갈 black-company 로고 추가 #18 --- FE/public/icons/blackCompany.svg | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 FE/public/icons/blackCompany.svg diff --git a/FE/public/icons/blackCompany.svg b/FE/public/icons/blackCompany.svg new file mode 100644 index 00000000..7a43211d --- /dev/null +++ b/FE/public/icons/blackCompany.svg @@ -0,0 +1,9 @@ +<svg width="29" height="29" viewBox="0 0 29 29" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<rect width="29" height="29" rx="5" fill="url(#pattern0_1119_2413)"/> +<defs> +<pattern id="pattern0_1119_2413" patternContentUnits="objectBoundingBox" width="1" height="1"> +<use xlink:href="#image0_1119_2413" transform="scale(0.00666667)"/> +</pattern> +<image id="image0_1119_2413" width="150" height="150" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAACWCAYAAAA8AXHiAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAluSURBVHgB7Z3NT1RXGMaPLaba+oHGGj+agFVr0mhAE9eCy7oAVu0OSLrqBth018CkfwCw6UoD7NoVsOjCRQO4NSlDYhrbagYSPxqbCBXqR6SZnucOl7mDM8O5l/Ne5px5fsnNjMMdZuT+5rzvec879+7JaxQhlnlPESIAxSIiUCwiAsUiIlAsIgLFIiJQLCICxSIiUCwiAsUiIlAsIgLFIiJQLCICxSIiUCwiAsUiIlAsIgLFIiJQLCICxSIiUCwiAsUiIlAsIgLFIiI0qDpiZWVFZbNZtbCwENwuLi4GGwhvc7mcam5uDu6fOXNm83ET8DxsjY2Nqq2tTV27dk21traquiTvOcvLy/mhoaG8PtD4xve2mxZr87laEqPnVNvwO3p6ekp+bz3grVgzMzPGMkmKFd3qSTDvxMKBSyJUGmKFG0ZQ3/FKrJGRkbzOb3Z00NMQKxy9EKZ9xQuxcIBwoGwc8LTEwqYTe2/lcr7cgJlee3u7Gh8fV66BmWlXV5fyEefFGhgYCA6Qq8zOzgb/B99wWqxMJuPkSLUVnRsGgvmEs2KhcKlnV8oXent7lU84W3nfSW6Cyjgq4thaWlqCWzwWVtzjguch18OWFHxQJiYmVHd3t/KCvIOMjY0lmoWhvoXCqelMzHRWGNalMKPEe0s6Q8Xr+YKTYsUtgHZ2diaqeMcVKwpeL4lgEN8HnMuxEDJME12ENz2CqMnJycRhLil4Pbx2dFHbBIRDH3BOrDizJwilRw21m0AqPQoZyzU1NaV8wDmxTD/Rg4ODQetKLRCOXiZgAuBD6cE5sUyKoQiBuz1SbQWSm4qOfjHXcUos0yk9DmDaOZUJpqUEl1cSQpwSy7Sbs1a7Nk3fV5yu1VqlJgqkyCm2tgtHR6f8xuV+dlKArAUQok2gWAkJE9TR0dFAJteFIe+SqlgQCDJh0ZUy+U1qYqE+g4VWChUfjOomrTWYtKDMUg787bcLsdWeHxdxsSAS/ig+tLfsFqa1rWozYTx/O7FszqRFxcJ/BF0IPkyfSTzExIJUaBn2YYZD4iNWx8JIRanqFxGx0DLM8FffWBfLt5ZhkgzrOZat3m1UqTs7O4MTaxD3sCoWprQ7afkIuxI6OjpqpuWFJMOqWEm7HyFUX1+f6u/vN15PI7WNNbFQxEtSBEWll0L5hzWx5ubmYu2PKi9ah+v2xGSeY02sOLlV3D5w4h7Wyg2mdStKVR9YE8u0yo6cilL5T+pioTZF/CfVnvfwjMLEf3iedyICxSIiUCwiAsUiIlAsIgLFIiJQLCICxSIiUCwiAsUiIlAsIgLFIiJQLCJC6qcxwtfu44LGQOIWqYvl28WISHkYCokIFIuIYE0sdoaSKNbE4vcDSRRrYvFcCySKNbG8uYAjsYI1sfANHI5aJMTqrNDWqZyJ+1gVCyMWzhxDiPU6VrWv0OPxfOFywbE24h7WxUI9iyf9ICKVd55Rhogt6VCu+kZ0rRBSzc/PM6GvQ8QXoZFzDQ8PB4Jx9KofUutuwFoiG/bqh5q4dG9SMBpiFIS0uG1qatq8T3YXp8SCMAirUZlIbeKcWGlOBHC5FV7BLBnsIK0CLoiQy+WCy7CQeFCsbcAoOTY2FgjG7g1zKJYhYcGXHRxmUKyY4FqMEIw9/tWhWAlASKRc1aFYCUG5A7mXK+DLwmlCsXYArrLhwjoopKJYjoGCba1fXnhqaspoP5uhnWJZoNbLEJlMxmg/mysZFMtzBgYGjFcPsNZqC7Elnbnnz9X4kydG+x5uaFD/rK9vu1/H8eOqU28lvHmq1PIdpdZXC9u+U0p9eF6pQ1eq/q5Z/f4WVlfV4qtXqlG/fsuhQ6rt6NHgvg8gp+rt7TUOg8Dmt9nF/oo5fcDGHz822rd5//7gAG+73759RbEg1MPvlXrxa/mdPzip1CdfK/XxjZKHp549U7337qmVt2/Lvo9+/ants/jJTZPwNFHT09PBclSchN32or6bH8+Xfyr12zeFEaoSoXi4hWCqIFXX/HzFp0Du/vv3g/suyoXRKc4IFcV2npiKWG1HjqixS5cq/rz97t3N+5OXL6vWgwfL7te4d29BlN+/LUrVoPc98aUOf5/p+wcK0j39sbAfeHSz8PiJr9To0lLxPemwN3zhgmrVITCrQ2LmwYNAPDCk73efPu1NWDShr69P2SS1vxzCjAk4mFX3XbpZlAbh7vMfCrchyK0gGkarv38uPPbollLHbpSEW4xIkApAZIg/e+dOECJXdL63+PLl5s99B90btnvb3PpIrq8VZQFN/aVSRWkaKE3q9f3m/cc35RrQIQ8SY+QCuL98/bqqRyQW1lMRa3Z5We25fbvsz8YvXiz5dzQsRsEolms9UHwAQh2tUphE+Dv2hVJ//VT4979/6FnlxWA2CCAYXgvhFSMWwjXCn+nI6gsIgRKduG7VscIQCCqNVFEaIrnaf2vBjG/w7NmSXRD6INvQw4fqjA6FwYzRoPThAxAK3RoSpDJiYRTAiFCOpi0jBMoJ5ZLmIHFXkVmgFiUJQ+fOqR49MiFZR9KOLQpKJBjNZq5eVT4T9pdJdWikI5auP1WbFUZBUh3mPe/w5nDxvg5tQe7UcLDyL4vWuD46X3w/Wubo+8GIhRljOCvEv7MvXnibvKfxLXW3QiHCH8oKIY9vVd4XSX5ErGzDlSCnCrcoEBlljsKoWGBhtUqNzGHCXjLpbzilMmItvn5dtQofzWmm9ahRqQofhNSTG6UEgHoVQHkhmnMhYUf9KkRX35sbP9Uj0S+bD2V0ThXNt7a+ZpNnSTxCHmZ/abX5pCOWPmhIik0YiRQxt9Jz6pRqu3SjMBKFZQfIhS1cG0SBNFqR31jaQd6G/C1aBIXsYdjF4+EyTyBwpXDsGBihcH5Y9I6l2fHqZmn57HdKvX+gWEoA5dYMIRv23RjNkFet6CWdaMlh60iKcIiwKEF4kpSurq5Y31eEECZLLvj92Df8Rji23Wqf3pMXOmUeDlp4AG3xzkiC8gNCHqQKSxFI5tHdgPBYoc4FmSb0ll1bK45SeoKBOlY/Dk4KSzlYJEafVDnBIAi+buYyYmIRM9CNMDExEdyGklEsYpVsNhsItqTzTLQ8uwzFIiKwNZmIQLGICBSLiECxiAgUi4hAsYgIFIuIQLGICBSLiECxiAgUi4hAsYgIFIuIQLGICBSLiECxiAgUi4hAsYgIFIuIQLGICBSLiECxiAgUi4hAsYgI/wM2ks4gi52cPQAAAABJRU5ErkJggg=="/> +</defs> +</svg> From 013a404f4ba6a9fe2e38c3559730d72dcc22ca83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= <geongyu09@gmail.com> Date: Fri, 12 Apr 2024 16:03:45 +0900 Subject: [PATCH 36/45] =?UTF-8?q?style:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=A0=88=EC=9D=B4=EC=95=84?= =?UTF-8?q?=EC=9B=83=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 로그인 페이지 레이아웃 수정 #18 --- FE/src/components/login/RightSection.tsx | 18 ++++++++++-------- FE/src/components/login/slack/LoginSection.tsx | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/FE/src/components/login/RightSection.tsx b/FE/src/components/login/RightSection.tsx index baca876b..72a2c867 100644 --- a/FE/src/components/login/RightSection.tsx +++ b/FE/src/components/login/RightSection.tsx @@ -10,14 +10,16 @@ const LoginRightSection = () => { className="flex flex-col items-center justify-center gap-24" > <Title text={"로그인"} /> - <LoginSection - title="에코노베이션 슬랙으로 로그인" - loginBtnComponent={<SlackLoginButton />} - /> - <LoginSection - title="게스트모드로 EEOS 둘러보기" - loginBtnComponent={<GuestLoginButton />} - /> + <div className="flex flex-col gap-6"> + <LoginSection + title="에코노베이션 슬랙으로 로그인" + loginBtnComponent={<SlackLoginButton />} + /> + <LoginSection + title="게스트모드로 EEOS 둘러보기" + loginBtnComponent={<GuestLoginButton />} + /> + </div> </div> ); }; diff --git a/FE/src/components/login/slack/LoginSection.tsx b/FE/src/components/login/slack/LoginSection.tsx index 87c3d941..a187254b 100644 --- a/FE/src/components/login/slack/LoginSection.tsx +++ b/FE/src/components/login/slack/LoginSection.tsx @@ -7,7 +7,7 @@ interface LoginSectionProps { const LoginSection = ({ title, loginBtnComponent }: LoginSectionProps) => { return ( - <div className="flex flex-col items-center gap-4"> + <div className="flex flex-col items-center gap-6"> <p className="font-light">{title}</p> {loginBtnComponent} </div> From a9616fb9714e38a1231655dc3f58b56e2bc32b73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= <geongyu09@gmail.com> Date: Fri, 12 Apr 2024 16:42:46 +0900 Subject: [PATCH 37/45] =?UTF-8?q?feat:=20=EB=B9=84=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20=EC=9C=A0=EC=A0=80=ED=94=8C=EB=A1=9C=EC=9A=B0=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 로그인이 안되어 있는 경우 첫 화면을 로그인 페이지로 변경 #18 --- FE/next.config.js | 4 ++-- FE/src/components/login/guest/GuestLoginButton.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/FE/next.config.js b/FE/next.config.js index 2817fe6f..7f0c90ec 100644 --- a/FE/next.config.js +++ b/FE/next.config.js @@ -5,8 +5,8 @@ const nextConfig = { return [ { source: "/", - destination: "/main", - permanent: true, + destination: "/login", + permanent: false, }, ]; }, diff --git a/FE/src/components/login/guest/GuestLoginButton.tsx b/FE/src/components/login/guest/GuestLoginButton.tsx index d91c433d..e295a553 100644 --- a/FE/src/components/login/guest/GuestLoginButton.tsx +++ b/FE/src/components/login/guest/GuestLoginButton.tsx @@ -3,7 +3,7 @@ import StyledLoginButton from "../ui/StyledLoginButton"; export default function GuestLoginButton() { return ( <StyledLoginButton - linkUrl="/main" + linkUrl="main?category=all&status=active&page=1" buttonText="Visit to EEOS" imageUrl="/icons/blackCompany.svg" color="guest" From f4ab34477533d0f13007114f2931ba673195050d Mon Sep 17 00:00:00 2001 From: geongyu09 <geongyu09@gmail.com> Date: Fri, 12 Apr 2024 21:02:58 +0900 Subject: [PATCH 38/45] =?UTF-8?q?feat:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=9C=A0=EC=A0=80=20=ED=94=8C=EB=A1=9C=EC=9A=B0=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 로그인시 기존과 동일하게 /main 페이지를 바로 볼 수 있도록 변경 #18 --- FE/next.config.js | 17 ++++++++--------- FE/src/app/(auth)/layout.tsx | 2 ++ FE/src/app/page.tsx | 3 +++ FE/src/components/common/validate/Auth.tsx | 13 +++++++++++-- .../components/login/guest/GuestLoginButton.tsx | 2 +- 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/FE/next.config.js b/FE/next.config.js index 7f0c90ec..afc9c01d 100644 --- a/FE/next.config.js +++ b/FE/next.config.js @@ -1,15 +1,14 @@ /** @type {import('next').NextConfig} */ const nextConfig = { // rewrite - async redirects() { - return [ - { - source: "/", - destination: "/login", - permanent: false, - }, - ]; - }, + // async rewrites() { + // return [ + // { + // source: "/main", + // destination: "/", + // }, + // ]; + // }, }; module.exports = nextConfig; diff --git a/FE/src/app/(auth)/layout.tsx b/FE/src/app/(auth)/layout.tsx index d5e7264a..e1c97542 100644 --- a/FE/src/app/(auth)/layout.tsx +++ b/FE/src/app/(auth)/layout.tsx @@ -1,8 +1,10 @@ import { PropsWithChildren } from "react"; +import AuthValidate from "@/components/common/validate/Auth"; export default function AuthLayout({ children }: PropsWithChildren) { return ( <main className="mb-28 mt-16 h-full w-full max-w-[500px] sm:max-w-[800px] lg:max-w-[1112px]"> + <AuthValidate isHaveToLoggedInRoute={false} /> {children} </main> ); diff --git a/FE/src/app/page.tsx b/FE/src/app/page.tsx index 01bd7eb3..e3b368fb 100644 --- a/FE/src/app/page.tsx +++ b/FE/src/app/page.tsx @@ -1,7 +1,10 @@ +import AuthValidate from "@/components/common/validate/Auth"; + export default function Home() { return ( <main> <h1>Home</h1> + <AuthValidate /> </main> ); } diff --git a/FE/src/components/common/validate/Auth.tsx b/FE/src/components/common/validate/Auth.tsx index 0f87d9d6..e226edec 100644 --- a/FE/src/components/common/validate/Auth.tsx +++ b/FE/src/components/common/validate/Auth.tsx @@ -5,16 +5,25 @@ import { useEffect } from "react"; import ROUTES from "@/constants/ROUTES"; import { deleteTokenInfo } from "@/utils/authWithStorage"; -const AuthValidate = () => { +interface AuthValidateProps { + isHaveToLoggedInRoute?: boolean; +} + +const AuthValidate = ({ isHaveToLoggedInRoute = true }: AuthValidateProps) => { const router = useRouter(); useEffect(() => { const accessToken = localStorage.getItem("accessToken"); const tokenExpiration = localStorage.getItem("tokenExpiration"); - if (!accessToken || !tokenExpiration) { + const isLoggedIn = accessToken || tokenExpiration; + + if (isHaveToLoggedInRoute && !isLoggedIn) { deleteTokenInfo(); router.push(ROUTES.LOGIN); } + if (!isHaveToLoggedInRoute && isLoggedIn) { + router.push(ROUTES.MAIN); + } }, []); return <></>; diff --git a/FE/src/components/login/guest/GuestLoginButton.tsx b/FE/src/components/login/guest/GuestLoginButton.tsx index e295a553..d91c433d 100644 --- a/FE/src/components/login/guest/GuestLoginButton.tsx +++ b/FE/src/components/login/guest/GuestLoginButton.tsx @@ -3,7 +3,7 @@ import StyledLoginButton from "../ui/StyledLoginButton"; export default function GuestLoginButton() { return ( <StyledLoginButton - linkUrl="main?category=all&status=active&page=1" + linkUrl="/main" buttonText="Visit to EEOS" imageUrl="/icons/blackCompany.svg" color="guest" From a35eaf28a516e5f60484654b1852f65db1f873a8 Mon Sep 17 00:00:00 2001 From: geongyu09 <geongyu09@gmail.com> Date: Fri, 12 Apr 2024 21:16:23 +0900 Subject: [PATCH 39/45] =?UTF-8?q?fix:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=EC=97=90=EC=84=9C=20/login=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=EB=A1=9C=20=EA=B0=80=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EB=8D=98=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FE/src/app/page.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FE/src/app/page.tsx b/FE/src/app/page.tsx index e3b368fb..58cbd423 100644 --- a/FE/src/app/page.tsx +++ b/FE/src/app/page.tsx @@ -1,10 +1,10 @@ -import AuthValidate from "@/components/common/validate/Auth"; +import { redirect } from "next/navigation"; export default function Home() { + redirect("/login"); return ( <main> <h1>Home</h1> - <AuthValidate /> </main> ); } From a2a89b2546f394f8748427eaf83f3ca6e6b1d852 Mon Sep 17 00:00:00 2001 From: geongyu09 <geongyu09@gmail.com> Date: Fri, 12 Apr 2024 23:20:40 +0900 Subject: [PATCH 40/45] =?UTF-8?q?feat:=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit guest모드의 도메인 변경에 따른 페이지 구조 변경 #23 --- .../(guest)/guest/detail/[programId]/page.tsx | 22 +++++ .../app/(guest)/{ => guest}/detail/error.tsx | 0 .../(guest)/{ => guest}/detail/loading.tsx | 0 FE/src/app/(guest)/{ => guest}/layout.tsx | 2 + .../app/(guest)/{ => guest}/main/loading.tsx | 0 FE/src/app/(guest)/guest/main/page.tsx | 98 +++++++++++++++++++ .../(program)}/detail/[programId]/page.tsx | 6 +- .../app/(private)/(program)/detail/error.tsx | 19 ++++ .../(private)/(program)/detail/loading.tsx | 4 + .../app/(private)/(program)/main/loading.tsx | 6 ++ .../(program)}/main/page.tsx | 1 + 11 files changed, 155 insertions(+), 3 deletions(-) create mode 100644 FE/src/app/(guest)/guest/detail/[programId]/page.tsx rename FE/src/app/(guest)/{ => guest}/detail/error.tsx (100%) rename FE/src/app/(guest)/{ => guest}/detail/loading.tsx (100%) rename FE/src/app/(guest)/{ => guest}/layout.tsx (73%) rename FE/src/app/(guest)/{ => guest}/main/loading.tsx (100%) create mode 100644 FE/src/app/(guest)/guest/main/page.tsx rename FE/src/app/{(guest) => (private)/(program)}/detail/[programId]/page.tsx (74%) create mode 100644 FE/src/app/(private)/(program)/detail/error.tsx create mode 100644 FE/src/app/(private)/(program)/detail/loading.tsx create mode 100644 FE/src/app/(private)/(program)/main/loading.tsx rename FE/src/app/{(guest) => (private)/(program)}/main/page.tsx (99%) diff --git a/FE/src/app/(guest)/guest/detail/[programId]/page.tsx b/FE/src/app/(guest)/guest/detail/[programId]/page.tsx new file mode 100644 index 00000000..72bb0405 --- /dev/null +++ b/FE/src/app/(guest)/guest/detail/[programId]/page.tsx @@ -0,0 +1,22 @@ +import AttendeeInfoContainer from "@/components/programDetail/attendee/AttendeeInfo.container"; +import ProgramInfo from "@/components/programDetail/program/ProgramInfo"; +import UserAttendModalContainer from "@/components/programDetail/userAttendModal/UserAttendModal.container"; + +interface ProgramDetailPageProps { + params: { + programId: string; + }; +} + +const ProgramDetailPage = ({ params }: ProgramDetailPageProps) => { + const { programId } = params; + + return ( + <div className="mb-16 space-y-16"> + <ProgramInfo programId={+programId} isLoggedIn={false} /> + <AttendeeInfoContainer programId={+programId} isLoggedIn={false} /> + <UserAttendModalContainer programId={+programId} isLoggedIn={false} /> + </div> + ); +}; +export default ProgramDetailPage; diff --git a/FE/src/app/(guest)/detail/error.tsx b/FE/src/app/(guest)/guest/detail/error.tsx similarity index 100% rename from FE/src/app/(guest)/detail/error.tsx rename to FE/src/app/(guest)/guest/detail/error.tsx diff --git a/FE/src/app/(guest)/detail/loading.tsx b/FE/src/app/(guest)/guest/detail/loading.tsx similarity index 100% rename from FE/src/app/(guest)/detail/loading.tsx rename to FE/src/app/(guest)/guest/detail/loading.tsx diff --git a/FE/src/app/(guest)/layout.tsx b/FE/src/app/(guest)/guest/layout.tsx similarity index 73% rename from FE/src/app/(guest)/layout.tsx rename to FE/src/app/(guest)/guest/layout.tsx index 972949b5..66e74b1a 100644 --- a/FE/src/app/(guest)/layout.tsx +++ b/FE/src/app/(guest)/guest/layout.tsx @@ -1,4 +1,5 @@ import Header from "@/components/common/header/Header"; +import AuthValidate from "@/components/common/validate/Auth"; export default function GuestLayout({ children, @@ -6,6 +7,7 @@ export default function GuestLayout({ return ( <> <Header /> + <AuthValidate isHaveToLoggedInRoute={false} /> <main className="my-16 w-full px-3 sm:max-w-[800px] lg:max-w-[1112px]"> {children} </main> diff --git a/FE/src/app/(guest)/main/loading.tsx b/FE/src/app/(guest)/guest/main/loading.tsx similarity index 100% rename from FE/src/app/(guest)/main/loading.tsx rename to FE/src/app/(guest)/guest/main/loading.tsx diff --git a/FE/src/app/(guest)/guest/main/page.tsx b/FE/src/app/(guest)/guest/main/page.tsx new file mode 100644 index 00000000..8af24436 --- /dev/null +++ b/FE/src/app/(guest)/guest/main/page.tsx @@ -0,0 +1,98 @@ +// TODO: 서버 컴포넌트로 변경하기 +"use client"; + +import { useSearchParams } from "next/navigation"; +import { Suspense, useEffect, useState } from "react"; +import { ErrorBoundary } from "react-error-boundary"; +import ErrorFallback from "@/components/common/ErrorFallback"; +import Tab from "@/components/common/tabs/Tab"; +import TextTab from "@/components/common/tabs/TextTab"; +import ProgramList from "@/components/main/ProgramList"; +import ProgramListLoader from "@/components/main/ProgramList.loader"; +import TeamBuildingDropup from "@/components/main/TeamBuildingDropup"; +import MAIN from "@/constants/MAIN"; +import PROGRAM from "@/constants/PROGRAM"; +import { ProgramCategoryWithAll, ProgramStatus } from "@/types/program"; + +const MainPage = () => { + const searchParams = useSearchParams(); + + // TODO: Hook으로 변경하기 + const [queryValue, setQueryValue] = useState(MAIN.DEFAULT_QUERY); + + // TODO: useEffect를 Hook으로 변경하기 + useEffect(() => { + setQueryValue({ + ...MAIN.DEFAULT_QUERY, + category: + (searchParams.get("category") as ProgramCategoryWithAll) ?? "all", + status: (searchParams.get("status") as ProgramStatus) ?? "active", + page: searchParams.get("page") ?? "1", + }); + }, [searchParams]); + + useEffect(() => { + window.history.replaceState( + {}, + "", + `?category=${queryValue.category}&status=${queryValue.status}&page=${queryValue.page}`, + ); + }, [queryValue]); + + const handleSetCategory = (category: ProgramCategoryWithAll) => { + setQueryValue({ + ...queryValue, + category, + page: "1", + }); + }; + + const handleSetStatus = (status: ProgramStatus) => { + setQueryValue({ + ...queryValue, + status, + page: "1", + }); + }; + + const handleSetPage = (page: number) => { + setQueryValue({ + ...queryValue, + page: page.toString(), + }); + }; + + // TODO: 합성 컴포넌트! + return ( + <div className="relative space-y-8"> + <Tab<ProgramCategoryWithAll> + options={Object.values(PROGRAM.CATEGORY_TAB_WITH_ALL)} + selected={queryValue.category} + onItemClick={(v) => handleSetCategory(v)} + size="lg" + baseColor="white" + pointColor="navy" + align="line" + /> + <TextTab<ProgramStatus> + options={Object.values(PROGRAM.STATUS_TAB)} + selected={queryValue.status} + onClick={(v) => handleSetStatus(v)} + /> + <ErrorBoundary FallbackComponent={ErrorFallback}> + <Suspense fallback={<ProgramListLoader />}> + <ProgramList + category={queryValue.category} + programStatus={queryValue.status} + page={+queryValue.page} + setPage={handleSetPage} + isLoggedIn={false} + /> + </Suspense> + </ErrorBoundary> + <TeamBuildingDropup /> + </div> + ); +}; + +export default MainPage; diff --git a/FE/src/app/(guest)/detail/[programId]/page.tsx b/FE/src/app/(private)/(program)/detail/[programId]/page.tsx similarity index 74% rename from FE/src/app/(guest)/detail/[programId]/page.tsx rename to FE/src/app/(private)/(program)/detail/[programId]/page.tsx index b9feb876..9315cc77 100644 --- a/FE/src/app/(guest)/detail/[programId]/page.tsx +++ b/FE/src/app/(private)/(program)/detail/[programId]/page.tsx @@ -13,9 +13,9 @@ const ProgramDetailPage = ({ params }: ProgramDetailPageProps) => { return ( <div className="mb-16 space-y-16"> - <ProgramInfo programId={+programId} /> - <AttendeeInfoContainer programId={+programId} /> - <UserAttendModalContainer programId={+programId} /> + <ProgramInfo programId={+programId} isLoggedIn /> + <AttendeeInfoContainer programId={+programId} isLoggedIn /> + <UserAttendModalContainer programId={+programId} isLoggedIn /> </div> ); }; diff --git a/FE/src/app/(private)/(program)/detail/error.tsx b/FE/src/app/(private)/(program)/detail/error.tsx new file mode 100644 index 00000000..adf565a8 --- /dev/null +++ b/FE/src/app/(private)/(program)/detail/error.tsx @@ -0,0 +1,19 @@ +"use client"; + +import ErrorFallback from "@/components/common/ErrorFallback"; + +const DetailPageError = () => { + const error = { + message: "행사 정보를 불러오는 중에 오류가 발생했습니다.", + }; + + return ( + <ErrorFallback + error={error} + resetErrorBoundary={() => { + window.location.reload(); + }} + /> + ); +}; +export default DetailPageError; diff --git a/FE/src/app/(private)/(program)/detail/loading.tsx b/FE/src/app/(private)/(program)/detail/loading.tsx new file mode 100644 index 00000000..4a5cb70e --- /dev/null +++ b/FE/src/app/(private)/(program)/detail/loading.tsx @@ -0,0 +1,4 @@ +import LoadingSpinner from "@/components/common/LoadingSpinner"; + +const DetailLoading = () => <LoadingSpinner />; +export default DetailLoading; diff --git a/FE/src/app/(private)/(program)/main/loading.tsx b/FE/src/app/(private)/(program)/main/loading.tsx new file mode 100644 index 00000000..2ec65fef --- /dev/null +++ b/FE/src/app/(private)/(program)/main/loading.tsx @@ -0,0 +1,6 @@ +import LoadingSpinner from "@/components/common/LoadingSpinner"; + +const MainLoading = () => { + return <LoadingSpinner />; +}; +export default MainLoading; diff --git a/FE/src/app/(guest)/main/page.tsx b/FE/src/app/(private)/(program)/main/page.tsx similarity index 99% rename from FE/src/app/(guest)/main/page.tsx rename to FE/src/app/(private)/(program)/main/page.tsx index e3dcb8b2..78b3e60d 100644 --- a/FE/src/app/(guest)/main/page.tsx +++ b/FE/src/app/(private)/(program)/main/page.tsx @@ -86,6 +86,7 @@ const MainPage = () => { programStatus={queryValue.status} page={+queryValue.page} setPage={handleSetPage} + isLoggedIn /> </Suspense> </ErrorBoundary> From 6c2cfed2646f334850e44d8889c0d61e7162840b Mon Sep 17 00:00:00 2001 From: geongyu09 <geongyu09@gmail.com> Date: Fri, 12 Apr 2024 23:21:29 +0900 Subject: [PATCH 41/45] =?UTF-8?q?feat:=20guest=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EC=B6=94=EA=B0=80=EC=97=90=20=EB=94=B0=EB=A5=B8=20?= =?UTF-8?q?url=20=EC=83=81=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit url 상수 추가 #23 --- FE/src/constants/ROUTES.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FE/src/constants/ROUTES.ts b/FE/src/constants/ROUTES.ts index a95dd097..a13007d5 100644 --- a/FE/src/constants/ROUTES.ts +++ b/FE/src/constants/ROUTES.ts @@ -1,7 +1,9 @@ const ROUTES = { MAIN: "/main", + GUEST_MAIN: "/guest/main", CREATE: "/create", DETAIL: (programId: number) => `/detail/${programId}`, + GUEST_DETAIL: (programId: number) => `/guest/detail/${programId}`, EDIT: (programId: number) => `/edit/${programId}`, ERROR: "/error", LOGIN: "/login", From 3f6e128104ee511fc2ea46636d05902bb0a66103 Mon Sep 17 00:00:00 2001 From: geongyu09 <geongyu09@gmail.com> Date: Fri, 12 Apr 2024 23:23:34 +0900 Subject: [PATCH 42/45] =?UTF-8?q?feat:=20guest=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EC=B6=94=EA=B0=80=EC=97=90=20=EB=94=B0=EB=A5=B8=20?= =?UTF-8?q?=EB=A6=AC=EB=8B=A4=EC=9D=B4=EB=A0=89=ED=8A=B8=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit /guest 접근시 로그인이 되어있는 경우 기존 페이지로 이동 /guest 에서 활동시 로고 클릭시 guest 도메인의 /main으로 이동 로그인 화면에서 게스트 모드로 체험 클릭시 /guest 로 이동 #23 --- FE/src/app/(private)/layout.tsx | 6 +++++- FE/src/components/common/header/Header.tsx | 2 +- FE/src/components/common/header/Logo.tsx | 14 ++++++++++---- FE/src/components/login/guest/GuestLoginButton.tsx | 2 +- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/FE/src/app/(private)/layout.tsx b/FE/src/app/(private)/layout.tsx index b3876d21..cbebc4be 100644 --- a/FE/src/app/(private)/layout.tsx +++ b/FE/src/app/(private)/layout.tsx @@ -1,11 +1,15 @@ import { PropsWithChildren } from "react"; +import Header from "@/components/common/header/Header"; import AuthValidate from "@/components/common/validate/Auth"; const PrivateLayout = ({ children }: PropsWithChildren) => { return ( <> <AuthValidate /> - {children} + <Header /> + <main className="my-16 w-full px-3 sm:max-w-[800px] lg:max-w-[1112px]"> + {children} + </main> </> ); }; diff --git a/FE/src/components/common/header/Header.tsx b/FE/src/components/common/header/Header.tsx index cdfc6b0e..0ec97a95 100644 --- a/FE/src/components/common/header/Header.tsx +++ b/FE/src/components/common/header/Header.tsx @@ -18,7 +18,7 @@ const Header = () => { return ( <header className="sticky top-0 z-50 flex w-full items-center justify-between rounded-b-xl bg-background px-2 py-4 shadow-sm sm:px-32"> - <Logo /> + <Logo isLoggedIn={isLoggedIn} /> {!isLoading && ( <section className="flex w-fit items-center gap-4 sm:gap-8"> {isLoggedIn ? ( diff --git a/FE/src/components/common/header/Logo.tsx b/FE/src/components/common/header/Logo.tsx index e01fab4d..f5b26fa2 100644 --- a/FE/src/components/common/header/Logo.tsx +++ b/FE/src/components/common/header/Logo.tsx @@ -6,16 +6,22 @@ const INIT_CATEGORY = "all"; const INIT_STATUS = "active"; const INIT_PAGE = "1"; -const Logo = () => { +interface LogoProps { + isLoggedIn: boolean; +} + +const Logo = ({ isLoggedIn }: LogoProps) => { const router = useRouter(); const pathname = usePathname(); + const mainUrl = isLoggedIn ? ROUTES.MAIN : ROUTES.GUEST_MAIN; + const handleClick = () => { - if (pathname === ROUTES.MAIN) { - window.location.href = `${ROUTES.MAIN}?category=${INIT_CATEGORY}&status=${INIT_STATUS}&page=${INIT_PAGE}`; + if (pathname === mainUrl) { + window.location.href = `${mainUrl}?category=${INIT_CATEGORY}&status=${INIT_STATUS}&page=${INIT_PAGE}`; return; } - router.push(ROUTES.MAIN); + router.push(mainUrl); }; return ( diff --git a/FE/src/components/login/guest/GuestLoginButton.tsx b/FE/src/components/login/guest/GuestLoginButton.tsx index d91c433d..6c556b66 100644 --- a/FE/src/components/login/guest/GuestLoginButton.tsx +++ b/FE/src/components/login/guest/GuestLoginButton.tsx @@ -3,7 +3,7 @@ import StyledLoginButton from "../ui/StyledLoginButton"; export default function GuestLoginButton() { return ( <StyledLoginButton - linkUrl="/main" + linkUrl="/guest/main" buttonText="Visit to EEOS" imageUrl="/icons/blackCompany.svg" color="guest" From fce9cdcd6379c829db1cfd6f9fc7aa1e9b66995a Mon Sep 17 00:00:00 2001 From: geongyu09 <geongyu09@gmail.com> Date: Fri, 12 Apr 2024 23:25:46 +0900 Subject: [PATCH 43/45] =?UTF-8?q?feat:=20guest=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EC=B6=94=EA=B0=80=EC=97=90=20=EB=94=B0=EB=A5=B8=20?= =?UTF-8?q?=EC=B5=9C=EC=A0=81=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit api는 guest에 따른 반환값이 동일하므로, 하나의 api 및 해당 api를 queryFn으로 받은 query는 유지하며, guest에 따른 url만 변경되도록 수정 /guest에 접근 확인은 layout에서 모두 처리하므로, /guest의 모든 페이지는 로그인이 안되어 있다는 가정하에 최적화, 기존 페이지는 로기인이 되어있다는 가정하에 최적화 #23 --- FE/src/apis/program.ts | 11 +++++-- FE/src/components/main/ProgramList.tsx | 9 +++++- FE/src/components/main/ProgramListItem.tsx | 8 +++-- .../attendee/AttendeeInfo.container.tsx | 30 +++++++++++-------- .../programDetail/program/ProgramInfo.tsx | 5 ++-- .../UserAttendModal.container.tsx | 8 +++-- FE/src/hooks/query/useProgramQuery.ts | 8 +++-- 7 files changed, 54 insertions(+), 25 deletions(-) diff --git a/FE/src/apis/program.ts b/FE/src/apis/program.ts index e88060db..88df4037 100644 --- a/FE/src/apis/program.ts +++ b/FE/src/apis/program.ts @@ -21,9 +21,13 @@ import MESSAGE from "@/constants/MESSAGE"; export const getProgramById = async ( programId: number, + isLoggedIn: boolean, ): Promise<ProgramInfoDto> => { + const url = isLoggedIn + ? API.PROGRAM.DETAIL(programId) + : API.PROGRAM.GUEST_DETAIL(programId); const { data } = await https({ - url: API.PROGRAM.GUEST_DETAIL(programId), + url, }); return new ProgramInfoDto(data?.data); }; @@ -37,6 +41,7 @@ export interface GetProgramListRequest { programStatus: ProgramStatus; size: number; page: number; + isLoggedIn: boolean; } export const getProgramList = async ({ @@ -44,9 +49,11 @@ export const getProgramList = async ({ programStatus, size, page, + isLoggedIn, }: GetProgramListRequest): Promise<ProgramListDto> => { + const url = isLoggedIn ? API.PROGRAM.LIST : API.PROGRAM.GUEST_LIST; const { data } = await https({ - url: API.PROGRAM.GUEST_LIST, + url, method: "GET", params: { category, diff --git a/FE/src/components/main/ProgramList.tsx b/FE/src/components/main/ProgramList.tsx index cabccb60..b661ff5c 100644 --- a/FE/src/components/main/ProgramList.tsx +++ b/FE/src/components/main/ProgramList.tsx @@ -10,6 +10,7 @@ interface ProgramListProps { programStatus?: ProgramStatus; page?: number; setPage: (page: number) => void; + isLoggedIn: boolean; } const ProgramList = ({ @@ -17,6 +18,7 @@ const ProgramList = ({ programStatus = "active", page = 1, setPage: handleSetPage, + isLoggedIn, }: ProgramListProps) => { const queryClient = useQueryClient(); const { data: programListData } = useGetProgramList({ @@ -24,6 +26,7 @@ const ProgramList = ({ programStatus, page: page - 1, size: PROGRAM.LIST_SIZE, + isLoggedIn, }); queryClient.setQueryData<number>(["totalPage"], programListData.totalPage); @@ -33,7 +36,11 @@ const ProgramList = ({ <> <div className="w-full space-y-5"> {programs.map((program) => ( - <ProgramListItem key={program.programId} programData={program} /> + <ProgramListItem + key={program.programId} + programData={program} + isLoggedIn={isLoggedIn} + /> ))} </div> <Paginataion diff --git a/FE/src/components/main/ProgramListItem.tsx b/FE/src/components/main/ProgramListItem.tsx index 0bc9439a..325fb703 100644 --- a/FE/src/components/main/ProgramListItem.tsx +++ b/FE/src/components/main/ProgramListItem.tsx @@ -5,14 +5,18 @@ import { convertDate } from "@/utils/convert"; interface ProgramListItemProps { programData: ProgramSimpleInfoDto; + isLoggedIn: boolean; } -const ProgramListItem = ({ programData }: ProgramListItemProps) => { +const ProgramListItem = ({ programData, isLoggedIn }: ProgramListItemProps) => { const { programId, title, deadLine } = programData; + const lingUrl = isLoggedIn + ? ROUTES.DETAIL(programId) + : ROUTES.GUEST_DETAIL(programId); return ( <Link - href={ROUTES.DETAIL(programId)} className="flex w-full flex-col items-center justify-between gap-4 rounded-lg bg-gray-10 px-8 py-6 transition-all hover:bg-secondary-20 sm:flex-row" + href={lingUrl} key={programId} > <p className="w-full truncate text-center text-lg font-bold sm:text-left"> diff --git a/FE/src/components/programDetail/attendee/AttendeeInfo.container.tsx b/FE/src/components/programDetail/attendee/AttendeeInfo.container.tsx index eff4c5d0..4e24007f 100644 --- a/FE/src/components/programDetail/attendee/AttendeeInfo.container.tsx +++ b/FE/src/components/programDetail/attendee/AttendeeInfo.container.tsx @@ -4,10 +4,10 @@ import { ErrorBoundary } from "react-error-boundary"; import AttendeeInfo from "./AttendeeInfo"; import BluredAttedee from "./BluredAttedee"; import ErrorFallback from "@/components/common/ErrorFallback"; -import { CheckIsLoggedIn } from "@/utils/authWithStorage"; interface AttendeeInfoContainerProps { programId: number; + isLoggedIn: boolean; } export const attendStatuses = [ @@ -17,24 +17,30 @@ export const attendStatuses = [ "nonResponse", ] as const; -const AttendeeInfoContainer = ({ programId }: AttendeeInfoContainerProps) => { - const isLoggedIn = CheckIsLoggedIn(); +const AttendeeInfoContainer = ({ + programId, + isLoggedIn, +}: AttendeeInfoContainerProps) => { return ( - <ErrorBoundary FallbackComponent={ErrorFallback}> - <div className="space-y-16"> - {isLoggedIn - ? attendStatuses.map((status) => ( + <> + {!isLoggedIn && + attendStatuses.map((status) => ( + <BluredAttedee key={status} status={status} /> + ))} + + <ErrorBoundary FallbackComponent={ErrorFallback}> + <div className="space-y-16"> + {isLoggedIn && + attendStatuses.map((status) => ( <AttendeeInfo key={status} programId={programId} status={status} /> - )) - : attendStatuses.map((status) => ( - <BluredAttedee key={status} status={status} /> ))} - </div> - </ErrorBoundary> + </div> + </ErrorBoundary> + </> ); }; export default AttendeeInfoContainer; diff --git a/FE/src/components/programDetail/program/ProgramInfo.tsx b/FE/src/components/programDetail/program/ProgramInfo.tsx index 632832ad..6c9a016c 100644 --- a/FE/src/components/programDetail/program/ProgramInfo.tsx +++ b/FE/src/components/programDetail/program/ProgramInfo.tsx @@ -7,14 +7,15 @@ import { useGetProgramById } from "@/hooks/query/useProgramQuery"; interface ProgramInfoProps { programId: number; + isLoggedIn: boolean; } -const ProgramInfo = ({ programId }: ProgramInfoProps) => { +const ProgramInfo = ({ programId, isLoggedIn }: ProgramInfoProps) => { const { data: programData, isLoading, isError, - } = useGetProgramById(programId); + } = useGetProgramById(programId, isLoggedIn); if (isLoading) return <ProgramInfoLoader />; if (isError) return <div>에러 발생</div>; diff --git a/FE/src/components/programDetail/userAttendModal/UserAttendModal.container.tsx b/FE/src/components/programDetail/userAttendModal/UserAttendModal.container.tsx index f6f0bd28..653782ad 100644 --- a/FE/src/components/programDetail/userAttendModal/UserAttendModal.container.tsx +++ b/FE/src/components/programDetail/userAttendModal/UserAttendModal.container.tsx @@ -8,16 +8,18 @@ import UserAttendModal from "./UserAttendModal"; import ErrorFallbackNoIcon from "@/components/common/ErrorFallbackNoIcon"; import useModal from "@/hooks/useModal"; import useOutsideRef from "@/hooks/useOutsideRef"; -import { CheckIsLoggedIn } from "@/utils/authWithStorage"; interface UserAttendModalProps { programId: number; + isLoggedIn: boolean; } -const UserAttendModalContainer = ({ programId }: UserAttendModalProps) => { +const UserAttendModalContainer = ({ + programId, + isLoggedIn, +}: UserAttendModalProps) => { const { isOpen, openModal, closeModal } = useModal(); const modalRef = useOutsideRef(closeModal); - const isLoggedIn = CheckIsLoggedIn(); const modalStyle = classNames( "fixed left-0 z-10 flex h-60 w-full flex-col items-center gap-5 rounded-t-3xl border-t-2 bg-background shadow-2xl transition-all duration-500", diff --git a/FE/src/hooks/query/useProgramQuery.ts b/FE/src/hooks/query/useProgramQuery.ts index 59413eb2..1534a5a5 100644 --- a/FE/src/hooks/query/useProgramQuery.ts +++ b/FE/src/hooks/query/useProgramQuery.ts @@ -71,13 +71,13 @@ export const useDeleteProgram = (programId: number) => { }); }; -export const useGetProgramById = (programId: number) => { +export const useGetProgramById = (programId: number, isLoggedIn: boolean) => { const queryClient = useQueryClient(); return useQuery({ queryKey: [API.PROGRAM.DETAIL(programId)], queryFn: () => - getProgramById(programId).then((res) => { + getProgramById(programId, isLoggedIn).then((res) => { queryClient.setQueryData<ProgramStatus>( ["programStatus", programId], res.programStatus, @@ -96,10 +96,12 @@ export const useGetProgramList = ({ programStatus, size, page, + isLoggedIn, }: GetProgramListRequest) => { return useQuery({ queryKey: [API.PROGRAM.LIST, category, programStatus, size, page], - queryFn: () => getProgramList({ category, programStatus, size, page }), + queryFn: () => + getProgramList({ category, programStatus, size, page, isLoggedIn }), select: (data) => ({ totalPage: data?.totalPage, programs: data?.programs, From a23d2d8040108d54387ab791b31e6c3b1de83c10 Mon Sep 17 00:00:00 2001 From: geongyu09 <geongyu09@gmail.com> Date: Fri, 12 Apr 2024 23:44:32 +0900 Subject: [PATCH 44/45] =?UTF-8?q?fix:=20=EC=9D=B8=EC=9E=90=EB=A5=BC=20?= =?UTF-8?q?=EC=A3=BC=EC=A7=80=20=EC=95=8A=EC=95=84=20=EB=B9=8C=EB=93=9C?= =?UTF-8?q?=EA=B0=80=20=EC=95=88=EB=90=98=EB=8D=98=20=EB=B2=84=EA=B7=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #23 --- FE/src/app/(private)/(program)/edit/[programId]/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FE/src/app/(private)/(program)/edit/[programId]/page.tsx b/FE/src/app/(private)/(program)/edit/[programId]/page.tsx index e9ec9227..4aa6aaec 100644 --- a/FE/src/app/(private)/(program)/edit/[programId]/page.tsx +++ b/FE/src/app/(private)/(program)/edit/[programId]/page.tsx @@ -14,7 +14,7 @@ interface ProgramEditPageProps { const ProgramEditPage = ({ params }: ProgramEditPageProps) => { const { programId } = params; - const { data: programInfo, isLoading } = useGetProgramById(+programId); + const { data: programInfo, isLoading } = useGetProgramById(+programId, true); if (isLoading) return <LoadingSpinner />; From e5ada64a4b178ded16ffd1ecd7d5aa65383e72a6 Mon Sep 17 00:00:00 2001 From: geongyu09 <geongyu09@gmail.com> Date: Fri, 3 May 2024 13:47:15 +0900 Subject: [PATCH 45/45] =?UTF-8?q?feat:=20detail=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EC=9D=98=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=B0=B8=EC=84=9D=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=ED=8A=B8=EB=A5=BC=20=EB=93=9C=EB=9E=98?= =?UTF-8?q?=EA=B7=B8=ED=95=98=EC=A7=80=20=EB=AA=BB=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95=20(MemberList.tsx)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 사용자의 참석 리스트를 확인하지 못하도록 드래그를 방지하기 위해 user-select를 none으로 설정 이는 블러 처리했을 때 사용자의 참여 여부를 확인하지 못하도록 하는 정책에 맞추기 위한 변경이다. 추가적으로 유저의 사용성을 높이기 위해 게스트 모드가 아니어도 드래그가 되지 않도록 하여 예측 가능성을 높혔다. --- FE/src/components/common/MemberList.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FE/src/components/common/MemberList.tsx b/FE/src/components/common/MemberList.tsx index 85b4aad3..c62f573c 100644 --- a/FE/src/components/common/MemberList.tsx +++ b/FE/src/components/common/MemberList.tsx @@ -21,7 +21,7 @@ const MemberList = ({ members, blur = false }: MemberListProps) => { const MemberListItem = ({ name }: Omit<SimpleMemberInfo, "memberId">) => { return ( - <div className="grid w-fit grid-cols-1 justify-items-center px-4 py-6 text-lg"> + <div className="grid w-fit cursor-default select-none grid-cols-1 justify-items-center px-4 py-6 text-lg"> <span>{name}</span> </div> );