- 개요 : 원티드 프론트엔드 프리온보딩 7기 2팀 과제 2-2 중 Best Practice
- 주제 : 광고현황 대시보드 및 광고관리 서비스
- 기간 : 2022.11.05 ~ 2022.11.06
- React
- redux-toolkit
- Recharts
- Styled-Components
- 구현사항
- 대시보드
- datePicker, 기간 필터
- 통합광고 현황
- 차트, 차트필터(지표별)
- 광고관리
- 광고조회, 필터
- 페이지 이동시 상태유지
- 대시보드
src
├── components // 공용 컴포넌트
├── constants
├── hooks
├── pages // 페이지 및 페이지별 컴포넌트
├── store // 리덕스 툴킷 전역상태관리
└── utils // format 함수
// src/pages/Dashboard/DatePicker
const DatePicker = () => {
const dispatch = useDispatch();
const { startDate, endDate } = useSelector((state) => state.period); //전역상태
const [startDateValue, handleStartValueChange] = useInput(startDate); //컴포넌트state
const [endDateValue, handleEndValueChange] = useInput(endDate); //컴포넌트state
const [isOpen, setIsOpen] = useState(false);
const [isValidPeriod, setIsValidPeriod] = useState(false);
useEffect(() => {
setIsValidPeriod(
startDateValue && endDateValue && startDateValue <= endDateValue
);
}, [startDateValue, endDateValue]);
const handleToggle = () => {
setIsOpen(!isOpen);
};
const handleClickDateSet = () => {
const payload = { startDate: startDateValue, endDate: endDateValue };
dispatch(changePeriod(payload));
setIsOpen(false);
};
return (
<Div>
<div className="period-and-button">
<div>{`${startDate} ~ ${endDate}`}</div>
<button onClick={handleToggle}>{isOpen ? "닫기" : "열기"}</button>
</div>
{isOpen && (
<div className="picker">
<input
type="date"
value={startDateValue}
onChange={handleStartValueChange}
/>
<span>~</span>
<input
type="date"
value={endDateValue}
onChange={handleEndValueChange}
/>
<button onClick={handleClickDateSet} disabled={!isValidPeriod}>
go
</button>
</div>
)}
</Div>
);
};
- 캘린더에서 날짜를 고르면 컴포넌트의 state가 변경됩니다.
- 날짜 설정 후 go 버튼을 누르면
periodSlice
(리덕스)로 기간이 전달됩니다. - 전역상태에 설정된 날짜데이터가 화면에 표시됩니다.
// src/pages/Dashboard/MetaList
const MetaList = () => {
const dispatch = useDispatch();
const { filteredData } = useSelector((state) => state.trendData);
const [metaData, setMetaData] = useState({});
useEffect(() => {
dispatch(getTrendData());
}, []);
useEffect(() => {
const metaObj = {
클릭수: 0,
광고비: 0,
전환수: 0,
노출수: 0,
매출: 0,
ROAS: 0,
};
filteredData.forEach((data) => {
metaObj.클릭수 += data.click;
metaObj.광고비 += data.cost;
metaObj.전환수 += data.conv;
metaObj.노출수 += (data.click / data.ctr) * 100;
metaObj.매출 += (data.roas * data.cost) / 100;
});
metaObj.ROAS = (metaObj.매출 / metaObj.광고비) * 100;
setMetaData({ ...metaObj });
}, [filteredData]);
return (
<Ul>
{Object.entries(metaData).map(([key, value]) => (
<MetaListItem key={key} objectKey={key} value={value} />
))}
</Ul>
);
};
getTrendData
로 데이터를 받아와trendDataSlice
로 디스패치합니다.periodSlice
에 설정된 기간에따라trendDataSlice
에 필터링된 데이터가 저장되고 출력됩니다.
- Git Clone
$ git clone [email protected]:pre-onboading-2team/pre-onboarding-7th-2-2-2.git
- 프로젝트 패키지 설치
$ npm install
- 프로젝트 실행
$ npm start