Skip to content

Commit

Permalink
Merge pull request #62 from Kernel360/page-signup
Browse files Browse the repository at this point in the history
페이지 UI: 회원가입
  • Loading branch information
bottlewook authored Jan 10, 2024
2 parents a8a84cb + 6dcb2b9 commit 91dca08
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 24 deletions.
7 changes: 7 additions & 0 deletions src/app/signup/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function Signuplayout({ children }: { children: React.ReactNode }) {
return (
<div style={{ padding: '0 24px' }}>{children}</div>
);
}

export default Signuplayout;
5 changes: 5 additions & 0 deletions src/app/signup/page.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.ageGroupContainer {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 18px;
}
60 changes: 60 additions & 0 deletions src/app/signup/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/* eslint-disable @typescript-eslint/no-misused-promises */

'use client';

import { useForm } from 'react-hook-form';

import classNames from 'classnames/bind';

import Button from '@components/shared/button/Button';
import Flex from '@components/shared/flex/Flex';
import Header from '@components/shared/header/Header';
import Radio from '@components/shared/radio/Radio';
import Spacing from '@components/shared/spacing/Spacing';
import Text from '@components/shared/text/Text';
import TextField from '@components/shared/text-field/TextField';
import Title from '@components/shared/title/Title';

import styles from './page.module.scss';

const cx = classNames.bind(styles);

function SignupPage() {
const { register, handleSubmit } = useForm();
// eslint-disable-next-line @typescript-eslint/require-await
const onSubmit = async () => {
// console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Header displayLogo={false} />
<Spacing size={20} />
<Title title="회원가입" />
<TextField label="아이디" required placeholder="아이디" {...register('id')} />
<TextField label="비밀번호" required placeholder="비밀번호" {...register('password')} />
<TextField label="비밀번호 확인" required placeholder="비밀번호 확인" {...register('confirmedPassword')} />
<TextField label="이메일" required placeholder="이메일" {...register('email')} />
<Text typography="t6"> 성별</Text>
<Spacing size={20} />
<Flex justify="space-between" gap={10}>
<Radio type="gender" label="남성" value="male" {...register('gender')} />
<Radio type="gender" label="여성" value="female" {...register('gender')} />
</Flex>
<Spacing size={20} />
<Text typography="t6">연령층</Text>
<Spacing size={20} />
<div className={cx('ageGroupContainer')}>
<Radio type="ageGroup" label="20대 이상" value="20" {...register('age')} />
<Radio type="ageGroup" label="30대" value="30" {...register('age')} />
<Radio type="ageGroup" label="40대" value="40" {...register('age')} />
<Radio type="ageGroup" label="50대" value="50" {...register('age')} />
<Radio type="ageGroup" label="60대 이상" value="60" {...register('age')} />
</div>
<Spacing size={50} />
<Button size="medium" full>약관 동의하러 가기</Button>
<Spacing size={20} />
</form>
);
}

export default SignupPage;
6 changes: 5 additions & 1 deletion src/components/shared/Input/Input.module.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
input {
.input {
box-sizing: border-box;
width: 100%;
height: 48px;
Expand All @@ -16,4 +16,8 @@ input {
&[aria-invaild="true"] {
border-color: var(--red);
}

&::placeholder {
color: var(--gray-100);
}
}
8 changes: 6 additions & 2 deletions src/components/shared/Input/Input.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { forwardRef, InputHTMLAttributes } from 'react';
import './Input.module.scss';

import classNames from 'classnames/bind';

import styles from './Input.module.scss';

const cx = classNames.bind(styles);
// eslint-disable-next-line prefer-arrow-callback
const Input = forwardRef<HTMLInputElement, InputHTMLAttributes<HTMLInputElement>>((props, ref) => {
return <input {...props} ref={ref} />;
return <input className={cx('input')} {...props} ref={ref} />;
});

export default Input;
7 changes: 4 additions & 3 deletions src/components/shared/flex/Flex.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@ interface FlexProps {
justify?: CSSProperties['justifyContent']
direction?: CSSProperties['flexDirection']
children: React.ReactNode
gap?: number
className?: string
}

function Flex({
align, justify, direction, children, className,
align, justify, direction, children, className, gap = 0,
}: FlexProps) {
const styles = useMemo(() => {
return {
display: 'flex', alignItems: align, justifyContent: justify, flexDirection: direction,
display: 'flex', alignItems: align, justifyContent: justify, flexDirection: direction, gap: `${gap}px`,
};
}, [align, justify, direction]);
}, [align, justify, direction, gap]);

return (
<div style={styles} className={className}>
Expand Down
22 changes: 11 additions & 11 deletions src/components/shared/radio/Radio.module.scss
Original file line number Diff line number Diff line change
@@ -1,48 +1,48 @@
input[type="radio"] {
.input[type="radio"] {
display: none;
}

label {
.label {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
}

label.gender {
.label.gender {
height: 48px;
border-radius: 8px;
}

input[type="radio"] + label.gender {
.input[type="radio"] + .label.gender {
border: 1px solid var(--gray-100);
background-color: var(--white);
color: var(--gray-300);
}

input[type="radio"]:checked + label.gender {
.input[type="radio"]:checked + .label.gender {
background-color: var(--primary);
color: var(--white);
}

label.ageGroup {
.label.ageGroup {
height: 47px;
border-radius: 30px;
}

label.additionalInfo {
.label.additionalInfo {
height: 60px;
border-radius: 10px;
}

input[type="radio"] + label.ageGroup,
input[type="radio"] + label.additionalInfo {
.input[type="radio"] + .label.ageGroup,
.input[type="radio"] + .label.additionalInfo {
background-color: var(--white-100);
color: var(--gray-300);
}

input[type="radio"]:checked + label.ageGroup,
input[type="radio"]:checked + label.additionalInfo {
.input[type="radio"]:checked + .label.ageGroup,
.input[type="radio"]:checked + .label.additionalInfo {
background-color: var(--primary);
color: var(--white-100);
}
6 changes: 3 additions & 3 deletions src/components/shared/radio/Radio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ interface RadioProps extends InputHTMLAttributes<HTMLInputElement> {
const cx = classNames.bind(styles);

const Radio = forwardRef<HTMLInputElement, RadioProps>(({
type, label, value,
type, label, value, ...props
}, ref) => {
return (
<>
<input id={label} type="radio" ref={ref} value={value} />
<label className={cx({ [type]: true })} htmlFor={label}>
<input className={cx('input')} id={label} type="radio" ref={ref} value={value} {...props} />
<label className={cx('label', { [type]: true })} htmlFor={label}>
{label}
</label>
</>
Expand Down
6 changes: 2 additions & 4 deletions src/components/shared/text-field/TextField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,9 @@ const TextField = forwardRef<HTMLInputElement, TextFieldProps>(function TextFiel
{required && <Text typography="t6" display="inline-block" color="red">*</Text>}
<Spacing size={12} />
<Input ref={ref} aria-vaild={hasError} onFocus={handleFocus} onBlur={handleBlur} {...props} />
<Spacing size={12} />
{hasError && (
<>
<Spacing size={12} />
<Text typography="t7" color={labelColor} display="inline-block">{helpMessage}</Text>
</>
<Text typography="t7" color={labelColor} display="inline-block">{helpMessage}</Text>
)}
</div>
);
Expand Down

0 comments on commit 91dca08

Please sign in to comment.