source: frontend/src/screens/AdminOrdersScreen.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: 6.9 KB
Line 
1import axios from "axios";
2import React, { useEffect, useReducer } from "react";
3import { Link, useLocation, useNavigate } from "react-router-dom";
4import { getError } from "../components/utils";
5import Button from "react-bootstrap/Button";
6import LoadingBox from "../components/LoadingBox";
7import MessageBox from "../components/MessageBox";
8import CheckIcon from "@mui/icons-material/Check";
9import ClearIcon from "@mui/icons-material/Clear";
10import PhonePausedIcon from "@mui/icons-material/PhonePaused";
11import HourglassBottomIcon from "@mui/icons-material/HourglassBottom";
12import LocalShippingIcon from "@mui/icons-material/LocalShipping";
13import LinkContainer from "react-router-bootstrap/LinkContainer";
14import Form from "react-bootstrap/Form";
15const reducer = (state, action) => {
16 switch (action.type) {
17 case "FETCH_REQUEST":
18 return { ...state, loading: true };
19 case "FETCH_SUCCESS":
20 console.log(action.payload);
21 return {
22 ...state,
23 //orders: action.payload,
24
25 orders: action.payload.orders,
26 page: action.payload.page,
27 pages: action.payload.pages,
28 countProducts: action.payload.countProducts,
29 loading: false,
30 };
31 case "FETCH_FAIL":
32 return { ...state, loading: false, error: action.payload };
33 default:
34 return state;
35 }
36};
37
38function AdminOrdersScreen() {
39 const navigate = useNavigate();
40 const { search } = useLocation();
41 const sp = new URLSearchParams(search);
42 const isConfirmed = sp.get("isConfirmed") || "all";
43 const isShipped = sp.get("isShipped") || "all";
44 const query = sp.get("query") || "all";
45 const page = sp.get("page") || 1;
46 const [{ loading, error, orders, pages, countProducts }, dispatch] =
47 useReducer(reducer, {
48 loading: true,
49 error: "",
50 });
51
52 useEffect(() => {
53 const fetchData = async () => {
54 dispatch({ type: "FETCH_REQUEST" });
55 try {
56 const { data } = await axios.get(
57 `/api/orders?page=${page}&isConfirmed=${isConfirmed}&isShipped=${isShipped}&query=${query}`
58 );
59 dispatch({ type: "FETCH_SUCCESS", payload: data });
60 } catch (error) {
61 dispatch({ type: "FETCH_FAIL", payload: getError(error) });
62 }
63 };
64 fetchData();
65 }, [isConfirmed, isShipped, page, query]);
66 const getFilterUrl = (filter) => {
67 const filterPage = filter.page || page;
68 const filterIsConfirmed = filter.isConfirmed || isConfirmed;
69 const filterIsShipped = filter.isShipped || isShipped;
70 const filterQuery = filter.query || query;
71 return `?page=${filterPage}&isConfirmed=${filterIsConfirmed}&isShipped=${filterIsShipped}&query=${filterQuery}`;
72 };
73
74 return (
75 <div id="pgContainer">
76 <div id="sidebarMenu">
77 <Link
78 to={"/admin/addProduct"}
79 style={{ textDecoration: "none", width: "100%" }}
80 >
81 <div className="dashboard-btn" to="/admin/addProduct">
82 Додади нов производ
83 </div>
84 </Link>
85 <Link
86 to={"/admin/products"}
87 style={{ textDecoration: "none", width: "100%" }}
88 >
89 <div className="dashboard-btn">Производи</div>
90 </Link>
91 <Link
92 to={"/admin/orders"}
93 style={{ textDecoration: "none", width: "100%" }}
94 >
95 <div className="dashboard-btn">Нарачки</div>
96 </Link>
97 </div>
98 <div id="mainScreen">
99 <div className="taskContainer">
100 <h1 style={{ marginTop: "20px" }}>Нарачки</h1>
101 <div
102 className="filterContainer"
103 style={{
104 width: "100%",
105 display: "flex",
106 justifyContent: "space-around",
107 }}
108 >
109 <Button
110 variant="danger"
111 onClick={(e) => {
112 navigate(
113 getFilterUrl({ isConfirmed: "false", isShipped: "false" })
114 );
115 }}
116 >
117 За потврда
118 </Button>
119 <Button
120 variant="danger"
121 onClick={(e) =>
122 navigate(
123 getFilterUrl({ isShipped: "false", isConfirmed: "true" })
124 )
125 }
126 >
127 За испорака
128 </Button>
129 <Button
130 variant="danger"
131 onClick={(e) =>
132 navigate(
133 getFilterUrl({ isShipped: "true", isConfirmed: "true" })
134 )
135 }
136 >
137 Пристигнати
138 </Button>
139 </div>
140 {loading ? (
141 <LoadingBox></LoadingBox>
142 ) : error ? (
143 <MessageBox variant="danger">{error}</MessageBox>
144 ) : (
145 <table
146 className="table"
147 style={{ marginTop: "20px", width: "90%", textAlign: "center" }}
148 >
149 <thead>
150 <tr>
151 <th>ID</th>
152 <th>Дата</th>
153 <th>Вкупно</th>
154 <th>Статус</th>
155 <th>Акции</th>
156 </tr>
157 </thead>
158 <tbody>
159 {orders.map((order) => (
160 <tr key={order._id}>
161 <td>{order._id.substring(0, 7)}</td>
162 <td>{order.createdAt.substring(0, 10)}</td>
163 <td>{order.totalPrice.toFixed(2)}</td>
164
165 <td>
166 {order.isDelivered ? (
167 <CheckIcon></CheckIcon>
168 ) : order.isShipped ? (
169 <LocalShippingIcon></LocalShippingIcon>
170 ) : order.isConfirmed ? (
171 <HourglassBottomIcon></HourglassBottomIcon>
172 ) : (
173 <PhonePausedIcon></PhonePausedIcon>
174 )}
175 </td>
176 <td>
177 <Button
178 type="button"
179 variant="primary"
180 onClick={() => {
181 navigate(`/admin/order/${order._id}`);
182 }}
183 >
184 Детали
185 </Button>
186 </td>
187 </tr>
188 ))}
189 </tbody>
190 </table>
191 )}
192 <div style={{ marginTop: "20px" }}>
193 {[...Array(pages).keys()].map((x) => (
194 <LinkContainer
195 key={x + 1}
196 className="mx-1"
197 to={getFilterUrl({ page: x + 1 })}
198 >
199 <Button
200 className={Number(page) === x + 1 ? "text-bold" : ""}
201 variant={Number(page) === x + 1 ? "danger" : "light"}
202 >
203 {x + 1}
204 </Button>
205 </LinkContainer>
206 ))}
207 </div>
208 </div>
209 </div>
210 </div>
211 );
212}
213
214export default AdminOrdersScreen;
Note: See TracBrowser for help on using the repository browser.