Skip to content

Commit

Permalink
Merge pull request #25 from Codeit-TripProduct-9team/feat-findPw
Browse files Browse the repository at this point in the history
✨Feat: 이메일 인증 모달
  • Loading branch information
kkh000 committed May 23, 2024
2 parents aa75ce8 + ef0c367 commit a9994a0
Show file tree
Hide file tree
Showing 9 changed files with 203 additions and 9 deletions.
26 changes: 26 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
"lint": "next lint"
},
"dependencies": {
<<<<<<< HEAD
"@toss/use-overlay": "^1.4.0",
=======
"@heroicons/react": "^2.1.3",
>>>>>>> aa75ce8a3ce4dd2554bf05b9ca5cf68e0447128a
"axios": "^1.7.1",
"emailjs-com": "^3.2.0",
"next": "14.2.3",
Expand Down
3 changes: 0 additions & 3 deletions src/components/common/input/InputField.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
// components/InputField.tsx

import React from 'react';
import { UseFormRegister, FieldError } from 'react-hook-form';

type InputFieldProps = {
Expand Down
52 changes: 52 additions & 0 deletions src/components/common/modal/emailConfirmModal/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { useRouter } from 'next/router';
import { useState } from 'react';

type ModalProps = {
isOpen: boolean;
close: () => void;
code: string;
};

const EmailConfirmModal = ({ isOpen, close, code }: ModalProps) => {
const [inputCode, setInputCode] = useState(''); //리엑트 훅 폼으로 사용 변경 필요
const router = useRouter();

const handleConfirm = () => {
if (inputCode === code) {
alert('이메일 인증이 완료되었습니다.');
close();
router.push('/reset-password/change-password'); // 비밀번호 변경 페이지로 이동
} else {
alert('인증 코드가 일치하지 않습니다.');
}
};

//스타일은 임시로 지피티의 도움^3^
return (
<>
{isOpen && (
<div className="fixed inset-0 bg-black bg-opacity-50 flex justify-center items-center">
<div className="bg-white p-5 rounded">
<h2 className="text-xl mb-4">인증 코드 입력</h2>
<input
type="text"
value={inputCode}
onChange={(e) => setInputCode(e.target.value)}
className="border p-2 mb-4"
/>
<div className="flex justify-end">
<button onClick={handleConfirm} className="bg-blue-500 text-white p-2 rounded mr-2">
확인
</button>
<button onClick={close} className="bg-gray-500 text-white p-2 rounded">
취소
</button>
</div>
</div>
</div>
)}
</>
);
};

export default EmailConfirmModal;
61 changes: 61 additions & 0 deletions src/components/resetPwContent/changePwContent/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { FieldError, useForm } from 'react-hook-form';
import PasswordInput from '../../common/input/passwordInput';

type ChangePwForm = {
text?: string;
email: string;
password: string;
newpassword?: string;
passwordcheck?: string;
checkbox?: boolean;
file?: string;
nickname?: string;
};

const ChangePwContent = () => {
const {
register,
formState: { errors },
handleSubmit,
clearErrors,
// setError,
} = useForm<ChangePwForm>({ mode: 'onBlur', reValidateMode: 'onBlur' });

const handleChangePassword = () => {
//async
};
return (
<form onSubmit={handleSubmit(handleChangePassword)}>
<PasswordInput
register={register('password', {
required: {
value: true,
message: '비밀번호를 입력해주세요.',
},
})}
type="password"
clearError={clearErrors}
error={errors.password as FieldError}
inputName="password"
inputContent="비밀번호"
labelId="password"
/>
<PasswordInput
register={register('password', {
required: {
value: true,
message: '비밀번호를 다시 입력해주세요.',
},
})}
type="password"
clearError={clearErrors}
error={errors.password as FieldError}
inputName="checkPassword"
inputContent="비밀번호"
labelId="checkPassword"
/>
</form>
);
};

export default ChangePwContent;
Original file line number Diff line number Diff line change
@@ -1,19 +1,54 @@
import InputField from '@/src/components/common/input/InputField';
import { SubmitHandler, useForm } from 'react-hook-form';
import InputField from '@/src/components/common/input/InputField';
import emailjs from 'emailjs-com';
import EmailConfirmModal from '@/src/components/common/modal/emailConfirmModal';
import { useOverlay } from '@toss/use-overlay';

type FormValues = {
email: string;
};

const FindPwPage = () => {
const SERVICE_ID = process.env.NEXT_PUBLIC_SERVICE_ID as string;
const TEMPLATE_ID = 'trip';
const PUBLIC_KEY = process.env.NEXT_PUBLIC_PUBLIC_KEY;

const ResetPwContent = () => {
const {
register,
handleSubmit,
formState: { errors, isValid },
} = useForm<FormValues>({ mode: 'onChange' });
const overlay = useOverlay();

// 폼 제출 핸들러
const onSubmit: SubmitHandler<FormValues> = (data) => {
console.log(data);
sendVerificationEmail(data.email); // 이메일 인증 코드 전송
};

// 이메일 인증 코드 전송 함수
const sendVerificationEmail = (userEmail: string) => {
const code = Math.floor(Math.random() * 1000000).toString(); // 랜덤 인증 코드 생성
const templateParams = {
to_email: userEmail,
from_name: 'test',
message: code.padStart(6, '0'),
};

const onModal = () => {
overlay.open(({ isOpen, close }) => <EmailConfirmModal isOpen={isOpen} close={close} code={code} />);
};

emailjs
.send(SERVICE_ID, TEMPLATE_ID, templateParams, PUBLIC_KEY)
.then((response) => {
if (response.status === 200) {
onModal();
}
})
.catch((error) => {
console.error(error);
alert('인증 이메일 발송에 실패했습니다.');
});
};

return (
Expand Down Expand Up @@ -46,7 +81,7 @@ const FindPwPage = () => {
</form>
</div>
<button
className={`mt-30 w-full h-40 ${isValid ? 'bg-sky-200 hover:bg-sky-300' : 'bg-gray-200 hover:bg-gray-300'} `}
className={`mt-30 w-full h-40 ${isValid ? 'bg-sky-200 hover:bg-sky-300' : 'bg-gray-200 hover:bg-gray-300'}`}
type="submit"
onClick={handleSubmit(onSubmit)}
disabled={!isValid}
Expand All @@ -58,4 +93,4 @@ const FindPwPage = () => {
);
};

export default FindPwPage;
export default ResetPwContent;
7 changes: 6 additions & 1 deletion src/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import '@/src/styles/globals.css';
import type { AppProps } from 'next/app';
import { OverlayProvider } from '@toss/use-overlay';

export default function App({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />;
return (
<OverlayProvider>
<Component {...pageProps} />{' '}
</OverlayProvider>
);
}
7 changes: 7 additions & 0 deletions src/pages/reset-password/change-password/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import ChangePwContent from '@/src/components/resetPwContent/changePwContent';

const ChangePassword = () => {
return <ChangePwContent />;
};

export default ChangePassword;
7 changes: 7 additions & 0 deletions src/pages/reset-password/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import ResetPwContent from '@/src/components/resetPwContent';

const ResetPw = () => {
return <ResetPwContent />;
};

export default ResetPw;

0 comments on commit a9994a0

Please sign in to comment.