본문 바로가기

공부일지/Project

비전공자의 프로젝트 만들기) Disneyplus App 만들기 part4

728x90
반응형

Disneyplus App 만들기 part4

 

firebase로 서비스 배포해보려고 한다.

프로젝트 제작할 때 프론트개발하면서 백엔드 서버까지 개발하기 위해서는 시간이 오래 걸리는데 그 부분을 해결해 주는 게 firebase이다 firebase가 전부 완벽하게 해결해 줄 순 없지만 인증, 데이터베이스, 스토리지, 푸시, 등등 꽤 많은걸 지원해준다.

 

firebase의 연동과 관련한 자세한 내용은 구글에 검색하면 자세히 나온다.

UI/UX가 잘되어 있어서 회원가입하고 버튼 몇 번 누르고 설명대로 작업하면 프로젝트와 연결된다.

https://firebase.google.com/?hl=ko

 

Firebase

Firebase는 고품질 앱을 빠르게 개발하고 비즈니스를 성장시키는 데 도움이 되는 Google의 모바일 플랫폼입니다.

firebase.google.com

 

파이어베이스에서 가입 후 프로젝트를 만들면 apiKey와 여러 가지 정보가 담긴 코드를 주는데 app.js가 있는 경로에 firebase.js 파일을 만들어 넣어준다.

 

로그인 기능을 작업할 예정이기 때문에 auth도 import 해준다.

그리고 index.js파일에서 app을 import 해준다. 참고로 app은 firebase파일에서 만든 app을 import 해야 한다. 

app이라는 이름이 헷갈리면 다른 이름을 사용해도 상관은 없다.

 

Login페이지 디자인을 작업을 한다. 여기서 해당 페이지는 회원가입 기능은 작업하지 않기 때문에 디자인 작업만 진행한다.

로그인은 Nav 컴포넌트에서 작업한다.

import React from "react";
import styled from "styled-components";

const LoginPage = () => {
  return (
    <Container>
      <Content>
        <Center>
          <LogoOne src="/images/cta-logo-one.svg" alt="logo-one" />
          <SignUpLink>지금 가입</SignUpLink>
          <Description>
            영화에 대한 프리미어 액세스를 얻으십시오. 디즈니 플러스 가격은 다음
            주부터 1000원 인상됩니다.
          </Description>
          <LogoTwo src="images/cta-logo-two.png" alt="logo-two" />
        </Center>
        <BgImage />
      </Content>
    </Container>
  );
};

export default LoginPage;

const BgImage = styled.div`
  height: 100%;
  background-position: top;
  background-image: url("/images/login-background.jpg");
  background-size: cover;
  background-repeat: no-repeat;
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  z-index: -1;
`;

const Container = styled.section`
  overflow: hidden;
  display: flex;
  flex-direction: column;
  text-align: center;
  height: 100vh;
`;

const Content = styled.div`
  margin-bottom: 10vw;
  width: 100%;
  position: relative;
  min-height: 100vh;
  box-sizing: border-box;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  padding: 80px 40px;
  height: 100%;
`;

const Center = styled.div`
  max-width: 650px;
  width: 100%;
  display: flex;
  flex-direction: column;
`;

const LogoOne = styled.img`
  margin-bottom: 12px;
  max-width: 600px;
  min-height: 1px;
  display: block;
  width: 100%;
`;

const SignUpLink = styled.a`
  font-weight: bold;
  color: #f9f9f9;
  background-color: #0063e5;
  margin-bottom: 12px;
  width: 100%;
  letter-spacing: 1.5px;
  font-size: 18px;
  padding: 16.5px 0;
  border: 1px solid transparent;
  border-radius: 4px;
  cursor: pointer;
  &:hover {
    background-color: #0483ee;
  }
`;

const Description = styled.p`
  font-size: 11px;
  margin: 0 0 24px;
  line-height: 1.5;
  letter-spacing: 1.5px;
`;

const LogoTwo = styled.img`
  max-width: 600px;
  margin-bottom: 20px;
  display: inline-block;
  vertical-align: bottom;
  width: 100%;
`;

로그인 페이지라고는 하지만 로그인하지 않았을 때의 메인 페이지이다.

 

이제 Nav 컴포넌트에서 로그인 기능만 작업하면 이번 프로젝트가 끝이 난다.

 

firebase의 프로젝트 사이트를 보면 메뉴에 auth관련 메뉴가 있다 거기서 어떤 방식으로 로그인할지 선택할 수 있다.

이번프로젝트에서는 구글로 로그인하는 기능만 추가로 넣을 예정이다.

 

