-
아마존 E-commerce 클론 -32) 차트 스크린 만들기NODE.JS 2021. 5. 30. 20:32
orderRouter로 가보자.
get/다음에 작성해주자.
mongoDB의 aggregate기능을 사용할 것이다.
각각의 주문들에 대해서 sum, 판매량 구하고,
각각의 사용자에 대해서 사용자 수를 구해서 사용한다.
orderRouter.get( '/summary', isAuth, isAdmin, expressAsyncHandler(async (req, res) => { const orders = await Order.aggregate([ { $group: { _id: null, numOrders: { $sum: 1 }, totalSales: { $sum: '$totalPrice' }, }, }, ]); const users = await User.aggregate([ { $group: { _id: null, numUsers: { $sum: 1 }, }, }, ]); const dailyOrders = await Order.aggregate([ { $group: { _id: { $dateToString: { format: '%Y-%m-%d', date: '$createdAt' } }, orders: { $sum: 1 }, sales: { $sum: '$totalPrice' }, }, }, { $sort: { _id: 1 } },//차트를 날짜순으로 배열한다. ]); const productCategories = await Product.aggregate([ { $group: { _id: '$category', count: { $sum: 1 }, }, }, ]); res.send({ users, orders, dailyOrders, productCategories }); }) );
새로 스크린을 만들어보자.
import React from 'react' import LoadingBox from '../components/LoadingBox' import MessageBox from '../components/MessageBox' function DashboardScreen() { return ( <div> <div className="row"> <h1>Dashboard</h1> </div> {loading? <LoadingBox></LoadingBox> : error?( <MessageBox variant='danger'>{error}</MessageBox> ):( <> <ul className="row summary"> <li> <div className="summary-title color1"> <span><i className="fa fa-users"></i>Users</span> </div> <div className="summary-body">{summary.users[0].numUsers}</div> </li> <li> <div className="summary-title color2"> <span><i className="fa fa-shopping-cart"></i>Orders</span> </div> <div className="summary-body">{summary.orders[0]? summary.orders[0].numOrders:0}</div> </li> <li> <div className="summary-title color3"> <span><i className="fa fa-money"></i>Orders</span> </div> <div className="summary-body">${summary.orders[0]? summary.orders[0].totalSales.toFixed(2):0}</div> </li> </ul> </> ) } </div> ) } export default DashboardScreen
이제 데이터를 patch하자.
orderConstants.js
export const ORDER_SUMMARY_REQUEST = 'ORDER_SUMMARY_REQUEST'; export const ORDER_SUMMARY_SUCCESS = 'ORDER_SUMMARY_SUCCESS'; export const ORDER_SUMMARY_FAIL = 'ORDER_SUMMARY_FAIL';
orderActions
export const summaryOrder = () => async (dispatch, getState) => { dispatch({ type: ORDER_SUMMARY_REQUEST }); const { userSignin: { userInfo }, } = getState(); try { const { data } = await axios.get('/api/orders/summary', { headers: { Authorization: `Bearer ${userInfo.token}` }, }); dispatch({ type: ORDER_SUMMARY_SUCCESS, payload: data }); } catch (error) { dispatch({ type: ORDER_CREATE_FAIL, payload: error.response && error.response.data.message ? error.response.data.message : error.message, }); } };
orderReducers.js
export const orderSummaryReducer = ( state = { loading: true, summary: {} }, action ) => { switch (action.type) { case ORDER_SUMMARY_REQUEST: return { loading: true }; case ORDER_SUMMARY_SUCCESS: return { loading: false, summary: action.payload }; case ORDER_SUMMARY_FAIL: return { loading: false, error: action.payload }; default: return state; } };
store.js
orderSummary:orderSummaryReducer
app.js에 페이지 추가
import DashboardScreen from './screens/DashboardScreen'; <AdminRoute path="/dashboard" component={DashboardScreen} exact></AdminRoute>
DashboardScreen.js
import { summaryOrder } from '../actions/orderActions' const orderSummary = useSelector(state => state.orderSummary) const {loading, summary, error} = orderSummary; const dispatch = useDispatch() useEffect(() => { dispatch(summaryOrder()) }, [dispatch])
스타일링하자.
/* Dashboard */ .summary > li { border: 0.1rem #c0c0c0 solid; margin: 2rem; border-radius: 0.5rem; flex: 1 1 20rem; } .summary-title { font-size: 2rem; padding: 1rem; } .summary-body { font-size: 4rem; padding: 1rem; text-align: center; } .summary-title.color1 { background-color: #f0e0e0; } .summary-title.color2 { background-color: #e0f0e0; } .summary-title.color3 { background-color: #e0e0f0; }
이제 차트를 넣자.
frontent> npm install react-google-charts
dash sceen
import Chart from 'react-google-charts'; <div> <div> <h2>Sales</h2> {summary.dailyOrders.length === 0 ? ( <MessageBox>No Sale</MessageBox> ) : ( <Chart width="100%" height="400px" chartType="AreaChart" loader={<div>Loading Chart</div>} data={[ ['Date', 'Sales'], ...summary.dailyOrders.map((x) => [x._id, x.sales]), ]} ></Chart> )} </div> </div> <div> <h2>Categories</h2> {summary.productCategories.length === 0 ? ( <MessageBox>No Category</MessageBox> ) : ( <Chart width="100%" height="400px" chartType="PieChart" loader={<div>Loading Chart</div>} data={[ ['Category', 'Products'], ...summary.productCategories.map((x) => [x._id, x.count]), ]} /> )} </div>
'NODE.JS' 카테고리의 다른 글
Social Media 만들기 - 2) Authentification 기능 만들기 (0) 2021.06.16 아마존 E-commerce 클론 -33) 채팅 기능 만들기(socket io) (0) 2021.05.30 아마존 E-commerce 클론 -31) Order Receipt 이메일로 보내기 (0) 2021.05.30 아마존 E-commerce 클론 -30) Pagination적용하기 (0) 2021.05.30 아마존 E-commerce 클론 -29) Google Map적용하기 (0) 2021.05.30