웹 개발 포트폴리오 | 예적금 상품 비교 플랫폼
내일배움캠프 4기 웹 개발 과정 React 트랙 수료생 최종 프로젝트 '팁퍼'를 소개합니다.
Sep 04, 2023
4조 프로젝트 : 팁퍼 (Tipper)
금융관리 초보자를 위한 팁을 드려요!
자금 마련의 기본인 예금, 적금 상품들을 비교해주고 꿀팁들을 공유하는 사이트입니다.
기능 소개
- 예적금 상품 비교 기능 설명
- 상품검색
상품 명, 은행 명을 입력하여 해당 상품을 찾아볼 수 있음
- 2-3개의 상품 비교
상품들 중 2-3개를 골라서 상품들의 조건과 만기 수령액을 미리 예상해 볼 수 있음
예금, 적금 상품들 끼리만 비교가 가능
각 상품이 단리, 복리인지 판단하여 적용
최고금리를 적용한 최대 만기 수령액을 제시
- 상품 찜하기 기능 (로그인 필요)
아 본 상품들이 마음에 든다면 찜하기 버튼을 눌러서 저장 가능함
찜한 상품은 언제든 상품 비교할 때 다시 선택하여 다른 상품과 비교 가능
마이페이지에서도 모아볼 수 있음
- 커뮤니티 기능 설명
- 금융상품 후기, 금융관리 노하우 총 2개의 탭으로 구성
- 게시글 CRUD 기능 구현 - 이미지 업로드 가능
- 게시글에 좋아요 기능 구현
- 마이페이지에서 내가 쓴 글과 좋아요를 누른 게시글 확인 가능
🏗 아키텍쳐
🍀 주요 기술
- firebase
- axios
- vercel
- lodash
🛠 트러블슈팅
CORS에러로 인한 문제
- Cross-Origin Resource Sharing(교차 출처 리소스 공유 정책)
cors에러로 openAPI의 data를 가져오지 못함
✅ 해결
→ CORS 를 해결하기 위해서는 (서버 측)Origin Allow 속성에 클라이언트에서 보내는 출처를 추가해주어야 하고 또한 배포하는 AWS 같은 곳에서도 따로 설정을 해주어야 한다고한다.
→ 서버를 수정할 수도 없어 heroku-anywhere이라는 프록시서버 설정을 사용
https://cors-anywhere.herokuapp.com/https://finlife.fss.or.kr/finlifeapi/savingProductsSearch.json?auth=`${개인인증키}`&topFinGrpNo=020000&pageNo=1
아쉬웠던 점
- 리액트쿼리와 같이 실시간으로 데이터를 받아오는 경우 한번씩 연결 끊기거나 데이터를 받아오지 못하는 에러 발생
- 서버 연결 해주기 heroku에서 남용으로 인해서 버튼을 눌렀을때만 서버를 연결할 수 있도록 변경해두어서 서버가 끊기게 되면 데이터를 가져오지 못하는 상황 발생
→위와 같은 사이트에 들어가서 서버 연결을 해줘야함
API 데이터 구조로 인한 문제
- 한 상품에 대한 기본정보(BASE_LIST)와 금리에 대한 정보가 담긴 옵션 정보(OPTION_LIST)가 같이 저장되어 있지 않고 분리되어있음
✅ 해결
기본 정보를 기준으로 중복되는 속성값인 fin_prdt_cd가 같은 데이터를 옵션정보에서 찾아서 읽어옴
코드 최적화 ( 상품 3개 선택후 비교 )
- 예금, 적금의 정보를 가져오는 함수를 각 2개씩 총 4개 생성(적금base, option / 예금base, option)
✅ 해결
→ Promiss.all() 메서드로 함수를 병렬실행
→ 전체 실행이 완료되면 한번에 모든 결과를 처리하도록 하여 최적화
- 2. 종류가 다른 3개의 배열로 선택된 금융상품의 상태 값을 각각 관리
✅ 해결
선택된 상품들의 정보를 하나의 배열에 순서대로 push함
//* 금융상품 리스트 가져오기 const handleButtonClick = async () => { const baseListPromises = [ getDocs(collection(db, "DEPOSIT_BASE_LIST")), getDocs(collection(db, "SAVING_BASE_LIST")), ]; const optionListPromises = [ getDocs(collection(db, "DEPOSIT_OPTION_LIST")), getDocs(collection(db, "SAVING_OPTION_LIST")), ]; const [baseListSnapshots, optionListSnapshots] = await Promise.all([ Promise.all(baseListPromises), Promise.all(optionListPromises), ]); const products = []; const depositOptionalList = []; const savingbaseList = []; const savingoptionalList = []; baseListSnapshots.forEach((snapshot, index) => { snapshot.forEach((doc) => { const newProduct = { id: doc.id, ...doc.data(), }; if (index === 0) { products.push(newProduct); } else { savingbaseList.push(newProduct); } }); }); optionListSnapshots.forEach((snapshot, index) => { snapshot.forEach((doc) => { const newProduct = { id: doc.id, ...doc.data(), }; if (index === 0) { depositOptionalList.push(newProduct); } else { savingoptionalList.push(newProduct); } }); }); setProducts(products); setdepositOptionalList(depositOptionalList); setSavingbaseList(savingbaseList); setSavingoptionalList(savingoptionalList); }; useEffect(() => { handleButtonClick(); }, []);
debounce처리 (lodash)
- 새 비밀번호 변경을 위해선 사용하고 있는 비밀번호를 입력하고 실시간으로 맞는지 유효성검사가 실행됨 (signInWithEmailAndPassword 메소드를 사용)
- 사용 이유 password input에서 onchange로 계속 값을 받고 있어서 signInWithEmailAndPassword메소드를 사용하는 것은 비효율적
✅ 해결
lodash에 debounce처리를 통해서 비밀번호 입력이 끝난 후 0.3초 후에 그때까지 입력된 값을 한번에 들고 한번만 함수가 실행
3번씩 호출하던 것에서 한번씩만 호출하는 것으로 효율성 높임
**렌더링 되는 모습
debounce처리 전 ⇒ 입력할 때 마다 렌더링
debounce 처리 후 ⇒ 한번만 렌더링
🧑🏻💻👩🏻💻 팀원
이름(역할) | 맡은 업무와 기능수행 | Github |
남마리나(팀장) | 프로젝트 진행, 문서 제작, 기능 구현
상품비교 결과창, 커뮤니티 게시글 작성,수정 기능 구현 | |
박상우(부팀장) | 프로젝트 진행, 기능 구현
상품비교 조건 검색 기능, 랜딩 페이지 기능 구현 | |
김원준(팀원) | 기능 구현
상품비교 조건 검색 기능, 랜딩 페이지 기능 구현 | |
남동현(팀원) | 발표, 기능 구현
홈 UI 제작, 커뮤니티 게시글 불러오기, 삭제 기능 구현 | |
조성아(팀원) | 프로젝트 기능 구현 서포트, 기능 구현
상품명 검색하기 기능, 마이페이지 기능 구현 | |
안시은(팀원) | UX/UI 디자인 | ㅤ |
Share article
Subscribe to our newsletter