From fc3f05ef2e316e7048fc4c880f69131a897bdb0e Mon Sep 17 00:00:00 2001 From: Im-younique Date: Mon, 3 Jun 2024 14:28:50 +0900 Subject: [PATCH 01/22] =?UTF-8?q?[chore]=20login,=20profile=20Navigation?= =?UTF-8?q?=20=EB=9D=BC=EC=9A=B0=ED=8C=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/Navigator/ProfileButton.tsx | 38 +++++++++++++++++-- client/src/components/Navigator/index.tsx | 7 +--- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/client/src/components/Navigator/ProfileButton.tsx b/client/src/components/Navigator/ProfileButton.tsx index d0a4298f..f1fbc201 100644 --- a/client/src/components/Navigator/ProfileButton.tsx +++ b/client/src/components/Navigator/ProfileButton.tsx @@ -1,9 +1,41 @@ +'use client'; + +import Link from 'next/link'; + +// redux +import { useSelector } from 'react-redux'; + +// components +import { Avatar } from '../'; + +// icons import { ProfileIcon } from '@/assets/Icon'; +// types +import { IReduxState } from '@/types/redux/IReduxState'; + +// services +import { BASE_URL } from '@/service/base/api'; + export default function ProfileButton() { + const user = useSelector((state: IReduxState) => state.auth); + return ( - + + + ); } diff --git a/client/src/components/Navigator/index.tsx b/client/src/components/Navigator/index.tsx index dbf32523..55437088 100644 --- a/client/src/components/Navigator/index.tsx +++ b/client/src/components/Navigator/index.tsx @@ -41,12 +41,7 @@ export default function Navigator({ viewMode }: NavitatorProps) { - - - + From 692be845d443cca1d142af2068aa143a11b5830e Mon Sep 17 00:00:00 2001 From: Im-younique Date: Mon, 3 Jun 2024 14:42:04 +0900 Subject: [PATCH 02/22] =?UTF-8?q?[chore]=20=EB=A9=94=EC=9D=B8=EB=A1=9C?= =?UTF-8?q?=EA=B3=A0=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/Navigator/Logo.tsx | 18 ++++++++++++++++++ client/src/components/Navigator/index.tsx | 23 ++++++++--------------- 2 files changed, 26 insertions(+), 15 deletions(-) create mode 100644 client/src/components/Navigator/Logo.tsx diff --git a/client/src/components/Navigator/Logo.tsx b/client/src/components/Navigator/Logo.tsx new file mode 100644 index 00000000..9d6ccde4 --- /dev/null +++ b/client/src/components/Navigator/Logo.tsx @@ -0,0 +1,18 @@ +import Link from 'next/link'; +import Image from 'next/image'; + +export default function Logo() { + return ( + + reDuck-icon + + reDuck + + + ); +} diff --git a/client/src/components/Navigator/index.tsx b/client/src/components/Navigator/index.tsx index 55437088..0f3f7212 100644 --- a/client/src/components/Navigator/index.tsx +++ b/client/src/components/Navigator/index.tsx @@ -1,12 +1,16 @@ -import Image from 'next/image'; -import Link from 'next/link'; +//components import Button from '../base/Button'; import SearchButton from './SearchButton'; import ChatButton from './ChatButton'; import AlarmButton from './AlarmButton'; import ProfileButton from './ProfileButton'; -import { ArrowDownIcon } from '@/assets/Icon'; import PostModeNavigation from './PostModeNavigation'; +import Logo from './Logo'; + +//icons +import { ArrowDownIcon } from '@/assets/Icon'; + +//types import { PostViewType } from '@/types'; interface NavitatorProps { @@ -17,18 +21,7 @@ export default function Navigator({ viewMode }: NavitatorProps) {
- - - reDuck - - reDuck-icon - - +
  • From 1758ea1bd25b7cd5fd0f6a2393c63c7ab34413ed Mon Sep 17 00:00:00 2001 From: Im-younique Date: Mon, 3 Jun 2024 16:23:34 +0900 Subject: [PATCH 03/22] =?UTF-8?q?[feat]=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=ED=8F=BC=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC=20=EB=B0=8F=20UI=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/login/components/LoginForm/index.tsx | 147 ++++++++++++ client/src/app/login/page.tsx | 211 +++--------------- 2 files changed, 184 insertions(+), 174 deletions(-) create mode 100644 client/src/app/login/components/LoginForm/index.tsx diff --git a/client/src/app/login/components/LoginForm/index.tsx b/client/src/app/login/components/LoginForm/index.tsx new file mode 100644 index 00000000..2d96aa42 --- /dev/null +++ b/client/src/app/login/components/LoginForm/index.tsx @@ -0,0 +1,147 @@ +'use client'; + +import { useCallback } from 'react'; +import { useRouter } from 'next/navigation'; + +//redux +import { useDispatch, useSelector } from 'react-redux'; +import { logIn } from '@/lib/redux/features/auth/authSlice'; + +//hooks +import useModal from '@/hooks/modal/useModal'; + +//formik +import { Formik, Form, Field, ErrorMessage } from 'formik'; +import * as Yup from 'yup'; + +//services +import { userManager } from '@/service/user'; + +//constant +import { + initialLoginValue, + errorMessage, + errorCodeToMessage, + ModalType, +} from '@/constants/constant'; +import { IReduxState } from '@/types/redux/IReduxState'; + +const ValidationSchema = Yup.object().shape({ + userId: Yup.string().required(errorMessage.blankID), + password: Yup.string().required(errorMessage.blankPassword), +}); + +interface ILogin { + userId: string; + password: string; +} + +export default function LoginForm() { + const dispatch = useDispatch(); + + const router = useRouter(); + + const modalState = useSelector((state: IReduxState) => state.modal); + const { openModal } = useModal(); + + const handleSubmit = useCallback( + async (sendData: ILogin, setSubmitting: (value: boolean) => void) => { + if (modalState.type === ModalType.CLOSE) { + setSubmitting(true); + try { + const userData = await userManager.loginUser({ data: sendData }); + dispatch(logIn(userData)); + router.push('/'); + } catch (error) { + if (error instanceof Error) { + type Code = 'USER_NOT_EXIST' | 'INVALID_PASSWORD'; + openModal({ + type: ModalType.ERROR, + message: + errorCodeToMessage[error.message as Code] || errorMessage.error, + }); + } else { + openModal({ + type: ModalType.ERROR, + message: errorMessage.error, + }); + } + } finally { + setSubmitting(false); + } + } + }, + [modalState] + ); + return ( + handleSubmit(data, setSubmitting)} + > + {({ errors, touched, isSubmitting }) => ( +
    +
    +
    + + + +
    +
    + + + +
    +
    +
    +
    + + +
    + 비밀번호 찾기 +
    +
    + +
    +
    + )} +
    + ); +} diff --git a/client/src/app/login/page.tsx b/client/src/app/login/page.tsx index fcc14c75..d7511b67 100644 --- a/client/src/app/login/page.tsx +++ b/client/src/app/login/page.tsx @@ -1,183 +1,46 @@ -'use client'; - -import { useCallback } from 'react'; import Link from 'next/link'; -import { useRouter } from 'next/navigation'; -import { useDispatch, useSelector } from 'react-redux'; -import { logIn } from '@/lib/redux/features/auth/authSlice'; - -// packages -import { Icon } from '@iconify/react'; -import { Formik, Form, Field, ErrorMessage } from 'formik'; -import * as Yup from 'yup'; // components -import { Divider } from '@/components'; - -// service -import { userManager } from '@/service/user'; - -// hooks -import useModal from '@/hooks/modal/useModal'; - -// constant -import { - initialLoginValue, - errorMessage, - errorCodeToMessage, - ModalType, -} from '@/constants/constant'; -import { IReduxState } from '@/types/redux/IReduxState'; - -const ValidationSchema = Yup.object().shape({ - userId: Yup.string().required(errorMessage.blankID), - password: Yup.string().required(errorMessage.blankPassword), -}); - -interface ILogin { - userId: string; - password: string; -} +import Logo from '@/components/Navigator/Logo'; +import LoginForm from './components/LoginForm'; export default function Login() { - const router = useRouter(); - const dispatch = useDispatch(); - - // Modal - const modalState = useSelector((state: IReduxState) => state.modal); - const { openModal } = useModal(); - - const handleSubmit = useCallback( - async (sendData: ILogin, setSubmitting: (value: boolean) => void) => { - if (modalState.type === ModalType.CLOSE) { - setSubmitting(true); - try { - const userData = await userManager.loginUser({ data: sendData }); - dispatch(logIn(userData)); - router.push('/'); - } catch (error) { - if (error instanceof Error) { - type Code = 'USER_NOT_EXIST' | 'INVALID_PASSWORD'; - openModal({ - type: ModalType.ERROR, - message: - errorCodeToMessage[error.message as Code] || errorMessage.error, - }); - } else { - openModal({ - type: ModalType.ERROR, - message: errorMessage.error, - }); - } - } finally { - setSubmitting(false); - } - } - }, - [modalState] - ); return ( -
    -

    로그인

    - - handleSubmit(data, setSubmitting) - } - > - {({ errors, touched, isSubmitting }) => ( -
    - - - - - -
    - - -
    - - 회원가입 - - - - openModal({ - type: ModalType.ERROR, - message: errorMessage.notComplete, - }) - } - > - 비밀번호찾기 - -
    - - )} -
    +
    +
    +
    + +
    +

    + 로그인 +

    + + {/*
    */} + {/* + */} +
    + + 회원가입 + +
    +
    ); } From d19fbeb9468f7bb8f876b6f50c9da4df5bd7bf63 Mon Sep 17 00:00:00 2001 From: Im-younique Date: Mon, 3 Jun 2024 16:47:48 +0900 Subject: [PATCH 04/22] =?UTF-8?q?[feat]=20=EB=B9=84=EB=B0=80=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EB=B3=B4=EA=B8=B0=20=EA=B8=B0=EB=8A=A5=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 --- .../app/login/components/LoginForm/index.tsx | 39 +++++++++++----- client/src/assets/Icon/eye_off.tsx | 45 +++++++++++++++++++ client/src/assets/Icon/eye_on.tsx | 29 ++++++++++++ client/src/assets/Icon/index.ts | 2 + 4 files changed, 104 insertions(+), 11 deletions(-) create mode 100644 client/src/assets/Icon/eye_off.tsx create mode 100644 client/src/assets/Icon/eye_on.tsx diff --git a/client/src/app/login/components/LoginForm/index.tsx b/client/src/app/login/components/LoginForm/index.tsx index 2d96aa42..ca57d075 100644 --- a/client/src/app/login/components/LoginForm/index.tsx +++ b/client/src/app/login/components/LoginForm/index.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useCallback } from 'react'; +import { useState, useCallback } from 'react'; import { useRouter } from 'next/navigation'; //redux @@ -10,6 +10,9 @@ import { logIn } from '@/lib/redux/features/auth/authSlice'; //hooks import useModal from '@/hooks/modal/useModal'; +//icons +import { EyeOnIcon, EyeOffIcon } from '@/assets/Icon'; + //formik import { Formik, Form, Field, ErrorMessage } from 'formik'; import * as Yup from 'yup'; @@ -24,6 +27,8 @@ import { errorCodeToMessage, ModalType, } from '@/constants/constant'; + +//types import { IReduxState } from '@/types/redux/IReduxState'; const ValidationSchema = Yup.object().shape({ @@ -37,6 +42,8 @@ interface ILogin { } export default function LoginForm() { + const [viewPassword, setViewPassword] = useState(false); + const dispatch = useDispatch(); const router = useRouter(); @@ -105,16 +112,26 @@ export default function LoginForm() { - +
    + +
    setViewPassword((prev) => !prev)} + > + {viewPassword ? : } +
    +
    ) { + return ( + + + + + + + ); +} diff --git a/client/src/assets/Icon/eye_on.tsx b/client/src/assets/Icon/eye_on.tsx new file mode 100644 index 00000000..5bb59370 --- /dev/null +++ b/client/src/assets/Icon/eye_on.tsx @@ -0,0 +1,29 @@ +import { SVGProps } from 'react'; + +export default function EyeOnIcon(props: SVGProps) { + return ( + + + + + ); +} diff --git a/client/src/assets/Icon/index.ts b/client/src/assets/Icon/index.ts index 7425cd5d..01084dec 100644 --- a/client/src/assets/Icon/index.ts +++ b/client/src/assets/Icon/index.ts @@ -17,3 +17,5 @@ export { default as LinkIcon } from './link'; export { default as ImageIcon } from './image'; export { default as ListIcon } from './list'; export { default as NumberListIcon } from './number-list'; +export { default as EyeOnIcon } from './eye_on'; +export { default as EyeOffIcon } from './eye_off'; From dc2d6b275e4ca94e6c726cf72970a1a4825e3518 Mon Sep 17 00:00:00 2001 From: Im-younique Date: Mon, 3 Jun 2024 18:53:02 +0900 Subject: [PATCH 05/22] =?UTF-8?q?[chore]=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20UI=20=EC=99=84=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/GithubLoginButton/index.tsx | 18 +++++++++++ .../components/GoogleLoginButton/index.tsx | 18 +++++++++++ .../app/login/components/LoginForm/index.tsx | 9 ++++-- client/src/app/login/page.tsx | 31 +++++++------------ 4 files changed, 54 insertions(+), 22 deletions(-) create mode 100644 client/src/app/login/components/GithubLoginButton/index.tsx create mode 100644 client/src/app/login/components/GoogleLoginButton/index.tsx diff --git a/client/src/app/login/components/GithubLoginButton/index.tsx b/client/src/app/login/components/GithubLoginButton/index.tsx new file mode 100644 index 00000000..77fe811f --- /dev/null +++ b/client/src/app/login/components/GithubLoginButton/index.tsx @@ -0,0 +1,18 @@ +'use client'; + +import { Icon } from '@iconify/react'; + +export default function GithubLoginButton() { + return ( +
    + +
    + ); +} diff --git a/client/src/app/login/components/GoogleLoginButton/index.tsx b/client/src/app/login/components/GoogleLoginButton/index.tsx new file mode 100644 index 00000000..b6ef43e6 --- /dev/null +++ b/client/src/app/login/components/GoogleLoginButton/index.tsx @@ -0,0 +1,18 @@ +'use client'; + +import { Icon } from '@iconify/react'; + +export default function GoogleLoginButton() { + return ( +
    + +
    + ); +} diff --git a/client/src/app/login/components/LoginForm/index.tsx b/client/src/app/login/components/LoginForm/index.tsx index ca57d075..b1927d6f 100644 --- a/client/src/app/login/components/LoginForm/index.tsx +++ b/client/src/app/login/components/LoginForm/index.tsx @@ -142,11 +142,16 @@ export default function LoginForm() {
    -
    - 비밀번호 찾기 + + 비밀번호 찾기 +
    - */} -
    +
    + + +
    + + {"아직 '리덕'회원이 아니신가요?"} + - 회원가입 + 회원가입 하기
    From 8eec5aaba8c8e37736a08e649e13aa8d493e6e96 Mon Sep 17 00:00:00 2001 From: Im-younique Date: Mon, 3 Jun 2024 21:51:52 +0900 Subject: [PATCH 06/22] =?UTF-8?q?[chore]=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=8A=A4=ED=83=80=EC=9D=BC=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 --- client/public/images/check.png | Bin 0 -> 188 bytes .../src/app/login/components/LoginForm/index.tsx | 14 +++++++++----- client/src/app/login/layout.tsx | 10 ---------- client/src/app/login/page.tsx | 6 +++--- 4 files changed, 12 insertions(+), 18 deletions(-) create mode 100644 client/public/images/check.png delete mode 100644 client/src/app/login/layout.tsx diff --git a/client/public/images/check.png b/client/public/images/check.png new file mode 100644 index 0000000000000000000000000000000000000000..a70c0a5b98ac6ff5a7c6502f51be524e198b65be GIT binary patch literal 188 zcmeAS@N?(olHy`uVBq!ia0vp@K+MI#1|;*}T{!}zI14-?iy0WWg+Z8+Vb&Z8pde#$ zkh>GZx^prwfgF}}M_)$E)e-c@N{6J3^$B+ufsb{%485DR}0+b~VYM9MF+mpni zJg2KmUg9>N%dvNc&qWvoew}`N{foKAjFVvj^So<2!W^<4wKi~Zs;e-ug$Wu2u*qL( e=B`?KnW2+w`$@U44Lg8_GkCiCxvX
    -
    - +
    +
    - + 비밀번호 찾기
    -
    +
    - + + openModal({ + type: ModalType.ERROR, + message: errorMessage.notComplete, + }) + } + > 비밀번호 찾기
    From 00269fc91a0f05c7da827e1107f0b17bb82af1e5 Mon Sep 17 00:00:00 2001 From: Im-younique Date: Wed, 5 Jun 2024 12:06:25 +0900 Subject: [PATCH 09/22] =?UTF-8?q?[feat]=20useClickAway=20Custom=20hook=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 --- client/src/hooks/common/useClickAway.ts | 37 +++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 client/src/hooks/common/useClickAway.ts diff --git a/client/src/hooks/common/useClickAway.ts b/client/src/hooks/common/useClickAway.ts new file mode 100644 index 00000000..dccee344 --- /dev/null +++ b/client/src/hooks/common/useClickAway.ts @@ -0,0 +1,37 @@ +import { useEffect, useRef } from 'react'; + +const events: Array<'mousedown' | 'touchstart'> = ['mousedown', 'touchstart']; + +type ClickEvent = MouseEvent | TouchEvent; + +const useClickAway = (handler: (e: ClickEvent) => void) => { + const ref = useRef(null); + const saveHandler = useRef(handler); + + useEffect(() => { + saveHandler.current = handler; + }, [handler]); + + useEffect(() => { + const element = ref.current; + if (!element) return; + + const handleEvent = (e: ClickEvent) => { + !element.contains(e.target as HTMLElement) && saveHandler.current(e); + }; + + for (const eventName of events) { + document.addEventListener(eventName, handleEvent); + } + + return () => { + for (const eventName of events) { + document.removeEventListener(eventName, handleEvent); + } + }; + }, [ref]); + + return ref; +}; + +export default useClickAway; From 0dbfa1052f6ba633608aecb537c955d6d0421f7a Mon Sep 17 00:00:00 2001 From: Im-younique Date: Thu, 6 Jun 2024 17:01:05 +0900 Subject: [PATCH 10/22] =?UTF-8?q?[chore]=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20store=20=ED=8C=8C=EC=9D=BC=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/lib/redux/store/index.ts | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 client/src/lib/redux/store/index.ts diff --git a/client/src/lib/redux/store/index.ts b/client/src/lib/redux/store/index.ts deleted file mode 100644 index 96a1723b..00000000 --- a/client/src/lib/redux/store/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -'use client'; -import { Action, ThunkAction, configureStore } from '@reduxjs/toolkit'; -import { reducer } from '../features'; -import { createWrapper } from 'next-redux-wrapper'; - -const makeStore = () => - configureStore({ - reducer, - middleware: (getDefaultMiddleware) => - getDefaultMiddleware({ serializableCheck: false }), - }); - -export type RootStore = ReturnType; -export type RootState = ReturnType; -export type RootThunk = ThunkAction< - ReturnType, - RootState, - unknown, - Action ->; - -export const wrapper = createWrapper(makeStore); From 9cda4d90af5cfaf16ba558c00513aa50e4459511 Mon Sep 17 00:00:00 2001 From: Im-younique Date: Thu, 6 Jun 2024 17:02:40 +0900 Subject: [PATCH 11/22] =?UTF-8?q?[chore]=20app-router=20=EC=9D=B4=EC=A0=84?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=A5=B8=20next-redux-wrapper=20=ED=8C=A8?= =?UTF-8?q?=ED=82=A4=EC=A7=80=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/package.json | 1 - client/yarn.lock | 5 ----- 2 files changed, 6 deletions(-) diff --git a/client/package.json b/client/package.json index 93fa6a9a..bd355ee1 100644 --- a/client/package.json +++ b/client/package.json @@ -35,7 +35,6 @@ "isomorphic-dompurify": "^2.2.0", "lowlight": "^3.1.0", "next": "^14.0.4", - "next-redux-wrapper": "^8.1.0", "openai": "^4.8.0", "postcss-nesting": "^12.0.1", "react": "^18.2.0", diff --git a/client/yarn.lock b/client/yarn.lock index 077eb7aa..e15f62b3 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -7992,11 +7992,6 @@ neo-async@^2.5.0, neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -next-redux-wrapper@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/next-redux-wrapper/-/next-redux-wrapper-8.1.0.tgz#d9c135f1ceeb2478375bdacd356eb9db273d3a07" - integrity sha512-2hIau0hcI6uQszOtrvAFqgc0NkZegKYhBB7ZAKiG3jk7zfuQb4E7OV9jfxViqqojh3SEHdnFfPkN9KErttUKuw== - next@^14.0.4: version "14.0.4" resolved "https://registry.yarnpkg.com/next/-/next-14.0.4.tgz#bf00b6f835b20d10a5057838fa2dfced1d0d84dc" From 81fc2dbe61395d063139b37c6f777c7e7f3380e7 Mon Sep 17 00:00:00 2001 From: Im-younique Date: Fri, 7 Jun 2024 14:30:24 +0900 Subject: [PATCH 12/22] =?UTF-8?q?[Add]=20redux-persist=20=ED=8C=A8?= =?UTF-8?q?=ED=82=A4=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/package.json | 1 + client/yarn.lock | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/client/package.json b/client/package.json index bd355ee1..ed5d9722 100644 --- a/client/package.json +++ b/client/package.json @@ -41,6 +41,7 @@ "react-dom": "^18.2.0", "react-error-boundary": "^4.0.11", "react-redux": "^8.0.5", + "redux-persist": "^6.0.0", "socketjs-client": "^1.0.2", "tiptap-extension-resize-image": "^1.0.2", "typescript": "5.0.2", diff --git a/client/yarn.lock b/client/yarn.lock index e15f62b3..3a0d9dd4 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -9405,6 +9405,11 @@ redux-devtools-extension@^2.13.9: resolved "https://registry.yarnpkg.com/redux-devtools-extension/-/redux-devtools-extension-2.13.9.tgz#6b764e8028b507adcb75a1cae790f71e6be08ae7" integrity sha512-cNJ8Q/EtjhQaZ71c8I9+BPySIBVEKssbPpskBfsXqb8HJ002A3KRVHfeRzwRo6mGPqsm7XuHTqNSNeS1Khig0A== +redux-persist@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-6.0.0.tgz#b4d2972f9859597c130d40d4b146fecdab51b3a8" + integrity sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ== + redux-thunk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.2.tgz#b9d05d11994b99f7a91ea223e8b04cf0afa5ef3b" From 29843a0c3f4f3b5cb70bb5944aedd1571162e189 Mon Sep 17 00:00:00 2001 From: Im-younique Date: Fri, 7 Jun 2024 14:45:20 +0900 Subject: [PATCH 13/22] =?UTF-8?q?[feat]=20redux-persist=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9=20(auth)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/app/StoreProvider.tsx | 11 +++++++++-- client/src/lib/redux/store.ts | 15 ++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/client/src/app/StoreProvider.tsx b/client/src/app/StoreProvider.tsx index c858b8cd..a2e6ff19 100644 --- a/client/src/app/StoreProvider.tsx +++ b/client/src/app/StoreProvider.tsx @@ -2,7 +2,8 @@ import { useRef } from 'react'; import { Provider } from 'react-redux'; -import { makeStore, AppStore, store } from '../lib/redux/store'; +import { makeStore, AppStore, store, persistor } from '../lib/redux/store'; +import { PersistGate } from 'redux-persist/integration/react'; export default function StoreProvider({ children, @@ -15,5 +16,11 @@ export default function StoreProvider({ storeRef.current = makeStore(); } - return {children}; + return ( + + + {children} + + + ); } diff --git a/client/src/lib/redux/store.ts b/client/src/lib/redux/store.ts index 8e0a3c4f..07c4470e 100644 --- a/client/src/lib/redux/store.ts +++ b/client/src/lib/redux/store.ts @@ -1,14 +1,27 @@ import { configureStore } from '@reduxjs/toolkit'; import { reducer } from './features/index'; +//redux-persist +import { persistStore, persistReducer } from 'redux-persist'; +import storage from 'redux-persist/lib/storage'; + +const persistConfig = { + key: 'root', + storage, + whitelist: ['auth'], +}; + +const persistedReducer = persistReducer(persistConfig, reducer); + export const makeStore = () => { return configureStore({ - reducer, + reducer: persistedReducer, middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: false }), }); }; export const store = makeStore(); +export const persistor = persistStore(store); export type AppStore = ReturnType; From 3e1b4ca47cb9cbec5b4aad46826e656697344e83 Mon Sep 17 00:00:00 2001 From: Im-younique Date: Fri, 7 Jun 2024 14:52:39 +0900 Subject: [PATCH 14/22] =?UTF-8?q?[feat]=20Navigator=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20=EC=B2=B4=ED=81=AC=20=EB=A1=9C=EC=A7=81=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 --- .../components/Navigator/NavigatorBottom.tsx | 40 +++++++++++++++ .../src/components/Navigator/NavigatorTop.tsx | 43 ++++++++++++++++ client/src/components/Navigator/index.tsx | 49 +++++-------------- .../src/hooks/common/useClientLoginCheck.ts | 19 +++++++ .../src/hooks/common/useServerLoginCheck.ts | 20 ++++++++ 5 files changed, 134 insertions(+), 37 deletions(-) create mode 100644 client/src/components/Navigator/NavigatorBottom.tsx create mode 100644 client/src/components/Navigator/NavigatorTop.tsx create mode 100644 client/src/hooks/common/useClientLoginCheck.ts create mode 100644 client/src/hooks/common/useServerLoginCheck.ts diff --git a/client/src/components/Navigator/NavigatorBottom.tsx b/client/src/components/Navigator/NavigatorBottom.tsx new file mode 100644 index 00000000..6caf3ed5 --- /dev/null +++ b/client/src/components/Navigator/NavigatorBottom.tsx @@ -0,0 +1,40 @@ +'use client'; + +//components +import Button from '../base/Button'; +import PostModeNavigation from './PostModeNavigation'; + +//hooks +import useClientLoginCheck from '@/hooks/common/useClientLoginCheck'; + +//icons +import { ArrowDownIcon } from '@/assets/Icon'; + +//types +import { PostViewType } from '@/types'; + +interface IProps { + viewMode?: PostViewType; + initialUserLogin: boolean; +} + +export default function NavigatorBottom({ + viewMode, + initialUserLogin, +}: IProps) { + const userLogin = useClientLoginCheck(initialUserLogin); + + return ( +
    +
    + + {userLogin && ( + + )} +
    +
    + ); +} diff --git a/client/src/components/Navigator/NavigatorTop.tsx b/client/src/components/Navigator/NavigatorTop.tsx new file mode 100644 index 00000000..c438c5d5 --- /dev/null +++ b/client/src/components/Navigator/NavigatorTop.tsx @@ -0,0 +1,43 @@ +'use client'; + +//components +import Logo from './Logo'; +import SearchButton from './SearchButton'; +import AlarmButton from './AlarmButton'; +import ChatButton from './ChatButton'; +import ProfileButton from './ProfileButton'; + +//hooks +import useClientLoginCheck from '@/hooks/common/useClientLoginCheck'; + +interface IProps { + initialUserLogin: boolean; +} + +export default function NavigatorTop({ initialUserLogin }: IProps) { + const userLogin = useClientLoginCheck(initialUserLogin); + + return ( +
    + +
    +
      +
    • + +
    • + {userLogin && ( + <> +
    • + +
    • +
    • + +
    • + + )} +
    + +
    +
    + ); +} diff --git a/client/src/components/Navigator/index.tsx b/client/src/components/Navigator/index.tsx index 0f3f7212..accefc7a 100644 --- a/client/src/components/Navigator/index.tsx +++ b/client/src/components/Navigator/index.tsx @@ -1,14 +1,9 @@ //components -import Button from '../base/Button'; -import SearchButton from './SearchButton'; -import ChatButton from './ChatButton'; -import AlarmButton from './AlarmButton'; -import ProfileButton from './ProfileButton'; -import PostModeNavigation from './PostModeNavigation'; -import Logo from './Logo'; +import NavigatorTop from './NavigatorTop'; +import NavigatorBottom from './NavigatorBottom'; -//icons -import { ArrowDownIcon } from '@/assets/Icon'; +//hooks +import useServerLoginCheck from '@/hooks/common/useServerLoginCheck'; //types import { PostViewType } from '@/types'; @@ -16,37 +11,17 @@ import { PostViewType } from '@/types'; interface NavitatorProps { viewMode?: PostViewType; } -export default function Navigator({ viewMode }: NavitatorProps) { +export default async function Navigator({ viewMode }: NavitatorProps) { + const initialUserLogin = useServerLoginCheck(); + return (
    -
    - -
    -
      -
    • - -
    • -
    • - -
    • -
    • - -
    • -
    - -
    -
    - -
    -
    - - -
    -
    + +
    ); diff --git a/client/src/hooks/common/useClientLoginCheck.ts b/client/src/hooks/common/useClientLoginCheck.ts new file mode 100644 index 00000000..49cea932 --- /dev/null +++ b/client/src/hooks/common/useClientLoginCheck.ts @@ -0,0 +1,19 @@ +import { useState, useEffect } from 'react'; + +//redux +import { useSelector } from 'react-redux'; +import { selectUser } from '@/lib/redux/features/auth/authSlice'; + +const useClientLoginCheck = (initialUserLogin: boolean) => { + const [userLogin, setUserLogin] = useState(initialUserLogin); + + const user = useSelector(selectUser); + + useEffect(() => { + setUserLogin(!!user.userId); + }, [user]); + + return userLogin; +}; + +export default useClientLoginCheck; diff --git a/client/src/hooks/common/useServerLoginCheck.ts b/client/src/hooks/common/useServerLoginCheck.ts new file mode 100644 index 00000000..c34a73c8 --- /dev/null +++ b/client/src/hooks/common/useServerLoginCheck.ts @@ -0,0 +1,20 @@ +'use server'; + +import { cookies } from 'next/headers'; + +const useServerLoginCheck = () => { + const cookieStore = cookies(); + const token = cookieStore.get('token')?.value; + + let initialUserLogin = null; + + if (token) { + initialUserLogin = true; + } else { + initialUserLogin = false; + } + + return initialUserLogin; +}; + +export default useServerLoginCheck; From 251738da0dfc7e2ccb9c617d2ca37aa91ed61b8d Mon Sep 17 00:00:00 2001 From: Im-younique Date: Fri, 7 Jun 2024 15:01:04 +0900 Subject: [PATCH 15/22] =?UTF-8?q?[fix]=20redux-persist=20=EC=84=9C?= =?UTF-8?q?=EB=B2=84=EC=82=AC=EC=9D=B4=EB=93=9C=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/lib/redux/store.ts | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/client/src/lib/redux/store.ts b/client/src/lib/redux/store.ts index 07c4470e..07cb2e9a 100644 --- a/client/src/lib/redux/store.ts +++ b/client/src/lib/redux/store.ts @@ -3,7 +3,26 @@ import { reducer } from './features/index'; //redux-persist import { persistStore, persistReducer } from 'redux-persist'; -import storage from 'redux-persist/lib/storage'; +import createWebStorage from 'redux-persist/lib/storage/createWebStorage'; + +const createNoopStorage = () => { + return { + getItem() { + return Promise.resolve(null); + }, + setItem(value: string) { + return Promise.resolve(value); + }, + removeItem() { + return Promise.resolve(); + }, + }; +}; + +const storage = + typeof window === 'undefined' + ? createNoopStorage() + : createWebStorage('local'); const persistConfig = { key: 'root', From 00c45c787018d869487f88476e92e4154e8c166a Mon Sep 17 00:00:00 2001 From: Im-younique Date: Fri, 7 Jun 2024 15:02:19 +0900 Subject: [PATCH 16/22] =?UTF-8?q?[chore]=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20async=20=ED=95=A8=EC=88=98=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/Navigator/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/components/Navigator/index.tsx b/client/src/components/Navigator/index.tsx index accefc7a..4507d5f7 100644 --- a/client/src/components/Navigator/index.tsx +++ b/client/src/components/Navigator/index.tsx @@ -11,7 +11,7 @@ import { PostViewType } from '@/types'; interface NavitatorProps { viewMode?: PostViewType; } -export default async function Navigator({ viewMode }: NavitatorProps) { +export default function Navigator({ viewMode }: NavitatorProps) { const initialUserLogin = useServerLoginCheck(); return ( From be95496521b303a66348d0ee6ec59fff2c63ca1c Mon Sep 17 00:00:00 2001 From: Im-younique Date: Fri, 7 Jun 2024 15:18:29 +0900 Subject: [PATCH 17/22] =?UTF-8?q?[chore]=20=EB=B9=84=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=EC=8B=9C=20=EB=84=A4=EB=B9=84=EA=B2=8C=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/Navigator/NavigatorTop.tsx | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/client/src/components/Navigator/NavigatorTop.tsx b/client/src/components/Navigator/NavigatorTop.tsx index c438c5d5..b08a23be 100644 --- a/client/src/components/Navigator/NavigatorTop.tsx +++ b/client/src/components/Navigator/NavigatorTop.tsx @@ -1,11 +1,14 @@ 'use client'; +import Link from 'next/link'; + //components import Logo from './Logo'; import SearchButton from './SearchButton'; import AlarmButton from './AlarmButton'; import ChatButton from './ChatButton'; import ProfileButton from './ProfileButton'; +import Button from '../base/Button'; //hooks import useClientLoginCheck from '@/hooks/common/useClientLoginCheck'; @@ -36,7 +39,18 @@ export default function NavigatorTop({ initialUserLogin }: IProps) { )}
