Skip to content

Commit

Permalink
✨:: #7 로그인 페이지 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
hyosin-Jang committed Mar 6, 2022
1 parent 27ac95a commit 4ed2b0e
Show file tree
Hide file tree
Showing 10 changed files with 476 additions and 0 deletions.
18 changes: 18 additions & 0 deletions src/component/Auth/AuthContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react';
import styled from 'styled-components';
import { theme } from '../../style/theme';

const AuthContent = ({ title }: { title: string }) => (
<div>
<Title>{title}</Title>
</div>
);

export default AuthContent;

const Title = styled.div`
font-size: 4rem;
font-weight: bold;
color: ${theme.color.dark_gray};
margin-bottom: 2rem;
`;
37 changes: 37 additions & 0 deletions src/component/Auth/FindButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { ReactChild } from 'react';
import { theme } from '../../style/theme';
import styled from 'styled-components';

interface FindButtonProps {
children?: ReactChild;
onClick?: any;
}
const FindButton = ({ children, onClick, ...rest }: FindButtonProps) => {
return (
<Wrapper onClick={onClick} {...rest}>
{children}
</Wrapper>
);
};

export default FindButton;

const Wrapper = styled.div`
display: flex;
justify-content: center;
align-items: center;
width: 300px;
border: 1px solid ${theme.color.purple};
border-radius: 5px;
cursor: pointer;
height: 40px;
margin-top: 1rem;
background: ${theme.color.white};
color: ${theme.color.purple};
height: ${(props) => props.height};
font-size: ${(props) => props.fontSize};
&:hover {
background: ${theme.color.purple};
color: white;
}
`;
47 changes: 47 additions & 0 deletions src/component/Auth/InputWithLabel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react';
import styled from 'styled-components';

const InputWithLabel = ({
label,
name,
placeholder,
...rest
}: {
label: string;
name: string;
placeholder: string;
}) => {
return (
<Wrapper>
<Label>{label}</Label>
<Input name={name} placeholder={placeholder} {...rest} />
</Wrapper>
);
};

export default InputWithLabel;

const Wrapper = styled.div`
& + & {
margin-top: 1rem;
}
`;

const Label = styled.div`
font-size: 1rem;
margin-bottom: 0.25rem;
font-weight: bold;
color: #9e9e9e;
`;

const Input = styled.input`
width: 300px;
border: 0;
border-bottom: 1px solid #e0e0e0;
outline: none;
border-radius: 0px;
line-height: 2.5rem;
font-size: 14px;
padding-left: 0.5rem;
padding-right: 0.5rem;
`;
27 changes: 27 additions & 0 deletions src/component/Auth/LoginButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';
import { theme } from '../../style/theme';
import styled from 'styled-components';

const LoginButton = ({ children, ...rest }: { children: string }) => {
return <Wrapper type="submit" value={children} {...rest} />;
};

export default LoginButton;

const Wrapper = styled.input`
display: flex;
justify-content: center;
align-items: center;
width: 300px;
border-radius: 5px;
cursor: pointer;
height: 40px;
margin-top: 1rem;
background: ${theme.color.Main};
color: white;
height: ${(props) => props.height};
&:hover {
background: ${theme.color.Main_lighten};
color: white;
}
`;
221 changes: 221 additions & 0 deletions src/component/Auth/Register.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
import { useRef, useState } from 'react';
import { useForm } from 'react-hook-form';
import styled from 'styled-components';
import { flexCenter, theme } from '../../style/theme';
import { AuthContent } from '.';
import usePassword from '../../hooks/usePassword';

