Skip to content

secondlinefirefist/caffeineMarket

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

☕️ caffeineMarket

1. 프로젝트 소개

커피를 좋아하는 현대인이라면 손쉽게 로그인하여 커피와 관련된 상품을 판매하고 일상을 공유할 수 있는 SNS 서비스입니다. 커피와의 일상을 게시글로 공유하며 좋아요와 댓글을 통해 사용자와 소통합니다. 다양한 사람들을 팔로우하고, 마음에 드는 피드가 있다면 '좋아요'를 누르거나 댓글을 달 수도 있습니다. 또한, 다른 사용자와 채팅창을 이용해 즐거운 대화도 나눌 수 있습니다.

🧷 배포 URL


2. 팀원 소개(2호선 불주먹팀)

김민영 김지수 김태희 채지훈
🔗 BradleyyKim 🔗 jsk3342 🔗 greenT-Hee 🔗 jihoon-chae

3. 목표

바닐라 자바스크립트를 통해 라우팅 활용 및 상태관리, 비동기 통신 개념 등 기초적인 활용을 학습하고 구체적인 이해를 목표로 제작

  • 빠른 기능 구현을 목표
  • 유저와의 상호작용이 큰 프로젝트에서 동적인 UI의 필요성 체감하기 위함
  • 웹 서비스의 규모의 커짐에 따라 리액트 컴포넌트의 중요성을 직접 확인하기 위함
  • DOM 이벤트의 복잡성을 직접 체감하면서 virtual DOM의 필요성을 체감하기 위함

4. 개발 환경

4.1 스택

  • Front-End : HTML CSS JavaScript Sass
  • Back-End : 제공된 API 사용

4.2 개발 관리

Jira Slack

5. 프로젝트 구조

.
├──📁 src
   ├──📁 pages
   |   └── ...html
   ├──📁 css
   ├──📁 img
   └──📁 js

6. 역할 분담

👨🏻‍🚒 김지수

  • splash 구현
  • 로그인 기능 구현
  • 회원가입 구현
  • 프로필 수정 구현
  • 홈피드 구현

👨🏻‍🚒 김민영

  • 게시글 등록(upload)
    • 텍스트 입력 및 업로드 구현
    • 여러 이미지 업로드 구현
    • POST요청으로 API에 데이터 저장
  • 게시글 상세 페이지(postDetail)
    • myProfile 페이지에서 이미지 클릭 시 postId값을 불러와 상세 페이지 UI 구현
    • API에 저장된 개인 로그인 토큰을 이용해 GET요청을 통해 UI 구성
    • 댓글 UI 구현
  • 댓글 작성 기능(commentLoad)
    • 댓글 작성 시 reload를 통해 댓글 실시간 추가 구현
  • 검색페이지(search)
    • 검색 결과 박스 실시간 구현 예정

👨🏻‍🚒 채지훈

  • 상품등록 (product)

    • 이미지 업로드 기능 구현
    • 상품 데이터 POST 요청
  • 상품수정(productModification)

    • 이미지 업로드 기능 구현
    • 상품 데이터 GET요청/ PUT 요청
  • 채팅방(chatRoom)

    • 텍스트 입력후 전송 버튼 클릭시 채팅창에 렌더링
    • 이미지 업로드시 채팅창에 렌더링

👷🏻‍♀️ 김태희

  • myProfile & yourProfile

    • 유저 정보, 상품&게시글 리스트 GET
  • 404, 공용 및 프로필 모달, 삭제, 로그아웃 기능 구현

  • follwing & follower

    • 팔로잉/ 팔로우 API GET, DELETE, POST
    • 팔로우 버튼 누르면 숫자 증감 반영
  • 좋아요 기능

    • 좋아요 API POST, DELETE 요청
  • 일러스트 로고 디자인

    • 카페인 마켓 캐릭터 로고 및 아이콘 제작

7. 개발 기간

2022.06.09 ~ 2022.07.29


8. UI

image

9. 페이지 기능

🧷 페이지 기능 상세 설명

1) 홈

splash 로그인 페이지 회원가입 페이지
splash login 회원가입
홈 페이지 채팅 페이지 404 페이지
image

2) 게시글

게시글 작성 페이지 게시물 상세 페이지
게시글 수정 게시글 삭제 댓글 기능

3) 프로필

마이 프로필 페이지 유어 프로필 페이지 팔로우/팔로잉 기능
마이프로필 유저프로필 팔로워페이지
로그아웃 페이지 프로필 수정 페이지

4) 판매 상품

상품 등록 페이지 & 상품 링크 이동 상품 수정 페이지 상품 삭제 페이지
상품등록 상품 수정 상품 삭제

10. 트러블 슈팅(핵심 로직)

🧷 트러블 슈팅 보러 가기

