NODE.JS
아마존 E-commerce 클론 -19) Order History screen 만들기
dodop
2021. 5. 28. 14:22
우선 screens>orderhistoryScreen.js를 만들어준다.
import React from 'react'
function OrderHistoryScreen() {
return (
<div>
<h1>Order History</h1>
</div>
)
}
export default OrderHistoryScreen
리덕스에서 오더 정보를 가져와서 보여주도록 하자.
orderConstants.js
export const ORDER_MINE_LIST_REWUEST = 'ORDER_MINE_LIST_REWUEST'
export const ORDER_MINE_LIST_SUCCESS= 'ORDER_MINE_LIST_SUCCESS'
export const ORDER_MINE_LIST_FAIL = 'ORDER_MINE_LIST_FAIL'
orderActions.js
export const listOrderMine = ()=> async(dispatch, getState) =>{
dispatch({
type:ORDER_MINE_LIST_REQUEST
})
const {userSignin:{userInfo}} = getState();
try{
const {data} = await axios.get('/api/orders/mine', {
headers:{Authorization:`Bearer ${userInfo.token}`}
})
dispatch({
type:ORDER_MINE_LIST_SUCCESS,
payload:data
})
}catch(error){
const message = error.response && error.response.data.message
? error.response.data.message
: error.message;
dispatch({
type:ORDER_MINE_LIST_FAIL,
payload: message
})
}
}
orderReducers.js
export const orderMineListReducer = (state={orders:[]}, action)=>{
switch(action.type){
case ORDER_MINE_LIST_REQUEST:
return {loading:true}
case ORDER_MINE_LIST_SUCCESS:
return {loading:false, orders:action.payload}
case ORDER_MINE_LIST_FAIL:
return {loading:false, error:action.payload}
default:
return state;
}
}
store.js
const reducer = combineReducers({
productList: productListReducer,
productDetails : productDetailsReducer,
cart:cartReducer,
userSignin: userSigninReducer,
userRegister: userRegisterReducer,
orderCreate:orderCreateReducer,
orderDetails:orderDetailsReducer,
orderPay: orderPayReducer,
orderMineList:orderMineListReducer
})
orderhistoryscreen.js
useselector이용하자.
테이블을 만들어서 나타낼 형식을 짠다.
import React from 'react'
import {useSelector} from 'react-redux'
import LoadingBox from '../components/LoadingBox'
import MessageBox from '../components/MessageBox'
function OrderHistoryScreen(props) {
const orderMineList = useSelector(state => state.orderMineList)
const {loading, error, orders} = orderMineList
return (
<div>
<h1>Order History</h1>
{
loading? <LoadingBox></LoadingBox> :
error? <MessageBox variant= 'danger'>{error}</MessageBox> :
(
<table className="table">
<thead>
<tr>
<th>ID</th>
<th>DATE</th>
<th>TOTAL</th>
<th>PAID</th>
<th>DELIVERED</th>
<th>ACTIONS</th>
</tr>
</thead>
<tbody>
{orders.map((order)=>(
<tr key = {order._id}>
<td>{order._id}</td>
<td>{order.createdAt.substring(0,10)}</td>
<td>{order.totalPrice.toFixed(2)}</td>
<td>{order.isPaid? order.paidAt.substring(0,10) : "No"}</td>
<td>{order.isDelivered? order.deliveredAt.substring(0,10): "No"}</td>
<td>
<button className="small" type="button" onClick={()=>{props.history.push(`/order/${order._id}`)}}>Details</button>
</td>
</tr>
))}
</tbody>
</table>
)
}
</div>
)
}
export default OrderHistoryScreen
app.js에 페이지 추가.
헤더부분에도 orderhistory부분 나오게끔 추가해준다.
import OrderHistoryScreen from './screens/OrderHistoryScreen';
<ul className="dropdown-content">
<li>
<Link to = "/orderhistory">Order History</Link>
</li>
<li>
<Link to="#signout" onClick={signoutHandler}>Sing Out</Link>
</li>
</ul>
<Route path="/orderhistory" component={OrderHistoryScreen} exact></Route>
히스토리페이지에 useEffect해주자.
import {useDispatch, useSelector} from 'react-redux'
import { listOrderMine } from '../actions/orderActions'
function OrderHistoryScreen(props) {
const dispatch = useDispatch();
useEffect(() => {
dispatch(listOrderMine());
}, [dispatch])
이제 백엔드로 넘어가서 라우트를작성해준다.
orderRouter.get('/mine', isAuth, expressAsyncHandler(async(req, res)=>{
const orders = await Order.find({user: req.user._id});
res.send(orders);
}))
스타일링을 추가하자.
}
button.block{
width:100%;
}
button.small{
font-size: 1.2rem;
}
...
/* Table */
.table{
width: 100%;
border-collapse: collapse;
}
.table tbody tr:nth-of-type(odd){
background-color: #f4f4f4;
}
.table td, .table th{
text-align: left;
border: 0.1rem solid #e4e4e4;
padding:0.5rem;
}
.table button{
margin:0 0.2rem;
}
디테일 버튼 누르면 잘 이동한다.