From 607a764cee9eb7bcece73e1f04c00db4a5405b20 Mon Sep 17 00:00:00 2001 From: JaberHPranto Date: Sun, 17 Oct 2021 16:35:42 +0600 Subject: [PATCH] done with payment --- client/src/components/Blog/BlogDetails.js | 4 +- .../Ecommerce/Screen/OrderDataScreen.js | 4 +- .../Ecommerce/Screen/OrderListScreen.js | 6 +- .../Ecommerce/Screen/OrderScreen.js | 43 ++++++++--- .../Ecommerce/Screen/ProfileScreen.js | 58 ++++++++++++-- client/src/constants/orderConstants.js | 9 +++ client/src/redux/actions/orderActions.js | 76 ++++++++++++++++++- client/src/redux/reducers/orderReducers.js | 39 +++++++++- client/src/store.js | 8 +- server/controller/orderController.js | 34 ++++++++- server/routes/orderRoutes.js | 6 +- 11 files changed, 254 insertions(+), 33 deletions(-) diff --git a/client/src/components/Blog/BlogDetails.js b/client/src/components/Blog/BlogDetails.js index 2a988d8..8835129 100644 --- a/client/src/components/Blog/BlogDetails.js +++ b/client/src/components/Blog/BlogDetails.js @@ -31,10 +31,10 @@ function BlogDetails({match}) {

Published in {blog.category}

{blog.createdAt && new Date(blog.createdAt).toDateString()}

-
+ {/*
-
+
*/}
diff --git a/client/src/components/Ecommerce/Screen/OrderDataScreen.js b/client/src/components/Ecommerce/Screen/OrderDataScreen.js index 1bb8963..0464b89 100644 --- a/client/src/components/Ecommerce/Screen/OrderDataScreen.js +++ b/client/src/components/Ecommerce/Screen/OrderDataScreen.js @@ -101,9 +101,9 @@ function OrderDataScreen({history}) { {orderData?.customerBuyData?.map(customer => ( - { customer.customer_name} + {customer.customer_name} {customer.customer_email} - {customer.total} + {Math.ceil(customer.total)} ))} diff --git a/client/src/components/Ecommerce/Screen/OrderListScreen.js b/client/src/components/Ecommerce/Screen/OrderListScreen.js index d62e39d..5fcbdea 100644 --- a/client/src/components/Ecommerce/Screen/OrderListScreen.js +++ b/client/src/components/Ecommerce/Screen/OrderListScreen.js @@ -52,14 +52,14 @@ function OrderListScreen({history}) { {order.createdAt.substring(0, 10)}  {order.totalPrice} - {order.isPaid ? order.paidAt.substring(0,10) : } + {order?.isPaid ? order.paidAt.substring(0,10) : } - {order.isDelivered ? order.deliveredAt.substring(0,10) : } + {order?.isDelivered ? order.deliverAt.substring(0,10) : } - + diff --git a/client/src/components/Ecommerce/Screen/OrderScreen.js b/client/src/components/Ecommerce/Screen/OrderScreen.js index d1e5c4f..e7599de 100644 --- a/client/src/components/Ecommerce/Screen/OrderScreen.js +++ b/client/src/components/Ecommerce/Screen/OrderScreen.js @@ -1,27 +1,33 @@ import axios from "axios"; import React, { useEffect, useState } from "react"; -import { Card, Col, Image, ListGroup, Row } from "react-bootstrap"; +import { Button, Card, Col, Image, ListGroup, Row } from "react-bootstrap"; import { PayPalButton } from 'react-paypal-button-v2'; import { useDispatch, useSelector } from "react-redux"; import { Link } from "react-router-dom"; -import { ORDER_PAY_RESET } from '../../../constants/orderConstants'; -import { getOrderDetails, payOrder } from "../../../redux/actions/orderActions"; +import { ORDER_DELIVER_RESET, ORDER_PAY_RESET } from '../../../constants/orderConstants'; +import { deliverOrder, getOrderDetails, payOrder } from "../../../redux/actions/orderActions"; import Loader from "../Loader"; import Message from "../Message"; -const OrderScreen = ({ match }) => { +const OrderScreen = ({ match,history }) => { const orderId = match.params.id const dispatch = useDispatch(); const [sdkReady, setSdkReady] = useState(false) + const orderDetails = useSelector((state) => state.orderDetails); const { order, loading, error } = orderDetails; - + const orderPay = useSelector((state) => state.orderPay); - const { loading:loadingPay, success:successPay } = orderPay; - + const { loading: loadingPay, success: successPay } = orderPay; + + const orderDeliver = useSelector((state) => state.orderDeliver); + const { success: successDeliver } = orderDeliver; + + const userLogin = useSelector((state) => state.userLogin); + const { userInfo:{user} } = userLogin; if (!loading) { @@ -37,6 +43,10 @@ const OrderScreen = ({ match }) => { useEffect(() => { + if (!user) { + return history.push('/login') + } + const addPayPalScript = async (req, res) => { const { data: clientId } = await axios.get('/api/config/paypal') console.log(clientId); @@ -53,7 +63,8 @@ const OrderScreen = ({ match }) => { } if (!order || successPay) { - dispatch({type:ORDER_PAY_RESET}) + dispatch({ type: ORDER_PAY_RESET }) + dispatch({ type: ORDER_DELIVER_RESET }) dispatch(getOrderDetails(orderId)) } else if (!order.isPaid) { if (!window.paypal) { @@ -61,13 +72,17 @@ const OrderScreen = ({ match }) => { }else setSdkReady(true) } - }, [dispatch,order,orderId,successPay]) + }, [dispatch,order,orderId,successPay,successDeliver,history,user]) const successPaymentHandler = (paymentResult) => { - console.log(paymentResult); dispatch(payOrder(orderId,paymentResult)) } + const handleDeliver = () => { + dispatch(deliverOrder(order)) + } + + // console.log(order._id) return loading ? : error ? {error} : <> @@ -158,7 +173,7 @@ const OrderScreen = ({ match }) => { - {!order.isPaid && ( + {user && !user.isAdmin && !order.isPaid && ( {loadingPay && } {!sdkReady ? : ( @@ -170,6 +185,12 @@ const OrderScreen = ({ match }) => { )} + + {user && user.isAdmin && order.isPaid && !order.isDelivered && ( + + + + )} diff --git a/client/src/components/Ecommerce/Screen/ProfileScreen.js b/client/src/components/Ecommerce/Screen/ProfileScreen.js index 50bba6a..b18c670 100644 --- a/client/src/components/Ecommerce/Screen/ProfileScreen.js +++ b/client/src/components/Ecommerce/Screen/ProfileScreen.js @@ -1,7 +1,9 @@ import React, { useEffect, useState } from 'react' -import { Button, Col, Form, Row } from 'react-bootstrap' +import { Button, Col, Form, Row, Table } from 'react-bootstrap' import { useDispatch, useSelector } from 'react-redux' +import { LinkContainer } from 'react-router-bootstrap' import { useLocation } from 'react-router-dom' +import { getMyOrders } from '../../../redux/actions/orderActions' import { getUserDetails, updateUserProfile } from '../../../redux/actions/userActions' import Loader from '../Loader' import Message from '../Message' @@ -23,6 +25,10 @@ function ProfileScreen({history}) { const userDetails = useSelector(state => state.userDetails) const { loading, error, user } = userDetails + + const myOrderList = useSelector(state => state.myOrderList) + const { loading: loadingOrders, error: errorOrders, orders } = myOrderList + useEffect(() => { if (!userInfo) { @@ -36,8 +42,10 @@ function ProfileScreen({history}) { } else { if (!user.name) { - dispatch(getUserDetails('profile')) - } + dispatch(getUserDetails('profile')) + dispatch(getMyOrders()) + } + else { setEmail(user.email) setName(user.name) @@ -80,10 +88,50 @@ function ProfileScreen({history}) { setConfirmPassword(e.target.value)} /> - + -

My Orders

+ + <> +

MY Orders

+ {loadingOrders ? : errorOrders ? {errorOrders} : ( + + + + + + + + + + + + + {orders.map(order=>( + + + + + + + + + ))} + +
IDDATETOTALPAIDDelivered
{order._id}{order.createdAt.substring(0, 10)} {order.totalPrice} + {order.isPaid ? order.paidAt.substring(0,10) : } + + {order.isDelivered ? order.deliverAt.substring(0,10) : } + + + + +
+ )} + + ) } diff --git a/client/src/constants/orderConstants.js b/client/src/constants/orderConstants.js index 6ed653f..7d593b1 100644 --- a/client/src/constants/orderConstants.js +++ b/client/src/constants/orderConstants.js @@ -6,6 +6,10 @@ export const ORDER_DETAILS_REQUEST = "ORDER_DETAILS_REQUEST"; export const ORDER_DETAILS_SUCCESS = "ORDER_DETAILS_SUCCESS"; export const ORDER_DETAILS_FAIL = "ORDER_DETAILS_FAIL"; +export const ORDER_MY_LIST_REQUEST = "ORDER_MY_LIST_REQUEST"; +export const ORDER_MY_LIST_SUCCESS = "ORDER_MY_LIST_SUCCESS"; +export const ORDER_MY_LIST_FAIL = "ORDER_MY_LIST_FAIL"; + export const ORDER_LIST_REQUEST = "ORDER_LIST_REQUEST"; export const ORDER_LIST_SUCCESS = "ORDER_LIST_SUCCESS"; export const ORDER_LIST_FAIL = "ORDER_LIST_FAIL"; @@ -15,6 +19,11 @@ export const ORDER_PAY_SUCCESS = "ORDER_PAY_SUCCESS"; export const ORDER_PAY_FAIL = "ORDER_PAY_FAIL"; export const ORDER_PAY_RESET = "ORDER_PAY_RESET"; +export const ORDER_DELIVER_REQUEST = "ORDER_DELIVER_REQUEST"; +export const ORDER_DELIVER_SUCCESS = "ORDER_DELIVER_SUCCESS"; +export const ORDER_DELIVER_FAIL = "ORDER_DELIVER_FAIL"; +export const ORDER_DELIVER_RESET = "ORDER_DELIVER_RESET"; + export const ORDER_DATA_REQUEST = "ORDER_DATA_REQUEST"; export const ORDER_DATA_SUCCESS = "ORDER_DATA_SUCCESS"; export const ORDER_DATA_FAIL = "ORDER_DATA_FAIL"; diff --git a/client/src/redux/actions/orderActions.js b/client/src/redux/actions/orderActions.js index 1c22cf6..60b9706 100644 --- a/client/src/redux/actions/orderActions.js +++ b/client/src/redux/actions/orderActions.js @@ -1,6 +1,6 @@ import axios from "axios"; import { - ORDER_CREATE_FAIL, ORDER_CREATE_REQUEST, ORDER_CREATE_SUCCESS, ORDER_DATA_FAIL, ORDER_DATA_REQUEST, ORDER_DATA_SUCCESS, ORDER_DETAILS_FAIL, ORDER_DETAILS_REQUEST, ORDER_DETAILS_SUCCESS, ORDER_LIST_FAIL, ORDER_LIST_REQUEST, ORDER_LIST_SUCCESS, ORDER_PAY_FAIL, ORDER_PAY_REQUEST, ORDER_PAY_SUCCESS, ORDER_SALE_DATA_FAIL, ORDER_SALE_DATA_REQUEST, ORDER_SALE_DATA_SUCCESS + ORDER_CREATE_FAIL, ORDER_CREATE_REQUEST, ORDER_CREATE_SUCCESS, ORDER_DATA_FAIL, ORDER_DATA_REQUEST, ORDER_DATA_SUCCESS, ORDER_DELIVER_FAIL, ORDER_DELIVER_REQUEST, ORDER_DELIVER_SUCCESS, ORDER_DETAILS_FAIL, ORDER_DETAILS_REQUEST, ORDER_DETAILS_SUCCESS, ORDER_LIST_FAIL, ORDER_LIST_REQUEST, ORDER_LIST_SUCCESS, ORDER_MY_LIST_FAIL, ORDER_MY_LIST_REQUEST, ORDER_MY_LIST_SUCCESS, ORDER_PAY_FAIL, ORDER_PAY_REQUEST, ORDER_PAY_SUCCESS, ORDER_SALE_DATA_FAIL, ORDER_SALE_DATA_REQUEST, ORDER_SALE_DATA_SUCCESS } from "../../constants/orderConstants"; @@ -88,6 +88,41 @@ export const getOrderList = () => async (dispatch,getState) => { } +export const getMyOrders = () => async (dispatch,getState) => { + + try { + dispatch({ + type:ORDER_MY_LIST_REQUEST + }) + + const { userLogin: { userInfo } } = getState() + + + const config = { + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${userInfo.token}` + } + } + + const { data } = await axios.get(`/api/orders/my-orders`,config) + + dispatch({ + type: ORDER_MY_LIST_SUCCESS, + payload:data + }) + + } catch (error) { + console.log(error); + dispatch({ + type: ORDER_MY_LIST_FAIL, + payload: error.response && error.response.data.message ? error.response.data.message : error.message + + }) + + } + +} export const getOrderDetails = (id) => async (dispatch,getState) => { @@ -164,6 +199,45 @@ export const payOrder = (id,paymentResult) => async (dispatch,getState) => { } +export const deliverOrder = (order) => async (dispatch,getState) => { + + try { + dispatch({ + type: ORDER_DELIVER_REQUEST + }) + + const { userLogin: { userInfo } } = getState() + + + const config = { + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${userInfo.token}` + } + + } + + const { data } = await axios.put(`/api/orders/${order._id}/deliver`,{},config) + + console.log(data); + dispatch({ + type: ORDER_DELIVER_SUCCESS, + payload:data + }) + + } catch (error) { + console.log(error); + dispatch({ + type: ORDER_DELIVER_FAIL, + payload: error.response && error.response.data.message ? error.response.data.message : error.message + + }) + + } + +} + + export const getOrderData = () => async (dispatch,getState) => { diff --git a/client/src/redux/reducers/orderReducers.js b/client/src/redux/reducers/orderReducers.js index 5306ed5..1b3fbe8 100644 --- a/client/src/redux/reducers/orderReducers.js +++ b/client/src/redux/reducers/orderReducers.js @@ -1,5 +1,5 @@ import { - ORDER_CREATE_FAIL, ORDER_CREATE_REQUEST, ORDER_CREATE_SUCCESS, ORDER_DATA_FAIL, ORDER_DATA_REQUEST, ORDER_DATA_SUCCESS, ORDER_DETAILS_FAIL, ORDER_DETAILS_REQUEST, ORDER_DETAILS_SUCCESS, ORDER_LIST_FAIL, ORDER_LIST_REQUEST, ORDER_LIST_SUCCESS, ORDER_PAY_FAIL, ORDER_PAY_REQUEST, ORDER_PAY_RESET, ORDER_PAY_SUCCESS, ORDER_SALE_DATA_FAIL, ORDER_SALE_DATA_REQUEST, ORDER_SALE_DATA_SUCCESS + ORDER_CREATE_FAIL, ORDER_CREATE_REQUEST, ORDER_CREATE_SUCCESS, ORDER_DATA_FAIL, ORDER_DATA_REQUEST, ORDER_DATA_SUCCESS, ORDER_DELIVER_FAIL, ORDER_DELIVER_REQUEST, ORDER_DELIVER_RESET, ORDER_DELIVER_SUCCESS, ORDER_DETAILS_FAIL, ORDER_DETAILS_REQUEST, ORDER_DETAILS_SUCCESS, ORDER_LIST_FAIL, ORDER_LIST_REQUEST, ORDER_LIST_SUCCESS, ORDER_MY_LIST_FAIL, ORDER_MY_LIST_REQUEST, ORDER_MY_LIST_SUCCESS, ORDER_PAY_FAIL, ORDER_PAY_REQUEST, ORDER_PAY_RESET, ORDER_PAY_SUCCESS, ORDER_SALE_DATA_FAIL, ORDER_SALE_DATA_REQUEST, ORDER_SALE_DATA_SUCCESS } from "../../constants/orderConstants"; export const orderCreateReducer = (state = {}, action) => { @@ -45,6 +45,23 @@ export const orderListReducer = (state = { orders: [] }, action) => { } } +export const myOrderListReducer = (state = { orders: [] }, action) => { + switch (action.type) { + case ORDER_MY_LIST_REQUEST: + return { ...state,loading: true } + + case ORDER_MY_LIST_SUCCESS: + return { loading: false, orders: action.payload } + + case ORDER_MY_LIST_FAIL: + return { loading: false, error: action.payload } + + + default: + return state + } +} + export const orderDetailsReducer = (state = { loading:true,orderItems: [],shippingAddress:{} }, action) => { switch (action.type) { case ORDER_DETAILS_REQUEST: @@ -74,10 +91,28 @@ export const orderPayReducer = (state ={}, action) => { return { loading: false, error: action.payload } case ORDER_PAY_RESET: - return { } + default: + return state + } +} + + +export const orderDeliverReducer = (state ={}, action) => { + switch (action.type) { + case ORDER_DELIVER_REQUEST: + return { loading: true } + + case ORDER_DELIVER_SUCCESS: + return { loading: false, success: true } + case ORDER_DELIVER_FAIL: + return { loading: false, error: action.DELIVERload } + + case ORDER_DELIVER_RESET: + return { } + default: return state } diff --git a/client/src/store.js b/client/src/store.js index e8525ac..27730cb 100644 --- a/client/src/store.js +++ b/client/src/store.js @@ -3,9 +3,7 @@ import { composeWithDevTools } from "redux-devtools-extension"; import thunk from "redux-thunk"; import { blogDetailsReducer, blogListReducer } from "./redux/reducers/blogReducers"; import { cartReducer } from "./redux/reducers/cartReducers"; -import { - orderCreateReducer, orderDataReducer, orderDetailsReducer, orderListReducer, orderPayReducer, orderSaleDataReducer -} from "./redux/reducers/orderReducers"; +import { myOrderListReducer, orderCreateReducer, orderDataReducer, orderDeliverReducer, orderDetailsReducer, orderListReducer, orderPayReducer, orderSaleDataReducer } from "./redux/reducers/orderReducers"; import { productCreateReducer, productCreateReviewReducer, productDeleteReducer, productDetailsReducer, productListReducer, productUpdateReducer @@ -36,7 +34,9 @@ const reducer = combineReducers({ orderData: orderDataReducer, orderDetails:orderDetailsReducer, orderSaleData: orderSaleDataReducer, - orderPay:orderPayReducer, + orderPay: orderPayReducer, + orderDeliver: orderDeliverReducer, + myOrderList:myOrderListReducer, blogList: blogListReducer, blogDetails: blogDetailsReducer }); diff --git a/server/controller/orderController.js b/server/controller/orderController.js index 8f75d97..a9793f4 100644 --- a/server/controller/orderController.js +++ b/server/controller/orderController.js @@ -86,6 +86,37 @@ const updateOrderToPaid = asyncHandler(async (req, res) => { } }) +// @desc get all orders +// @route POST /api/orders/:id/deliver +// @access Private/Admin +const updateOrderToDelivered = asyncHandler(async (req, res) => { + const order = await Order.findById(req.params.id) + if (order) { + order.isDelivered = true; + order.deliverAt = Date.now() + + const updatedOrder = await order.save() + + res.json(updatedOrder) + + } else { + res.status(404) + throw new Error("Order not found") + } +}) + +// @desc get all orders +// @route POST /api/orders/my-orders +// @access Private/User +const getMyOrders = asyncHandler(async (req, res) => { + const orders = await Order.find({ user: req.user._id }) + if (orders) { + res.json(orders) + } else { + res.status(404) + throw new Error("No Order") + } +}) const getOrderData = async (req, res) => { @@ -134,6 +165,7 @@ const getOrderData = async (req, res) => { } + const getSaleDataByYear = async (req, res) => { try { const year = 2021 @@ -300,5 +332,5 @@ const saleByAProduct = asyncHandler(async (req, res) => { }) -export { addOrderItems, getOrders, getOrderData, getSaleDataByYear, getSaleDataByMonth, saleByAProduct, getOrderById, updateOrderToPaid }; +export { addOrderItems, getOrders, getOrderData, getSaleDataByYear, getSaleDataByMonth, saleByAProduct, getOrderById, updateOrderToPaid, getMyOrders, updateOrderToDelivered }; diff --git a/server/routes/orderRoutes.js b/server/routes/orderRoutes.js index f29f8a9..d38bd5c 100644 --- a/server/routes/orderRoutes.js +++ b/server/routes/orderRoutes.js @@ -1,5 +1,5 @@ import express from "express"; -import { addOrderItems, getOrderById, getOrderData, getOrders, getSaleDataByMonth, getSaleDataByYear, saleByAProduct, updateOrderToPaid } from "../controller/orderController.js"; +import { addOrderItems, getMyOrders, getOrderById, getOrderData, getOrders, getSaleDataByMonth, getSaleDataByYear, saleByAProduct, updateOrderToDelivered, updateOrderToPaid } from "../controller/orderController.js"; import { isAdmin, isLoggedIn } from "../middlewares/authMiddleware.js"; const router = express.Router(); @@ -9,8 +9,10 @@ router.get("/order-data", isLoggedIn, isAdmin, getOrderData) router.get("/saleDataByYear", isLoggedIn, isAdmin, getSaleDataByYear) router.post("/saleDataByMonth", isLoggedIn, isAdmin, getSaleDataByMonth) router.post("/saleByAProduct", isLoggedIn, isAdmin, saleByAProduct) -router.get("/:id",isLoggedIn, getOrderById); +router.get("/my-orders", isLoggedIn, getMyOrders) +router.put("/:id/deliver",isLoggedIn,isAdmin,updateOrderToDelivered); router.put("/:id/pay",isLoggedIn,updateOrderToPaid); +router.get("/:id",isLoggedIn, getOrderById);