1. UI 구현하기

 

 

1. AuthForm.js 화면

import styled from "styled-components";
/*
 * <pre>
 * @title AuthForm.js
 * @desc 회원가입폼
 * </pre>
 *
 * @author yunrap
 * @since 2022.07.18 20:18:22
 * @version 0.1.0
 * @see =================== 변경 내역 ==================
 *   날짜       변경자     내용
 *  2022.07.18.  yunrap  최초작성
 */

const AuthFormBlock = styled.div``;

export default function AuthForm() {
  return <AuthFormBlock>AuthForm</AuthFormBlock>;
}

 

회원가입을 위한 폼이다.

src/components/auth/ AuthForm.js 파일을 만든다.

 

 

 

2. AuthTemplate 화면

/*
 * <pre>
 * @title AuthTemplate.js
 * @desc 클래스 대한 설명
 * </pre>
 *
 * @author yunrap
 * @since 2022.07.18 20:23:08
 * @version 0.1.0
 * @see =================== 변경 내역 ==================
 *   날짜       변경자     내용
 *  2022.07.18.  yunrap  최초작성
 */

import styled from "styled-components";

const AuthTemplateBlock = styled.div``;

export default function AuthTemplate() {
  return <AuthTemplateBlock></AuthTemplateBlock>;
}

 

회원가입/로그인 페이지의레이아웃을 담당하는 컴포넌트이다.

src/components/auth/AuthTemplate.js 파일을 만든다.

 

 

컴포넌트를 만들때 VS Code의 snippet 기능을 사용하면 매우유용하다.

우선 이부분은 스킵을한다.

 

 

3. AuthTemplage.js 렌더링

/*
 * <pre>
 * @title AuthTemplate.js
 * @desc 클래스 대한 설명
 * </pre>
 *
 * @author yunrap
 * @since 2022.07.18 20:23:08
 * @version 0.1.0
 * @see =================== 변경 내역 ==================
 *   날짜       변경자     내용
 *  2022.07.18.  yunrap  최초작성
 */

import styled from "styled-components";

const AuthTemplateBlock = styled.div``;

export default function AuthTemplate({ children }) {
  return <AuthTemplateBlock>{children}</AuthTemplateBlock>;
}

 

 

children을 렌더링한다.

 

4. LoginPage, RegisterPage 둘다 렌더링

/*
 * <pre>
 * @title RegisterPage.js
 * @desc 등록화면
 * </pre>
 *
 * @author yunrap
 * @since 2022.07.18 20:39:52
 * @version 0.1.0
 * @see =================== 변경 내역 ==================
 *   날짜       변경자     내용
 *  2022.07.18.  yunrap  최초작성
 */
import AuthTemplate from "../components/auth/AuthTemplate";
import AuthForm from "../components/auth/AuthForm";
export default function RegisterPage() {
  return (
    <AuthTemplate>
      <AuthForm></AuthForm>
    </AuthTemplate>
  );
}

등록화면에 아까만든 Template 컴포넌트와 AuthForm 컴포넌트를 렌더링해준다.

 

/*
 * <pre>
 * @title LoginPage.js
 * @desc 로그인화면
 * </pre>
 *
 * @author yunrap
 * @since 2022.07.18 20:39:29
 * @version 0.1.0
 * @see =================== 변경 내역 ==================
 *   날짜       변경자     내용
 *  2022.07.18.  yunrap  최초작성
 */

import AuthTemplate from "../components/auth/AuthTemplate";
import AuthForm from "../components/auth/AuthForm";
export default function LoginPage() {
  return (
    <AuthTemplate>
      <AuthForm></AuthForm>
    </AuthTemplate>
  );
}

 

 

5. AuthTemplate완성하기

 

template 기능이므로 흰색배경으로 css 적용후,  {children}을 활용할 것이다.

/*
 * <pre>
 * @title AuthTemplate.js
 * @desc 클래스 대한 설명
 * </pre>
 *
 * @author yunrap
 * @since 2022.07.18 20:23:08
 * @version 0.1.0
 * @see =================== 변경 내역 ==================
 *   날짜       변경자     내용
 *  2022.07.18.  yunrap  최초작성
 */

import styled from "styled-components";
import palette from "../../lib/styles/palette";
import { Link } from "react-router-dom";
const AuthTemplateBlock = styled.div`
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  right: 0;
  background: ${palette.gray[2]};
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
`;

const WhiteBox = styled.div`
  .logo-area {
    display: block;
    padding-bottom: 2rem;
    text-align: center;
    font-weight: bold;
    letter-spacing: 2px;
  }
  box-shadow: 0 0 8px rgba(0, 0, 0, 0.025);
  padding: 2rem;
  width: 360px;
  background: white;
  border-radis: 2px;
`;