1. Location Property

  • 문제 상황

    • 하나의 html파일과 API로 yourProfile, myProfile & 나의 팔로잉/팔로워 리스트와 다른 유저의 팔로잉/팔로워 리스트 동시에 구현해야 함
    • following/follower 리스트에서 프로필로 넘어갈 때, 해당 유저에 맞는 yourProfile을 보여줘야 함
    • 토큰에서는 상대방의 accountname을 가져올 수 없다는 것과 클릭 했을 때 해당 유저의 accountname만을 정확하게 집어내지 못하고 있었음
  • 원인 추론

    • GET 요청 url뒤에 accountname을 넣어줘야 하는데, 나의 프로필은 로컬스토리지에서 getItem으로 사용하면 되지만 상대방 프로필 accountname을 가져오지 못했음
  • 해결 방법

    • Location (현재 URL) Property 중에서 query string이라고 불리는 search string을 사용하여 해결
    • search string은 url에서 ? 를 포함한 뒷부분을 string 형식으로 반환해주는 역할

    실제 적용 코드)

    followingList.html에서 유저를 선택할 때 넘어가는 a태그의 href 주소를 ?accountname=유저의 accountname 붙여서 보냄

    link.setAttribute(
          'href',
          '../pages/myProfile.html?accountname=' + resJson[i].accountname
        );

프로필 html로 넘어와서 상대방의 accountname을 location.search로 변수에 담아 사용

image

내 계정일 경우에는 로컬스토리지에서, 상대방 프로필이면 url을 query string값이 accountname에 들어가게 처리

  1. location.search⇒ ?accountname=유저아이디

  2. location.search.replace(’?’,’’) ⇒ accountname=유저아이디

  3. location.search.replace(’?’,’’).split(’=’) ⇒ ['accountname', '유저아이디']

📌 userInfo.js (프로필 상단, 유저 정보 API GET 요청 코드)

    const myAccountname = `${window.localStorage.getItem('accountname')}`;
    const yourAccountname = location.search.replace('?', '').split('=')[1];
    const accountname = yourAccountname ? yourAccountname : myAccountname;
    //프로필 정보 보여주기
    async function infoUser() {
      try {
        const res = await fetch(url + '/profile/' + accountname, {
          method: 'GET',
      
          ..생략..}
    }

라우팅 예외처리에도 사용

  • 마이프로필로/유어프로필과 팔로잉/팔로워가 서로 같은 html 파일을 공유하고 있어, 404 에러를 많이 겪게 됨
  • JS에서 흔하게 사용하는 뒤로가기인 window.history.back() 또는 window.history.go(-1)만 썼을 때 에러 발생
  • Location Porperty를 사용해서 예외처리로 Error 해결

이전 코드)

const btnBack = document.querySelector('.btnBack');
btnBack.addEventListener('click', () => {
  location.href = window.history.back();
});
  • location pathname: 위치에 대한 URL의 경로를 포함하는 문자열
  • 사용 의도: html 파일명을 뽑아서 조건식에 사용하기 위해

해결 코드)

const locationPath = location.pathname.split('.')[0].split('/')[3]; 
const btnBack = document.querySelector('.btnBack');
btnBack.addEventListener('click', () => {
  if (accountname == yourAccountname) {
    location.href = `../pages/${locationPath}.html?accountname=${yourAccountname}`;
  } else if (accountname == myAccountname) {
    location.href = `../pages/${locationPath}.html`;
  }else {
  location.href = window.history.back();
  }
});

bradley의 팔로잉 목록에서 bradley의 프로필로 성공적으로 이동

image

image

11. 스페셜 포인트

  • 팀원들과 가까운 거리에 거주하여, 물리적 허들이 없다는 장점을 통해 최소 주 2회 오프라인 만남을 통해 빠른 피드백으로 비용 절감
  • 팀원 간 이슈가 발생했을 때, 대면을 통한 솔직한 대화를 통해 바로 해결하여 시간 절약
  • 로그인 기능과 배포 페이지를 우선적으로 구현함으로써 시스템적으로 연결된 기능들을 빠르게 구현
  • 압도적인 커밋 수 (over 760 commits)

12. 고생담

  • API와 비동기로 통신하는 로직에 대한 이해가 어려움
  • 팀원 절반이 중간에 코로나에 걸린 건강 이슈
  • 초반에 커밋 컨벤션이 혼재되어 사용된 이슈

13. 레슨런

Team Operation

Tech Operation

  • 잘 이행된 부분
    • 간단한 CI/CD action 기능으로 자동 배포 수행 및 개념 이해
    • API 명세에 대해 구체적으로 미리 파악해 서버와 통신을 원활하게 유지
    • 비동기 작업에 대한 이해를 통해 유연하게 이벤트를 동작
    • 폴더 구조를 미리 지정해 파일 경로 문제 제거
    • 시작 전 git branch 대한 이해를 통해 branch 구체적으로 세분화하여 에러 방지
    • 팀원 간 페이지 별로 작업 진행하여 충돌 최소화
    • 재사용성을 고려하여 javaScript 기능을 구현해 모듈화 리팩토링 단계를 위한 기반을 마련
  • 개선 및 학습한 부분
    • 기능 복잡도가 올라갈 수록 javaScript 기능별로 구현하는 것이 더 낫다는 결론에 도달
      • 파일을 기능별로 세분화하여 라우팅 주소 변경
    • MVC 패턴에 대해 학습하여 모듈화 패턴에 맞추어 프로젝트 아키텍쳐를 구현
      • 추상화 단계에 따라 함수를 분류 및 기능별 모듈화 작업

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •