[나랑놀래?] 프로젝트를 마치며 🥺

나는경서·2022년 4월 25일
4

프로젝트

목록 보기
3/3
post-thumbnail

나랑놀래?

남의집 사이트를 모티브로 하여 진행한 프로젝트로 자신의 공간에서 모임을 주최하고 이끌어갈 호스트를 중심으로 취향이 맞는 사람들을 연결한다. 연결된 사람들은 가정집, 작업실, 동네가게 등 모임이 진행되는 공간에 모여 공통된 관심사로 대화하며 취향을 나누는 목적으로 만든 커뮤니티 & 예약 사이트이다.

Stack

Frontend

  • React.js (v18.0)
  • Styled-Components

    Styled-Components 의 사용

    컴포넌트 기반의 리액트를 사용하며 CSS 스타일링 또한 컴포넌트 기반으로 재구성되며 Styled-Components를 사용한다. 기존의 문제로는 CSS 클래스명을 작명해야하는 고민과 클래스명이 중복되는 경우, 클래스로 조건부 스타일링을 하는 경우 등 여러 어려움이 발생했었다. 하여 이번 프로젝트는 Styled-Components를 사용하여 프로젝트를 진행하게 되었다.
  • JavaScript(ES6)
  • HTML5/CSS3

Backend

Backend github 링크

  • Django Web Framework
  • Pyhton
  • Mysql
  • AWS(EC2, S3, RDS)
  • Bcrypt
  • JWT

Collaboration tool

  • git, github
  • Trello
  • Notion
  • Slack

Product

나랑놀래? 바로가기

데모 영상

개발 기간 및 인원

개발기간 : 2022.04.11 - 2022.04.22

Team = {
 "Front-end" : ["김재도", "노규현", "박경서"],
 "Back-end" : ["이산", "최창환", "황정현"]
 }

Trello :: 협업 툴

우리팀은 앞으로 해야 할 모든 티켓들(Backlog), 이번 스프린트에 해야 할 티켓들(This Sprint), 현재 개발중인 티켓들(In Progress), PR 작성 후 리뷰중인 티켓들(In Review), 완료된 티켓들(Done) 으로 탭을 나누었다. 이렇게 해야 할 과제들과 이미 완료된 과제들, 팀 구성원 별로 맡은 업무들과 현재 진행 중인 업무들, 앞으로 해야 할 일들과 이번 주에 당장 해야 할 일들을 보기 좋게 구별하여 업무의 생산성과 효율성을 높일 수 있었다.

또한 앞에서의 몇 번의 프로젝트로 팀원간의 태도와 소통의 중요성을 알았기에 팀원들의 눈에도 나의 진행사항을 쉽게 알릴 수 있도록 작성하려고 노력하였고 기능별로 티켓을 만들 수 있도록 노력하였다. 티켓의 생성도 중요하지만 이 과정에서 나의 해야할 일 과 Blocker를 어떻게 공유할 지, 해야할 일의 우선순위를 정하고 구별하여 팀원에게 잘 전달할 지 고민하였다.

초기세팅

public
├── data
├── images
├── index.html
src
├── components 
│   ├── Nav.js
│   ├── Footer.js
├── pages
│   ├── Host
│   ├── Login
│   ├── Main
│   ├── Mypage
│   ├── ProductList
│   ├── Search
├── styles
│   ├── GlobalStyles.js
│   └── Mixin.js
│   └── theme.js
├── index.js
└── Router.js
└── .prettierrc
└── .eslintrc

Planning Meeting ::필수 구현 사항

프로젝트 첫 날, Planning Meeting 에서 호스트 등록 페이지의 결제, 진행관리, 정산 기능을 삭제하면서 마이페이지와 병합하자고 하였지만 프로젝트 도중, 병합하게 되면 마이페이지에서 기능이 생각보다 많아져서 다시 나누는 수정사항이 발생하기도 하였다.

1. 회원가입 및 로그인
	- kakaoOAuth(소셜 로그인) 만 구현
	- 일반회원가입 로그인(X)
2. 마이페이지
	- 후기 리스트, 신청 및 환불 내역, 결제 금액 충전
3. 메인페이지
	- 이미지 슬라이드, GNB, FOOTER
4. 카테고리 상품 리스트
	- 패스 파라미터를 통한 카테고리별 전체 상품 리스트
5. 상품 디테일 페이지
	- 신청예약(예약 기능), 후기
6. 호스트 등록
	- 현재의 경우 다른 페이지로 이동 → 마이페이지와 병합될 예정

config.js

config.js에서 API를 관리하여 사용하였다.

const BASE_URL = 'http://13.209.8.56:8000';

const API = {
  Login: `${BASE_URL}/users/signin`,
  Point: `${BASE_URL}/users/point`,
  Review: `${BASE_URL}/users/review`,
  Aside: `${BASE_URL}/users/userinfo`,
  History: `${BASE_URL}/users/reservation`,
  Productlist: `${BASE_URL}/places/placelist`,
  Product: `${BASE_URL}/places/placeinformation`,
  Placehost: `${BASE_URL}/places`,
  Placereview: `${BASE_URL}/places`,
  Placereservation: `${BASE_URL}/places/reservation`,
  Search: `${BASE_URL}/places/search`,
  Main: `${BASE_URL}/places/main`,
  Hostuser: `${BASE_URL}/users/host`,
  Hostcreate: `${BASE_URL}/users/placeregist`,
  Hostmain: `${BASE_URL}/places/hostregstlist`,
  Userinfo: `${BASE_URL}/users/userinfo`,
  Hostinfo: `${BASE_URL}/places/hostinformation`,
};
export default API;

내가 구현한 기능의 요구사항과 후기

OAuth 2.0 기반의 카카오 소셜 로그인 서비스

  • 카카오 연동 로그인은 REST API를 이용하였습니다.
  • 사용자가 서비스에서 카카오 로그인 버튼 클릭 시, 카카오 인증 서버로 인가 코드(code=_____) 발급을 요청합니다.
  • 첫 로그인 시, 카카오 계정으로 로그인 화면이 나타나며 사용자가 직접 입력한 카카오 계정의 자격 정보를 통해 사용자 인증이 이뤄집니다.
  • 사용자가 필수 동의 항목에 동의하고 로그인을 요청하면, 카카오 인증 서버는 인가 코드(Authorization Code)를 발급해 서비스 앱에 등록된 Redirect URI로 전달합니다.
  • 서비스는 전달받은 인가 코드로 토큰을 요청하여 액세스 토큰과 리프레시 토큰을 발급받습니다.
  • 전달 받은 액세스 토큰을 서버에 전달하고 서버는 카카오 서버에 유효성 검증을 하여 받은 토큰을 서비스 전용 토큰을 발행하여 다시 프론트로 전달하고 로컬 스토리지에 저장합니다.

https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api

카카오 로그인 과정을 이해하기 위해서 위의 카카오 공식 문서를 몇번이나 읽어보고 구글링해서 관련된 kakao REST API 글은 정말 다 읽어본 것 같다. 흐름을 이해한 지금은 남에게 설명할 수 있을 정도지만 처음에는 인가코드, Redirect URI, Access token, Refresh token, id_token 등 생소한 단어들이 너무 많아서 힘들었다. 그리고 인가 코드 발급 시, 정말 많은 인가 코드 관련 에러를 마주쳤는데 대게 아래 3개의 에러를 가장 많이 만났으며, 도대체 어떤 부분을 내가 놓치고 있길래 에러를 잡지 못하는 걸까 답답하여 다시 찬찬히 흐름을 이해해보고, 왜 인가코드를 받지 못하는지? 왜 Redirect URI로 이동하지 못해서 리다이랙션이 안되는지? 이해하기 위해서 공식문서를 읽고 또 읽었다.

KOE101 - 잘못된 앱 키 타입을 사용하거나 앱 키에 오타가 있을 경우
KOE008 - 인가 코드 요청 시 Admin Key를 사용한 경우
KOE006 - 관리자 설정 이슈, 등록되지 않은 Redirect URI를 인가 코드 요청에 사용한 경우

대게 인가코드 관련 에러는 Request URI에서 발생하였다.

카카오 로그인 버튼 클릭 시, https://kauth.kakao.com/oauth/authorize?client_id=${process.env.REACT_APP_CLIENT_ID}&redirect_uri=${process.env.REACT_APP_REDIRECT_URI}&response_type=code 의 주소로 이동한다.

여기서 client_id 는 카카오 앱 REST API 키에서 발급받은 앱키이며 REDIRECT_URI 는 인가 코드가 리다이렉트될 URI 이다. response_type는 code로 고정이다.

fetch('https://kauth.kakao.com/oauth/token', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded;',
      },
      body: `grant_type=authorization_code&client_id=${process.env.REACT_APP_CLIENT_ID}&code=${code}&redirect_uri=${process.env.REACT_APP_REDIRECT_URI}`,
    })

이렇게 필수적인 파라미터들을 포함해서 https://kauth.kakao.com/oauth/token 에 POST로 요청한다. 요청 성공 시 액세스 토큰, 리프레시 토큰과 토큰 정보를 포함한 JSON객체를 받는다.

{
    "token_type": "bearer",
    "access_token": "${ACCESS_TOKEN}",
    "id_token": "${ID_TOKEN}",
    "expires_in": 7199,
    "refresh_token": "${REFRESH_TOKEN}",
    "refresh_token_expires_in": 86399,
    "scope": "profile_image openid profile_nickname"
}

앱 키 같은 경우, 소스코드에 노출이 되어선 보안상 큰 문제이기 때문에 .env 를 root에 만들어서 관리한다. 만들고나면 별거 아니지만 처음 마주친 환경변수 파일이었기 때문에 이 부분도 공부하게 되었다. 꼭 이럴 보안 상황 뿐만 아니라 실제 인증 키와 테스트용 인증 키가 다르게 사용되어야 할 때도, .env를 이용한다.

Node.js에서 환경변수를 사용할 땐${process.env.REACT_APP_CLIENT_ID} 와 같이 process.env 라는 자바스크립트 내장 전역 객체를 이용하며, 전역 객체이기 때문에 별도로 import 하지 않아도 접근이 가능하다. 환경변수는 아래와 같이 “키=값" 형태로 정의해주면 노드가 실행되는 동안에만 존재하고 프로세스가 종료되면 소멸된다.

REACT_APP_CLIENT_ID =REACT_APP_MAP_KEY =

그래서 아래와 같이 운영체제의 명령어를 이용해 노드가 종료되어도 환경변수가 실행될 수 있도록 export 키=값 의 형태로 사용하였다. 하지만 이런 방법은 매우 번거롭고 프로젝트 별 의존성 문제가 발생한다.

export REACT_APP_CLIENT_ID =export REACT_APP_MAP_KEY =

그래서 이를 위해 현재는 react-scripts@0.2.3 이상을 사용한다면 환경변수 관리를 위한 라이브러리는 필요없으며, CRA에 포함되있는 react-script내부 에서 dotenv 라이브러리 처리를 해준다.

dotenv를 사용하는 방법은 다음과 같다.

1.프로젝트 루트에 .env 파일 생성
2.REACT_APP_ 로 시작하는 환경 변수를 거기 에 설정하십시오.
3.구성 요소에서 process.env.REACT_APP_... 로 액세스하십시오.

아, 그리고 당연하지만 주의할 점으로 .env는 민감한 정보를 담고 있는 파일이기 때문에 꼭 .gitignore를 통해 스테이징에서 제외시켜 레포에 올라가지 않도록 해야한다.

마이페이지

내역

  • 게스트는 놀이터를 예약하면 호스터가 지정한 놀이터 가격에 따라 포인트가 차감되며 마이페이지 내역 페이지에서 예약한 내역을 볼 수 있습니다.
  • 예약 취소를 누르면 포인트가 다시 환불되며 예약 내역에서 삭제됩니다.
  • 진행일자가 이미 지난 내역은 예약 취소 버튼이 없습니다.

후기

  • 진행일자가 지난 내역들은 후기를 작성할 수 있습니다.
  • 작성 가능한 후기에서 작성한 후기는 내가 작성한 후기 탭에서 바로 확인이 가능하며, 놀이터 상세 페이지에도 바로 반영이 됩니다.
  • 작성 가능한 후기에서 다시 작성 시, 후기 수정이 가능합니다.

