Skip to content

preOnboarding-5-team/madup-team-5b

Repository files navigation

매드업 프론트엔드 팀 과제 - Team 5B

  • 사용 기술: Create React App, TypeScript, Sass(SCSS), React Router, Recoil, Victory,react-datepicker, date-fns, lodash, classnames, ESLint, Stylelint, Prettier

  • 팀 구성원: 문재석, 이선아, 이지정

1. 구현된 과제 확인 방법

1) Netlify로 배포된 페이지

🔗 링크

전반적인 기능을 모두 사용해볼 수 있도록 Netlify로 배포하였습니다.

2) 레포지토리 클론

git clone https://github.com/preOnboarding-5-team/madup-team-5b.git
cd madeup-team-5b
npm install
npm start

코드를 더 면밀하게 살펴보기 위해 로컬 환경에서 실행해볼 수 있습니다.

2. 폴더 구조

  • 📁assets

    • 아이콘을 모아둔 폴더입니다.
    • 이 프로젝트에선 svgs 파일만 존재합니다.
  • 📁components

    • 화면을 구성하는데에 있어 필요한 컴포넌트들을 모아둔 폴더입니다.
    • 페이지 전반적으로 사용될 수 있는 컴포넌트인 DatePicker와 Dropdown은 common 폴더에 넣어뒀습니다.
    • 그 외에 SNB와 TopBar는 페이지 전반에 자주 쓰이진 않기 때문에 common 밖에 넣어뒀습니다.
  • 📁hooks

    • Custom hooks를 모아둔 폴더입니다.
    • 이번 프로젝트에선 Recoil을 위한 useRecoil만 존재합니다.
  • 📁layouts

    • 페이지 전체에 적용할 레이아웃을 넣은 폴더입니다.
  • 📁pages

    • 라우터를 기준으로 각각의 페이지를 모아둔 폴더입니다.
    • 해당 페이지에서만 사용되는 컴포넌트들은 components 폴더가 아닌 페이지 폴더 내부에 있습니다.
  • 📁states

    • Recoil과 관련된 파일들을 모아둔 폴더입니다.
    • Atom과 Selector를 구분하여 파일을 작성하였습니다.
  • 📁styles

    • 전역 스타일링, 변수, mixins 등 전역에서 사용되는 스타일링 관련 파일들을 모아둔 폴더입니다.
  • 📁types

    • 전역적으로 사용되는 타입을 모아둔 폴더입니다.
  • 📁utils

    • 앱 전반적으로 사용되는 데이터나 서비스를 담아둔 폴더입니다.
    • 이 프로젝트에선 데이터만 존재합니다.

3. 구현 방향성

  • Airbnb 설정을 기반으로 한 기본적인 ESLint 설정을 하고, 추후 논의를 통해 제약을 점점 강하게 걸어가며 코드 오류를 최소화 했습니다.
  • 전역 상태를 최대한 재사용하여 불필요한 상태 선언을 최소화 했습니다.
  • 필요한 라이브러리가 있다면 최대한 활용하되 작동 방식을 이해 하지 못한 상태로 무작정 사용하는 것은 지양하였습니다.
  • HTML을 최대한 semantic하게 작성하였습니다.
  • Breakpoint를 4단계로 나누어 반응형으로 구현하였습니다.

4. 구현 사항

기본 구현 사항들은 대부분 구현했으나 시간의 부족으로 인해 리팩토링과 면밀한 테스팅은 진행 하지 못하였습니다. 아쉬운 대로 다크 모드와 광고 관리 페이지에서 항목 추가하기를 구현해 보았습니다.

0) ESlint와 Prettier

eslint-config-react-app를 기반으로 하여 eslint-config-airbnb및 관련 peer dependency를 적용하여 기본적인 코드 스타일을 설정하였습니다. 이후 eslint-plugin-react, eslint-plugin-prettier를 적용해줌으로써 강한 강도의 제약을 걸었고, 각각의 설정들이 어떤 역할을 하는지 공부하고 그에 맞춰 확장 순서를 정해 .eslintrcextends에 추가하였습니다.

1) 주요 패키지

대부분의 코드들은 index.ts에서 일괄적으로 import 후 export하여 사용하였습니다.

Victory

화면에 차트를 그리기 위한 라이브러리입니다. 선형 및 막대 차트를 그리기 위해 사용되었으며 각각의 차트를 구현하기 위해 공식문서를 참고하여 구현하였습니다.

Recoil

전역 상태 관리 라이브러리입니다. Recoil과 관련된 모든 파일은 states 폴더에 넣어두었으며 상황에 맞게 사용할 수 있도록 atom과 selector를 둘 다 활용하였습니다.