Nav.js

  const auth = getAuth();
  const provider = new GoogleAuthProvider();
  const initialUserData = localStorage.getItem("user")
    ? JSON.parse(localStorage.getItem("user")) 
    : {}
  const [userData, setUserData] = useState(initialUserData)
  
  const handleAuth = () => {
    signInWithPopup(auth, provider)
      .then((result) => {
          setUserData(result.user)
          localStorage.setItem("user", JSON.stringify(result.user))
      })
      .catch(error => {
        console.log(error)
      })
  }

  const handleSignOut = () => {
    signOut(auth).then(()=>{
      setUserData({});
      navigate("/")
      localStorage.removeItem("user")
    }).catch((error)=>{
      console.log(error)
    })
  }

getAuth라고 firebase에서 지원하는 로그인기능이다. 거기서 구글 로그인만 작업할 예정이기 때문에 googleAuthProvider를 가져와 provider로 할당해 준다.

 

그런 다음 signInwithPopup도 firebase에서 지원하는 기능인데 로그인 시 팝업 화면이 나와 로그인할 계정을 선택하고 하는 기능인 거 같다.

 

auth, provider을 전달하고 성공적으로 로그인이 되면 데이터를 저장하기 위해 userData라는 state를 만들어 저장하고 localStorage에 저장을 한다.

session으로 저장하지 않은 이유는 브라우저를 종료하면 데이터가 날라가기 때문에 로컬로 했다. 

대부분 사이트가 자동 로그인 기능은 로컬스토리지에 저장하고 자동로그인 아닌 사이트들은 세션에 저장될 것이다.

자동 로그인이 되더라도 로컬에 저장 후 세션에 저장되게 하는 곳도 있는 거 같았다.

 

로그인이 완료작업을 했으면 이번엔 로그아웃 기능과 로그인 표시 부분이다.

 

로그아웃부터 작업을 진행하게 되면 로그인과 반대로 작업하면 된다.

로그아웃 버튼을 누르면 회원정보를 전달하고 해당 회원정보가 맞으면 userData를 초기화하고 loacalStorage를 초기화시킨 후 로그인 페이지로 이동시킨다.

 

return (
    <NavWrapper handleShow={handleShow}>
      <Logo>
        <img
          alt="Disney Plus Logo"
          src="/images/logo.svg"
          onClick={() => (window.location.href = "/")}
        />
      </Logo>
      {pathname === "/" ? (
        <Login onClick={()=>handleAuth()}>Login</Login>
      ) : (
        <>
          <Input 
            value={searchValue}
            onChange={(e)=>handleChange(e)}
            className="nav__input"
            type="text"
            placeholder="검색해 주세요"
          />
          <SignOut>
            <UserImg src={userData.photoURL} alt={userData.dispayName} />
            <DropDown>
              <span onClick={()=> handleSignOut()}>Sign Out</span>
            </DropDown>
          </SignOut>
        </>
      )}
    </NavWrapper>
  );

: 기준으로 로그인했을 때는 검색과, 로그인정보가 표시되면 되고 로그인하지 않았을 때는 로그인버튼이 출력된다.

유저 정보는 userData에 저장되어 있는 photoUrl와 이름을 들고 온다.

DropDown은 styled로 직점 만든 컴포넌트이다. 누르면 로그아웃 버튼이 나와 해당 버튼 누를 수 있게 했다.

 

Nav파일은 공통이기 때문에 로그인 여부를 해당 페이지에서 처리했다. 

상단에 넣어주면 된다. user정보가 있으면 main페이지로 없으면 최상위 페이지로 이동되게 작업하였다.

  useEffect(() => {
    onAuthStateChanged(auth, (user)=>{
      if(user){
        if(pathname === "/"){
          navigate("/main");
        }
      }else{
        navigate("/");
      }
    })

 

 

이상 디즈니앱 프로젝트를 완료하였다.

아직 모르는 것도 많고 이해 안 되는 부분도 많은 것 같다. 하나씩 하나씩 익혀가야겠다.

 

다음시간부터는 개인 프로젝트 및 알고리즘 공부를 할 예정이라 프로젝트 일지는 많이 작성하지 못 할것 같다.

그래도 최대한 열심히 일지를 작성할 예정이다.

 

최근에 너무 단기간에 많은 정보를 다 기억하려고 해서 그런지 혼자 자괴감에 많이 빠졌던 거 같다. 

너무 단기간에 모든 걸 다 기억할 필요 없고 하나씩 익혀가며 익숙해지는 게 중요한 거 같다.

파이팅!!

 

728x90
반응형