export default function AuthTemplate({ children }) {
  return (
    <AuthTemplateBlock>
      <AuthTemplateBlock>
        <WhiteBox>
          <div className="logo-area">
            <Link to="/">REACTERS</Link>
          </div>
          {children}
        </WhiteBox>
      </AuthTemplateBlock>
    </AuthTemplateBlock>
  );
}

 

6. AuthForm 완성하기

 

회원가입 창을 렌더링해준다.

/*
 * <pre>
 * @title AuthForm.js
 * @desc 회원가입폼
 * </pre>
 *
 * @author yunrap
 * @since 2022.07.18 20:18:22
 * @version 0.1.0
 * @see =================== 변경 내역 ==================
 *   날짜       변경자     내용
 *  2022.07.18.  yunrap  최초작성
 */
import { Link } from "react-router-dom";
import styled from "styled-components";
import palette from "../../lib/styles/palette";
import Button from "../common/Button";
const AuthFormBlock = styled.div`
  h3 {
    margin: 0;
    color: ${palette.gray[8]};
    margin-bottom: 1rem;
  }
`;

const StyledInput = styled.input`
  font-size: 1rem;
  border: none;
  border-bottom: 1px solid ${palette.gray[5]};
  padding-bottom: 0.5rem;
  outline: none;
  width: 100%;
  &:focus {
    color: $oc-teal-7;
    border-bottom: 1px solid ${palette.gray[7]};
  }
  & + & {
    margin-top: 1rem;
  }
`;

// 폼 하단에 로그인 혹은 회원가입 링크를 보여줌
const Footer = styled.div`
  margin-top: 2rem;
  text-align: right;
  a {
    color: ${palette.gray[6]};
    text-decoration: underline;
    &:hover {
      color: ${palette.gray[9]};
    }
  }
`;

export default function AuthForm() {
  return (
    <AuthFormBlock>
      <h3>로그인</h3>
      <form>
        <StyledInput
          autoComplete="username"
          name="username"
          placeholder="아이디"
        ></StyledInput>
        <StyledInput
          autoComplete="new-password"
          name="password"
          placeholder="비밀번호"
          typd="password"
        ></StyledInput>
        <Button>로그인</Button>
      </form>
      <Footer>
        <Link to="/register">회원가입</Link>
      </Footer>
    </AuthFormBlock>
  );
}

 

해준다. 

 

 

여기서 로그인 버튼에 밝은 파란색을 넣어주고 width를 100% 차지하는 효과를 넣어보겠습니다.

 

/*
 * <pre>
 * @title Button.js
 * @desc Button 공통컴포넌트 생성
 * </pre>
 *
 * @author yunrap
 * @since 2022.07.17 17:28:10
 * @version 0.1.0
 * @see =================== 변경 내역 ==================
 *   날짜       변경자     내용
 *  2022.07.17.  yunrap  최초작성
 */

import styled, { css } from "styled-components";
import palette from "../../lib/styles/palette";
const StyledButton = styled.button`
  border: none;
  boder-radis: 4px;
  font-size: 1rem;
  font-weight: bold;
  padding: 0.25rem 1rem;
  color: white;
  outline: none;
  cursor: pointer;

  background: ${palette.gray[8]};
  &:hover {
    background: ${palette.gray[6]};
  }

  ${(props) =>
    props.fullWidth &&
    css`
      padding-top: 0.75rem;
      padding-top: 0.75rem;
      padding-bottom: 0.75rem;
      width: 100%;
      font-size: 1.125rem;
    `}

  ${(props) =>
    props.cyan &&
    css`
      background: ${palette.cyan[5]};
      &:hover {
        background: ${palette.cyan[4]};
      }
    `}
`;

export default function Button(props) {
  return (
    <div>
      <StyledButton {...props}></StyledButton>
    </div>
  );
}

 

버튼 컴포넌트에 cyan과 fullwidth라는 prop를 넣어주면 다른스타일이 적용된다.

다시 AuthForm 을 열어서 Button컴포넌트에 propr를 넣어줍니다.

 

/*
 * <pre>
 * @title AuthForm.js
 * @desc 회원가입폼
 * </pre>
 *
 * @author yunrap
 * @since 2022.07.18 20:18:22
 * @version 0.1.0
 * @see =================== 변경 내역 ==================
 *   날짜       변경자     내용
 *  2022.07.18.  yunrap  최초작성
 */
import { Link } from "react-router-dom";
import styled from "styled-components";
import palette from "../../lib/styles/palette";
import Button from "../common/Button";
const AuthFormBlock = styled.div`
  h3 {
    margin: 0;
    color: ${palette.gray[8]};
    margin-bottom: 1rem;
  }
`;

const StyledInput = styled.input`
  font-size: 1rem;
  border: none;
  border-bottom: 1px solid ${palette.gray[5]};
  padding-bottom: 0.5rem;
  outline: none;
  width: 100%;
  &:focus {
    color: $oc-teal-7;
    border-bottom: 1px solid ${palette.gray[7]};
  }
  & + & {
    margin-top: 1rem;
  }
`;

