| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- 'use client';
- import './style.scss';
- import Link from 'next/link';
- import { useRouter } from 'next/navigation';
- import { useState, useEffect, useRef } from 'react';
- import { Checkbox } from '@/components/ui/checkbox';
- import { Dialog, DialogTrigger } from '@/components/ui/dialog';
- import TermsDialog from '@/app/component/TermsDialog';
- import { VerificationType } from '@/constants/common';
- import { fetchApi, throwError } from '@/lib/utils/client';
- import { RegisterRequest } from '@/types/request/auth';
- import { RegisterResponse } from '@/types/response/auth';
- export default function Page()
- {
- const router = useRouter();
- const [error, setError] = useState<string>('');
- const [loading, setLoading] = useState<boolean>(false);
- const [email, setEmail] = useState<string>('');
- const [password, setPassword] = useState<string>('');
- const [rePassword, setRePassword] = useState<string>('');
- const [agree1, setAgree1] = useState<boolean>(false);
- const [agree2, setAgree2] = useState<boolean>(false);
- const emailRef = useRef<HTMLInputElement>(null);
- const passwordRef = useRef<HTMLInputElement>(null);
- const rePasswordRef = useRef<HTMLInputElement>(null);
- useEffect(() => {
- if (error) {
- alert(error);
- setError('');
- }
- }, [error]);
- const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
- e.preventDefault();
- try {
- if (email.length < 1) {
- emailRef.current?.focus();
- throw new Error('이메일을 입력해주세요.');
- }
- if (password.length < 1) {
- passwordRef.current?.focus();
- throw new Error('비밀번호를 입력해주세요.');
- }
- if (rePassword.length < 1) {
- rePasswordRef.current?.focus();
- throw new Error('비밀번호 확인을 입력해주세요.');
- }
- if (password !== rePassword) {
- throw new Error('비밀번호가 서로 일치하지 않습니다.');
- }
- if (!agree1 || !agree2) {
- throw new Error('모든 필수 약관에 동의해주세요.');
- }
- await new Promise(resolve => setTimeout(resolve, 500));
- const res = await fetchApi<RegisterResponse>('/api/auth/register', {
- method: 'POST',
- body: {
- Email: email,
- Password: password,
- IsPolicyAgree: agree1,
- IsPrivacyAgree: agree2
- } as RegisterRequest
- });
- throwError(res);
- // 시간 제한 생성
- const expiration: string = (Date.now() + 10 * 60 * 1000).toString();
- const callbackURL: string = location.pathname;
- sessionStorage.setItem('type', VerificationType.Registration.toString());
- sessionStorage.setItem('expiration', expiration);
- sessionStorage.setItem('callbackURL', callbackURL);
- sessionStorage.setItem('email', email);
- if (res.data!.isRegisterEmailAuth) {
- // 이메일 인증 필요
- router.push('/approval');
- } else {
- // 회원가입 완료
- router.push('/welcome');
- }
- } catch (err) {
- if (err instanceof Error) {
- setError(err.message);
- }
- } finally {
- setLoading(false);
- }
- }
- return (
- <>
- <div id="registForm" className="row-start-2">
- <fieldset>
- <legend>회원가입</legend>
- <form method="post" acceptCharset="utf-8" autoComplete="off" onSubmit={handleSubmit}>
- <div className="flex flex-row flex-wrap">
- <section className="sm:pt-4 sm:pb-4">
- <dl>
- <dt hidden> </dt>
- <dd>{ process.env.NEXT_PUBLIC_SITE_NAME } 에 오신 것을 환영합니다.</dd>
- <dd>빠르고 간단하게 회원가입을 진행하세요.</dd>
- </dl>
- <br/>
- <dl>
- <dt hidden> </dt>
- <dd>가입 확인을 위해 유효한 이메일을 입력해주세요.</dd>
- <dd>비밀번호는 최소 8자 이상 입력해주세요.</dd>
- </dl>
- </section>
- <section className="sm:pt-4">
- <article className="grid">
- <label htmlFor="email">이메일</label>
- <input type="email" name="email" id="email" ref={emailRef} maxLength={30} onChange={e => setEmail(e.target.value)} autoComplete="off" />
- <label htmlFor="password">비밀번호</label>
- <input type="password" name="password" id="password" ref={passwordRef} maxLength={20} onChange={e => setPassword(e.target.value)} />
- <label htmlFor="rePassword">비밀번호 확인</label>
- <input type="password" name="re_password" id="rePassword" ref={rePasswordRef} maxLength={20} onChange={e => setRePassword(e.target.value)} />
- </article>
- </section>
- </div>
- <hr />
- <div className="flex flex-row flex-wrap">
- <section>
- <dl>
- <dt>회원가입 약관</dt>
- <dd>원활한 서비스 이용을 위해 약관 동의가 필요합니다.</dd>
- <dd>약관 내용을 자세히 확인하신 후 동의해주세요.</dd>
- </dl>
- </section>
- <section className="pt-4 sm:pt-0">
- <p>
- <Checkbox name="agree_1" id="agree_1" onCheckedChange={(checked) => setAgree1(Boolean(checked))} />
- <label htmlFor="agree_1">
- <Dialog>
- <DialogTrigger>이용약관</DialogTrigger>
- <TermsDialog subject="이용약관" code="terms" />
- </Dialog>
- 에 동의합니다.
- </label>
- </p>
- <p>
- <Checkbox name="agree_2" id="agree_2" onCheckedChange={(checked) => setAgree2(Boolean(checked))} />
- <label htmlFor="agree_2">
- <Dialog>
- <DialogTrigger>개인정보처리방침</DialogTrigger>
- <TermsDialog subject="개인정보처리방침" code="privacy" />
- </Dialog>
- 에 동의합니다.
- </label>
- </p>
- <div className="grid grid-cols-2 gap-2 mt-3">
- <button type="submit" className="btn btn-submit" disabled={loading}>
- {loading ? "회원가입 중..." : "회원가입"}
- </button>
- <Link href="/login" className="btn btn-default">취소</Link>
- </div>
- </section>
- </div>
- </form>
- </fieldset>
- </div>
- </>
- );
- }
|