Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 146 additions & 38 deletions src/components/auth/AuthForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,102 @@ import React from 'react';

import styled from '@emotion/styled';

import { Link } from 'react-router-dom';

import Responsive from '../../styles/Responsive';
import palette from '../../styles/palette';
import Button from '../../styles/Button';

const AuthFormWrapper = styled(Responsive)`
height: 400px;
width: 400px;
display: flex;
justify-items: center;
align-items: center;
flex-direction: column;
background: ${palette.gray[1]};
border-radius: 1rem;
box-shadow: rgba(0, 0, 0, 0.04) 0px 4px 16px 0px;
padding: 3rem;
h2{
margin-top: 0;
color: black;
font-weight: bold;
font-size: 2rem;
}
Comment on lines +12 to +27
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

홀맨님께서 말씀해주셨던 CSS 정리가 필요하다.. 하고나서 문득 생각이 났다

fontSize
fontWeight
position
top
left
...
display
margin
padding
width
height
border
...
background
color
...

boxmodel 이외의 background, color와 같이 꾸며주는 애들은 뒤로 보내자.
가장 중요한 건 박스모델과 다른 걸 분리하는 것.

`;

const FormWrapper = styled.form`
margin-top: 32px;
display: grid;
grid-template-rows: repeat(1,1fr);
grid-row-gap: 1rem;
`;

const ErrorWrapper = styled.div`
font-weight: bold;
font-size: 0.8rem;
color: ${palette.warn[2]};
text-align: center;
`;

const InputWrapper = styled.input`
background: white;
height: 40px;
border-radius: 0.25rem;
font-size: 1rem;
line-height: 24px;
color: #5f5f5f;
box-shadow: none;
border: 0;
transition-duration: 0.08s;
transition-property: all;
transition-timing-function: ease-in-out;
transition-delay: initial;
padding: 8px 12px;
border: 2px solid #D7E2EB;
&:focus{
border: 2px solid ${palette.teal[5]};
}
&:hover{
border: 2px solid ${palette.teal[5]};
}
width: 400px;
`;

const AuthFormWrapper = styled(Responsive)``;
const Footer = styled.div`
margin-top: 1.5rem;
border-top: 1px solid ${palette.gray[4]};
padding-top: 20px;
display: flex;
justify-content: flex-end;

a {
font-weight: bold;
color: ${palette.teal[5]};
&:hover {
color: ${palette.teal[3]};
}
}

span {
font-weight: lighter;
color: ${palette.gray[6]};
margin-right: 0.75rem;
}
`;

const SpaceBlock = styled.div`
height: 11rem;
`;

const StyledButton = styled(Button)`
height: 40px;
border: 2px solid ${palette.teal[5]};
&:hover{
border: 2px solid ${palette.teal[5]};
}
`;

const FORM_TYPE = {
login: '로그인',
Expand All @@ -31,46 +124,61 @@ const AuthForm = ({
};

return (
<AuthFormWrapper>
<h2>{formType}</h2>
<form onSubmit={handleSubmit}>
<input
type="text"
value={userEmail}
name="userEmail"
placeholder="이메일"
autoComplete="email"
onChange={handleChange}
/>
<input
type="password"
value={password}
name="password"
placeholder="비밀번호"
autoComplete="password"
onChange={handleChange}
/>
{type === 'register' && (
<input
<>
<SpaceBlock />
<AuthFormWrapper>
<h2>{formType}</h2>
<FormWrapper onSubmit={handleSubmit}>
<InputWrapper
type="text"
value={userEmail}
name="userEmail"
placeholder="이메일"
autoComplete="email"
onChange={handleChange}
/>
<InputWrapper
type="password"
value={fields.passwordConfirm}
name="passwordConfirm"
placeholder="비밀번호 확인"
autoComplete="new-password"
value={password}
name="password"
placeholder="비밀번호"
autoComplete="password"
onChange={handleChange}
/>
)}
{error && (
<div>{error}</div>
)}
<button
data-testid="auth-button"
type="submit"
>
{formType}
</button>
</form>
</AuthFormWrapper>
{type === 'register' && (
<InputWrapper
type="password"
value={fields.passwordConfirm}
name="passwordConfirm"
placeholder="비밀번호 확인"
autoComplete="new-password"
onChange={handleChange}
/>
)}
{error && (
<ErrorWrapper>{error}</ErrorWrapper>
)}
<StyledButton
success
type="submit"
data-testid="auth-button"
>
{formType}
</StyledButton>
{type === 'login' && (
<Footer>
<span>아직 회원이 아니신가요?</span>
<Link
to="/register"
data-testid="sign-up-link"
>
회원가입
</Link>
</Footer>
)}
</FormWrapper>
</AuthFormWrapper>
</>
);
};

Expand Down
34 changes: 28 additions & 6 deletions src/components/auth/AuthForm.test.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React from 'react';

import { MemoryRouter } from 'react-router-dom';

import { render, fireEvent } from '@testing-library/react';

import AuthForm from './AuthForm';
Expand All @@ -14,12 +16,14 @@ describe('AuthForm', () => {
});

const renderAuthForm = ({ type, fields }) => render((
<AuthForm
type={type}
fields={fields}
onChange={handleChange}
onSubmit={handleSubmit}
/>
<MemoryRouter>
<AuthForm
type={type}
fields={fields}
onChange={handleChange}
onSubmit={handleSubmit}
/>
</MemoryRouter>
));

context('when type is login', () => {
Expand Down Expand Up @@ -110,4 +114,22 @@ describe('AuthForm', () => {
expect(handleSubmit).toBeCalled();
});
});

context('when type is login', () => {
const login = {
type: 'login',
fields: {
userEmail: 'tktmdals@naver.com',
password: '1234',
},
};

it('renders register link', () => {
const { getByTestId } = renderAuthForm(login);

const link = getByTestId('sign-up-link');

expect(link).not.toBeNull();
});
});
});
5 changes: 4 additions & 1 deletion src/containers/auth/LoginFormContainer.test.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';

