Skip to content

Commit 9964089

Browse files
authored
Merge pull request #101 from imaginer-dev/8-회원가입-폼을-입력하고-유효성-검증을-할-수-있어야-한다
feat: joinpage 화면구성&뒤로가기 버튼 중간완성
2 parents 291eada + c076379 commit 9964089

16 files changed

+290
-1
lines changed

src/components/Join/EmailInput.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import InputForm from '../common/InputForm.tsx';
2+
import { useJoinState } from '../../stores/joinStore.ts';
3+
4+
const EmailInput = () => {
5+
const { email, emailHandler } = useJoinState();
6+
7+
return (
8+
<InputForm
9+
defaultValue={email}
10+
title={'이메일'}
11+
placeholder={'이메일을 입력하세요'}
12+
hint={'Hint Text'}
13+
onChange={(e) => emailHandler(e.target.value)}
14+
type={'email'}
15+
name={'email'}
16+
/>
17+
);
18+
};
19+
20+
export default EmailInput;

src/components/Join/JoinButton.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { useJoinState } from "../../stores/joinStore";
2+
3+
const JoinButton = () => {
4+
const { name, phone, email, password, pwCheck, useTermsCheck, privacyTermsCheck } = useJoinState();
5+
6+
const onClick = () => {
7+
console.log('name: ', name);
8+
console.log('phone: ', phone);
9+
console.log('email: ', email);
10+
console.log('password: ', password);
11+
console.log('pwCheck: ', pwCheck);
12+
console.log('useTermsCheck: ', useTermsCheck);
13+
console.log('privacyTermsCheck: ', privacyTermsCheck);
14+
};
15+
16+
return (
17+
<button type={'submit'} onClick={onClick} className="btn btn-outline btn-primary w-full">
18+
회원가입 하기
19+
</button>
20+
);
21+
};
22+
23+
export default JoinButton;

src/components/Join/JoinForm.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { FC, ReactNode } from 'react';
2+
3+
interface Props {
4+
children: ReactNode;
5+
}
6+
7+
const JoinForm: FC<Props> = ({ children }) => {
8+
return <form className={'flex w-full flex-col mt-9'}>{children}</form>;
9+
};
10+
11+
export default JoinForm;
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { FC, ReactNode } from 'react';
2+
3+
interface Props {
4+
children: ReactNode;
5+
}
6+
7+
const JoinFormActions: FC<Props> = ({ children }) => {
8+
return <div className={'flex w-full flex-col gap-2'}>{children}</div>;
9+
};
10+
11+
export default JoinFormActions;

src/components/Join/NameInput.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import InputForm from '../common/InputForm.tsx';
2+
import { useJoinState } from '../../stores/joinStore.ts';
3+
4+
const NameInput = () => {
5+
const { name, nameHandler } = useJoinState();
6+
7+
return (
8+
<InputForm
9+
defaultValue={name}
10+
title={'이름'}
11+
placeholder={'이름을 입력하세요'}
12+
hint={'Hint Text'}
13+
onChange={(e) => nameHandler(e.target.value)}
14+
type={'name'}
15+
name={'name'}
16+
/>
17+
);
18+
};
19+
20+
export default NameInput;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import InputForm from '../common/InputForm.tsx';
2+
import { useJoinState } from '../../stores/joinStore.ts';
3+
4+
const PasswordInput = () => {
5+
const { password, passwordHandler } = useJoinState();
6+
7+
return (
8+
<InputForm
9+
defaultValue={password}
10+
title={'비밀번호'}
11+
placeholder={'Password'}
12+
hint={'Hint Text'}
13+
onChange={(e) => passwordHandler(e.target.value)}
14+
name={'password'}
15+
type={'password'}
16+
/>
17+
);
18+
};
19+
20+
export default PasswordInput;

src/components/Join/PhoneInput.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import InputForm from '../common/InputForm.tsx';
2+
import { useJoinState } from '../../stores/joinStore.ts';
3+
4+
const PhoneInput = () => {
5+
const { phone, phoneHandler } = useJoinState();
6+
7+
return (
8+
<InputForm
9+
defaultValue={phone}
10+
title={'핸드폰 번호'}
11+
placeholder={'핸드폰 번호를 입력하세요'}
12+
hint={'Hint Text'}
13+
onChange={(e) => phoneHandler(e.target.value)}
14+
type={'phone'}
15+
name={'phone'}
16+
/>
17+
);
18+
};
19+
20+
export default PhoneInput;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import InputForm from '../common/InputForm.tsx';
2+
import { useJoinState } from '../../stores/joinStore.ts';
3+
4+
const PwCheckInput = () => {
5+
const { pwCheck, pwCheckHandler } = useJoinState();
6+
7+
return (
8+
<InputForm
9+
defaultValue={pwCheck}
10+
title={'비밀번호 확인'}
11+
placeholder={'Password Check'}
12+
hint={'Hint Text'}
13+
onChange={(e) => pwCheckHandler(e.target.value)}
14+
name={'pwCheck'}
15+
type={'password'}
16+
/>
17+
);
18+
};
19+
20+
export default PwCheckInput;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { useJoinState } from '../../stores/joinStore.ts';
2+
3+
const TermsCheckInput = () => {
4+
const { useTermsCheck, privacyTermsCheck, useTermsCheckHandler, privacyTermsCheckHandler } = useJoinState();
5+
6+
return (
7+
<label className="form-control w-full mt-5 mb-9">
8+
<div className="flex flex-col">
9+
<label className='font-bold'>약관 동의</label>
10+
</div>
11+
<div className="flex justify-between items-center mt-2">
12+
<label htmlFor="termsOne">이용약관 동의 (필수)</label>
13+
<input type="radio" className='radio radio-primary' checked={useTermsCheck} onClick={useTermsCheckHandler} />
14+
</div>
15+
{!useTermsCheck ? <span className="text-red-500">이용약관에 동의해 주세요.</span> : <span className='h-6'></span> }
16+
<div className="flex justify-between items-center mt-2">
17+
<label htmlFor="termsTwo">개인정보 수집, 이용 동의 (필수)</label>
18+
<input type="radio" className='radio radio-primary' checked={privacyTermsCheck} onClick={privacyTermsCheckHandler} />
19+
20+
</div>
21+
{!privacyTermsCheck ? <span className="text-red-500">개인정보 수집, 이용에 동의해 주세요.</span> : <span className='h-6'></span> }
22+
</label>
23+
);
24+
};
25+
26+
export default TermsCheckInput;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { useNavigate } from 'react-router-dom';
2+
3+
const HistoryBackButton: React.FC = () => {
4+
const navigate = useNavigate();
5+
6+
const handleBack = () => {
7+
navigate(-1);
8+
};
9+
10+
return (
11+
<div className="relative">
12+
<svg onClick={handleBack}
13+
className={'shrink-0'}
14+
width="256"
15+
height="512"
16+
viewBox="0 0 256 512"
17+
fill="none"
18+
preserveAspectRatio='xMinYMin meet'
19+
xmlns="http://www.w3.org/2000/svg"
20+
>
21+
<path d="M9.4 278.6c-12.5-12.5-12.5-32.8 0-45.3l128-128c9.2-9.2 22.9-11.9 34.9-6.9s19.8 16.6 19.8 29.6l0 256c0 12.9-7.8 24.6-19.8 29.6s-25.7 2.2-34.9-6.9l-128-128z"/>
22+
</svg>
23+
</div>
24+
);
25+
};
26+
27+
export default HistoryBackButton;

0 commit comments

Comments
 (0)