styled-component를사용해 컴포넌트의 상태를 props로 받아 스타일 적용을 다르게 할 수 있었다.

color: ${props => (props.selectReview === 'First' ? '#000' : '#ddd')};
border-bottom: ${props => props.selectReview === 'First' ? '2px solid #000' : '1px solid #ddd'}; ;

포인트 충전

  • 숫자만 입력이 가능하며, 빈 값을 충전 시 "포인트를 입력해주세요!" 라는 경고 문구가 나타납니다.
  • 놀이터를 예약하면 포인트가 차감되며, 예약을 취소하면 다시 포인트가 환불됩니다.
  • 로컬스토리지 토큰 유무에 따라 로그인한 사용자는 마이페이지와 호스트 등록페이지로, 로그인 하지 않은 사용자는 호스트 등록을 할 수 없으며 로그인 페이지로 이동하게끔 조건부 렌더링 하였습니다.

기억하고 싶은 코드

Link와 useNavigate의 구별

내가 참 useNavigate를 좋아하는 것을 알게되었다. ㅋㅋㅋㅋㅋㅋㅋ

Link

  • 클릭 시 바로 이동하는 로직 구현 시에 사용
  • ex) 상품 리스트에서 상세 페이지 이동 시

useNavigate

  • 페이지 전환 시 추가로 처리해야 하는 로직이 있을 경우 useNavigate 사용
  • ex) 로그인 버튼 클릭 시
    • 회원가입 되어 있는 사용자 -> Main 페이지로 이동
    • 회원가입이 되어 있지 않은 사용자 -> SignUp 페이지로 이동

Link를 써줘도 충분한 곳에 useNavigate를 남발한 적이 있었다..

styled-components 를 사용할 때 Link 사용은 다음과 같이 쓸 수 있다.


<StyledLink to={`/places/placeinformation/${place_id}`}>
     <h2>{title}</h2>
</StyledLink>

const StyledLink = styled(Link)`
	margin: 20px auto 0;
  height: 50px;
  width: 140px;
`;

프로젝트를 마치며

잘했던 점

저번 팀프로젝트 때 가장 고민을 많이 했던 부분들이 응답받은 데이터를 활용하여 어떻게 화면에 그려줄 지, query string이나, path로 동적 라우팅이 어떻게 구현되는지 어려웠는데 그래도 기본적인 것들이 먼저 그려지니까 저번 프로젝트 때보다 더 많은 기능 구현을 할 수 있었던 것 같다. 그냥 쓰는 게 아니라 용도와 흐름을 이해하고 쓰는 useStateuseEffect 로 로직을 구현하려고 노력하니 며칠전의 나는 어려웠을 이 로직이, 조금씩 구현이 나아진다는 느낌을 스스로 받아서 너무 행복했다. 역시 성장을 스스로 느낀다는 것은 정말 뿌듯쓰...

그리고 정말 좋았던 점은 팀원들 팀워크가 너무 좋았다. 공유 사항이 빨랐고 피드백이 빠르다보니 팀원간의 블로커가 생길 일이 없었던 것 같다. 그만큼 서로의 진행 사항을 인지하고 있었기에 자신이 부딪힌 어려움이 생기면 그 팀원에게 가서 미리 알려주거나 다른 팀원의 분량이더라도 자신이 생각했을 때, 그 로직을 어떻게 구현했을지 궁금하면 가서 물어보거나 서로 서로를 인지하고 챙기는게 보였다. 프로젝트 다 끝나고 짧은 회고시간에 .. 정말 고맙다는 말밖에 할 말이 없었다!!!! 서운한 점..? 없어서 얘기 못했다..

아쉬운 점

Redux의 사용에 익숙하지 않아서 state를 전달용으로 사용되는 컴포넌트들이 존재한다. 리덕스.. 처음 개념만 이해하면 쓰는 건 어렵지 않다고 하시는데 이번 프로젝트에서 코드 리팩토링을 하면서 리덕스를 적용해볼 시간이 부족하였다. 어서 빨리 리덕스 공부해.........

profile
얼레벌레 돌아가는 Frontend Developer

0개의 댓글