page.tsx 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. 'use client';
  2. import './style.scss';
  3. import Link from 'next/link';
  4. import { useRouter } from 'next/navigation';
  5. import { useState, useEffect, useRef } from 'react';
  6. import { ForgotPasswordRequest } from '@/dtos/request/auth';
  7. import { fetchForgotPassword } from '@/lib/api/auth';
  8. import { throwError } from '@/lib/utils/client';
  9. import { VerificationType } from '@/constants/common';
  10. import Loading from '@/app/component/Loading';
  11. export default function ForgotPassword()
  12. {
  13. const router = useRouter();
  14. const [loading, setLoading] = useState<boolean>(false);
  15. const [error, setError] = useState<string>('');
  16. const [email, setEmail] = useState<string>('');
  17. const emailRef = useRef<HTMLInputElement>(null);
  18. useEffect(() => {
  19. if (error) {
  20. alert(error);
  21. setError('');
  22. }
  23. }, [error]);
  24. const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
  25. e.preventDefault();
  26. try {
  27. setLoading(true);
  28. setError('');
  29. if (!email) {
  30. emailRef.current?.focus();
  31. throw new Error('이메일을 입력해주세요.');
  32. }
  33. await new Promise(resolve => setTimeout(resolve, 500));
  34. const res = await fetchForgotPassword({
  35. Email: email
  36. } as ForgotPasswordRequest);
  37. if (!res.ok) {
  38. throwError(res);
  39. }
  40. // 시간 제한 생성
  41. const expiration: string = (Date.now() + 10 * 60 * 1000).toString();
  42. const callbackURL: string = location.pathname;
  43. sessionStorage.setItem("type", VerificationType.ForgotPassword.toString());
  44. sessionStorage.setItem("expiration", expiration);
  45. sessionStorage.setItem("callbackURL", callbackURL);
  46. sessionStorage.setItem("email", email);
  47. router.push("/approval");
  48. } catch (err: any) {
  49. setError(err.message);
  50. } finally {
  51. setLoading(false);
  52. }
  53. }
  54. return (
  55. <>
  56. {loading && <Loading />}
  57. <div id="forgotPasswordForm" className="row-start-2">
  58. <fieldset>
  59. <legend>비밀번호 재설정</legend>
  60. <form method="post" acceptCharset="utf-8" autoComplete="off" className="grid pt-4 pl-4 pr-4 pb-1" onSubmit={handleSubmit}>
  61. <p>{process.env.SITE_NAME} 계정과 연결된 이메일 주소를 입력해주세요.</p>
  62. <p>해당 이메일로 인증번호가 발송되며 아래 입력란에 인증번호를 확인하면 비밀번호 재설정이 가능합니다.</p>
  63. <br />
  64. <label htmlFor="email">이메일</label>
  65. <input type="email" name="email" id="email" ref={emailRef} maxLength={30} onChange={e => setEmail(e.target.value)} autoComplete="off" />
  66. <button type="submit" className="btn btn-submit" disabled={loading}>
  67. {loading ? "조회 중..." : "다음 단계로"}
  68. </button>
  69. <hr />
  70. <Link href="/login">취소하기</Link>
  71. </form>
  72. </fieldset>
  73. </div>
  74. </>
  75. );
  76. }