Atoms

  • dateRangeState: Datepicker에서 날짜를 선택하면 시작 날짜와 끝 날짜가 들어갑니다.
  • selectedServiceState, serviceListState: SNB의 드롭다운에서 선택한 서비스와 드롭다운의 리스트입니다.
  • firstTrendState, secondTrendState, trendTermState: 통합 광고 현황에서 사용되는 상태들로 각각 선택된 카테고리와 일간/주간을 나타냅니다.
  • adListStatusState: 광고 관리 페이지에서 사용되는 상태로써 광고 리스트 필터링에 활용됩니다.
  • themeState: 다크모드를 위한 상태입니다.

Selectors

  • refinedDateRangeState: Datepicker에서 날짜를 선택하면 Date() 생성자를 통해 만들어진 날짜가 반환이 되는데, 이를 활용하기 쉽도록 20220526과 같은 형태로 바꿔주어 반환해주는 selector 입니다.
  • getTheme: 다크 모드를 토글할 때 현재 테마에 따라 필요한 값을 반환해줍니다.

_lodash

차트를 만드는 과정에서 객체를 깊은 복사를 해야하는 상황에서 _.cloneDeep을 활용하였습니다.

React Router

대시보드 페이지와 광고 관리 페이지를 설정하였습니다. 잘못된 주소가 입력될 경우를 생각하여 '*'에 대한 페이지도 설정하였습니다.

2) 페이지

대시보드

통합 광고 현황과 매체 현황을 확인할 수 있는 페이지입니다.

  • 통합 광고 현황

    • 상단의 데이트피커에 따라 표시되는 자료들의 내용이 달라집니다.
    • 데이트 피커의 기본값은 자료의 시작인 2022년 2월 1일이며, 선택 가능한 날짜의 범주는 자료의 시작일자와 마지막 일자인 2022년 4월 20일까지입니다.
    • 통합 광고 현황의 상단에는 데이트피커에서 설정한 날짜 범주 동안의 자료를 합산하여, 해당 날짜만큼의 이전 날짜와 비교해 변화량을 나타내줍니다. 예를 들어, 2022년 3월 6일2022년 3월 8일을 선택했을 경우 총 3일의 기간이므로 2022년 3월 3일 2022년 3월 5일까지의 자료와 비교하여 변화량을 표시해줍니다.
    • 통합 광고 현황의 하단에는 데이트피커에서 설정한 날짜 범주 동안의 설정한 카테고리에 해당하는 자료르 보여줍니다.
  • 매체 현황

    • 데이트피커에 따라 설정된 기간 동안의 페이스북, 네이버, 구글, 그리고 카카오의 매체 현황을 차트와 표로 표시해줍니다.
    • 백분율로 이루어진 파트이기 때문에 만약 수치가 너무 낮을 경우 표시되지 않을 수 있습니다.

광고관리

광고를 관리할 수 있는 페이지입니다. 데이터에 있는 내용을 기반으로 카드가 생성되는 방식입니다.

  • 기본적으로 웹광고와 앱광고로 이루어져 있습니다.
  • 전체, 진행중, 중단됨의 세 가지 상태가 존재하며 드롭다운으로 필터링할 수 있습니다.
  • 종료 일자가 있을 시 광고 생성일 옆에 나타납니다.
  • 광고 만들기를 누르면 새로운 카드를 생성할 수 있습니다.

5. 구현 상세 설명

과제에서 중요하게 다뤄진 부분은 데이터 정제, 차트 및 그래프 만들기, 그리고 전역 상태 관리라고 볼 수 있습니다. 기본적으로 데이터 정제가 잘 이루어져야 차트와 그래프를 만들 수 있고, 그 정제된 데이터를 앱 전반적으로 활용하고 유지하려면 전역 상태 관리가 뒷받침 돼야 하기 때문입니다.

Dropdown

다양한 props를 전달 받아 다른 모양 및 작동을 할 수 있도록 재사용성을 살린 드롭다운 컴포넌트입니다.

전달 받을 수 있는 props

  • type: 'large', 'medium', 'small'에 따라 드롭다운의 크기와 모양이 변합니다.
  • selected: 드롭다운의 선택된 요소를 의미하는 전역 상태를 전달합니다.
  • setSelected: 드롭다운의 선택된 요소를 바꾸는 전역 상태 setter를 전달합니다.
  • list: 드롭다운 리스트를 형성할 배열을 전달합니다.
  • setList?: 드롭다운 리스트를 형성할 배열을 수정할 때 사용하는 setter를 전달합니다.
  • itemAdder?: 드롭다운 리스트에 새로운 요소를 추가할 input창의 활성화 여부를 boolean으로 전달합니다.
  • color?: 전달하는 색상으로 항목의 왼편에 작은 원을 만들어줍니다.

