개발입문 첫 프로젝트
이솝페이지를 모티브로 하여 새로운 기획으로 재구성하는 1차 프로젝트를 시행하였다. 우리팀은 프로젝트에 우리의 개성을 살리기 위해 제품을 Tea로 구성했고, 실제 Aesop페이지에서 불편했던 점 혹은 개선해야될 점을 중심으로 회의하며 프로젝트를 계획했다.
Project Manager
홈페이지에 들어온 순간부터 제품을 구매하기 까지의 고객의 관점에서 바라보는 ProductManager의 역할은 나에게 큰 호기심을 자극했다. 코드의 기술적인 부분보다 회사 제품의 본질을 바라본다는 점에서, 개발자이지만 고객과 가장 가깝게 연결될 수 도 있다는 생각에 지원하게 되었다. 프로젝트 발표는 덤으로..
1. Carousel
홈페이지를 로딩하면 가장 먼저 보이는 메인페이지를 맡게되어 심리적 부담이 컸었다. 캐러셀을 꼭 만들어 보고 싶어 지원했지만, 라이브러리 없이 캐러셀은 만드는 것은 꽤 힘들었다.
//Main.js 캐러셀 작동 함수
const [slide, setSlide] = useState(0);
const carouselButtonCount = MAIN_CATEGORY.length / 2;
const handleSlideBtn = value => {
if (slide + value === carouselButtonCount + 1 || slide + value === -1)
return;
setSlide(prev => prev + value);
};
useEffect(() => {
sectionRef.current.style.transition = 'all 0.5s ease-in-out';
sectionRef.current.style.transform = `translateX(-${slide * 600}px)`;
}, [slide]);
최종적으로 코드의 구성이 간결해졌다.
캐러셀 이미지 리스트가 화면을 넘어가는 것을 막는 것 부터, 버튼을 별개로 구성하여 캐러셀 z-index로 띄워 absolute시키며 작동시킬 때 까지 정말 많은 고민을 하며 이틀 밤을 꼬박 새어 완성했던 기억이 새록새록하다. 후에 코드의 가독성과 재사용성을 고려하여 "MAIN_CATEGORY.length / 2" 를 구성하는 것으로 개인 노션에 메모하여 마무리지었다.
2. Filter
Filter를 구현하며 useSearchParams의 사용에 익숙해졌다.
url에 Backend와 합의한 대로 key값과 value값을 구성하여 체크박스에 클릭과 해제에 따라 append되고 delete되는 것 까지 구현하였지만 한참을 헤메었는데, useEffect의 사용을 간과하고 있었다.
backend와 합의한 url만 구현하면 되는줄 알았지만, url의 변화에 따라 렌더링을 다시 하도록 코드를 구성하였더니 쉽게 필터링이 되는 것을 확인할 수 있었다.
//ProductList.js Filter 컴포넌트 주요 구성
useEffect(() => {
fetch(
`${APIS.items}/${params.category}/${params.subcategory}${location.search}`
)
.then(res => res.json())
.then(data => setProductData(data));
}, [location.search, location.pathname]);
//Filter.js
const [searchParams, setSearchParams] = useSearchParams();
const setQuery = (value, e) => {
if (e.target.checked) {
searchParams.append('tasting_notes', `"${value}"`);
setSearchParams(searchParams);
} else {
const search = searchParams.getAll('tasting_notes');
searchParams.delete('tasting_notes');
search
.filter(list => list !== `"${value}"`)
.forEach(value => {
searchParams.append('tasting_notes', value);
});
setSearchParams(searchParams);
}
};
4. 결제페이지
결제페이지를 구성하며 Backend와 정말 많은 소통을 했다.
특히 데이터 구조에 따른 UI 구현에 많은 공부를 하게 되었다. 데이터를 객체로 받을 때와 배열로 받을 때, 최초 마운트시 데이터가 없을 때 렌더링을 막는 법이 가장 기억에 남는다.
if (!orderViewData.orderStatus) return null;
input값을 backend로 'POST'해주기 위해 입력값을 배열에 담는 코드도 이해를 하지 못해 애먹었던 기억이 있다.
useEffect를 이용한 fetch함수 다른 프론트 팀원들보다 일찍 경험하게 되어 자신감이 생겼고, Agile방식을 활용해 css가 거의 없다한 UI에 데이터가 들어오는 것을 처음 경험했다. Backend와 데이터 구조 변경 등을 통해 완성시켜 나갈 때 큰 뿌듯함을 느꼈다.
4. 결제완료 페이지
프로젝트 마감 D-1
Backend팀원의 요구에 급하게 만들어 보았다. Backend팀원이 미안한 표정으로 가능한지 질문하였고, 나는 오히려 괜찮다며 자신감있게 점심시간 전까지 가능하다고 했다. 프로젝트 초기에 비해 훨씬 간단하게 생각하며 빠르게 페이지의 구조와 코드를 구성할 수 있었다. UI구성, useEffect사용, data구성에 따른 UI구현 등 프로젝트를 진행하며 많이 고민했었던 기능들이었기에 손쉽게 만들 수 있었다. 다만 데이터가 구현되는 detail을 올리기 위해 나름 고심했다.
특히, Backend서버에서는 회원가입을 하는 순서대로 쌓이게 되는데, 하나의 배열로 들어가있어 해결하기 위해 대부분의 시간을 소비했다. 결국 마지막 회원가입 한 회원의 데이터를 받아오는 것을 성공했고, 시간은 프로젝트 발표 10시간 전 새벽이었다.
//orderView.js 결제완료 페이지 기억에 남던 코드
const [orderViewData, setOrderViewData] = useState({});
if (!orderViewData.orderStatus) return null;
const OS = orderViewData.orderStatus;
const date = OS[OS.length - 1].order_number;
const newDate = `${date.substring(0, 4)}년 ${date
.substring(4, 6)
.replace(/(^0+)/, '')}월 ${date
.substring(6, 8)
.replace(/(^0+)/, '')}일 ${date.substring(8, 10)}시 ${date
.substring(10, 12)
.replace(/(^0+)/, '')}분 ${date.substring(12, 14).replace(/(^0+)/, '')}초`;
프로젝트 발표 Demo-Day
막차가 끊겨 택시를 타고 집에가는 새벽 4시에 벌써 홀가분한 기분이었다.
대부분의 기능 구현 모두 잘될뿐만 아니라 페이지 이동도 잘됐다. 서버도 탄탄해서 끊기는 현상도 거의 없었다. 물론 허술한 부분이 존재했지만 기능들을 보여줄 때 크게 필요없던 부분이었다.
나는 팀원들의 걱정과 만류에도 불구하고, 프로젝트 발표에 직접 시연하자는 의견을 강력히 어필했다. 우리가 만든 탄탄하고 안정된 프로젝트를 발표에 직접 보여주고 싶은 마음이 컸다. 그렇게 프로젝트 시연이 결정되었다.
끝으로
이 프로젝트는 회고록으로 끝나는 것이 아닌, 배포를 통해 업데이트를 하며 보다 완성도있게 refactoring을 진행할 예정이다. 내가 작성하지 않은 코드들과 구현하지 않은 기능들을 다시 복기하며 프로젝트에서 쓰인 코드들과 기능들을 천천히 살펴봐야겠다.
>대학생활 학점을 따기위한 의미없는 조별활동, 회의, 과제수행 등에서 느낄 수 없었던 모든 구성원이 목표를 향해서 나아가는 상황이 나를 뛰게 만들었고, PM의 역할로 항상 책임감을 느끼도록 만들었다. 2주간 온전히 몰입하는 환경속에서 첫 프로젝트를 통해 나의 한계를 여러번 뛰어넘었고, 팀원들과 수 많은 소통속에서 진취적인 팀워크를 배울 수 있었다.
첫 프로젝트를 무사히 마칠 수 있게 서로 으쌰으쌰하며 열심히 노력한 sipscent조 앞으로도 화이팅!!
'개발기록' 카테고리의 다른 글
[Next.js] context를 이용해보자! + TypeScript (0) | 2023.08.25 |
---|---|
RunBase ( 2 ) - 극한의 컴포넌트 재활용 (0) | 2023.08.13 |
RunBase ( 1 ) - 기획 (0) | 2023.08.01 |
TwoMinutes(이분) Web Frontend Develop Internship (0) | 2023.05.31 |
Wecode 2차 프로젝트 회고록 (0) | 2023.04.20 |