source: frontend/src/screens/PlaceOrderScreen.js@ 16237c4

Last change on this file since 16237c4 was 16237c4, checked in by Nace Gjorgjievski <nace.gorgievski123@…>, 22 months ago

Added Order Functionality

  • Property mode set to 100644
File size: 7.1 KB
Line 
1import React, { useContext, useEffect, useReducer } from "react";
2import Axios from "axios";
3import { Helmet } from "react-helmet-async";
4import CheckoutSteps from "../components/CheckoutSteps";
5import Row from "react-bootstrap/Row";
6import Col from "react-bootstrap/Col";
7import Card from "react-bootstrap/Card";
8import Button from "react-bootstrap/Button";
9import ListGroup from "react-bootstrap/ListGroup";
10import { getError } from "../components/utils";
11import { toast } from "react-toastify";
12import { Store } from "../Store";
13import { Link, useNavigate } from "react-router-dom";
14import LoadingBox from "../components/LoadingBox";
15
16const reducer = (state, action) => {
17 switch (action.type) {
18 case "CREATE_REQUEST":
19 return { ...state, loading: true };
20 case "CREATE_SUCCESS":
21 return { ...state, loading: false };
22 case "CREATE_FAIL":
23 return { ...state, loading: false };
24 default:
25 return state;
26 }
27};
28
29function PlaceOrderScreen() {
30 const navigate = useNavigate();
31
32 const [{ loading }, dispatch] = useReducer(reducer, {
33 loading: false,
34 });
35
36 const { state, dispatch: ctxDispatch } = useContext(Store);
37 const { cart, userInfo } = state;
38
39 const round2 = (num) => Math.round(num * 100 + Number.EPSILON) / 100;
40 cart.itemsPrice = round2(
41 cart.cartItems.reduce((a, c) => a + c.quantity * c.price, 0)
42 );
43 cart.shippingPrice = cart.itemsPrice > 1500 ? round2(0) : round2(150);
44 cart.totalPrice = cart.itemsPrice + cart.shippingPrice;
45
46 const paymentHandler = async () => {
47 navigate(`/placeorder/payment`);
48 };
49
50 const placeOrderHandler = async () => {
51 try {
52 dispatch({ type: "CREATE_REQUEST" });
53 const { data } = await Axios.post(
54 "/api/orders",
55 {
56 orderItems: cart.cartItems,
57 shippingAddress: cart.shippingAddress,
58 paymentMethod: cart.paymentMethod,
59 itemsPrice: cart.itemsPrice,
60 shippingPrice: cart.shippingPrice,
61 totalPrice: cart.totalPrice,
62 },
63 {
64 headers: {
65 authorization: `Bearer ${userInfo.token}`,
66 },
67 }
68 );
69 ctxDispatch({ type: "CART_CLEAR" });
70 dispatch({ type: "CREATE_SUCCESS" });
71 localStorage.removeItem("cartItems");
72 navigate(`/order/${data.order._id}`);
73 } catch (err) {
74 dispatch({ type: "CREATE_FAIL" });
75 toast.error(getError(err));
76 }
77 };
78
79 useEffect(() => {
80 if (!cart.paymentMethod) {
81 navigate("/payment");
82 }
83 }, [cart, navigate]);
84
85 return (
86 <div className="pageContainer shipPC">
87 <CheckoutSteps step1 step2 step3 step4 />
88
89 <Helmet>
90 <title>Потврди нарачка</title>
91 </Helmet>
92 <h1 style={{ marginTop: "20px" }}>Потврди нарачка</h1>
93 <Row style={{ width: "90%" }}>
94 <Col md={8}>
95 <Card className="mb-3">
96 <Card.Body>
97 <Card.Title>Испорака</Card.Title>
98 <Card.Text>
99 <strong>Име:</strong> {cart.shippingAddress.fullName}
100 <br />
101 <strong>Адреса:</strong> {cart.shippingAddress.address},
102 {cart.shippingAddress.city},{cart.shippingAddress.postalCode},
103 {cart.shippingAddress.country}
104 <br />
105 </Card.Text>
106 <Link to="/shipping">Измени</Link>
107 </Card.Body>
108 </Card>
109 <Card className="mb-3">
110 <Card.Body>
111 <Card.Title>Плаќање</Card.Title>
112 <Card.Text>
113 <strong>Начин:</strong>{" "}
114 {cart.paymentMethod === "Karticka"
115 ? "Со платежна картичка"
116 : "Во готово при достава"}
117 </Card.Text>
118 <Link to="/payment">Измени</Link>
119 </Card.Body>
120 </Card>
121
122 <Card className="mb-3">
123 <Card.Body>
124 <Card.Title>Продукти</Card.Title>
125 <ListGroup variant="flush">
126 {cart.cartItems.map((item) => (
127 <ListGroup.Item key={item._id}>
128 <div
129 style={{
130 display: "flex",
131 justifyContent: "space-between",
132 }}
133 >
134 <div style={{ display: "flex", alignItems: "center" }}>
135 <img
136 src={item.image}
137 alt={item.name}
138 className="img-fluid rounded img-thumbnail"
139 style={{ margin: "0px" }}
140 ></img>
141 <Link to={`/product/${item.slug}`}>{item.name}</Link>
142 </div>
143
144 <span>{item.quantity}</span>
145
146 <span>{item.price} ден</span>
147 </div>
148 </ListGroup.Item>
149 ))}
150 </ListGroup>
151 <Link to="/cart">Измени</Link>
152 </Card.Body>
153 </Card>
154 </Col>
155 <Col md={4}>
156 <Card>
157 <Card.Body>
158 <Card.Title>Нарачка</Card.Title>
159 <ListGroup variant="flush">
160 <ListGroup.Item>
161 <Row>
162 <Col>Продукти:</Col>
163 <Col>{cart.itemsPrice.toFixed(2)} ден</Col>
164 </Row>
165 </ListGroup.Item>
166 <ListGroup.Item>
167 <Row>
168 <Col>Испорака:</Col>
169 <Col>{cart.shippingPrice.toFixed(2)} ден</Col>
170 </Row>
171 </ListGroup.Item>
172
173 <ListGroup.Item>
174 <Row>
175 <Col>
176 <strong>Вкупно</strong>
177 </Col>
178 <Col>
179 <strong>{cart.totalPrice.toFixed(2)} ден</strong>
180 </Col>
181 </Row>
182 </ListGroup.Item>
183 <ListGroup.Item>
184 <div className="d-grid">
185 {cart.paymentMethod === "Karticka" ? (
186 <Button
187 type="button"
188 onClick={paymentHandler}
189 disabled={cart.cartItems.length === 0}
190 variant="danger"
191 >
192 Плати
193 </Button>
194 ) : (
195 <Button
196 type="button"
197 onClick={placeOrderHandler}
198 disabled={cart.cartItems.length === 0}
199 variant="danger"
200 >
201 Потврди нарачка
202 </Button>
203 )}
204 </div>
205 {loading && <LoadingBox></LoadingBox>}
206 </ListGroup.Item>
207 </ListGroup>
208 </Card.Body>
209 </Card>
210 </Col>
211 </Row>
212 </div>
213 );
214}
215
216export default PlaceOrderScreen;
Note: See TracBrowser for help on using the repository browser.