부연 설명

상황에 따라 문자열로 이루어진 배열과 객체로 이루어진 배열이 전달될 수 있는데, 각각의 배열 타입에 따라 내부에서 다르게 작동하도록 타입 판별을 구현하였습니다.

DatePicker

날짜 범위를 선택할 수 있게 해주는 컴포넌트입니다.

  • 시작 날짜와 마지막 날짜를 선택하면 dateRangeState 전역 상태에 날짜들이 저장됩니다.
  • 만약 시작 날짜만 선택하고 마지막 날짜를 선택하지 않는다면 마지막 날짜는 오늘 혹은 가능한 마지막 날짜로 설정됩니다.

MediaChannel

매체 현황에 대한 차트와 표를 만드는 컴포넌트입니다.

  • 전달 받은 데이터를 정제하고 분석하여 카테고리 별로 분류됩니다.
  • 분류된 항목들은 Victory 라이브러리의 재료가 되어 차트를 그리는데 활용됩니다.

TrendDataBoard

통합 광고 현황에 대한 전광판과 그래프를 만드는 컴포넌트입니다.

  • 매체 현황과 마찬가지로 전달 받은 데이터를 정제하여 카테고리 별로 분류됩니다.
  • 반응형으로 구현 되어 화면이 줄어듦에 따라 전광판의 행과 열의 개수가 변화합니다.
  • 선택된 카테고리에 맞는 자료가 보여질 수 있도록 조건문과 계산식을 많이 활용하였습니다.

AdManagement

광고 관리 항목을 생성하는 컴포넌트입니다.

  • 데이터에서 필요한 항목들을 잘라와 필요한 곳에 붙이는 코드를 구현하였습니다.
  • 추가 구현으로 광고 관리 항목을 추가하는 기능을 넣었습니다.

6. 어려웠던 점, 배운 점, 그리고 느낀 점

문재석

Dropdown

재사용성을 고려하여 컴포넌트를 만드는 일은 항상 어려운 것 같습니다. 사용하고 싶은 상황은 많고, 상황이 많을 수록 컴포넌트 내부는 복잡해지기 마련인데, 그 와중에도 효율적으로 알고리즘을 작성하여 최소한의 코드로 최대한의 재사용성을 살리는 것이 관건인 것 같습니다. 이번 프로젝트에서는 재사용성은 살릴 수 있었지만 코드 효율성은 잡지 못했다고 느꼈습니다. 막상 코드를 다 작성하고 컴포넌트를 사용하다 보니 코드를 더 줄이거나 알고리즘을 개선할 수 있는 부분이 많이 눈에 들어왔고, 앞으로의 컴포넌트 설계에 있어 도움이 될만한 아이디어들도 많이 얻을 수 있었습니다. 이번 프로젝트에서는 시간이 부족하여 리팩토링을 진행하지 못하였지만 앞으로의 프로젝트에서 이번에 공부한 내용들을 십분 발휘할 예정입니다.

Datepicker

데이트피커가 필요하여 구글에 'react date picker'라고 검색하였더니 최상단에 이번 프로젝트에서 사용한 라이브러리가 있었습니다. 최상단에 있기도 하고 깃허브 star도 적지 않은 편이라 우선 사용을 해보았는데, 공식 문서는 굉장히 부실할 뿐더러 스타일링도 직접 하기 어렵게 설계되어 있었습니다. 또한 작동 방식도 설명이 되어 있지 않아 직접 코드를 입력해 보고 실행해 보며 사용법을 익혀가야 했는데, 생각보다 시간이 많이 들어 구현이 더뎌지는 현상을 경험하였습니다. 공식 문서가 굉장히 잘 되어 있는 Victory를 함께 사용했던 프로젝트라 그런지 react date-picker의 부실한 공식 문서와 설명이 더 와닿는 느낌이었습니다. 앞으로는 라이브러리를 사용하기 전에 라이브러리에 대해 꼼꼼히 찾아보고 다른 유사한 것들과 비교, 분석을 통해 최선책을 찾아야겠다고 생각했습니다.

어려웠던 점과 느낀점

