0
import axios from 'axios'; import React, { useContext, useEffect, useReducer, useState } from 'react'; import { Helmet } from 'react-helmet-async'; import { useNavigate, useParams } from 'react-router-dom'; import LoadingBox from '../components/LoadingBox'; import MessageBox from '../components/MessageBox'; import { Store } from '../Store'; import { getError } from '../utils'; import Row from 'react-bootstrap/Row'; import Col from 'react-bootstrap/Col'; import ListGroup from 'react-bootstrap/ListGroup'; import Card from 'react-bootstrap/Card'; import { Link } from 'react-router-dom'; import StripeCheckout from '../components/StripeCheckout'; import { loadStripe } from '@stripe/stripe-js/pure'; function reducer(state, action) { switch (action.type) { case 'FETCH_REQUEST': return { ...state, loading: true, error: '' }; case 'FETCH_SUCCESS': return { ...state, loading: false, order: action.payload, error: '' }; case 'FETCH_FAIL': return { ...state, loading: false, error: action.payload }; default: return state; } } export default function OrderScreen() { const { state } = useContext(Store); const { userInfo } = state; const params = useParams(); const { id: orderId } = params; const navigate = useNavigate(); const [{ loading, error, order }, dispatch] = useReducer(reducer, { loading: true, order: {}, error: '', }); const [stripe, setStripe] = useState(null); useEffect(() => { const addStripeScript = async () => { const { data: clientId } = await axios.get('/api/stripe/key'); const stripeObj = await loadStripe(clientId); setStripe(stripeObj); }; if (order.paymentMethod === 'stripe') { if (!stripe) { addStripeScript(); } } const fetchOrder = async () => { try { dispatch({ type: 'FETCH_REQUEST' }); const { data } = await axios.get(`/api/orders/${orderId}`, { headers: { authorization: `Bearer ${userInfo.token}` }, }); dispatch({ type: 'FETCH_SUCCESS', payload: data }); } catch (err) { dispatch({ type: 'FETCH_FAIL', payload: getError(err) }); } }; if (!userInfo) { return navigate('/login'); } if (!order._id || (order._id && order._id !== orderId)) { fetchOrder(); } }, [order, userInfo, orderId, navigate, stripe]); return loading ? ( <LoadingBox></LoadingBox> ) : error ? ( <MessageBox variant="danger">{error}</MessageBox> ) : ( <div> <Helmet> <title>Order {orderId}</title> </Helmet> <h1 className="my-3">Order {orderId}</h1> <Row> <Col md={8}> <Card className="mb-3"> <Card.Body> <Card.Title>Shipping</Card.Title> <Card.Text> <strong>Name:</strong> {order.shippingAddress.fullName} <br /> <strong>Address:</strong> {order.shippingAddress.address},{order.shippingAddress.city}, {order.shippingAddress.postalCode}, {order.shippingAddress.country} </Card.Text> {order.isDelivered ? ( <MessageBox variant="success"> Delivered at {order.deliveredAt} </MessageBox> ) : ( <MessageBox variant="danger">Not delivered</MessageBox> )} </Card.Body> </Card> <Card className="mb-3"> <Card.Body> <Card.Title>Payment</Card.Title> <Card.Text> <strong>Method:</strong> {order.paymentMethod} </Card.Text> {order.isPaid ? ( <MessageBox variant="success"> Paid at {order.paidAt} </MessageBox> ) : ( <MessageBox variant="danger">Not Paid</MessageBox> )} </Card.Body> </Card> <Card className="mb-3"> <Card.Body> <Card.Title>Items</Card.Title> <ListGroup variant="flush"> {order.orderItems.map((item) => ( <ListGroup.Item key={item._id}> <Row className="align-items-center"> <Col md={6}> <img src={item.image} alt={item.name} className="img-fluid rounded img-thumbnail" ></img>{' '} <Link to={`/product/${item.slug}`}>{item.name}</Link> </Col> <Col md={3}> <span>{item.quantity}</span> </Col> <Col md={3}>${item.price}</Col> </Row> </ListGroup.Item> ))} </ListGroup> </Card.Body> </Card> </Col> <Col md={4}> <Card className="mb-3"> <Card.Body> <Card.Title>Order Summary</Card.Title> <ListGroup variant="flush"> <ListGroup.Item> <Row> <Col>Items</Col> <Col>${order.itemsPrice.toFixed(2)}</Col> </Row> </ListGroup.Item> <ListGroup.Item> <Row> <Col>Shipping</Col> <Col>${order.shippingPrice.toFixed(2)}</Col> </Row> </ListGroup.Item> <ListGroup.Item> <Row> <Col>Tax</Col> <Col>${order.taxPrice.toFixed(2)}</Col> </Row> </ListGroup.Item> <ListGroup.Item> <Row> <Col> <strong>Order Total</strong> </Col> <Col> <strong>${order.taxPrice.toFixed(2)}</strong> </Col> </Row> </ListGroup.Item> {!order.isPaid && !stripe && <LoadingBox />} {!order.isPaid && stripe && ( <StripeCheckout stripe={stripe} orderId={order._id} handleSuccessPayment={handleSuccessPayment} /> )} </ListGroup> </Card.Body> </Card> </Col> </Row> </div> ); }
Basir Answered question March 10, 2023