source: frontend/src/screens/PlaceOrderScreen.js@ 55ed171

Last change on this file since 55ed171 was 55ed171, checked in by Nace Gjorgjievski <nace.gorgievski123@…>, 21 months ago

Full Admin Functionality Added

  • 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 isConfirmed: false,
63 contactNumber: userInfo.contact,
64 },
65 {
66 headers: {
67 authorization: `Bearer ${userInfo.token}`,
68 },
69 }
70 );
71 ctxDispatch({ type: "CART_CLEAR" });
72 dispatch({ type: "CREATE_SUCCESS" });
73 localStorage.removeItem("cartItems");
74 navigate(`/order/${data.order._id}`);
75 } catch (err) {
76 dispatch({ type: "CREATE_FAIL" });
77 toast.error(getError(err));
78 }
79 };
80
81 useEffect(() => {
82 if (!cart.paymentMethod) {
83 navigate("/payment");
84 }
85 }, [cart, navigate]);
86
87 return (
88 <div className="pageContainer shipPC">
89 <CheckoutSteps step1 step2 step3 step4 />
90
91 <Helmet>
92 <title>Потврди нарачка</title>
93 </Helmet>
94 <h1 style={{ marginTop: "20px" }}>Потврди нарачка</h1>
95 <Row style={{ width: "90%" }}>
96 <Col md={8}>
97 <Card className="mb-3">
98 <Card.Body>
99 <Card.Title>Испорака</Card.Title>
100 <Card.Text>
101 <strong>Име:</strong> {cart.shippingAddress.fullName}
102 <br />
103 <strong>Адреса:</strong> {cart.shippingAddress.address},
104 {cart.shippingAddress.city},{cart.shippingAddress.postalCode},
105 {cart.shippingAddress.country}
106 <br />
107 </Card.Text>
108 <Link to="/shipping">Измени</Link>
109 </Card.Body>
110 </Card>
111 <Card className="mb-3">
112 <Card.Body>
113 <Card.Title>Плаќање</Card.Title>
114 <Card.Text>
115 <strong>Начин:</strong>{" "}
116 {cart.paymentMethod === "Karticka"
117 ? "Со платежна картичка"
118 : "Во готово при достава"}
119 </Card.Text>
120 <Link to="/payment">Измени</Link>
121 </Card.Body>
122 </Card>
123
124 <Card className="mb-3">
125 <Card.Body>
126 <Card.Title>Продукти</Card.Title>
127 <ListGroup variant="flush">
128 {cart.cartItems.map((item) => (
129 <ListGroup.Item key={item._id}>
130 <div
131 style={{
132 display: "flex",
133 justifyContent: "space-between",
134 }}
135 >
136 <div style={{ display: "flex", alignItems: "center" }}>
137 <img
138 src={item.image}
139 alt={item.name}
140 className="img-fluid rounded img-thumbnail"
141 style={{ margin: "0px" }}
142 ></img>
143 <Link to={`/product/${item.slug}`}>{item.name}</Link>
144 </div>
145
146 <span>{item.quantity}</span>
147
148 <span>{item.price} ден</span>
149 </div>
150 </ListGroup.Item>
151 ))}
152 </ListGroup>
153 <Link to="/cart">Измени</Link>
154 </Card.Body>
155 </Card>
156 </Col>
157 <Col md={4}>
158 <Card>
159 <Card.Body>
160 <Card.Title>Нарачка</Card.Title>
161 <ListGroup variant="flush">
162 <ListGroup.Item>
163 <Row>
164 <Col>Продукти:</Col>
165 <Col>{cart.itemsPrice.toFixed(2)} ден</Col>
166 </Row>
167 </ListGroup.Item>
168 <ListGroup.Item>
169 <Row>
170 <Col>Испорака:</Col>
171 <Col>{cart.shippingPrice.toFixed(2)} ден</Col>
172 </Row>
173 </ListGroup.Item>
174
175 <ListGroup.Item>
176 <Row>
177 <Col>
178 <strong>Вкупно</strong>
179 </Col>
180 <Col>
181 <strong>{cart.totalPrice.toFixed(2)} ден</strong>
182 </Col>
183 </Row>
184 </ListGroup.Item>
185 <ListGroup.Item>
186 <div className="d-grid">
187 {cart.paymentMethod === "Karticka" ? (
188 <Button
189 type="button"
190 onClick={paymentHandler}
191 disabled={cart.cartItems.length === 0}
192 variant="danger"
193 >
194 Плати
195 </Button>
196 ) : (
197 <Button
198 type="button"
199 onClick={placeOrderHandler}
200 disabled={cart.cartItems.length === 0}
201 variant="danger"
202 >
203 Потврди нарачка
204 </Button>
205 )}
206 </div>
207 {loading && <LoadingBox></LoadingBox>}
208 </ListGroup.Item>
209 </ListGroup>
210 </Card.Body>
211 </Card>
212 </Col>
213 </Row>
214 </div>
215 );
216}
217
218export default PlaceOrderScreen;
Note: See TracBrowser for help on using the repository browser.