1차 프로젝트인 마켓컬리에 이어 2차 프로젝트는 에어비엔비를 하게되었다.
이번에 프로젝트를 함께 한 팀원들
백엔드
김세형님, 박국현님
프론트
윤찬호(나), 권유진님, 김미현님, 김상연님
1차 마켓컬리 프로젝트 팀원인 세형님과 유진님이 다시 같은팀이 되었다 😁
1차때는 뭔가 "이거 이거 다 하자! 할 수 있어!!" 라면 이번 2차 때는 1차 때에 알게 된 여러 개의 페이지를 찍어내는 것 보다 하나의 기능이라도 제대로 만들어보자 해서 에어비엔비에서 필수로 들어가야 하는 기능들 빼고는 우리 기준으로 이런 건 빼도 되겠다 하는 기능들은 가차없이 다 쳐냈다.
위와 같이 기능들을 뺀 이유 중에 백엔드는 유닛테스트 프론트는 Hooks, styled-component 와 같은 새로운 기술을 익혀가면서 프로젝트에 적용해야 했기 때문이다.
나는 에어비엔비를 모티브로 한 프로젝트에서 숙소 리스트 부분을 맡았다
먼저 에어비엔비는 프로젝트 선정할 때 내가 냈던 프로젝트 였지만 막상 1차가 끝나고 2차때에 하려니 새로운 기술 적응(Hooks,styled-component, google map api)과 시간적 압박, 체력 고갈로 인해 내심 안됐으면 했던 프로젝트였지만 되어버렸다 🥲
하지만 지도 부분에 직접적으로 마커를 커스터마이징해서 지도에 뿌려줄 땐 너무 재밌게해서 하길 잘했다는 생각이 들었다.
먼저 숙소 리스트에서는 메인에서 입력한 위치, 체크인, 체크아웃, 게스트(성인, 어린이, 유아) 값을 받아 리스트 헤더 부분에서 보여질 수 있도록 했다.
// main에서 넘어온 지역, 예약날짜, 게스트 정보
const roomLocation = useLocation();
const perday = getPerDay(getHeaderInfo);
setHeaderInfo({
checkin: getHeaderInfo[2].split('=')[1].replaceAll('-', '~'),
checkout: getHeaderInfo[3].split('=')[1].replaceAll('-', '~'),
adult: getHeaderInfo[4].split('=')[1],
child: getHeaderInfo[5].split('=')[1],
baby: getHeaderInfo[6].split('=')[1],
per_day: perday,
});
// 몇 박인지 계산해서 반환해주는 함수
function getPerDay(getHeaderInfo) {
const startDay = getHeaderInfo[2].split('=')[1].split('-');
const endDay = getHeaderInfo[3].split('=')[1].split('-');
const startData = new Date(startDay[0], startDay[1], startDay[2]);
const endData = new Date(endDay[0], endDay[1], endDay[2]);
const getSecond = endData.getTime() - startData.getTime();
return getSecond / 1000 / 60 / 60 / 24;
}
필터 부분은 숙소 유형, 요금에 따라 서버 API로 요청을 해서 해당 리스트들을 다시 받아올 수 있도록 로직을 구현했다.
숙소 유형과 요금을 쿼리스트링으로 보내는데 숙소 유형 옵션이 1(true),2(false),3(true),4(false) 라면 해당하는 것들만 &typelist=1&typelist=3
와 같이 보냈어야 했는데 아래와 같은 로직으로 처리했다.
또한 아래와 같이 옵션을 설정했을 경우 해당 버튼이 클릭된 것 처럼 보이도록 처리했다.
숙소 마커
지도 마커 모달창, 페이지네이션
구글 map api는 google-map-react
를 사용하였다.
google-maps-react
를 처음 사용했지만 마커 부분 커스터마이징 하기가 어려워서 google-map-react
라이브러리를 선택하게 되었다.
원래는 지도를 마우스로 클릭 이동할 때 해당 지도의 center position
값으로 위도와 경도의 정보를 서버로 보내면 서버에서 해당 지역 반경에 있는 숙소 리스트를 반환해주기로 했는데 부득이하게 백엔드 업무 과부하로 프론트에서 직접 강남구
,용산구
,...
와 같은 키워드로 직접 해당구 위도와 경도를 입력해서 지도에 센터 값을 찍기로 하였다.
main에서 입력한 지역구의 위치를 가져오고 해당 구의 id값을 알기 위해 LocationInfoData.js
를 위와 같이 만들었다.
main에서 넘어온 지역, 예약날짜, 게스트 정보
const roomLocation = useLocation();
const getHeaderInfo = roomLocation.search.substr(roomLocation.search.indexOf('?') + 1).split('&');
LocationInfoData를 이용해서 메인에서 넘어온 HeaderInfo 지역값을 기준으로 id값을 추출하고, 구글 지도 컴포넌트로 위도와 경도를 전달해서 해당구로 지도의 센터 포지션이 이동할 수 있도록 함
const location = LocationInfoData();
const getLocationInfo = element => {
if (element.name === getHeaderInfo[1].split('=')[1]) {
setCenterPosition({
lat: Number(element.lat),
lng: Number(element.lng),
});
setLocationInfo(getHeaderInfo);
return element.id;
}
};
const getLocationId = location.find(getLocationInfo);
시간이 너무 촉박했던 점?? 1차와 달리 2차는 뭔가 시간이 더욱 더 훅 지나갔다.
백엔드도 마찬가지겠지만 새로운 Hooks
,styled-component
기술 적용도 그렇고 프로젝트의 난이도, 체력적으로 너무 힘들었다.
Trello를 사용할 때 하나의 카드에 너무 많은 기능을 한 번에 담아서 스프린트가 제대로 지켜지지 못한 점이 너무 아쉽다. 앞으로는 큰 기능 하나(카드)에 세부적으로 작성해야 할 것들을 모조리 나열하는 것 보다는 그것을 조금 더 세분화하고 잘게 쪼개서 스프린트가 지켜질 수 있도록 해야겠다.
그리고 가독성 좋은 코드와 그것을 위한 컴포넌트 분리를 잘하지 못한 것 같다. 시간이 촉박했던 걸까 아니면 나의 실력 부족일까 싶지만 시간이 촉박했더라도 처음부터 코드를 작성해 나갈 때 조금 더 깊이 생각했더라면 지금의 코드 보다는 조금 더 가독성이 좋은 코드와 컴포넌트 분리를 잘하지 않았을까하는 마음이 강하게 남아있어 아쉽다.
그리고 1차 프로젝트때에 하루 4,5시간씩 자며 미친듯이 열정 넘치게 했던 체력은 온 데 간 데 없이 사라져버렸던 점이 너무 아쉬웠고 1차 프로젝트 시작 전부터 멘토님들이 그렇게 강조 하셨던 체력관리의 중요성을 뼈저리게 느끼게 되었던 계기가 되었다.
1차 때의 경험을 통해 최대한 서로 소통을 많이 하려고 노력했던 점. 한 가지를 예를 들어 프론트에서 mockdata
를 만들어 사용할 때 백과 프론트 모두 key
값이 뭐고 어떻게 바뀌는지 데이터 타입은 뭔지 지속적인 소통으로 서버와 연동했을 때 data key
값으로 인해 발생하는 에러들을 정말 많이 줄일 수 있었다.
또한 프론트와 백엔드 모두 서로 편하게 할려고 하는게 아닌 프론트가 힘들다고 하면 백엔드에서 편하게 데이터를 뿌려줄 수 있도록 배려하고 백엔드에서 조금 힘들다고 하면 프론트에서 조금 더 편하게 해줄려고 배려 했던점이 좋았다.
새로운 프로젝트, 새로운 기술 적용, 기업협업, 누적된 피로, 부족한 시간으로 서로 많이 힘들었을텐데 서로 으쌰으쌰하는 분위기를 유지해준 팀원분들에게 너무 감사하게 생각한다.
스펀지처럼 뭐든 잘 흡수해버리는 개발자가 되겠다!😁
찬호님 에어드롭더비트 너무 멋있었어요 고생 많으셨어요!