const Register = () => {
const [isEmailError, setIsEmailError] = useState(false);

// hooks
const [passwordType, handlePasswordType] = usePassword({
type: 'password',
visible: false,
});

const [passwordConfirmType, handlePasswordConfirmType] = usePassword({
type: 'password',
visible: false,
});

interface Form {
email: string;
id: string;
pw: string;
pwConfirm: string;
}
const initValue: Form = {
email: '',
id: '',
pw: '',
pwConfirm: '',
};

const {
handleSubmit,
register,
watch,
formState: { errors },
} = useForm<Form>({
mode: 'onSubmit',
defaultValues: initValue,
});
const password = useRef();
const email = useRef();
password.current = watch('pw'); // pw 관찰
// 데이터 전송시 작동할 함수
const onSubmit = (data: Form) => {
console.log(data);
};
console.log(watch());

return (
<Wrapper>
<AuthContent title="회원가입" />
<div className="info">회원가입하여 다양한 서비스를 이용해보세요!</div>
<form onSubmit={handleSubmit(onSubmit)}>
<InputWrapper>
<div className="label">이메일</div>
<input
className={isEmailError ? 'error' : 'correct'}
placeholder="[email protected]"
{...register('email', {
required: '이메일을 입력해주세요.',
pattern: {
value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
message: '이메일을 형식에 맞게 작성해주세요',
},
})}
/>
{errors.email && (
<SubmitMessage>{errors.email.message}</SubmitMessage>
)}
</InputWrapper>
<InputWrapper>
<div className="label">아이디</div>
<Input
placeholder="아이디"
{...register('id', {
required: '아이디를 입력해주세요.',
pattern: {
// 아이디 정규식 패턴 다시 작성하기
value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
message: '아이디를 형식에 맞게 작성해주세요',
},
})}
/>
{errors.id && <SubmitMessage>{errors.id.message}</SubmitMessage>}
</InputWrapper>
<InputWrapper>
<div className="label">비밀번호</div>
<Input
type={passwordType.type}
placeholder="영문, 숫자를 혼용하여 8~16자를 입력해주세요"
{...register('pw', {
required: '비밀번호를 입력해주세요.',
minLength: {
value: 8,
message: '최소 8자 이상의 비밀번호를 입력해주세요.',
},
maxLength: {
value: 16,
message: '16자 이하의 비밀번호만 사용 가능합니다.',
},
pattern: {
value: /^(?=.*[A-Za-z])(?=.*d)[A-Za-zd]{8,}/,
message: '영문, 숫자를 혼용해서 입력해주세요.',
},
})}
/>
{errors.pw && <SubmitMessage>{errors.pw.message}</SubmitMessage>}
<span onClick={handlePasswordType} />
</InputWrapper>
<InputWrapper>
<div className="label">비밀번호 확인</div>
<Input
type={passwordConfirmType.type}
placeholder="비밀번호 확인"
{...register('pwConfirm', {
required: '비밀번호를 적어주세요',
validate: (value) => value === password.current, // 콜백 함수 넘겨줌
})}
/>
{errors.pwConfirm && errors.pwConfirm.type == 'validate' && (
<SubmitMessage>비밀번호가 일치하지 않습니다</SubmitMessage>
)}
<span onClick={handlePasswordConfirmType} />
</InputWrapper>

<RegisterButton type="submit" value="회원가입" />
</form>
</Wrapper>
);
};

export default Register;

const Wrapper = styled.div`
width: 100%;
flex-direction: column;
${flexCenter}
.info {
${flexCenter}
color: #bdbdbd;
font-size: 2rem;
margin-bottom: 3rem;
text-align: center;
}
.label {
font-size: 1.6rem;
margin-bottom: 1rem;
font-weight: bold;
color: #9e9e9e;
}
& + & {
margin: 5rem;
}
`;

const Input = styled.input`
width: 58rem;
border: 0;
border-bottom: 1px solid #e0e0e0;
outline: none;
border-radius: 0px;
line-height: 2.5rem;
font-size: 1.4rem;
padding-left: 0.5rem;
padding-right: 0.5rem;
margin-bottom: 1.8rem;
`;

const SubmitMessage = styled.div`
font-size: 1.2rem;
height: 2rem;
color: #ff1717;
`;

const InputWrapper = styled.div`
input {
width: 58rem;
border: 0;
border-bottom: 1px solid #e0e0e0;
outline: none;
border-radius: 0px;
line-height: 2.5rem;
font-size: 1.4rem;
padding-left: 0.5rem;
padding-right: 0.5rem;
margin-bottom: 1.8rem;
&.error {
border-bottom: 1px solid red;
}
&.correct {
border-bottom: 1px solid green;
}
}
.input-error {
}
& + & {
margin-top: 1rem;
}
`;

const RegisterButton = styled.input`
${flexCenter}
width: 58rem;
border-radius: 5px;
cursor: pointer;
height: 40px;
margin-top: 1rem;
background: ${theme.color.Main};
color: white;
height: 7rem;
font-size: 14px;
&:hover {
background: grey;
color: white;
}
`;
39 changes: 39 additions & 0 deletions src/component/Auth/RegisterButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react';
import { useNavigate } from 'react-router-dom';
import { theme, flexCenter } from '../../style/theme';
import styled from 'styled-components';

const RegisterButton = ({
children,
to,
...rest
}: {
children: string;
to: string;
}) => {
const navigate = useNavigate();
return (
<Wrapper onClick={() => navigate(`/${to}`)} {...rest}>
{children}
</Wrapper>
);
};

export default RegisterButton;

const Wrapper = styled.div`
${flexCenter};
width: 58rem;
border-radius: 5px;
border: 1px solid grey;
cursor: pointer;
height: 7rem;
margin-top: 1rem;
background: ${theme.color.white};
color: black;
font-size: 1.4rem;
&:hover {
background: ${theme.color.Main_lighten};
color: white;
}
`;
Loading

0 comments on commit 4ed2b0e

Please sign in to comment.