import { MemoryRouter } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';

import { render, fireEvent } from '@testing-library/react';
Expand Down Expand Up @@ -34,7 +35,9 @@ describe('LoginFormContainer', () => {
});

const renderLoginFormContainer = () => render((
<LoginFormContainer />
<MemoryRouter>
<LoginFormContainer />
</MemoryRouter>
));

it('renders login form text', () => {
Expand Down
4 changes: 4 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ body {
margin: 0;
}

input {
outline:none;
}

code {
padding: 0.2em 0.4em;
margin: 0;
Expand Down
5 changes: 4 additions & 1 deletion src/pages/LoginPage.test.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';

import { MemoryRouter } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';

import { render } from '@testing-library/react';
Expand All @@ -25,7 +26,9 @@ describe('LoginPage', () => {
});

const renderLoginPage = () => render((
<LoginPage />
<MemoryRouter>
<LoginPage />
</MemoryRouter>
));

describe('renders Login page text contents', () => {
Expand Down
12 changes: 7 additions & 5 deletions src/styles/Button.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { css } from '@emotion/react';

import palette from './palette';

const ButtonWrapper = (props) => css`
const ButtonWrapper = ({ warn, success }) => css`
border-radius: 4px;
font-size: 1rem;
font-weight: bold;
Expand All @@ -19,13 +19,16 @@ const ButtonWrapper = (props) => css`
cursor: pointer;
border: 1px solid ${palette.gray[7]};
background: white;
transition-duration: 0.08s;
transition-property: all;
transition-timing-function: ease-in-out;
transition-delay: initial;
&:hover {
color: white;
background: ${palette.gray[7]};
}

${props.warn
&& css`
${warn && css`
color: white;
padding: 0.15rem 0.9rem;
background: ${palette.warn[1]};
Expand All @@ -37,8 +40,7 @@ const ButtonWrapper = (props) => css`
}
`}

${props.success
&& css`
${success && css`
color: white;
background: ${palette.teal[5]};
border: 1px solid ${palette.teal[5]};
Expand Down
43 changes: 43 additions & 0 deletions src/styles/Button.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react';

import { MemoryRouter } from 'react-router-dom';

import { render } from '@testing-library/react';

import Button from './Button';

describe('Button', () => {
const renderButton = ({ to, warn }) => render((
<MemoryRouter>
<Button
warn={warn}
to={to}
>
button
</Button>
</MemoryRouter>
));

context('with to, link', () => {
const to = '/login';
it('renders tags name', () => {
const { getByText } = renderButton({ to, warn: null });

expect(getByText('button').href).toBe('http://localhost/login');
});

it('check props true to be 1', () => {
const { getByText } = renderButton({ to, warn: true });

expect(getByText('button')).toHaveStyle('color: white;');
});
});

context('without to', () => {
it('nothing renders tags name', () => {
const { getByText } = renderButton({});

expect(getByText('button').href).not.toBe('http://localhost/login');
});
});
});