// 폼 하단에 로그인 혹은 회원가입 링크를 보여줌
const Footer = styled.div`
  margin-top: 2rem;
  text-align: right;
  a {
    color: ${palette.gray[6]};
    text-decoration: underline;
    &:hover {
      color: ${palette.gray[9]};
    }
  }
`;

export default function AuthForm() {
  return (
    <AuthFormBlock>
      <h3>로그인</h3>
      <form>
        <StyledInput
          autoComplete="username"
          name="username"
          placeholder="아이디"
        ></StyledInput>
        <StyledInput
          autoComplete="new-password"
          name="password"
          placeholder="비밀번호"
          typd="password"
        ></StyledInput>
        <Button cyan fullWidth>
          로그인
        </Button>
      </form>
      <Footer>
        <Link to="/register">회원가입</Link>
      </Footer>
    </AuthFormBlock>
  );
}

 

 

이제 이 컴포넌트에 상단 여백을 넣어보겠다

 

(......)

const ButtonWithMarginTop = styled(Button)`
  margin-top: 1rem;
`;

export default function AuthForm() {
  return (
    <AuthFormBlock>
      <h3>로그인</h3>
      <form>
        <StyledInput
          autoComplete="username"
          name="username"
          placeholder="아이디"
        ></StyledInput>
        <StyledInput
          autoComplete="new-password"
          name="password"
          placeholder="비밀번호"
          typd="password"
        ></StyledInput>
        <ButtonWithMarginTop cyan fullWidth>
          <Button cyan fullWidth>
            로그인
          </Button>
        </ButtonWithMarginTop>
      </form>
      <Footer>
        <Link to="/register">회원가입</Link>
      </Footer>
    </AuthFormBlock>
  );
}

 

 

 

이젠 AuthForm 에서 type props 에따라 다른내용을 보여주도록 수정해보자

 

type 값에따라 문구도달라지고 type가 register일때는 비밀번호 확인 인풋을 보여주자

 

 

1. AuthForm 화면

/*
 * <pre>
 * @title AuthForm.js
 * @desc 회원가입폼
 * </pre>
 *
 * @author yunrap
 * @since 2022.07.18 20:18:22
 * @version 0.1.0
 * @see =================== 변경 내역 ==================
 *   날짜       변경자     내용
 *  2022.07.18.  yunrap  최초작성
 */

const textMap = {
  login: "로그인",
  register: "회원가입",
};

export default function AuthForm({ type }) {
  const text = textMap[type];
  return (
    <AuthFormBlock>
      <h3>{text}</h3>
      <form>
        <StyledInput
          autoComplete="username"
          name="username"
          placeholder="아이디"
        ></StyledInput>
        <StyledInput
          autoComplete="new-password"
          name="password"
          placeholder="비밀번호"
          typd="password"
        ></StyledInput>
        {type === "register" && (
          <StyledInput
            autoComplete="new-password"
            name="passwordConfirm"
            placeholder="비밀번호 확인"
            typd="password"
          ></StyledInput>
        )}
        <ButtonWithMarginTop cyan fullWidth style={{ marginTop: "1rem" }}>
          {text}
        </ButtonWithMarginTop>
      </form>
      <Footer>
        {type === "login" ? (
          <Link to="/register">회원가입</Link>
        ) : (
          <Link to="/login">로그인</Link>
        )}
      </Footer>
    </AuthFormBlock>
  );
}

 

 

그리고 로그인과 회원가입을 type로 구별해서 페이지를 보여준다.

 

 

2. LoginPage.js

/*
 * <pre>
 * @title LoginPage.js
 * @desc 로그인화면
 * </pre>
 *
 * @author yunrap
 * @since 2022.07.18 20:39:29
 * @version 0.1.0
 * @see =================== 변경 내역 ==================
 *   날짜       변경자     내용
 *  2022.07.18.  yunrap  최초작성
 */

import AuthTemplate from "../components/auth/AuthTemplate";
import AuthForm from "../components/auth/AuthForm";
export default function LoginPage() {
  return (
    <AuthTemplate>
      <AuthForm type="login"></AuthForm>
    </AuthTemplate>
  );
}

 

 

3. RegisterPage.js

/*
 * <pre>
 * @title RegisterPage.js
 * @desc 등록화면
 * </pre>
 *
 * @author yunrap
 * @since 2022.07.18 20:39:52
 * @version 0.1.0
 * @see =================== 변경 내역 ==================
 *   날짜       변경자     내용
 *  2022.07.18.  yunrap  최초작성
 */
import AuthTemplate from "../components/auth/AuthTemplate";
import AuthForm from "../components/auth/AuthForm";
export default function RegisterPage() {
  return (
    <AuthTemplate>
      <AuthForm type="register"></AuthForm>
    </AuthTemplate>
  );
}

 

이제 회원인증에 필요한  UI를 모두 완성했다.

 

이제 리덕스로 폼상태관리하는것을 보겠다.

+ Recent posts