Skip to content

Commit 15c9478

Browse files
committed
feat: 전화번호 인증 api 구현
1 parent 00d4972 commit 15c9478

File tree

6 files changed

+53
-48
lines changed

6 files changed

+53
-48
lines changed

design-system/ui/Button.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ interface ButtonProps {
33
onClick: () => void; // 클릭 핸들러
44
disabled?: boolean; // 비활성화 여부
55
className?: string; // 추가 스타일링 클래스
6+
type?: 'button' | 'submit' | 'reset';
67
}
78

8-
const Button = ({ label, onClick, disabled = false, className = '' }: ButtonProps) => {
9+
const Button = ({ label, onClick, disabled = false, className = '', type = 'submit' }: ButtonProps) => {
910
return (
1011
<button
12+
type={type}
1113
onClick={onClick}
1214
disabled={disabled}
1315
className={`py-2 px-4 text-white font-semibold transition text-base sm:text-xs md:text-sm lg:text-base

src/features/dashboard/api/participants.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,18 @@ export const downloadExcel = async (eventId:number): Promise<void> => {
2929
params: { eventId },
3030
}
3131
);
32+
console.log(response.headers)
3233

3334
//파일이름 추출
3435
const disposition = response.headers['content-disposition'];
35-
let filename = '같이가요_구매참가자목록.xlsx'; // 기본값
36-
if (disposition) {
37-
const match = disposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
38-
if (match && match[1]) {
39-
filename = decodeURIComponent(match[1].replace(/['"]/g, ''));
40-
}
36+
let filename = '기본값.xlsx';
37+
if (disposition) {
38+
const match = disposition.match(/filename\*=UTF-8''(.+)/);
39+
if (match && match[1]) {
40+
filename = decodeURIComponent(match[1]);
4141
}
42+
}
43+
console.log(disposition)
4244

4345
//저장
4446
const blob = new Blob([response.data], {

src/features/join/api/user.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,13 @@ export const agreeTerms = async (data: TermsAgreementRequest) => {
2222
});
2323
return response.data;
2424
};
25+
26+
//인증번호 발급
27+
export const sendCertificationCode = async (phoneNum: string): Promise<void> => {
28+
await axiosClient.post('/sms/send', { phoneNum });
29+
};
30+
31+
//인증번호 검증
32+
export const verifyCertificationCode = async (phoneNum: string, certificationCode: string): Promise<void> => {
33+
await axiosClient.post('/sms/verify', { phoneNum, certificationCode });
34+
};

src/features/join/hooks/useUserHook.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useMutation, useQuery } from '@tanstack/react-query';
2-
import { agreeTerms, readUser, updateUser } from '../api/user';
2+
import { agreeTerms, readUser, sendCertificationCode, updateUser, verifyCertificationCode } from '../api/user';
33
import { UserInfoRequest, UserInfoResponse } from '../model/userInformation';
44

55
export const useUserInfo = (enabled: boolean = true) => {
@@ -26,4 +26,32 @@ export const useAgreeTerms = () => {
2626
alert('약관 동의 처리에 실패했습니다.');
2727
}
2828
});
29-
};
29+
};
30+
31+
32+
// 인증번호 발급
33+
export const useSendCertificationCode = () => {
34+
return useMutation({
35+
mutationFn: (phoneNum: string) => sendCertificationCode(phoneNum),
36+
onSuccess: () => {
37+
alert('인증번호를 발송했습니다.');
38+
},
39+
onError: () => {
40+
alert('인증번호 전송에 실패했습니다.');
41+
},
42+
});
43+
};
44+
45+
// 인증번호 확인
46+
export const useVerifyCertificationCode = () => {
47+
return useMutation({
48+
mutationFn: (params: { phoneNum: string; certificationCode: string }) =>
49+
verifyCertificationCode(params.phoneNum, params.certificationCode),
50+
onSuccess: () => {
51+
alert('인증에 성공했습니다.');
52+
},
53+
onError: () => {
54+
alert('인증번호가 일치하지 않습니다.');
55+
},
56+
});
57+
}

src/pages/join/InfoInputPage.tsx

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useEffect, useState } from 'react';
1+
import { useEffect} from 'react';
22
import { useNavigate } from 'react-router-dom';
33
import { useForm, SubmitHandler } from 'react-hook-form';
44
import Header from '../../../design-system/ui/Header';
@@ -41,21 +41,6 @@ const InfoInputPage = () => {
4141
const formatted = formatPhoneNumber(e.target.value);
4242
setValue('phone', formatted, { shouldValidate: true });
4343
};
44-
// 전화번호 인증
45-
const [isVerifyVisible, setIsVerifyVisible] = useState(false);
46-
const [verificationCode, setVerificationCode] = useState('');
47-
const handlePhoneVerifyClick = () => {
48-
if (!phoneValue) {
49-
alert('연락처를 입력해주세요.');
50-
return;
51-
}
52-
setIsVerifyVisible(true);
53-
};
54-
const handleVerifySubmit = () => {
55-
// 여기서 인증번호 검증 로직 실행 (백엔드 호출 등)
56-
console.log("tets");
57-
};
58-
5944
const onSubmit: SubmitHandler<FormData> = formData => {
6045
const agreementStates = getAgreementStates();
6146
const updatedData = {
@@ -131,29 +116,7 @@ const InfoInputPage = () => {
131116
onChange={handlePhoneChange}
132117
/>
133118
</div>
134-
<Button
135-
label="인증하기"
136-
onClick={handlePhoneVerifyClick}
137-
className="h-11 px-4 rounded-md"
138-
/>
139119
</div>
140-
141-
{/* 인증번호 입력 필드 */}
142-
{isVerifyVisible && (
143-
<div className="flex flex-col gap-2 mt-2">
144-
<UnderlineTextField
145-
placeholder="인증번호 4자리"
146-
value={verificationCode}
147-
onChange={(e) => setVerificationCode(e.target.value)}
148-
className="text-xl"
149-
label={''} />
150-
<Button
151-
label="인증 확인"
152-
onClick={handleVerifySubmit}
153-
className="w-full h-10 rounded-full"
154-
/>
155-
</div>
156-
)}
157120
{/* 이메일 필드 */}
158121
<UnderlineTextField
159122
label="이메일"

src/shared/lib/formValidation.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export const formSchema = z.object({
99
.regex(/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/, '올바른 이메일 형식이어야 합니다.'),
1010
phone: z
1111
.string()
12-
.regex(/^[0-9]{3}-[0-9]{3,4}-[0-9]{4}$/, '연락처는 휴대전화 번호 형식(예: 010-1234-5678)이어야 합니다.'),
12+
.regex(/^[0-9]{3}-[0-9]{3,4}-[0-9]{4}$/, '000-0000-0000 형식으로 입력해주세요.'),
1313
});
1414
export const organizerFormSchema = formSchema.pick({ email: true, phone: true });
1515
export const eventTitleSchema = z.object({

0 commit comments

Comments
 (0)