- + {userLogin ? ( + + ) : ( +
+ + + + + + +
+ )}
); From 403f02a7bcce81d457a2c5df4ce7cb22b62c57dd Mon Sep 17 00:00:00 2001 From: Im-younique Date: Fri, 7 Jun 2024 16:17:26 +0900 Subject: [PATCH 18/22] =?UTF-8?q?[feat]=20Dropdown=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/Dropdown/Content/index.tsx | 14 ++++++++ .../src/components/Dropdown/Wrapper/index.tsx | 35 +++++++++++++++++++ client/src/components/Dropdown/index.tsx | 9 +++++ client/src/components/index.tsx | 1 + 4 files changed, 59 insertions(+) create mode 100644 client/src/components/Dropdown/Content/index.tsx create mode 100644 client/src/components/Dropdown/Wrapper/index.tsx create mode 100644 client/src/components/Dropdown/index.tsx diff --git a/client/src/components/Dropdown/Content/index.tsx b/client/src/components/Dropdown/Content/index.tsx new file mode 100644 index 00000000..20498272 --- /dev/null +++ b/client/src/components/Dropdown/Content/index.tsx @@ -0,0 +1,14 @@ +import { HTMLAttributes } from 'react'; + +const DropdownContent = (props: HTMLAttributes) => { + return ( +
+ {props.children} +
+ ); +}; + +export default DropdownContent; diff --git a/client/src/components/Dropdown/Wrapper/index.tsx b/client/src/components/Dropdown/Wrapper/index.tsx new file mode 100644 index 00000000..5afd5703 --- /dev/null +++ b/client/src/components/Dropdown/Wrapper/index.tsx @@ -0,0 +1,35 @@ +'use client'; + +import { PropsWithChildren } from 'react'; + +// hooks +import useClickAway from '@/hooks/common/useClickAway'; + +interface IProps extends PropsWithChildren { + setDropdownOpen: (value: boolean) => void; + position?: string; +} + +const DropdownWrapper = ({ setDropdownOpen, children, position }: IProps) => { + const ref = useClickAway((e) => { + if (!ref.current || !ref.current.parentNode) { + return; + } + if (!ref.current.parentNode.contains(e.target as HTMLElement)) { + setDropdownOpen(false); + } + }); + + const DROPDOWN_POSITION = position || 'right-0 -bottom-24'; + + return ( +
+ {children} +
+ ); +}; + +export default DropdownWrapper; diff --git a/client/src/components/Dropdown/index.tsx b/client/src/components/Dropdown/index.tsx new file mode 100644 index 00000000..3fa017ab --- /dev/null +++ b/client/src/components/Dropdown/index.tsx @@ -0,0 +1,9 @@ +import DropdownWrapper from './Wrapper'; +import DropdownContent from './Content'; + +const Dropdown = { + Wrapper: DropdownWrapper, + Content: DropdownContent, +}; + +export default Dropdown; diff --git a/client/src/components/index.tsx b/client/src/components/index.tsx index 321462ee..d8fc8dc1 100644 --- a/client/src/components/index.tsx +++ b/client/src/components/index.tsx @@ -13,3 +13,4 @@ export { default as Form } from './Form'; export { default as Alert } from './Alert'; export { default as Button } from './base/Button'; export { default as Tooltip } from './Tooltip'; +export { default as Dropdown } from './Dropdown'; From 251a47528baa4bc68f951340cd4d93f96ad1c0c5 Mon Sep 17 00:00:00 2001 From: Im-younique Date: Fri, 7 Jun 2024 16:30:30 +0900 Subject: [PATCH 19/22] =?UTF-8?q?[feat]=20ProfileButton=EB=82=B4=20Dropdow?= =?UTF-8?q?n=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/Navigator/ProfileButton.tsx | 82 ++++++++++++++----- 1 file changed, 61 insertions(+), 21 deletions(-) diff --git a/client/src/components/Navigator/ProfileButton.tsx b/client/src/components/Navigator/ProfileButton.tsx index f1fbc201..eccbf0a9 100644 --- a/client/src/components/Navigator/ProfileButton.tsx +++ b/client/src/components/Navigator/ProfileButton.tsx @@ -1,41 +1,81 @@ 'use client'; +import { useState } from 'react'; import Link from 'next/link'; +import { useRouter } from 'next/navigation'; // redux -import { useSelector } from 'react-redux'; +import { useSelector, useDispatch } from 'react-redux'; +import { selectUser } from '@/lib/redux/features/auth/authSlice'; +import { logOut } from '@/lib/redux/features/auth/authSlice'; // components -import { Avatar } from '../'; +import { Avatar, Dropdown } from '../'; + +// hooks +import useModal from '@/hooks/modal/useModal'; // icons import { ProfileIcon } from '@/assets/Icon'; -// types -import { IReduxState } from '@/types/redux/IReduxState'; - // services import { BASE_URL } from '@/service/base/api'; +import { userManager } from '@/service/user'; + +// types +import { ModalType, errorMessage } from '@/constants/constant'; export default function ProfileButton() { - const user = useSelector((state: IReduxState) => state.auth); + const user = useSelector(selectUser); + const dispatch = useDispatch(); + + const router = useRouter(); + + const { openModal } = useModal(); + + const [dropdownOpen, setDropdownOpen] = useState(false); + + const handleLogout = async () => { + try { + await userManager.logoutUser(); + dispatch(logOut()); + router.replace('/'); + } catch { + openModal({ + type: ModalType.ERROR, + message: errorMessage.tryAgain, + }); + } + }; return ( - setDropdownOpen((prev) => !prev)} > - - + {user.userProfileImgPath ? ( + + ) : ( + + )} + {dropdownOpen && ( + + + 내 프로필 + + 임시 글 + 스크랩 게시물 + 설정 + 로그아웃 + + )} + ); } From beff118b4b15478cb732c267e3519b57986d51e8 Mon Sep 17 00:00:00 2001 From: Im-younique Date: Sat, 8 Jun 2024 12:38:56 +0900 Subject: [PATCH 20/22] =?UTF-8?q?[chore]=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=84=B1=EA=B3=B5=EC=8B=9C=20=EB=9D=BC=EC=9A=B0=ED=8C=85=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 --- .../src/app/login/components/LoginForm/index.tsx | 2 +- client/src/components/Navigator/NavigatorTop.tsx | 14 +++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/client/src/app/login/components/LoginForm/index.tsx b/client/src/app/login/components/LoginForm/index.tsx index 0e28add9..24ea0c5a 100644 --- a/client/src/app/login/components/LoginForm/index.tsx +++ b/client/src/app/login/components/LoginForm/index.tsx @@ -61,7 +61,7 @@ export default function LoginForm() { try { const userData = await userManager.loginUser({ data: sendData }); dispatch(logIn(userData)); - router.push('/'); + router.replace(window.sessionStorage.getItem('previousURL') || '/'); } catch (error) { if (error instanceof Error) { type Code = 'USER_NOT_EXIST' | 'INVALID_PASSWORD'; diff --git a/client/src/components/Navigator/NavigatorTop.tsx b/client/src/components/Navigator/NavigatorTop.tsx index b08a23be..bd7dc5bb 100644 --- a/client/src/components/Navigator/NavigatorTop.tsx +++ b/client/src/components/Navigator/NavigatorTop.tsx @@ -1,6 +1,7 @@ 'use client'; import Link from 'next/link'; +import { useRouter } from 'next/navigation'; //components import Logo from './Logo'; @@ -20,6 +21,13 @@ interface IProps { export default function NavigatorTop({ initialUserLogin }: IProps) { const userLogin = useClientLoginCheck(initialUserLogin); + const router = useRouter(); + + const handleLinkToLogin = () => { + window.sessionStorage.setItem('previousURL', window.location.href); + router.push('login'); + }; + return (
@@ -43,9 +51,9 @@ export default function NavigatorTop({ initialUserLogin }: IProps) { ) : (
- - - + From 2ef25077e3a1fe9d51e60498fc6ee2e82a4a45cd Mon Sep 17 00:00:00 2001 From: Im-younique Date: Sat, 8 Jun 2024 12:53:56 +0900 Subject: [PATCH 21/22] =?UTF-8?q?[chore]=20useClickAwayRef=EB=A1=9C=20?= =?UTF-8?q?=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/Dropdown/Wrapper/index.tsx | 4 ++-- .../src/hooks/common/{useClickAway.ts => useClickAwayRef.ts} | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename client/src/hooks/common/{useClickAway.ts => useClickAwayRef.ts} (89%) diff --git a/client/src/components/Dropdown/Wrapper/index.tsx b/client/src/components/Dropdown/Wrapper/index.tsx index 5afd5703..4919a15f 100644 --- a/client/src/components/Dropdown/Wrapper/index.tsx +++ b/client/src/components/Dropdown/Wrapper/index.tsx @@ -3,7 +3,7 @@ import { PropsWithChildren } from 'react'; // hooks -import useClickAway from '@/hooks/common/useClickAway'; +import useClickAwayRef from '@/hooks/common/useClickAwayRef'; interface IProps extends PropsWithChildren { setDropdownOpen: (value: boolean) => void; @@ -11,7 +11,7 @@ interface IProps extends PropsWithChildren { } const DropdownWrapper = ({ setDropdownOpen, children, position }: IProps) => { - const ref = useClickAway((e) => { + const ref = useClickAwayRef((e) => { if (!ref.current || !ref.current.parentNode) { return; } diff --git a/client/src/hooks/common/useClickAway.ts b/client/src/hooks/common/useClickAwayRef.ts similarity index 89% rename from client/src/hooks/common/useClickAway.ts rename to client/src/hooks/common/useClickAwayRef.ts index dccee344..a4a4fc54 100644 --- a/client/src/hooks/common/useClickAway.ts +++ b/client/src/hooks/common/useClickAwayRef.ts @@ -4,7 +4,7 @@ const events: Array<'mousedown' | 'touchstart'> = ['mousedown', 'touchstart']; type ClickEvent = MouseEvent | TouchEvent; -const useClickAway = (handler: (e: ClickEvent) => void) => { +const useClickAwayRef = (handler: (e: ClickEvent) => void) => { const ref = useRef(null); const saveHandler = useRef(handler); @@ -34,4 +34,4 @@ const useClickAway = (handler: (e: ClickEvent) => void) => { return ref; }; -export default useClickAway; +export default useClickAwayRef; From 1dec3929d22f908f423f132edd1fbdf40a93d584 Mon Sep 17 00:00:00 2001 From: Im-younique Date: Sat, 8 Jun 2024 12:57:38 +0900 Subject: [PATCH 22/22] =?UTF-8?q?[chore]=20useServerLoginCheck=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EB=8B=A8=EC=88=9C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/hooks/common/useServerLoginCheck.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/client/src/hooks/common/useServerLoginCheck.ts b/client/src/hooks/common/useServerLoginCheck.ts index c34a73c8..3b3e3abb 100644 --- a/client/src/hooks/common/useServerLoginCheck.ts +++ b/client/src/hooks/common/useServerLoginCheck.ts @@ -6,13 +6,7 @@ const useServerLoginCheck = () => { const cookieStore = cookies(); const token = cookieStore.get('token')?.value; - let initialUserLogin = null; - - if (token) { - initialUserLogin = true; - } else { - initialUserLogin = false; - } + const initialUserLogin = !!token; return initialUserLogin; };