From 165916cce668b43a6c2d244f5fd6bf350912d7b8 Mon Sep 17 00:00:00 2001 From: Eugene Kim <67894159+eugene028@users.noreply.github.com> Date: Fri, 9 Aug 2024 19:26:09 +0900 Subject: [PATCH] =?UTF-8?q?[Fix]:=200807=20QA=20=EB=B0=98=EC=98=81=20(#95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: navigate 정상화 * fix: 모집 차수 깨져 보이는 현상 개선 * fix: 모집 기간 아닐 때 에러 화면 제거 * fix: signup화면 제출 문구 수정 * refac: 이메일 도메인 직접 입력할 수 있도록 변경 * feat: 로그아웃 로직 붙임 * fix: wowds-ui 버전 업데이트 --- package.json | 2 +- pnpm-lock.yaml | 8 +- src/apis/auth/authApi.ts | 9 ++ .../JoinRegularMemberBottomSheet.tsx | 5 +- src/components/myPage/ApproveBox.tsx | 54 +++---- src/components/myPage/BasicUserInfo.tsx | 11 +- .../{auth => signup}/DepartmentSelect.tsx | 0 src/components/signup/EmailInputField.tsx | 139 ++++++++++++++++++ src/hooks/auth/useStudentVerification.ts | 2 +- src/hooks/mutation/index.ts | 1 + src/hooks/mutation/useLogout.ts | 23 +++ src/pages/Auth.tsx | 3 - src/pages/SignUp.tsx | 96 +----------- src/pages/StudentVerification.tsx | 51 +++++-- .../redirect/AuthServerRedirectNavigate.tsx | 5 +- src/utils/auth.ts | 4 - src/utils/mypage/recruitmentNameFormat.ts | 14 +- 17 files changed, 269 insertions(+), 158 deletions(-) create mode 100644 src/apis/auth/authApi.ts rename src/components/{auth => signup}/DepartmentSelect.tsx (100%) create mode 100644 src/components/signup/EmailInputField.tsx create mode 100644 src/hooks/mutation/useLogout.ts diff --git a/package.json b/package.json index 34b505c..c5f4747 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "wowds-icons": "^0.1.0", "wowds-tokens": "^0.0.9", "zustand": "^4.5.0", - "wowds-ui": "^0.1.8" + "wowds-ui": "^0.1.9" }, "devDependencies": { "@sentry/react": "^8.22.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8d23160..dc189e9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -54,8 +54,8 @@ dependencies: specifier: ^0.0.9 version: 0.0.9 wowds-ui: - specifier: ^0.1.8 - version: 0.1.8(next@14.2.4)(react-dom@18.2.0)(react@18.2.0) + specifier: ^0.1.9 + version: 0.1.9(next@14.2.4)(react-dom@18.2.0)(react@18.2.0) zustand: specifier: ^4.5.0 version: 4.5.1(@types/react@18.2.58)(react@18.2.0) @@ -10273,8 +10273,8 @@ packages: resolution: {integrity: sha512-fMGyb92sZ1iSf0TGSabQVym/MWsYyfetgBBNbZ0K6eGfESKtZF8AM1aDYRODmwyPkPSnt0SmOtRWMDxnPsnCqg==} dev: false - /wowds-ui@0.1.8(next@14.2.4)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-a6DSdxoQxZPRMkFodbY1GKYWxzuzCpSAir5WAKU0lPO3cmTmK1ILLXqlI+lANfI9fRAzCZDY9RoX5vdBl9yz7A==} + /wowds-ui@0.1.9(next@14.2.4)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-MDH0HqUCoRlHF1jtl+S6h+vusy5Lli+SVdu2SLhTaxlWJ6JQIqubesvNa16vaq/hRpn4WByX6x+aHrtM57cz3A==} peerDependencies: next: ^14.1.1 react: ^18.2.0 diff --git a/src/apis/auth/authApi.ts b/src/apis/auth/authApi.ts new file mode 100644 index 0000000..150379e --- /dev/null +++ b/src/apis/auth/authApi.ts @@ -0,0 +1,9 @@ +import apiClient from '..'; + +const authApi = { + LOGOUT: async () => { + const response = await apiClient.get(`/auth/logout`); + return response.data; + } +}; +export default authApi; diff --git a/src/components/bottomsheet/JoinRegularMemberBottomSheet.tsx b/src/components/bottomsheet/JoinRegularMemberBottomSheet.tsx index ad1ea79..b8b4ca6 100644 --- a/src/components/bottomsheet/JoinRegularMemberBottomSheet.tsx +++ b/src/components/bottomsheet/JoinRegularMemberBottomSheet.tsx @@ -19,7 +19,10 @@ const JoinRegularMemberBottomSheet = ({ currentRecruitment: CurrentRecruitmentType; }) => { const { joinRegularMember } = useJoinRegularMember(); - const bottomSheetTitle = convertRecruitmentName(currentRecruitment.name); + const bottomSheetTitle = convertRecruitmentName( + currentRecruitment.name, + currentRecruitment.roundTypeValue + ); const recruitmentPeriod = convertRecruitmentPeriod(currentRecruitment.period); return ( diff --git a/src/components/myPage/ApproveBox.tsx b/src/components/myPage/ApproveBox.tsx index 7a7b276..d6df24e 100644 --- a/src/components/myPage/ApproveBox.tsx +++ b/src/components/myPage/ApproveBox.tsx @@ -19,6 +19,17 @@ export const ApproveBox = ({ currentRecruitment: CurrentRecruitmentType; }) => { const { handleBottomSheet } = useBottomSheet(); + + if (!currentRecruitment) { + return ( + + ); + } const boxContent: Record< UserRoleType, { @@ -29,13 +40,13 @@ export const ApproveBox = ({ } > = { GUEST: { - title: `${convertRecruitmentName(currentRecruitment.name)}`, + title: `${convertRecruitmentName(currentRecruitment.name, currentRecruitment.roundTypeValue)}`, description: '하단의 준회원 가입 조건을 완료해주세요.', boxVariant: 'warn', status: 'error' }, ASSOCIATE: { - title: `${convertRecruitmentName(currentRecruitment.name)}`, + title: `${convertRecruitmentName(currentRecruitment.name, currentRecruitment.roundTypeValue)}`, description: `${convertRecruitmentPeriod(currentRecruitment.period)}`, boxVariant: 'arrow', status: 'error' @@ -47,31 +58,20 @@ export const ApproveBox = ({ } }; return ( - <> - {currentRecruitment ? ( - { - if (role === 'ASSOCIATE') handleBottomSheet(); - else { - return; - } - }}> - - - ) : ( - - )} - + { + if (role === 'ASSOCIATE') handleBottomSheet(); + else { + return; + } + }}> + + ); }; diff --git a/src/components/myPage/BasicUserInfo.tsx b/src/components/myPage/BasicUserInfo.tsx index 3ded725..3858f7a 100644 --- a/src/components/myPage/BasicUserInfo.tsx +++ b/src/components/myPage/BasicUserInfo.tsx @@ -1,17 +1,12 @@ import { Flex, Text } from '@/components/common/Wrapper'; import { User } from '@/types/user'; -import { logout } from '@/utils/auth'; +import { useLogout } from '@/hooks/mutation'; import { typography, color } from 'wowds-tokens'; -import { useNavigate } from 'react-router-dom'; - const BasicUserInfo = ({ member }: { member: User }) => { - const navigate = useNavigate(); - + const { mutate } = useLogout(); const handleLogoutClick = () => { - logout(); - navigate('/'); - location.reload(); + mutate(); }; return ( diff --git a/src/components/auth/DepartmentSelect.tsx b/src/components/signup/DepartmentSelect.tsx similarity index 100% rename from src/components/auth/DepartmentSelect.tsx rename to src/components/signup/DepartmentSelect.tsx diff --git a/src/components/signup/EmailInputField.tsx b/src/components/signup/EmailInputField.tsx new file mode 100644 index 0000000..fa2f587 --- /dev/null +++ b/src/components/signup/EmailInputField.tsx @@ -0,0 +1,139 @@ +import { useState } from 'react'; +import styled from '@emotion/styled'; +import { Control, Controller } from 'react-hook-form'; +import DropDown from 'wowds-ui/DropDown'; +import DropDownOption from 'wowds-ui/DropDownOption'; +import { space } from 'wowds-tokens'; +import TextField from 'wowds-ui/TextField'; + +type DepartmentSelectProps = { + control: + | Control<{ + name: string; + studentId: string; + phone: string; + department: string; + email: string; + emailDomain: string; + terms: boolean; + personalPrivacy: boolean; + }> + | undefined; +}; + +const EmailInputField = ({ control }: DepartmentSelectProps) => { + const [customEmail, setCustomEmail] = useState(false); + return ( + + ( + + + + )} + /> + ( + + {customEmail ? ( + + + + ) : ( + { + if (selectedValue === 'custom') { + setCustomEmail(true); + } else { + field.onChange(selectedValue); + } + }} + style={{ marginTop: '22px', flex: 1, width: '100%' }}> + + + + + + + )} + + )} + /> + + ); +}; + +export default EmailInputField; + +const TextFieldWrapper = styled.div` + flex: 1; + height: 84.8px; +`; + +const EmailFieldWrapper = styled.div` + position: relative; + width: 100%; + display: flex; + gap: ${space.sm}; + align-items: center; + justify-content: space-between; +`; diff --git a/src/hooks/auth/useStudentVerification.ts b/src/hooks/auth/useStudentVerification.ts index ec800f5..7c452e5 100644 --- a/src/hooks/auth/useStudentVerification.ts +++ b/src/hooks/auth/useStudentVerification.ts @@ -24,7 +24,7 @@ export default function useStudentVerification() { const onSubmit = async ({ univEmail }: FieldValues) => { event?.preventDefault(); updateUnivEmail(univEmail); - sendStudentEmail(univEmail); + sendStudentEmail(`${univEmail}@g.hongik.ac.kr`); }; const onVerifyStudent = () => { diff --git a/src/hooks/mutation/index.ts b/src/hooks/mutation/index.ts index f15ca8d..f79133a 100644 --- a/src/hooks/mutation/index.ts +++ b/src/hooks/mutation/index.ts @@ -1,2 +1,3 @@ export { default as useSendStudentEmail } from './useSendStudentEmail'; export { default as useVerifyStudentEmail } from './useVerifyStudentEmail'; +export { default as useLogout } from './useLogout'; diff --git a/src/hooks/mutation/useLogout.ts b/src/hooks/mutation/useLogout.ts new file mode 100644 index 0000000..1e085ce --- /dev/null +++ b/src/hooks/mutation/useLogout.ts @@ -0,0 +1,23 @@ +import { useMutation } from '@tanstack/react-query'; +import authApi from '@/apis/auth/authApi'; +import { useNavigate } from 'react-router-dom'; +import RoutePath from '@/routes/routePath'; +import { toast } from 'react-toastify'; + +export default function useLogout() { + const navigate = useNavigate(); + + const mutation = useMutation({ + mutationFn: authApi.LOGOUT, + onSuccess: () => { + sessionStorage.clear(); + navigate(RoutePath.Home); + location.reload(); + }, + onError: () => { + toast.error('로그아웃에 실패했어요.'); + } + }); + + return mutation; +} diff --git a/src/pages/Auth.tsx b/src/pages/Auth.tsx index 2d38871..63923f8 100644 --- a/src/pages/Auth.tsx +++ b/src/pages/Auth.tsx @@ -11,9 +11,6 @@ import { Link } from 'react-router-dom'; /** 깃허브 로그인 및 가입하기 */ export const Auth = () => { const handleClick = () => { - //TODO: QA용으로 임시로 설정 - sessionStorage.setItem('isLogin', 'true'); - // GitHub 로그인 페이지로 직접 리다이렉트 setTimeout(function () { document.location.href = RoutePath.AuthGithubLoginRedirect; diff --git a/src/pages/SignUp.tsx b/src/pages/SignUp.tsx index 3c37b2b..81db15e 100644 --- a/src/pages/SignUp.tsx +++ b/src/pages/SignUp.tsx @@ -1,4 +1,4 @@ -import DepartmentSelect from '@/components/auth/DepartmentSelect'; +import DepartmentSelect from '@/components/signup/DepartmentSelect'; import { useForm, Controller } from 'react-hook-form'; import type { color as colorType } from 'wowds-tokens'; import GlobalSize from '@/constants/globalSize'; @@ -10,15 +10,14 @@ import useCreateUserBasicInfo from '@/hooks/mutation/useCreateUserBasicInfo'; import Button from 'wowds-ui/Button'; import Checkbox from 'wowds-ui/Checkbox'; import TextField from 'wowds-ui/TextField'; -import DropDownOption from 'wowds-ui/DropDownOption'; -import DropDown from 'wowds-ui/DropDown'; import { LoadingForm } from '@/components/common/LoadingForm'; import RoutePath from '@/routes/routePath'; +import { Suspense } from 'react'; import { formatPhoneNumberInProgress } from '@/utils/phone'; import styled from '@emotion/styled'; -import { Suspense } from 'react'; import { Link } from 'react-router-dom'; +import EmailInputField from '@/components/signup/EmailInputField'; export type FormStateType = { name: string; @@ -174,77 +173,7 @@ export const SignUp = () => { }> - - ( - - - - )} - /> - ( - - { - field.onChange(selectedValue); - }} - style={{ marginTop: '22px', flex: 1, width: '100%' }}> - - - - - - - )} - /> - + { role="button" disabled={!isValid} style={{ maxWidth: '100%' }}> - 가입 신청하기 + 입력 완료하기 @@ -377,18 +306,3 @@ const InputFormWrapper = styled.div` height: 84.8px; width: 100%; `; - -const TextFieldWrapper = styled.div` - flex: 1; - height: 84.8px; - width: 50%; -`; - -const EmailFieldWrapper = styled.div` - position: relative; - width: 100%; - display: flex; - gap: ${space.sm}; - align-items: center; - justify-content: space-between; -`; diff --git a/src/pages/StudentVerification.tsx b/src/pages/StudentVerification.tsx index 776e797..153b6a0 100644 --- a/src/pages/StudentVerification.tsx +++ b/src/pages/StudentVerification.tsx @@ -66,23 +66,37 @@ export const StudentVerification = () => { message: '* 이메일을 입력해주세요.' }, pattern: { - value: /^[a-zA-Z0-9._%+-]+@g\.hongik\.ac\.kr$/, - message: '* 홍익대학교 이메일 형식을 지켜주세요.' + value: /^[a-zA-Z0-9._%+-]/, + message: '* 이메일 형식을 지켜주세요.' } }} render={({ field, fieldState }) => ( - + + + + + + @g.hongik.ac.kr + + )} /> + * 메일 전송이 최대 30분 가량 늦어질 수 있어요. @@ -158,3 +172,16 @@ const ButtonContainer = styled.div` align-items: center; gap: ${space.xs}; `; + +const EmailContainer = styled.div` + display: flex; + flex-direction: row; + align-items: center; + gap: ${space.xs}; +`; + +const TextFieldWrapper = styled.div` + flex: 1; + height: 84.8px; + width: 50%; +`; diff --git a/src/pages/redirect/AuthServerRedirectNavigate.tsx b/src/pages/redirect/AuthServerRedirectNavigate.tsx index c8ff639..de00c82 100644 --- a/src/pages/redirect/AuthServerRedirectNavigate.tsx +++ b/src/pages/redirect/AuthServerRedirectNavigate.tsx @@ -1,13 +1,14 @@ import RoutePath from '@/routes/routePath'; import { useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; + export const AuthServerRedirectNavigate = () => { const navigate = useNavigate(); useEffect(() => { sessionStorage.setItem('isLogin', 'true'); - }, []); - navigate(RoutePath.Dashboard); + navigate(RoutePath.Dashboard); + }, [navigate]); return null; }; diff --git a/src/utils/auth.ts b/src/utils/auth.ts index fb9014d..ec3524b 100644 --- a/src/utils/auth.ts +++ b/src/utils/auth.ts @@ -4,7 +4,3 @@ export const isAuthenticated = () => { if (isLogin === 'true') return true; else return false; }; -//TODO: 서버에서 로그아웃 로직 생성할 예정 -export function logout() { - sessionStorage.clear(); -} diff --git a/src/utils/mypage/recruitmentNameFormat.ts b/src/utils/mypage/recruitmentNameFormat.ts index 33cbc38..337badf 100644 --- a/src/utils/mypage/recruitmentNameFormat.ts +++ b/src/utils/mypage/recruitmentNameFormat.ts @@ -9,11 +9,17 @@ export const convertRecruitmentPeriod = (period: { return `지원 기간 : ${startDate} ~ ${endDate}`; }; -export const convertRecruitmentName = (name: string) => { - const [period, round] = name.split(' '); +export const convertRecruitmentName = ( + name: string, + roundValueType: string +) => { + const [period] = name.split(' '); const [year, semester] = period.split('-'); if (year === undefined || semester === undefined) { - return `${round} 정회원 지원하기`; + return `정회원 지원하기`; } - return `${year}년 ${semester}학기 ${round} 정회원 지원하기`; + if (roundValueType === undefined) { + return `${year}년 ${semester}학기 정회원 지원하기`; + } + return `${year}년 ${semester}학기 ${roundValueType} 정회원 지원하기`; };