diff --git a/src/assets/icon/errorIcon.svg b/src/assets/icon/errorIcon.svg new file mode 100644 index 0000000..21df4d0 --- /dev/null +++ b/src/assets/icon/errorIcon.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/components/commons/Input.tsx b/src/components/commons/Input.tsx index 8c6ff12..0c909b1 100644 --- a/src/components/commons/Input.tsx +++ b/src/components/commons/Input.tsx @@ -3,7 +3,7 @@ import { Controller, Control, FieldValues, Path } from 'react-hook-form'; interface InputProps { control: Control; name: Path; - label: string | React.ReactNode; + label?: string | React.ReactNode; type: string; autoFocus?: boolean; maxLength?: number; diff --git a/src/components/error/index.tsx b/src/components/error/index.tsx new file mode 100644 index 0000000..b21ce1b --- /dev/null +++ b/src/components/error/index.tsx @@ -0,0 +1,19 @@ +import ErrorIcon from '@/assets/icon/errorIcon.svg?react'; +import BackButton from '../commons/BackButton'; + +const ErrorPage = () => { + return ( +
+ +

+ 요청하신 페이지를 찾는 중
+ 오류가 발생했습니다. +

+
+ +
+
+ ); +}; + +export default ErrorPage; diff --git a/src/components/modal/AccountNumberModal.tsx b/src/components/modal/AccountNumberModal.tsx new file mode 100644 index 0000000..512b176 --- /dev/null +++ b/src/components/modal/AccountNumberModal.tsx @@ -0,0 +1,83 @@ +import Modal from '@/components/modal'; +import Button from '../commons/Button'; +import { useModal } from '@/contexts/ModalContext'; +import Input from '../commons/Input'; +import useUserStore from '@/store/useUserStore'; +import { z } from 'zod'; +import { accountNumberVerificationSchema } from '@/libs/schemas/auth'; +import { AccountNumberVerificationTypes } from 'gachTaxi-types'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { useForm, SubmitHandler, useWatch } from 'react-hook-form'; +import { useToast } from '@/contexts/ToastContext'; +import handleAxiosError from '@/libs/apis/axiosError.api'; +import { getAccountNumber } from '@/libs/apis/getAccountNumber.api'; + +const AccountNumberModal = () => { + const { closeModal } = useModal(); + + const { user } = useUserStore(); + + const profileForm = useForm>({ + resolver: zodResolver(accountNumberVerificationSchema), + defaultValues: { + accountNumber: user?.accountNumber || '', + }, + mode: 'onSubmit', + }); + const { setUser } = useUserStore(); + const { openToast } = useToast(); + const accountNumber = useWatch({ + control: profileForm.control, + name: 'accountNumber', + }); + + const handleSubmitChange: SubmitHandler< + AccountNumberVerificationTypes + > = async () => { + try { + const updateData = profileForm.getValues(); + + const res = await getAccountNumber(updateData); + if (res?.code === 200) { + const userData = res?.data; + setUser(userData); + openToast(res.message, 'success'); + closeModal(); + } + } catch (error) { + const errorMessage = handleAxiosError(error); + openToast(errorMessage, 'error'); + } + }; + + return ( + <> + + 계좌번호 + + +
+ >, + )} + > + + + +
+
+ + ); +}; + +export default AccountNumberModal; diff --git a/src/components/my-page/MyProfileHeader.tsx b/src/components/my-page/MyProfileHeader.tsx index 20210b0..cdabd9f 100644 --- a/src/components/my-page/MyProfileHeader.tsx +++ b/src/components/my-page/MyProfileHeader.tsx @@ -31,7 +31,7 @@ const MyProfileHeader = () => { />

- 추가 정보 + {user?.studentNumber}

diff --git a/src/hooks/useChangeButtonData.tsx b/src/hooks/useChangeButtonData.tsx index 464e310..6bad353 100644 --- a/src/hooks/useChangeButtonData.tsx +++ b/src/hooks/useChangeButtonData.tsx @@ -2,6 +2,7 @@ import BackIcon from '@/assets/icon/backIcon.svg?react'; import { Link } from 'react-router-dom'; import { useModal } from '@/contexts/ModalContext'; import MyPageModal from '@/components/modal/MyPageModal'; +import AccountNumberModal from '@/components/modal/AccountNumberModal'; interface ButtonItem { label: string; @@ -17,24 +18,31 @@ export const useChangeButtonData = (): JSX.Element[] => { { label: '공지 사항', path: '/mypage/notice' }, { label: '문의 사항', path: '/mypage/inquiry' }, { label: '이용 기록', path: '/mypage/useage' }, - { label: '알림 설정', path: '/mypage/notification' }, { - label: '로그아웃', + label: '계좌 번호', component: (
openModal()} + key="accountNumber" + onClick={() => openModal()} className="flex justify-between items-center w-full text-captionHeader cursor-pointer" > - 로그아웃 + 계좌번호
), }, { - label: '전화번호 인증', - path: '/mypage/phone-verification', - isVerified: false, + label: '로그아웃 및 탈퇴', + component: ( +
openModal()} + className="flex justify-between items-center w-full text-captionHeader cursor-pointer" + > + 로그아웃 및 탈퇴 + +
+ ), }, ]; @@ -43,27 +51,6 @@ export const useChangeButtonData = (): JSX.Element[] => { return
{item.component}
; } - if (item.isVerified !== undefined) { - return ( - - {item.label} - - 인증확인 - - - ); - } - return ( { + try { + const res = await client.post('/api/accounts', data); + return res.data; + } catch (error) { + console.log('프로필 업데이트 실패', error); + } +}; diff --git a/src/libs/schemas/auth.ts b/src/libs/schemas/auth.ts index 33ff1e0..d4ccc80 100644 --- a/src/libs/schemas/auth.ts +++ b/src/libs/schemas/auth.ts @@ -23,8 +23,7 @@ const accountNumberSchema = z .min(10, '올바른 계좌번호를 입력해주세요!') .refine((value) => !isNaN(Number(value)), { message: '계좌번호는 숫자로만 입력해야 합니다!', - }) - .optional(); + }); const editNickNameSchema = z .string() @@ -116,6 +115,9 @@ export const userInfoVerificationSchema = z.object({ export const profileEditVerificationSchema = z.object({ profilePicture: profileImageSchema, nickName: editNickNameSchema, +}); + +export const accountNumberVerificationSchema = z.object({ accountNumber: accountNumberSchema, }); diff --git a/src/pages/chat/index.tsx b/src/pages/chat/index.tsx index 38d033a..2cfbd06 100644 --- a/src/pages/chat/index.tsx +++ b/src/pages/chat/index.tsx @@ -2,9 +2,11 @@ import ChatInput from '@/components/chat/MessageInput'; import MessageList from '@/components/chat/messageList/index'; import BackButton from '@/components/commons/BackButton'; import useWebSocket from '@/hooks/useWebSocket'; +import { useParams } from 'react-router-dom'; const ChatPage = () => { - const roomId = 1; + const { id } = useParams<{ id: string }>(); + const roomId = Number(id); const { messages, sendMessage, participantCount } = useWebSocket(roomId); diff --git a/src/pages/my-page/EditProfilePage.tsx b/src/pages/my-page/EditProfilePage.tsx index a3fc509..7e0fcd0 100644 --- a/src/pages/my-page/EditProfilePage.tsx +++ b/src/pages/my-page/EditProfilePage.tsx @@ -21,7 +21,6 @@ const EditProfilePage = () => { defaultValues: { nickName: user?.nickName || '', profilePicture: user?.profilePicture || undefined, - accountNumber: user?.accountNumber || '', }, mode: 'onSubmit', }); @@ -93,14 +92,6 @@ const EditProfilePage = () => { type="text" /> - - diff --git a/src/pages/my-page/index.tsx b/src/pages/my-page/index.tsx index 2949860..0bd6712 100644 --- a/src/pages/my-page/index.tsx +++ b/src/pages/my-page/index.tsx @@ -1,8 +1,6 @@ import Notice from './Notice'; import Inquiry from './Inquiry'; import Usage from './Usage'; -import Notification from './Notification'; -import PhoneVerificationPage from './PhoneVerificationPage'; import MyProfileHeader from '@/components/my-page/MyProfileHeader'; import MyPageButton from '@/components/my-page/MyPageButton'; import BackButton from '@/components/commons/BackButton'; @@ -24,11 +22,9 @@ const MyPage = () => { return ( } /> - } /> } /> } /> } /> - } /> } /> ); diff --git a/src/types/auth.d.ts b/src/types/auth.d.ts index b4e0696..4850532 100644 --- a/src/types/auth.d.ts +++ b/src/types/auth.d.ts @@ -34,7 +34,10 @@ declare module 'gachTaxi-types' { interface ProfileEditVerificationTypes { profilePicture?: file | string | undefined; nickName?: string; - accountNumber?: string; + } + + interface AccountNumberVerificationTypes { + accountNumber: string; } interface AgreementsTypes {