import { Button, Label, Spinner, TextInput } from "flowbite-react";
import { useState } from "react";
import toast from "react-hot-toast";
import { Link, useNavigate, } from "react-router-dom";
import { signup } from "../apis/auth";
const SignUp = () => {
const navigate = useNavigate();
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [email, setEmail] = useState("");
const [loading, setLoading] = useState(false);
const [errors, setErrors] = useState({
username: "",
password: "",
name: "",
email: "",
});
const handleSubmit = async (e) => {
e.preventDefault();
try {
if (validateForm()) {
setLoading(true);
const result = await signup({username, password, email});
setLoading(false);
if (result.status === 201) {
toast.success('회원가입이 완료되었습니다.');
navigate('/signin');
} else {
toast.error(result.data.message);
}
}
} catch (error) {
toast.error('회원가입에 실패했습니다. 다시 시도해주세요.', error.message);
setLoading(false);
}
}
const validateForm = () => {
let isValid = true;
const newErrors = { ...errors }; // 기존 에러 상태 복사
if (!username) {
newErrors.username = "아이디를 입력하세요.";
isValid = false;
} else if (username.length < 2) {
newErrors.username = "아이디는 최소 2자 이상이어야 합니다.";
isValid = false;
}
if (!password) {
newErrors.password = "비밀번호를 입력하세요.";
isValid = false;
} else if (password.length < 4) {
newErrors.password = "비밀번호는 최소 4자 이상이어야 합니다.";
isValid = false;
}
if (!email) {
newErrors.email = "이메일을 입력하세요.";
isValid = false;
} else if (!/\S+@\S+\.\S+/.test(email)) {
newErrors.email = "유효한 이메일 주소를 입력하세요.";
isValid = false;
}
setErrors(newErrors);
return isValid;
}
return (
<div className="min-h-screen mt-20">
<div className="flex p-3 max-w-3xl mx-auto flex-col md:flex-row gap-5">
{/* left */}
<div className="flex-1">
<Link
to="/"
className="font-bold dark:text-white text-4xl"
>
<span
className="px-2 py-1 bg-gradient-to-r from-indigo-500
via-purple-500 to-pink-500 rounded-lg text-white"
>
김기태
</span>
블로그
</Link>
<p className="text-sm mt-5">
현재 블로그 개발 중입니다.
<br />
회원은 이메일과 비밀번호로 가입하실 수 있습니다. 또는 Google 계정으로 가입하실 수 있습니다.
</p>
</div>
{/* right */}
<div className="flex-1">
<form className="flex flex-col gap-4" xxxxonSubmit={handleSubmit}>
<div>
<Label value='이름' />
<TextInput
type='text'
placeholder='사용자 이름을 입력하세요.'
id='username'
xxxxonChange={e => setUsername(e.target.value)}
color={errors.username ? 'failure' : undefined} // flowbite-react 스타일 오류 처리
helperText={
errors.username && (
<span className="text-sm text-red-600">{errors.username}</span>
)
}
/>
</div>
<div>
<Label value='이메일' />
<TextInput
type='email'
placeholder='사용할 이메일을 입력하세요'
id='email'
xxxxonChange={e => setEmail(e.target.value)}
color={errors.email ? 'failure' : undefined} // flowbite-react 스타일 오류 처리
helperText={
errors.email && (
<span className="text-sm text-red-600">{errors.email}</span>
)
}
/>
</div>
<div>
<Label value='비밀번호' />
<TextInput
type='password'
placeholder='사용할 비밀번호를 입력하세요'
id='password'
xxxxonChange={(e) => setPassword(e.target.value)}
color={errors.password ? 'failure' : undefined} // flowbite-react 스타일 오류 처리
helperText={
errors.password && (
<span className="text-sm text-red-600">{errors.password}</span>
)
}
/>
</div>
<Button
gradientDuoTone='purpleToPink'
type='submit'
disabled={loading} // 로딩 중에는 버튼 비활성화
>
{
loading ? (
<>
<Spinner size='sm' />
<span className='pl-3'>로딩 중...</span>
</>
) : ('회원 가입')
}
</Button>
</form>
<div className='flex gap-2 text-sm mt-5'>
<span>이미 회원 이신가요?</span>
<Link to='/sign-in' className='text-blue-500'>
로그인
</Link>
</div>
</div>
</div>
</div>
);
};
export default SignUp;