Skip to content

Commit

Permalink
Merge pull request #40 from epigram5-9/feat/FE-68
Browse files Browse the repository at this point in the history
FE-68 ✨ 회원가입 페이지 유효성 검사
  • Loading branch information
jangmoonwon authored Jul 19, 2024
2 parents 61098fb + 91e1fff commit 03d62c5
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 21 deletions.
62 changes: 41 additions & 21 deletions src/pages/auth/SignUp.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import Image from 'next/image';
import Link from 'next/link';
import AuthLayout from '@/pageLayout/AuthLayout/AuthLayout';
import z from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
import { PostSignUpRequest, PostSignUpRequestType } from '@/schema/auth';
import { useForm } from 'react-hook-form';
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form';

export default function SignUp() {
const form = useForm<z.infer<typeof formSchema>>({
const form = useForm<PostSignUpRequestType>({
resolver: zodResolver(PostSignUpRequest),
mode: 'onBlur',
defaultValues: {
email: '',
password: '',
Expand All @@ -17,13 +20,6 @@ export default function SignUp() {
},
});

const formSchema = z.object({
email: z.string(),
password: z.string(),
passwordConfirmation: z.string(),
nickname: z.string(),
});

return (
<AuthLayout>
<header className='mb-[50px] md:mb-[60px]'>
Expand All @@ -37,11 +33,16 @@ export default function SignUp() {
<FormField
control={form.control}
name='email'
render={({ field }) => (
render={({ field, fieldState }) => (
<FormItem className='flex flex-col md:gap-5 gap-4 w-full space-y-0'>
<FormLabel className='font-pretendard text-blue-900 lg:text-xl md:text-base sm:text-sm'>이메일</FormLabel>
<FormLabel className={`font-pretendard lg:text-xl md:text-base sm:text-sm ${fieldState.invalid ? 'text-state-error' : 'text-blue-900'}`}>이메일</FormLabel>
<FormControl>
<Input type='text' placeholder='이메일' className='lg:h-16 h-11 px-4 lg:text-xl md:text-base placeholder-blue-400 rounded-xl bg-blue-200 font-pretendard' {...field} />
<Input
type='text'
placeholder='이메일'
className={`lg:h-16 h-11 px-4 lg:text-xl md:text-base placeholder-blue-400 rounded-xl bg-blue-200 font-pretendard ${fieldState.invalid ? 'border-2 border-state-error' : ''}`}
{...field}
/>
</FormControl>
<FormMessage className='flex justify-end text-[13px] text-state-error' />
</FormItem>
Expand All @@ -51,11 +52,16 @@ export default function SignUp() {
<FormField
control={form.control}
name='password'
render={({ field }) => (
render={({ field, fieldState }) => (
<FormItem className='flex flex-col md:gap-5 gap-4 w-full space-y-0'>
<FormLabel className='font-pretendard text-blue-900 lg:text-xl md:text-base sm:text-sm'>비밀번호</FormLabel>
<FormLabel className={`font-pretendard lg:text-xl md:text-base sm:text-sm ${fieldState.invalid ? 'text-state-error' : 'text-blue-900'}`}>비밀번호</FormLabel>
<FormControl>
<Input type='password' placeholder='비밀번호' className='lg:h-16 h-11 px-4 lg:text-xl md:text-base placeholder-blue-400 rounded-xl bg-blue-200 font-pretendard' {...field} />
<Input
type='password'
placeholder='비밀번호'
className={`lg:h-16 h-11 px-4 lg:text-xl md:text-base placeholder-blue-400 rounded-xl bg-blue-200 font-pretendard ${fieldState.invalid ? 'border-2 border-state-error' : ''}`}
{...field}
/>
</FormControl>
<FormMessage className='flex justify-end text-[13px] text-state-error' />
</FormItem>
Expand All @@ -64,10 +70,15 @@ export default function SignUp() {
<FormField
control={form.control}
name='passwordConfirmation'
render={({ field }) => (
render={({ field, fieldState }) => (
<FormItem className='flex flex-col md:gap-5 gap-4 w-full space-y-0'>
<FormControl>
<Input type='password' placeholder='비밀번호 확인' className='lg:h-16 h-11 px-4 lg:text-xl md:text-base placeholder-blue-400 rounded-xl bg-blue-200 font-pretendard' {...field} />
<Input
type='password'
placeholder='비밀번호 확인'
className={`lg:h-16 h-11 px-4 lg:text-xl md:text-base placeholder-blue-400 rounded-xl bg-blue-200 font-pretendard ${fieldState.invalid ? 'border-2 border-state-error' : ''}`}
{...field}
/>
</FormControl>
<FormMessage className='flex justify-end text-[13px] text-state-error' />
</FormItem>
Expand All @@ -77,18 +88,27 @@ export default function SignUp() {
<FormField
control={form.control}
name='nickname'
render={({ field }) => (
render={({ field, fieldState }) => (
<FormItem className='flex flex-col md:gap-5 gap-4 w-full space-y-0'>
<FormLabel className='font-pretendard text-blue-900 lg:text-xl md:text-base sm:text-sm'>닉네임</FormLabel>
<FormLabel className={`font-pretendard lg:text-xl md:text-base sm:text-sm ${fieldState.invalid ? 'text-state-error' : 'text-blue-900'}`}>닉네임</FormLabel>
<FormControl>
<Input type='text' placeholder='닉네임' className='lg:h-16 h-11 px-4 lg:text-xl md:text-base placeholder-blue-400 rounded-xl bg-blue-200 font-pretendard' {...field} />
<Input
type='text'
placeholder='닉네임'
className={`lg:h-16 h-11 px-4 lg:text-xl md:text-base placeholder-blue-400 rounded-xl bg-blue-200 font-pretendard ${fieldState.invalid ? 'border-2 border-state-error' : ''}`}
{...field}
/>
</FormControl>
<FormMessage className='flex justify-end text-[13px] text-state-error' />
</FormItem>
)}
/>
</div>
<Button type='submit' className='w-full lg:max-w-[640px] md:max-w-[384px] lg:h-16 h-11 bg-black-500 font-pretendard text-white lg:text-xl md:text-base rounded-xl'>
<Button
disabled={!form.formState.isValid}
type='submit'
className={`w-full lg:max-w-[640px] md:max-w-[384px] lg:h-16 h-11 bg-black-500 font-pretendard text-white lg:text-xl md:text-base rounded-xl ${!form.formState.isValid ? 'bg-blue-300' : 'bg-black-500'}`}
>
가입하기
</Button>
</form>
Expand Down
20 changes: 20 additions & 0 deletions src/schema/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import z from 'zod';

const PWD_VALIDATION = /^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[!@#$%^&*])[a-zA-Z0-9!@#$%^&*]{8,}$/;
export const PostSignUpRequest = z
.object({
email: z.string().min(1, { message: '이메일은 필수 입력입니다.' }).email({ message: '이메일 형식으로 작성해 주세요.' }),
password: z
.string()
.min(1, { message: '비밀번호는 필수 입력입니다.' })
.min(8, { message: '비밀번호는 최소 8자 이상입니다.' })
.regex(PWD_VALIDATION, { message: '비밀번호는 숫자, 영문, 특수문자로만 가능합니다.' }),
passwordConfirmation: z.string().min(1, { message: '비밀번호 확인을 입력해주세요.' }),
nickname: z.string().min(1, { message: '닉네임은 필수 입력입니다.' }).max(20, { message: '닉네임은 최대 20자까지 가능합니다.' }),
})
.refine((data) => data.password === data.passwordConfirmation, {
message: '비밀번호가 일치하지 않습니다.',
path: ['passwordConfirmation'],
});

export type PostSignUpRequestType = z.infer<typeof PostSignUpRequest>;

0 comments on commit 03d62c5

Please sign in to comment.