From fa4f70dd634c98f1f6a213a559ddb41f55b18401 Mon Sep 17 00:00:00 2001 From: badahertz52 Date: Mon, 19 Aug 2024 17:53:24 +0900 Subject: [PATCH] =?UTF-8?q?[FE]=20feat=20:=20=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=EC=97=B0=EA=B2=B0=20=ED=8E=98=EC=9D=B4=EC=A7=80=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EB=B9=84=EB=B0=80=EB=B2=88=ED=98=B8=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20api=20=EC=A0=81=EC=9A=A9=20(#436)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: ReviewGroupTestPage 삭제 * fix: PasswordResponse 타입 수정 * refactor: 비밀번호 일치 조회 api 변경에 따른 코드 수정 * chore: PasswordTestPage 삭제 * chore: PasswordModal의 InputContainer 태그 변경 (div-> form) ,button 타입을 submit으로 수정 * style: PasswordModal 스타일 코드 stylelint 적용 * feat : 리뷰 연결 페이지에서 비밀번호 조회 api 적용 * fix:useCheckPasswordValidation의 staleTime 복구 * chore: 비밀번호 조회 endpont 명 변경 * fix: 복수형 상수 네이밍 단수로 수정 - 파일명도 같이 수정 --- frontend/src/apis/endpoints.ts | 7 +-- frontend/src/apis/group.ts | 10 ++-- frontend/src/constants/errorMessage.ts | 4 +- frontend/src/constants/index.ts | 2 +- .../constants/{queryKeys.ts => queryKey.ts} | 2 +- .../src/constants/{routes.ts => route.ts} | 4 +- .../review/useGetDetailedReview/index.ts | 4 +- .../hooks/review/useGetReviewList/index.ts | 6 +- .../useGetDataToWrite/index.ts | 4 +- .../writingCardForm/useMutateReview/index.ts | 4 +- .../useCheckPasswordValidation/index.ts | 9 ++- frontend/src/hooks/useBreadcrumbPaths.ts | 14 ++--- frontend/src/index.tsx | 19 +++---- frontend/src/mocks/handlers/group.ts | 34 ++++++------ .../components/URLGeneratorForm/index.tsx | 4 +- frontend/src/pages/PasswordTestPage.tsx | 55 ------------------- .../components/PasswordModal/index.tsx | 39 ++++++++++--- .../components/PasswordModal/styles.ts | 18 +++--- frontend/src/pages/ReviewZonePage/index.tsx | 10 ++-- frontend/src/types/reviewGroup.ts | 2 +- 20 files changed, 104 insertions(+), 147 deletions(-) rename frontend/src/constants/{queryKeys.ts => queryKey.ts} (91%) rename frontend/src/constants/{routes.ts => route.ts} (72%) delete mode 100644 frontend/src/pages/PasswordTestPage.tsx diff --git a/frontend/src/apis/endpoints.ts b/frontend/src/apis/endpoints.ts index a19b2faf2..cce9ac299 100644 --- a/frontend/src/apis/endpoints.ts +++ b/frontend/src/apis/endpoints.ts @@ -20,8 +20,7 @@ export const REVIEW_WRITING_API_PARAMS = { export const REVIEW_PASSWORD_API_PARAMS = { resource: 'groups', queryString: { - code: 'code', - reviewRequestCode: 'reviewRequestCode', + check: 'check', }, }; @@ -34,7 +33,6 @@ export const REVIEW_GROUP_DATA_API_PARAMS = { }, }; -export const REVIEW_PASSWORD_API_URL = `${process.env.API_BASE_URL}/${VERSION2}/${REVIEW_PASSWORD_API_PARAMS.resource}/${REVIEW_PASSWORD_API_PARAMS.queryString.code}`; export const REVIEW_GROUP_DATA_API_URL = `${process.env.API_BASE_URL}/${VERSION2}/${REVIEW_GROUP_DATA_API_PARAMS.resource}`; const endPoint = { @@ -44,8 +42,7 @@ const endPoint = { `${REVIEW_WRITING_API_URL}/${REVIEW_WRITING_API_PARAMS.queryString.write}?${REVIEW_WRITING_API_PARAMS.queryString.reviewRequestCode}=${reviewRequestCode}`, gettingReviewList: `${process.env.API_BASE_URL}/${VERSION2}/reviews`, postingDataForReviewRequestCode: `${process.env.API_BASE_URL}/${VERSION2}/groups`, - gettingPasswordValidation: (reviewRequestCode: string) => - `${REVIEW_PASSWORD_API_URL}?${REVIEW_PASSWORD_API_PARAMS.queryString.reviewRequestCode}=${reviewRequestCode}`, + checkingPassword: `${process.env.API_BASE_URL}/${VERSION2}/${REVIEW_PASSWORD_API_PARAMS.resource}/${REVIEW_PASSWORD_API_PARAMS.queryString.check}`, gettingReviewGroupData: (reviewRequestCode: string) => `${REVIEW_GROUP_DATA_API_URL}?${REVIEW_GROUP_DATA_API_PARAMS.queryString.reviewRequestCode}=${reviewRequestCode}`, }; diff --git a/frontend/src/apis/group.ts b/frontend/src/apis/group.ts index b97e26594..bfdc6c642 100644 --- a/frontend/src/apis/group.ts +++ b/frontend/src/apis/group.ts @@ -1,3 +1,5 @@ +import { json } from 'react-router'; + import { INVALID_REVIEW_PASSWORD_MESSAGE } from '@/constants'; import { PasswordResponse, ReviewGroupData } from '@/types'; @@ -35,16 +37,16 @@ export interface GetPasswordValidationApiParams { /** * @param groupAccessCode L 비밀번호 */ -export const getPasswordValidationApi = async ({ +export const postPasswordValidationApi = async ({ groupAccessCode, reviewRequestCode, }: GetPasswordValidationApiParams) => { - const response = await fetch(endPoint.gettingPasswordValidation(reviewRequestCode), { - method: 'GET', + const response = await fetch(endPoint.checkingPassword, { + method: 'POST', headers: { 'Content-Type': 'application/json', - GroupAccessCode: groupAccessCode, }, + body: JSON.stringify({ reviewRequestCode, groupAccessCode }), }); //요청 실패 if (response.status === 401) return new Error(INVALID_REVIEW_PASSWORD_MESSAGE); diff --git a/frontend/src/constants/errorMessage.ts b/frontend/src/constants/errorMessage.ts index fcf77b822..80616aaef 100644 --- a/frontend/src/constants/errorMessage.ts +++ b/frontend/src/constants/errorMessage.ts @@ -1,9 +1,9 @@ -interface ApiErrorMessages { +interface ApiErrorMessage { [key: number]: string; serverError: string; } -export const API_ERROR_MESSAGE: ApiErrorMessages = { +export const API_ERROR_MESSAGE: ApiErrorMessage = { 400: '잘못된 요청이에요.', 401: '인증을 실패했어요.', 403: '요청권한이 없어요.', diff --git a/frontend/src/constants/index.ts b/frontend/src/constants/index.ts index 73418fe47..4678c4d2e 100644 --- a/frontend/src/constants/index.ts +++ b/frontend/src/constants/index.ts @@ -1,6 +1,6 @@ export * from './page'; export * from './errorMessage'; export * from './review'; -export * from './queryKeys'; +export * from './queryKey'; export * from './system'; export * from './routerParam'; diff --git a/frontend/src/constants/queryKeys.ts b/frontend/src/constants/queryKey.ts similarity index 91% rename from frontend/src/constants/queryKeys.ts rename to frontend/src/constants/queryKey.ts index be74a173d..e89c803dc 100644 --- a/frontend/src/constants/queryKeys.ts +++ b/frontend/src/constants/queryKey.ts @@ -1,5 +1,5 @@ // TODO: 내용이 배열이 아니므로 단수형으로 수정하기 -export const REVIEW_QUERY_KEYS = { +export const REVIEW_QUERY_KEY = { detailedReview: 'detailedReview', reviews: 'reviews', writingReviewInfo: 'writingReviewInfo', diff --git a/frontend/src/constants/routes.ts b/frontend/src/constants/route.ts similarity index 72% rename from frontend/src/constants/routes.ts rename to frontend/src/constants/route.ts index 36550e6f6..d79e9aed8 100644 --- a/frontend/src/constants/routes.ts +++ b/frontend/src/constants/route.ts @@ -1,5 +1,5 @@ -// TODO: ROUTES -> ROUTE 및 상수 인덱스에 추가하기 -export const ROUTES = { +// TODO: ROUTE -> ROUTE 및 상수 인덱스에 추가하기 +export const ROUTE = { home: '/', reviewList: 'user/review-list', reviewWriting: 'user/review-writing', diff --git a/frontend/src/hooks/review/useGetDetailedReview/index.ts b/frontend/src/hooks/review/useGetDetailedReview/index.ts index bf1ea3b60..e8a440492 100644 --- a/frontend/src/hooks/review/useGetDetailedReview/index.ts +++ b/frontend/src/hooks/review/useGetDetailedReview/index.ts @@ -1,7 +1,7 @@ import { useSuspenseQuery } from '@tanstack/react-query'; import { getDetailedReviewApi } from '@/apis/review'; -import { REVIEW_QUERY_KEYS } from '@/constants'; +import { REVIEW_QUERY_KEY } from '@/constants'; import { DetailReviewData } from '@/types'; interface UseGetDetailedReviewProps { @@ -21,7 +21,7 @@ const useGetDetailedReview = ({ reviewId, groupAccessCode }: UseGetDetailedRevie }; const result = useSuspenseQuery({ - queryKey: [REVIEW_QUERY_KEYS.detailedReview, reviewId], + queryKey: [REVIEW_QUERY_KEY.detailedReview, reviewId], queryFn: () => fetchDetailedReview({ reviewId, groupAccessCode }), }); diff --git a/frontend/src/hooks/review/useGetReviewList/index.ts b/frontend/src/hooks/review/useGetReviewList/index.ts index 606d08a69..ec6cb94d4 100644 --- a/frontend/src/hooks/review/useGetReviewList/index.ts +++ b/frontend/src/hooks/review/useGetReviewList/index.ts @@ -1,17 +1,17 @@ import { useSuspenseQuery } from '@tanstack/react-query'; import { getReviewListApi } from '@/apis/review'; -import { REVIEW_QUERY_KEYS } from '@/constants'; +import { REVIEW_QUERY_KEY } from '@/constants'; const useGetReviewList = (groupAccessCode: string) => { const { data, isLoading, error, isSuccess } = useSuspenseQuery({ - queryKey: [REVIEW_QUERY_KEYS.reviews], + queryKey: [REVIEW_QUERY_KEY.reviews], queryFn: () => getReviewListApi(groupAccessCode), }); // NOTE: 무한스크롤 관련 코드 일단 주석 처리 // const { data, fetchNextPage, hasNextPage, isLoading, error } = useInfiniteQuery({ - // queryKey: [REVIEW_QUERY_KEYS.reviews], + // queryKey: [REVIEW_QUERY_KEY.reviews], // queryFn: ({ pageParam }) => getReviewListApi(pageParam), // initialPageParam: GROUP_ACCESS_CODE, // getNextPageParam: (data) => { diff --git a/frontend/src/hooks/review/writingCardForm/useGetDataToWrite/index.ts b/frontend/src/hooks/review/writingCardForm/useGetDataToWrite/index.ts index 51a499e73..3683a48f0 100644 --- a/frontend/src/hooks/review/writingCardForm/useGetDataToWrite/index.ts +++ b/frontend/src/hooks/review/writingCardForm/useGetDataToWrite/index.ts @@ -1,7 +1,7 @@ import { useSuspenseQuery } from '@tanstack/react-query'; import { getDataToWriteReviewApi } from '@/apis/review'; -import { REVIEW_QUERY_KEYS } from '@/constants'; +import { REVIEW_QUERY_KEY } from '@/constants'; import { ReviewWritingFrom } from '@/types'; interface UseGetDataToWriteProps { @@ -16,7 +16,7 @@ const useGetDataToWrite = ({ reviewRequestCode }: UseGetDataToWriteProps) => { }; const result = useSuspenseQuery({ - queryKey: [REVIEW_QUERY_KEYS.writingReviewInfo, reviewRequestCode], + queryKey: [REVIEW_QUERY_KEY.writingReviewInfo, reviewRequestCode], queryFn: () => fetchReviewFormData(reviewRequestCode), }); diff --git a/frontend/src/hooks/review/writingCardForm/useMutateReview/index.ts b/frontend/src/hooks/review/writingCardForm/useMutateReview/index.ts index 686ab889c..b49f8d8fc 100644 --- a/frontend/src/hooks/review/writingCardForm/useMutateReview/index.ts +++ b/frontend/src/hooks/review/writingCardForm/useMutateReview/index.ts @@ -1,7 +1,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { postReviewApi } from '@/apis/review'; -import { REVIEW_QUERY_KEYS } from '@/constants'; +import { REVIEW_QUERY_KEY } from '@/constants'; import { ReviewWritingFormResult } from '@/types'; interface UseMutateReviewProps { @@ -13,7 +13,7 @@ const useMutateReview = ({ executeAfterMutateSuccess }: UseMutateReviewProps) => const reviewMutation = useMutation({ mutationFn: (formResult: ReviewWritingFormResult) => postReviewApi(formResult), onSuccess: () => { - queryClient.invalidateQueries({ queryKey: [REVIEW_QUERY_KEYS.postReview] }); + queryClient.invalidateQueries({ queryKey: [REVIEW_QUERY_KEY.postReview] }); executeAfterMutateSuccess(); }, }); diff --git a/frontend/src/hooks/reviewGroup/useCheckPasswordValidation/index.ts b/frontend/src/hooks/reviewGroup/useCheckPasswordValidation/index.ts index ee2c40106..664206846 100644 --- a/frontend/src/hooks/reviewGroup/useCheckPasswordValidation/index.ts +++ b/frontend/src/hooks/reviewGroup/useCheckPasswordValidation/index.ts @@ -1,7 +1,7 @@ import { useQuery } from '@tanstack/react-query'; import { useEffect } from 'react'; -import { getPasswordValidationApi, GetPasswordValidationApiParams } from '@/apis/group'; +import { postPasswordValidationApi, GetPasswordValidationApiParams } from '@/apis/group'; import { GROUP_QUERY_KEY, INVALID_REVIEW_PASSWORD_MESSAGE } from '@/constants'; import { PasswordResponse } from '@/types'; @@ -22,16 +22,15 @@ const useCheckPasswordValidation = ({ onError, }: UseCheckPasswordValidationProps) => { const fetchPasswordValidation = async (params: GetPasswordValidationApiParams) => { - const result = await getPasswordValidationApi(params); - + const result = await postPasswordValidationApi(params); return result; }; const result = useQuery({ queryKey: [GROUP_QUERY_KEY.password, groupAccessCode, reviewRequestCode], queryFn: () => fetchPasswordValidation({ groupAccessCode, reviewRequestCode }), - staleTime: 1000 * 60 * 5, enabled: !!groupAccessCode && !!reviewRequestCode, + staleTime: 1000 * 60 * 5, }); /** @@ -49,7 +48,7 @@ const useCheckPasswordValidation = ({ // case2 요청 성공 // data 속 비밀번호 유효성 여부에 따른 액션 // 2-1 유효하지 않은 비밀번호 - if (!data?.isValidAccess) { + if (!data?.hasAccess) { return onError(new Error(INVALID_REVIEW_PASSWORD_MESSAGE)); } // 2-2 유효한 비밀번호 diff --git a/frontend/src/hooks/useBreadcrumbPaths.ts b/frontend/src/hooks/useBreadcrumbPaths.ts index c9d95bc98..98df90789 100644 --- a/frontend/src/hooks/useBreadcrumbPaths.ts +++ b/frontend/src/hooks/useBreadcrumbPaths.ts @@ -1,30 +1,30 @@ import { useLocation } from 'react-router-dom'; import { Path } from '@/components/common/Breadcrumb'; -import { ROUTES } from '@/constants/routes'; +import { ROUTE } from '@/constants/route'; const useBreadcrumbPaths = () => { const { pathname } = useLocation(); const breadcrumbPathList: Path[] = [ - { pageName: '연결 페이지', path: ROUTES.home }, // TODO: 연결 페이지 경로 결정되면 수정 필요 + { pageName: '연결 페이지', path: ROUTE.home }, // TODO: 연결 페이지 경로 결정되면 수정 필요 ]; - if (pathname === `/${ROUTES.reviewList}`) { + if (pathname === `/${ROUTE.reviewList}`) { breadcrumbPathList.push({ pageName: '목록 페이지', path: pathname }); } - if (pathname.includes(`/${ROUTES.reviewWriting}/`)) { + if (pathname.includes(`/${ROUTE.reviewWriting}/`)) { breadcrumbPathList.push({ pageName: '작성 페이지', path: pathname }); } - if (pathname === `/${ROUTES.reviewWritingComplete}`) { + if (pathname === `/${ROUTE.reviewWritingComplete}`) { breadcrumbPathList.push({ pageName: '작성 페이지', path: -1 }, { pageName: '작성 완료 페이지', path: pathname }); } - if (pathname.includes(ROUTES.detailedReview)) { + if (pathname.includes(ROUTE.detailedReview)) { breadcrumbPathList.push( - { pageName: '목록 페이지', path: ROUTES.reviewList }, + { pageName: '목록 페이지', path: ROUTE.reviewList }, { pageName: '상세 페이지', path: pathname }, ); } diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index 20982644e..d3cfcff6e 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -19,8 +19,7 @@ import { import { ErrorSuspenseContainer } from './components'; import { DEV_ENVIRONMENT, ROUTE_PARAM } from './constants'; -import { ROUTES } from './constants/routes'; -import PasswordTestPage from './pages/PasswordTestPage'; +import { ROUTE } from './constants/route'; import globalStyles from './styles/globalStyles'; import theme from './styles/theme'; @@ -50,7 +49,7 @@ const queryClient = new QueryClient({ const router = createBrowserRouter([ { - path: ROUTES.home, + path: ROUTE.home, element: , errorElement: , children: [ @@ -62,22 +61,18 @@ const router = createBrowserRouter([ path: 'user', element:
user
, }, - { path: `${ROUTES.reviewWriting}/:${ROUTE_PARAM.reviewRequestCode}`, element: }, - { path: ROUTES.reviewWritingComplete, element: }, + { path: `${ROUTE.reviewWriting}/:${ROUTE_PARAM.reviewRequestCode}`, element: }, + { path: ROUTE.reviewWritingComplete, element: }, { - path: ROUTES.reviewList, + path: ROUTE.reviewList, element: , }, { - path: `${ROUTES.detailedReview}/:${ROUTE_PARAM.reviewId}`, + path: `${ROUTE.detailedReview}/:${ROUTE_PARAM.reviewId}`, element: , }, { - path: 'password-check/:reviewRequestCode', - element: , - }, - { - path: `${ROUTES.reviewZone}/:${ROUTE_PARAM.reviewRequestCode}`, // NOTE: 임시 경로, 추후 논의 및 상수화 필요 + path: `${ROUTE.reviewZone}/:${ROUTE_PARAM.reviewRequestCode}`, element: ( diff --git a/frontend/src/mocks/handlers/group.ts b/frontend/src/mocks/handlers/group.ts index d2a117150..713f986fa 100644 --- a/frontend/src/mocks/handlers/group.ts +++ b/frontend/src/mocks/handlers/group.ts @@ -1,11 +1,6 @@ import { http, HttpResponse } from 'msw'; -import endPoint, { - REVIEW_GROUP_DATA_API_PARAMS, - REVIEW_GROUP_DATA_API_URL, - REVIEW_PASSWORD_API_PARAMS, - REVIEW_PASSWORD_API_URL, -} from '@/apis/endpoints'; +import endPoint, { REVIEW_GROUP_DATA_API_PARAMS, REVIEW_GROUP_DATA_API_URL } from '@/apis/endpoints'; import { API_ERROR_MESSAGE } from '@/constants'; import { PasswordResponse } from '@/types'; @@ -30,22 +25,25 @@ const postDataForReviewRequestCode = () => { // }); // }; -const getPassWordValidation = () => { - return http.get(new RegExp(`^${REVIEW_PASSWORD_API_URL}`), async ({ request }) => { - const url = new URL(request.url); - const params = new URLSearchParams(url.search); - const { queryString } = REVIEW_PASSWORD_API_PARAMS; - // 가로채는 요청 url이 맞는 지 확인(reviewRequestCode 쿼리 키가 있어야함) - if (!params.has(queryString.reviewRequestCode)) return; +const postPassWordValidation = () => { + return http.post(endPoint.checkingPassword, async ({ request }) => { + // password가 있는 경우 + if (!request.body) return HttpResponse.json({ error: API_ERROR_MESSAGE[400] }, { status: 400 }); + + const rawBody = await request.body.getReader().read(); + const textDecoder = new TextDecoder(); + const bodyText = textDecoder.decode(rawBody.value); + // password가 유효한 패스워드인지 확인 - const password = request.headers.get('GroupAccessCode'); + const { reviewRequestCode, groupAccessCode: password } = JSON.parse(bodyText); + // reviewRequestCode가 없는 경우 //password가 없을 경우 - if (!password) return HttpResponse.json({ error: API_ERROR_MESSAGE[400] }, { status: 400 }); - + if (!password || !reviewRequestCode) return HttpResponse.json({ error: API_ERROR_MESSAGE[400] }, { status: 400 }); // password가 있는 경우 + const response: PasswordResponse = { - isValidAccess: password === VALIDATED_PASSWORD, + hasAccess: password === VALIDATED_PASSWORD, }; return HttpResponse.json(response, { status: 200 }); @@ -74,6 +72,6 @@ const getReviewGroupData = () => { return HttpResponse.json({ error: '잘못된 리뷰 그룹 데이터 요청' }, { status: 404 }); }); }; -const groupHandler = [postDataForReviewRequestCode(), getReviewGroupData(), getPassWordValidation()]; +const groupHandler = [postDataForReviewRequestCode(), getReviewGroupData(), postPassWordValidation()]; export default groupHandler; diff --git a/frontend/src/pages/HomePage/components/URLGeneratorForm/index.tsx b/frontend/src/pages/HomePage/components/URLGeneratorForm/index.tsx index ff82763b4..c0a85faa2 100644 --- a/frontend/src/pages/HomePage/components/URLGeneratorForm/index.tsx +++ b/frontend/src/pages/HomePage/components/URLGeneratorForm/index.tsx @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'; import { DataForReviewRequestCode } from '@/apis/group'; import { Button, Input, EyeButton } from '@/components'; -import { ROUTES } from '@/constants/routes'; +import { ROUTE } from '@/constants/route'; import { useEyeButton } from '@/hooks'; import useModals from '@/hooks/useModals'; import { debounce } from '@/utils/debounce'; @@ -74,7 +74,7 @@ const URLGeneratorForm = () => { }; const getCompleteReviewZoneURL = (reviewRequestCode: string) => { - return `${window.location.origin}/${ROUTES.reviewZone}/${reviewRequestCode}`; + return `${window.location.origin}/${ROUTE.reviewZone}/${reviewRequestCode}`; }; const handleNameInputChange = (event: React.ChangeEvent) => { diff --git a/frontend/src/pages/PasswordTestPage.tsx b/frontend/src/pages/PasswordTestPage.tsx deleted file mode 100644 index bebe8ce5d..000000000 --- a/frontend/src/pages/PasswordTestPage.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { useRef, useState } from 'react'; -import { useNavigate } from 'react-router'; - -import { ROUTES } from '@/constants/routes'; -import { useCheckPasswordValidation, useGroupAccessCode, useSearchParamAndQuery } from '@/hooks'; - -const PasswordTestPage = () => { - // NOTE: 연결 페이지가 develop에 머지되지 않아서, 비밀 번호 확인을 위한 컴포넌트를 생성 추후에 삭제 예정 - - const { param: reviewRequestCode } = useSearchParamAndQuery({ - paramKey: 'reviewRequestCode', - }); - - if (!reviewRequestCode) throw new Error('유효하지 않은 리뷰 요청 코드입니다.'); - const inputRef = useRef(null); - const [password, setPassword] = useState(''); - const [errorMessage, setErrorMessage] = useState(''); - const navigate = useNavigate(); - const { updateGroupAccessCode } = useGroupAccessCode(); - - const handleValidatedPassword = () => { - updateGroupAccessCode(password); - setErrorMessage(''); - navigate(`/${ROUTES.reviewList}`); - }; - - const handleInvalidatedPassword = (error: Error) => { - setErrorMessage(error.message); - }; - - useCheckPasswordValidation({ - groupAccessCode: password, - reviewRequestCode, - onSuccess: handleValidatedPassword, - onError: handleInvalidatedPassword, - }); - - const handleSubmit = (event: React.MouseEvent) => { - event.preventDefault(); - if (!inputRef.current) return; - - setPassword(inputRef.current.value); - }; - return ( -
- - -
{errorMessage}
-
- ); -}; - -export default PasswordTestPage; diff --git a/frontend/src/pages/ReviewZonePage/components/PasswordModal/index.tsx b/frontend/src/pages/ReviewZonePage/components/PasswordModal/index.tsx index c953d3f5c..be0521e53 100644 --- a/frontend/src/pages/ReviewZonePage/components/PasswordModal/index.tsx +++ b/frontend/src/pages/ReviewZonePage/components/PasswordModal/index.tsx @@ -3,25 +3,48 @@ import { useNavigate } from 'react-router'; import { Input, Button, EyeButton } from '@/components'; import ContentModal from '@/components/common/modals/ContentModal'; -import { ROUTES } from '@/constants/routes'; -import { useEyeButton } from '@/hooks'; +import { ROUTE } from '@/constants/route'; +import { useCheckPasswordValidation, useEyeButton, useGroupAccessCode } from '@/hooks'; import * as S from './styles'; interface PasswordModalProps { closeModal: () => void; + reviewRequestCode: string; } -const PasswordModal = ({ closeModal }: PasswordModalProps) => { +const PasswordModal = ({ closeModal, reviewRequestCode }: PasswordModalProps) => { const [password, setPassword] = useState(''); + const [validatedPassword, setValidatedPassword] = useState(''); const [errorMessage, setErrorMessage] = useState(''); const navigate = useNavigate(); + const { isOff, handleEyeButtonToggle } = useEyeButton(); - const handleConfirmButtonClick = () => { - // NOTE: 추후 이곳에 API 호출 함수 추가 - //closeModal(); - // navigate(`/${ROUTES.reviewList}/${}`); // NOTE: 추후 뒤에 groupAccessCode 추가하기 + const { updateGroupAccessCode } = useGroupAccessCode(); + + const handleValidatedPassword = () => { + updateGroupAccessCode(password); + setErrorMessage(''); + navigate(`/${ROUTE.reviewList}`); + }; + + const handleInvalidatedPassword = (error: Error) => { + setErrorMessage(error.message); + }; + + useCheckPasswordValidation({ + groupAccessCode: validatedPassword, + reviewRequestCode, + onSuccess: handleValidatedPassword, + onError: handleInvalidatedPassword, + }); + + const handleConfirmButtonClick = (event: React.MouseEvent) => { + event.preventDefault(); + if (!password) return; + + setValidatedPassword(password); }; const handlePasswordInputChange = (event: React.ChangeEvent) => { @@ -44,7 +67,7 @@ const PasswordModal = ({ closeModal }: PasswordModalProps) => { /> - diff --git a/frontend/src/pages/ReviewZonePage/components/PasswordModal/styles.ts b/frontend/src/pages/ReviewZonePage/components/PasswordModal/styles.ts index 75bf03eb2..d39ab01e6 100644 --- a/frontend/src/pages/ReviewZonePage/components/PasswordModal/styles.ts +++ b/frontend/src/pages/ReviewZonePage/components/PasswordModal/styles.ts @@ -3,39 +3,35 @@ import styled from '@emotion/styled'; export const PasswordModal = styled.div` display: flex; flex-direction: column; - height: 14rem; `; export const ModalTitle = styled.h3` - font-weight: ${({ theme }) => theme.fontWeight.bold}; - margin-bottom: 2rem; + font-weight: ${({ theme }) => theme.fontWeight.bold}; `; -export const InputContainer = styled.div` +export const InputContainer = styled.form` display: flex; gap: 1rem; - justify-content: space-between; width: 100%; `; export const Label = styled.label` - font-size: 1.4rem; - margin-left: 0.2rem; margin-bottom: 0.5rem; + margin-left: 0.2rem; + font-size: 1.4rem; `; export const PasswordInputContainer = styled.div` - display: flex; position: relative; + display: flex; `; export const ErrorMessage = styled.p` - font-size: 1.2rem; - color: ${({ theme }) => theme.colors.red}; - margin-top: 0.2rem; margin-left: 0.4rem; + font-size: 1.2rem; + color: ${({ theme }) => theme.colors.red}; `; diff --git a/frontend/src/pages/ReviewZonePage/index.tsx b/frontend/src/pages/ReviewZonePage/index.tsx index 7e4e265b9..62a3a5b66 100644 --- a/frontend/src/pages/ReviewZonePage/index.tsx +++ b/frontend/src/pages/ReviewZonePage/index.tsx @@ -2,8 +2,8 @@ import { useNavigate } from 'react-router'; import ReviewZoneIcon from '@/assets/reviewZone.svg'; import { Button } from '@/components'; -// TODO: ROUTES 상수명을 단수로 고치기 -import { ROUTES } from '@/constants/routes'; +// TODO: ROUTE 상수명을 단수로 고치기 +import { ROUTE } from '@/constants/route'; import { useGetReviewGroupData, useSearchParamAndQuery } from '@/hooks'; import useModals from '@/hooks/useModals'; @@ -28,7 +28,7 @@ const ReviewZonePage = () => { const { data: reviewGroupData } = useGetReviewGroupData({ reviewRequestCode }); const handleReviewWritingButtonClick = () => { - navigate(`/${ROUTES.reviewWriting}/ABCD1234`); + navigate(`/${ROUTE.reviewWriting}/ABCD1234`); }; const handleReviewListButtonClick = () => { @@ -67,7 +67,9 @@ const ReviewZonePage = () => { - {isOpen(MODAL_KEYS.content) && closeModal(MODAL_KEYS.content)} />} + {isOpen(MODAL_KEYS.content) && ( + closeModal(MODAL_KEYS.content)} /> + )} ); }; diff --git a/frontend/src/types/reviewGroup.ts b/frontend/src/types/reviewGroup.ts index 440a3e846..1fdfa12e5 100644 --- a/frontend/src/types/reviewGroup.ts +++ b/frontend/src/types/reviewGroup.ts @@ -1,5 +1,5 @@ export interface PasswordResponse { - isValidAccess: boolean; + hasAccess: boolean; } export interface ReviewGroupData { revieweeName: string;