굉장히 짧은 시간에 걸쳐 진행된 프로젝트인 와중에 팀원 한 명이 중도 하차하는 사태가 벌어졌습니다. 4명이 역할 분담을 하여 진행하려던 일정은 꼬이게 되었고, 아무래도 4~5명으로 이루어진 다른 팀에 비하면 시간이 촉박할 것이라는 예상은 적중하였습니다. 기본 구현도 완벽하게 진행하지 못했을 뿐더러 코드 리팩토링을 할 시간도 전혀 없었습니다. 진작에 공부를 더 했더라면, 실력이 더 좋았더라면 한 명이 하차하는 것과 무관하게 프로젝트를 제대로 완수할 수 있었을텐데 그러지 못했다는 점이 아쉬웠습니다. 앞으로 진행될 프로젝트들에 대해선 더욱 심혈을 기울여 기본 구현은 물론이고 추가 구현까지도 모두 완수해낼 수 있도록 최선을 다해야겠다고 생각했습니다.

이선아

victory.js

이번 과제에서는 차트 그리는 것을 처음 배우게 되었습니다. victory.js를 이용해서 처음으로 차트를 그려보았는데, 공식 문서가 잘 되어있어서 생각보다 쉽게 따라할 수 있었습니다. tooltip과 legend 등 다양한 기능을 사용하며 차트를 꾸며가니 재미가 있었고 생각보다 다양한 기능들이 있어서 아직 더 알아가야 할 게 많다고 생각됩니다. 다만 해당 차트를 그리는 과정에서 수식 계산을 하는 부분에서 어려움을 느꼈습니다..

다크모드

이전 수업에서 배운 기능을 활용하여 이번 과제에 가산점을 위해 추가 구현 하였습니다. recoil로 theme 상태 값을 관리하고, toogle을 통해 dark와 light로 바꿔가며 다크 모드를 구현했습니다. 생각보다 바꿔야 하는 css가 많아서 손이 많이 가긴 했지만, 다 만들고 나니 뿌듯했습니다.

느낀점

팀 과제를 하면서 점점 더 팀원 분들과 친해지고, 서로 모르는 점을 물어보고 찾아가는 과정에서 편하게 물어볼 수 있어서 보람찼습니다. 자신이 맡은 부분의 코드를 작성하고, pr을 올려 코드 리뷰를 통해 리팩토링을 거치며 좀 더 효율적으로 코드를 짜는 방법도 배우고, conflict 발생 시 대처하는 방법도 배우게 되었습니다.

이지정

광고 관리

광고 관리 페이지는 불러온 데이터를 가공하여 화면에 뿌려주고,  드롭 다운을 누를 때마다 선택된 항목에 따른 광고들만 보이도록 하는 부분이라 초반에는 원활하게 진행할 수 있었습니다. 하지만 부가 기능인 광고 만들기, 수정하기 기능 구현에 시간이 오래 걸려 아쉬움이 많이 남았습니다.

광고 만들기는 빈 값을 Recoil로 관리되는 출력 데이터에 추가한 후, 취소를 누른다면 지우고 저장을 누르면 데이터가 업데이트 되도록 했습니다. 그리고 수정하기 기능은 버튼을 클릭하면 input 박스로 변환되고, 수정을 한 후 저장 버튼을 누르면 Recoil에 저장된 데이터에 추가되도록 구현했습니다.

데이터가 저장되는 과정에서 화면에 보이는 데이터와 저장된 데이터 형태가 다른데, 사용자는 화면에 보이는 데이터와 같은 형식으로 작성을 할 것이라 생각하여 여러 번 가공하는 과정을 추가했고, 이로 인해 코드가 많이 복잡해져 아쉬웠습니다.

통합 광고 현황

Victory.js

차트 관련한 기능 개발은 처음이었기 때문에 라이브러리에 대해 공부하는 시간이 오래 걸렸습니다. 공식 문서를 바탕으로 원활하게 그래프 그리는 부분은 구현했으나, 데이터를 불러오고, 가공한 후 그래프로 출력하는 부분이 어려워 시간을 많이 사용했습니다. 화면에 원하는 대로 출력은 됐지만, 아쉬운 점이 많았던 부분입니다.

느낀점

전체적으로 시간이 모자라서 아쉬웠습니다. 하지만 팀 과제를 진행하면서 개발 부분 뿐만 아니라 협업과 관련해서도 많이 배웠습니다. 협업을 통해 다양한 기능을 개발할 기회가 없었는데 이번 과제를 통해 경험할 수 있어 좋았습니다. 또한 이번 과제에서는 기능 구현에만 집중하다 보니 코드가 많이 복잡해지고, 너무 복잡하다 보니 리팩토링을 진행할 수 없었습니다. 다음 팀 과제에서는 효율적인 코드를 작성하는 것을 우선으로 두고 진행해보고 싶습니다.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published