source: frontend/src/screens/AdminProductsScreen.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: 15.4 KB
Line 
1import axios from "axios";
2import React, { useEffect, useReducer, useState } from "react";
3import { Link, useNavigate, useLocation } from "react-router-dom";
4import ListGroup from "react-bootstrap/ListGroup";
5import Button from "react-bootstrap/Button";
6import Form from "react-bootstrap/Form";
7import { getError } from "../components/utils";
8import { toast } from "react-toastify";
9import LoadingBox from "../components/LoadingBox";
10import MessageBox from "../components/MessageBox";
11import LinkContainer from "react-router-bootstrap/LinkContainer";
12
13const reducer = (state, action) => {
14 switch (action.type) {
15 case "FETCH_REQUEST":
16 return { ...state, loading: true };
17 case "FETCH_SUCCESS":
18 return {
19 ...state,
20 products: action.payload.products,
21 page: action.payload.page,
22 pages: action.payload.pages,
23 countProducts: action.payload.countProducts,
24 loading: false,
25 };
26 case "FETCH_FAIL":
27 return { ...state, loading: false, error: action.payload };
28 default:
29 return state;
30 }
31};
32
33function AdminProductsScreen() {
34 const navigate = useNavigate();
35 const { search } = useLocation();
36 const sp = new URLSearchParams(search);
37 const category = sp.get("category") || "all";
38 const query = sp.get("query") || "all";
39 const subCategory = sp.get("subCategory") || "all";
40 //const name = sp.get("name") || "all";
41 const order = sp.get("order") || "newest";
42 const page = sp.get("page") || 1;
43
44 const [{ loading, error, products, pages, countProducts }, dispatch] =
45 useReducer(reducer, { loading: true, error: "" });
46
47 useEffect(() => {
48 const fetchData = async () => {
49 try {
50 dispatch({ type: "FETCH_REQUEST" });
51 /*
52 const { data } = await axios.get(
53 `/api/products/search?page=${page}&query=${query}&category=${category}&subCategory=${subCategory}&order=${order}`
54 );*/
55 const { data } = await axios.get(
56 `/api/products?page=${page}&query=${query}&category=${category}&subCategory=${subCategory}&order=${order}`
57 );
58 dispatch({ type: "FETCH_SUCCESS", payload: data });
59 } catch (err) {
60 dispatch({ type: "FETCH_FAIL", payload: getError(err) });
61 }
62 };
63 fetchData();
64 }, [category, page, query, order, subCategory, error]);
65
66 const getFilterUrl = (filter) => {
67 const filterPage = filter.page || page;
68 const filterCategorry = filter.category || category;
69 const filterQuery = filter.query || query;
70 const filterSubCategory = filter.subCategory || subCategory;
71 const sortOrder = filter.order || order;
72 return `?category=${filterCategorry}&query=${filterQuery}&subCategory=${filterSubCategory}&page=${filterPage}&order=${sortOrder}`;
73 };
74
75 return (
76 <div
77 style={{
78 display: "flex",
79 flexDirection: "column",
80 alignItems: "center",
81 justifyContent: "center",
82 }}
83 >
84 {loading ? (
85 <LoadingBox></LoadingBox>
86 ) : error ? (
87 <MessageBox varriant="danger">{error}</MessageBox>
88 ) : (
89 <div id="pgContainer">
90 <div id="sidebarMenu">
91 <Link
92 to={"/admin/addProduct"}
93 style={{ textDecoration: "none", width: "100%" }}
94 >
95 <div className="dashboard-btn" to="/admin/addProduct">
96 Додади нов производ
97 </div>
98 </Link>
99 <Link
100 to={"/admin/products"}
101 style={{ textDecoration: "none", width: "100%" }}
102 >
103 <div className="dashboard-btn">Производи</div>
104 </Link>
105 <Link
106 to={"/admin/orders"}
107 style={{ textDecoration: "none", width: "100%" }}
108 >
109 <div className="dashboard-btn">Нарачки</div>
110 </Link>
111 </div>
112 <div className="taskContainer">
113 <h1>Производи</h1>
114 <div className="filterContainer" style={{ width: "100%" }}>
115 <Form
116 id="fff"
117 style={{
118 display: "flex",
119 alignItems: "center",
120 justifyContent: "space-around",
121 }}
122 >
123 {/*
124 <Form.Group>
125 <Form.Control
126 id="filterName"
127 placeholder="Име"
128 onSubmit={submitHandler}
129 required
130 ></Form.Control>
131 </Form.Group>*/}
132 <Form.Group>
133 <Form.Select
134 value={category}
135 onChange={(e) => {
136 if (e.target.value === "all") {
137 navigate(
138 getFilterUrl({
139 page: 1,
140 category: e.target.value,
141 subCategory: "all",
142 })
143 );
144 } else {
145 navigate(
146 getFilterUrl({ category: e.target.value, page: 1 })
147 );
148 }
149 }}
150 >
151 <option value="all">Категорија</option>
152 <option value={"dnevna"}>Дневна</option>
153 <option value={"spalna"}>Спална</option>
154 <option value={"kancelarija"}>Канцеларија</option>
155 <option value={"hodnik"}>Ходник</option>
156 <option value={"gradina"}>Градина</option>
157 <option value={"trpezarija"}>Трпезарија</option>
158 <option value={"kujna"}>Кујна</option>
159 <option value={"detska"}>Детска</option>
160 </Form.Select>
161 </Form.Group>
162 <Form.Group>
163 <Form.Select
164 value={subCategory}
165 onChange={(e) => {
166 navigate(
167 getFilterUrl({ subCategory: e.target.value, page: 1 })
168 );
169 }}
170 >
171 <option value="all">Подкатегорија</option>
172
173 {category === "dnevna" && (
174 <option value="agolni-garnituri">Аголни Гарнитури</option>
175 )}
176 {category === "dnevna" && (
177 <option value="sofi">Софи</option>
178 )}
179 {category === "dnevna" && (
180 <option value="fotelji">Фотелји</option>
181 )}
182 {category === "dnevna" && (
183 <option value="taburetki">Табуретки</option>
184 )}
185 {category === "dnevna" && (
186 <option value="klub-masi">Клуб маси</option>
187 )}
188 {category === "dnevna" && (
189 <option value="tv-komodi">ТВ комоди</option>
190 )}
191 {category === "dnevna" && (
192 <option value="komodi">Комоди</option>
193 )}
194 {category === "spalna" && (
195 <option value="spalni-kompleti">Спални Комплети</option>
196 )}
197 {category === "spalna" && (
198 <option value="lezai">Лежаи</option>
199 )}
200 {category === "spalna" && (
201 <option value="kreveti">Кревети</option>
202 )}
203 {category === "spalna" && (
204 <option value="plakari">Плакари</option>
205 )}
206 {category === "spalna" && (
207 <option value="nokni-skafcinja">Ноќни шкафчиња</option>
208 )}
209 {category === "spalna" && (
210 <option value="toaletni-masi">Тоалетни маси</option>
211 )}
212 {category === "kancelarija" && (
213 <option value="biroa">Бироа</option>
214 )}
215 {category === "kancelarija" && (
216 <option value="kancelariski-stolovi">
217 Канцелариски столови
218 </option>
219 )}
220 {category === "kancelarija" && (
221 <option value="gejmerski-stolovi">
222 Гејмерски столови
223 </option>
224 )}
225 {category === "kancelarija" && (
226 <option value="kancelariski-skafovi">
227 Канцелариски шкафови
228 </option>
229 )}
230 {category === "hodnik" && (
231 <option value="skafovi-za-cevli">Шкафови за чевли</option>
232 )}
233 {category === "hodnik" && (
234 <option value="zakacalki-i-ogledala">
235 Закачалки и огледала
236 </option>
237 )}
238 {category === "hodnik" && (
239 <option value="kolekcii-za-hodnik">
240 Колекции за ходник
241 </option>
242 )}
243 {category === "gradina" && (
244 <option value="gradinarski-kompleti">
245 Градинарски комплети
246 </option>
247 )}
248 {category === "gradina" && (
249 <option value="gradinarski-lulki">
250 Градинарски лулки
251 </option>
252 )}
253 {category === "gradina" && (
254 <option value="gradinarski-cadori">
255 Градинарски чадори
256 </option>
257 )}
258 {category === "gradina" && (
259 <option value="gradinarski-masi">Градинарски маси</option>
260 )}
261 {category === "gradina" && (
262 <option value="gradinarski-stolovi">
263 Градинарски столови
264 </option>
265 )}
266 {category === "gradina" && (
267 <option value="gradinarsko-osvetluvanje">
268 Градинарско осветлување
269 </option>
270 )}
271 {category === "trpezarija" && (
272 <option value="trpezariski-masi">Трпезариски маси</option>
273 )}
274 {category === "trpezarija" && (
275 <option value="trpezariski-stolovi">
276 Трпезариски столови
277 </option>
278 )}
279 {category === "trpezarija" && (
280 <option value="kujnski-garnituri">
281 Кујнски гарнитури
282 </option>
283 )}
284 {category === "trpezarija" && (
285 <option value="bar-stolovi-i-masi">
286 Бар столови и маси
287 </option>
288 )}
289 {category === "kujna" && (
290 <option value="kujnski-agolni-garnituri">
291 Кујнски аголни гарнитури
292 </option>
293 )}
294 {category === "kujna" && (
295 <option value="standardni-kujni">Стандардни кујни</option>
296 )}
297 {category === "detska" && (
298 <option value="kolekcii-za-detska-soba">
299 Колекции за детска соба
300 </option>
301 )}
302 {category === "detska" && (
303 <option value="detski-biroa">Детски бироа</option>
304 )}
305 {category === "detska" && (
306 <option value="detski-lezai">Детски лежаи</option>
307 )}
308 </Form.Select>
309 </Form.Group>
310 <Form.Group>
311 <Form.Select
312 id="sortOrder"
313 onChange={(e) => {
314 navigate(getFilterUrl({ order: e.target.value }));
315 }}
316 >
317 <option value={"newest"}>Сортирај по цена</option>
318 <option value={"lowFirst"}>Од ниска кон висока</option>
319 <option value={"highFirst"}>Од висока кон ниска</option>
320 </Form.Select>
321 </Form.Group>
322 </Form>
323 </div>
324 <ListGroup
325 id="filteredProductsContainer"
326 variant="success"
327 style={{ width: "95%", margin: "auto", marginTop: "20px" }}
328 >
329 {products.map((item) => (
330 <ListGroup.Item key={item._id}>
331 <div
332 style={{
333 display: "flex",
334 alignItems: "center",
335 justifyContent: "space-between",
336 }}
337 >
338 <div style={{ display: "flex", alignItems: "center" }}>
339 <img
340 src={item.image}
341 alt={item.name}
342 className="img-fluid rounded img-thumbnail"
343 style={{ margin: "0px" }}
344 ></img>
345 <span style={{ marginLeft: "20px" }}>{item.name}</span>
346 </div>
347 <span>{item.category}</span>
348 <span>{item.subCategory}</span>
349 <span>{item.countInStock}</span>
350
351 <span>{item.price} ден</span>
352 <Button
353 type="button"
354 variant="primary"
355 style={{ height: "50px" }}
356 onClick={() => {
357 navigate(`/admin/product/${item.slug}`);
358 }}
359 >
360 Измени
361 </Button>
362 </div>
363 </ListGroup.Item>
364 ))}
365 </ListGroup>
366 <div style={{ marginTop: "20px" }}>
367 {[...Array(pages).keys()].map((x) => (
368 <LinkContainer
369 key={x + 1}
370 className="mx-1"
371 to={getFilterUrl({ page: x + 1 })}
372 >
373 <Button
374 className={Number(page) === x + 1 ? "text-bold" : ""}
375 variant={Number(page) === x + 1 ? "danger" : "light"}
376 >
377 {x + 1}
378 </Button>
379 </LinkContainer>
380 ))}
381 </div>
382 </div>
383 </div>
384 )}
385 </div>
386 );
387}
388
389export default AdminProductsScreen;
Note: See TracBrowser for help on using the repository browser.