Skip to content

Commit

Permalink
refactor: Refactor sign in form using react-hook-form
Browse files Browse the repository at this point in the history
  • Loading branch information
bk-git-hub committed May 11, 2024
1 parent ff659cd commit be585da
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 83 deletions.
112 changes: 67 additions & 45 deletions components/SignInForm/SignInForm.tsx
Original file line number Diff line number Diff line change
@@ -1,58 +1,80 @@
import { useState } from 'react';
import AuthInput from '../AuthInput/AuthInput';
import Button from '../Button/Button';
import styles from '@/styles/AuthForm.module.scss';
import { validateEmail } from '@/utils/validateEmail';
import { setegid } from 'process';
import { z } from 'zod';
import { useForm, SubmitHandler } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';

export default function SignInForm() {
const [emailValue, setEmailValue] = useState('');
const [passwordValue, setPasswordValue] = useState('');
const [emailError, setEmailError] = useState(false);
const schema = z.object({
email: z
.string()
.min(1, { message: '이메일을 입력해주세요' })
.email({ message: '올바른 이메일 형식이 아닙니다' }),

const handleEmailChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setEmailValue(e.target.value);
};
password: z
.string()
.min(1, { message: '비밀번호를 입력해주세요' })
.min(8, { message: '비밀번호는 최소 8자 이상이어야 합니다.' }),
});

const handlePasswordChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setPasswordValue(e.target.value);
};
type SignInFormFields = z.infer<typeof schema>;

const handleEmailFocusOut = () => {
const isValidEmail = validateEmail(emailValue);
if (!isValidEmail) {
setEmailError(true);
}
};
export default function SignInForm() {
const {
register,
handleSubmit,
formState: { errors, isSubmitting },
} = useForm<SignInFormFields>({
resolver: zodResolver(schema),
});

const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const onSubmit: SubmitHandler<SignInFormFields> = async (data) => {
await new Promise((resolve) => setTimeout(resolve, 1000));
console.log(data);
};

return (
<form className={styles.authForm} onSubmit={handleSubmit}>
<AuthInput
type='email'
labelText='이메일'
id='user-email'
enableVisibilityToggle={false}
value={emailValue}
onChange={handleEmailChange}
onBlur={handleEmailFocusOut}
error='올바른 이메일 주소가 아닙니다'
hasError={emailError}
/>

<AuthInput
type='password'
labelText='비밀번호'
id='password'
enableVisibilityToggle={true}
value={passwordValue}
onChange={handlePasswordChange}
hasError={false}
/>
<Button className={styles.signUpButton} type='submit'>
<form className={styles.authForm} onSubmit={handleSubmit(onSubmit)}>
<div className={styles.inputBox}>
<label htmlFor='email'>이메일</label>
<div
className={`${styles.inputWrapper} ${
errors.email && styles.errorInput
}`}
>
<input
{...register('email')}
type='text'
placeholder='Email'
className={styles.authInput}
/>
</div>
{errors.email && (
<div className={styles.errorMessage}>{errors.email.message}</div>
)}
</div>
<div className={styles.inputBox}>
<label htmlFor='password'>비밀번호</label>
<div
className={`${styles.inputWrapper} ${
errors.password && styles.errorInput
}`}
>
<input
{...register('password')}
type='password'
placeholder='Password'
className={styles.authInput}
/>
</div>
{errors.password && (
<div className={styles.errorMessage}>{errors.password.message}</div>
)}
</div>
<Button
className={styles.signUpButton}
type='submit'
disabled={isSubmitting}
>
로그인
</Button>
</form>
Expand Down
50 changes: 15 additions & 35 deletions package-lock.json

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

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
"lint": "next lint"
},
"dependencies": {
"@hookform/resolvers": "^3.3.4",
"next": "13.5.6",
"react": "^18",
"react-dom": "^18",
"react-hook-form": "^7.51.4",
"yup": "^1.4.0"
"zod": "^3.23.8"
},
"devDependencies": {
"@types/node": "^20",
Expand Down
49 changes: 47 additions & 2 deletions styles/AuthForm.module.scss
Original file line number Diff line number Diff line change
@@ -1,11 +1,56 @@
@use '@/styles/mixins' as a;
@use '@/styles/mixins' as m;

.authForm {
@include a.flex(column);
@include m.flex(column);
gap: 24px;
}

.signUpButton {
padding: 16px 20px;
margin-top: 20px;
}

.inputBox {
@include m.flex(column);
position: relative;
gap: 12px;
}

.inputWrapper {
display: flex;
justify-content: space-between;
border: 1px solid #ccd5e3;
padding: 18px 15px;
border-radius: 8px;
background-color: #fff;
width: 370px;
}

.inputWrapper:focus-within {
border: 1px solid var(--Linkbrary-primary-color);
}

.authInput {
width: 100%;
border: none; /* Remove border from authInput to avoid double border */
}

.toggleButton {
position: relative;
width: 16px;
height: 16px;

&:hover {
filter: brightness(0);
}
}

.errorMessage {
position: absolute;
bottom: -25px;
color: red;
}

.errorInput {
border: 1px solid red;
}

0 comments on commit be585da

Please sign in to comment.