Skip to content

Commit f17944a

Browse files
[#162] ✨ 회원가입 페이지 개발 (#183)
* [#162] 🌱 Initialize SignUp page creation * [#162] ✨ Complete SignUp page UI implementation * [#98] ♻️ Refactor FormText to use div as top-level element and Update FormCheckbox label prop * [#45] ♻️ Update label prop * [#162] 💄 update checkbox label using highlight components * [#162] ♻️ add button type to checkbox + add twmergeex to remove border when checked * [#162] ♻️ type modification * [#162] ✨ develop signup page * [#162] ♻️ update signin mutation * [#103] ♻️ Update login and signup URLs in header * [#103] ♻️ Update login and signup URLs in header --------- Co-authored-by: KingNono1030 <[email protected]>
1 parent d1ecf72 commit f17944a

File tree

7 files changed

+187
-81
lines changed

7 files changed

+187
-81
lines changed

src/app/(pages)/sign-up/page.tsx

Lines changed: 0 additions & 63 deletions
This file was deleted.

src/app/(pages)/signup/page.tsx

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
'use client'
2+
3+
import { useForm } from 'react-hook-form'
4+
5+
import { SignUpRequest } from '@/types/api/Auth.types'
6+
7+
import { Button } from '@/components/common/button'
8+
import { Label } from '@/components/common/label'
9+
import { Highlight, Text } from '@/components/common/text'
10+
import { Form } from '@/components/shared/form'
11+
12+
import { useSignUpMutation } from '@/queries/auth'
13+
14+
interface SignUpForm extends SignUpRequest {
15+
passwordConfirmation: boolean
16+
}
17+
/**
18+
* 1. 회원가입 체크박스 백엔드 api 수정 필요할듯
19+
*/
20+
21+
export default function SignUp(): JSX.Element {
22+
const methods = useForm<SignUpForm>({
23+
mode: 'onChange',
24+
defaultValues: {
25+
email: '',
26+
password: '',
27+
name: '',
28+
gitHub: '',
29+
},
30+
})
31+
32+
const {
33+
handleSubmit,
34+
watch,
35+
formState: { errors, isValid },
36+
} = methods
37+
38+
const emailValue = watch('email')
39+
const isEmailValid = emailValue && !errors.email
40+
const { mutate: signUp } = useSignUpMutation()
41+
42+
const onSubmit = (data: SignUpForm) => {
43+
const { passwordConfirmation, ...signUpData } = data
44+
signUp({
45+
...signUpData,
46+
gitHub: data.gitHub || '',
47+
})
48+
}
49+
50+
return (
51+
<div className='m-auto flex h-auto w-420 flex-col pt-80'>
52+
<Text.Heading as='h2' variant='heading2' className='mb-20'>
53+
회원가입
54+
</Text.Heading>
55+
<Form methods={methods} onSubmit={handleSubmit(onSubmit)}>
56+
<Label labelText='이메일' required className='mb-20'>
57+
<div className='flex items-baseline gap-x-8'>
58+
<Form.Text
59+
name='email'
60+
className='h-48 w-325'
61+
placeholder='이메일을 입력해주세요'
62+
/>
63+
<Button disabled={!isEmailValid} className='w-87' size='lg'>
64+
중복확인
65+
</Button>
66+
</div>
67+
</Label>
68+
<Label labelText='이름' required className='mb-20'>
69+
<Form.Text name='name' placeholder='이름을 입력해주세요' />
70+
</Label>
71+
<Label labelText='비밀번호' required className='mb-20'>
72+
<Form.Password
73+
name='password'
74+
placeholder='비밀번호를 입력해주세요'
75+
/>
76+
</Label>
77+
<Label labelText='비밀번호 확인' required className='mb-20'>
78+
<Form.Password
79+
name='passwordConfirmation'
80+
placeholder='비밀번호를 다시 한번 입력해주세요'
81+
/>
82+
</Label>
83+
<Label labelText='나의 Github 주소' className='mb-20'>
84+
<div className='flex flex-row items-center gap-x-8'>
85+
<Text.Body as='p' variant='body1' color='gray500'>
86+
https://github.com/
87+
</Text.Body>
88+
<Form.Text name='gitHub' className='w-276' />
89+
</div>
90+
</Label>
91+
<Form.Checkbox
92+
name='agreeToAll'
93+
variant='checkbox'
94+
label={
95+
<Text.Title variant='title2' weight='700'>
96+
전체동의
97+
</Text.Title>
98+
}
99+
/>
100+
{/**
101+
* TODO
102+
* 1. 구분선 컴포넌트 들어가야함
103+
* 2. font-weight 적용 안 되는 문제 해결
104+
* */}
105+
<div className='mb-40 mt-16 flex flex-col gap-y-8'>
106+
<Form.Checkbox
107+
name='age'
108+
variant='checkbox'
109+
label={
110+
<Text.Body variant='body1' color='gray500'>
111+
{'만 14세 미만입니다 '}
112+
<Highlight className='text-gray-800'>(필수)</Highlight>
113+
</Text.Body>
114+
}
115+
/>
116+
<Form.Checkbox
117+
name='termsAgreement'
118+
variant='checkbox'
119+
label={
120+
<Text.Body variant='body1' color='gray500'>
121+
{'서비스 이용약관 동의 '}
122+
<Highlight className='text-gray-800'>(필수)</Highlight>
123+
</Text.Body>
124+
}
125+
/>
126+
<Form.Checkbox
127+
name='userInfo'
128+
variant='checkbox'
129+
label={
130+
<Text.Body variant='body1' color='gray500'>
131+
{'개인정보 수집 및 이용 동의 '}
132+
<Highlight className='text-gray-800'>(필수)</Highlight>
133+
</Text.Body>
134+
}
135+
/>
136+
<Form.Checkbox
137+
name='marketingConsent'
138+
variant='checkbox'
139+
label={
140+
<Text.Body variant='body1' color='gray500'>
141+
이벤트 등 마케팅 정보 수신 동의 (선택)
142+
</Text.Body>
143+
}
144+
/>
145+
<div className='ml-30 flex gap-x-20'>
146+
<Form.Checkbox
147+
name='email'
148+
variant='check'
149+
label='이메일'
150+
className='ml-4'
151+
/>
152+
<Form.Checkbox
153+
name='sms'
154+
variant='check'
155+
label='문자'
156+
className='ml-4'
157+
/>
158+
</div>
159+
</div>
160+
<Button
161+
type='submit'
162+
disabled={!isValid}
163+
size='lg'
164+
fullWidth
165+
className='mb-110'
166+
>
167+
회원가입
168+
</Button>
169+
</Form>
170+
</div>
171+
)
172+
}

src/components/common/input/CheckboxInput.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { toggleCheckbox } from '@/utils/toggleCheckbox'
66

77
export interface CheckboxInputProps
88
extends React.InputHTMLAttributes<HTMLInputElement> {
9-
label: string
9+
label: string | React.ReactNode
1010
variant: 'checkbox' | 'check'
1111
}
1212

@@ -59,6 +59,7 @@ export const CheckboxInput = ({
5959
disabled && 'cursor-not-allowed opacity-50'
6060
)
6161
const labelTextClass = cn(className)
62+
6263
return (
6364
<label className={labelClass}>
6465
<input
@@ -71,6 +72,7 @@ export const CheckboxInput = ({
7172
/>
7273
<span
7374
role='checkbox'
75+
type='button'
7476
tabIndex={0}
7577
aria-checked={checked}
7678
aria-label={'checkbox button'}

src/components/shared/form/Form.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ const FormText = ({
6161
const isSuccess = touchedFields[name] && !errors[name] && value
6262

6363
return (
64-
<>
64+
<div>
6565
<TextInput
6666
{...register(name, VALIDATION_RULES[name])}
6767
error={Boolean(errors[name])}
@@ -78,7 +78,7 @@ const FormText = ({
7878
가입 가능한 이메일입니다.
7979
</StatusMessage>
8080
)} */}
81-
</>
81+
</div>
8282
)
8383
}
8484

@@ -147,7 +147,7 @@ const FormCheckbox = ({
147147
name: string
148148
rules?: Record<string, unknown>
149149
options?: { label: string; value: string }[]
150-
label?: string
150+
label?: string | React.ReactNode
151151
} & CheckboxInputProps): JSX.Element => {
152152
const { control } = useFormContext()
153153
return (

src/components/shared/header/Header.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ const renderUserMenu = (isAuthenticated: boolean, user: User | null) => {
2424
<HeaderUserMenu user={user} />
2525
) : (
2626
<Container className='flex items-center justify-between gap-12'>
27-
<Link href='/auth/sign-in' variant='outlined' size='lg'>
27+
<Link href='/login' variant='outlined' size='lg'>
2828
로그인
2929
</Link>
30-
<Link href='/auth/sign-up' size='lg'>
30+
<Link href='/signup' size='lg'>
3131
회원가입
3232
</Link>
3333
</Container>

src/constants/formValidation.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ export type FormField =
99
| 'name'
1010
| 'nickname'
1111
| 'introduce'
12-
| 'github'
13-
| string
12+
| 'gitHub'
1413

1514
const FIELD_DICTIONARY: Record<FormField, string> = {
1615
email: '이메일',
@@ -19,7 +18,7 @@ const FIELD_DICTIONARY: Record<FormField, string> = {
1918
name: '이름',
2019
nickname: '닉네임',
2120
introduce: '소개',
22-
github: '깃허브',
21+
gitHub: '깃허브',
2322
}
2423
const EMAIL_PATTERN = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
2524
const PASSWORD_PATTERN = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d!@#$%^&*]{8,16}$/
@@ -104,5 +103,5 @@ export const VALIDATION_RULES: Record<FormField, RegisterOptions> = {
104103
name: NAME_RULES,
105104
nickname: NICKNAME_RULES,
106105
introduce: INTRODUCE_RULES,
107-
github: GITHUB_RULES,
106+
gitHub: GITHUB_RULES,
108107
}

src/queries/auth/index.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,10 @@ export const useSignUpMutation = () => {
4545

4646
return useMutation({
4747
mutationFn: SignUp,
48-
onSuccess: result => {
49-
console.log('회원가입 성공', result)
50-
alert('회원가입 성공')
51-
router.push(`/sign-in`)
52-
},
53-
onError: (error: unknown) => {
54-
console.error('SignUp Error:', error)
55-
alert('회원가입 요청 중 오류가 발생했습니다')
48+
onSuccess: result => {},
49+
onError: (error: any) => {
50+
console.error('Sign-up error:', error.response)
51+
alert(error.response?.message || '회원가입 요청 중 오류가 발생했습니다.')
5652
},
5753
})
5854
}

0 commit comments

Comments
 (0)