source: frontend/src/screens/AdminProductsScreen.js

Last change on this file was a2e5735, checked in by Nace Gjorgjievski <nace.gorgievski123@…>, 19 months ago

Final Version

  • Property mode set to 100644
File size: 15.7 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/addCategory"}
101 style={{ textDecoration: "none", width: "100%" }}
102 >
103 <div className="dashboard-btn">Додади категорија</div>
104 </Link>
105 <Link
106 to={"/admin/products"}
107 style={{ textDecoration: "none", width: "100%" }}
108 >
109 <div className="dashboard-btn">Производи</div>
110 </Link>
111 <Link
112 to={"/admin/orders"}
113 style={{ textDecoration: "none", width: "100%" }}
114 >
115 <div className="dashboard-btn">Нарачки</div>
116 </Link>
117 </div>
118 <div className="taskContainer">
119 <h1>Производи</h1>
120 <div className="filterContainer" style={{ width: "100%" }}>
121 <Form
122 id="fff"
123 style={{
124 display: "flex",
125 alignItems: "center",
126 justifyContent: "space-around",
127 }}
128 >
129 {/*
130 <Form.Group>
131 <Form.Control
132 id="filterName"
133 placeholder="Име"
134 onSubmit={submitHandler}
135 required
136 ></Form.Control>
137 </Form.Group>*/}
138 <Form.Group>
139 <Form.Select
140 value={category}
141 onChange={(e) => {
142 if (e.target.value === "all") {
143 navigate(
144 getFilterUrl({
145 page: 1,
146 category: e.target.value,
147 subCategory: "all",
148 })
149 );
150 } else {
151 navigate(
152 getFilterUrl({ category: e.target.value, page: 1 })
153 );
154 }
155 }}
156 >
157 <option value="all">Категорија</option>
158 <option value={"dnevna"}>Дневна</option>
159 <option value={"spalna"}>Спална</option>
160 <option value={"kancelarija"}>Канцеларија</option>
161 <option value={"hodnik"}>Ходник</option>
162 <option value={"gradina"}>Градина</option>
163 <option value={"trpezarija"}>Трпезарија</option>
164 <option value={"kujna"}>Кујна</option>
165 <option value={"detska"}>Детска</option>
166 </Form.Select>
167 </Form.Group>
168 <Form.Group>
169 <Form.Select
170 value={subCategory}
171 onChange={(e) => {
172 navigate(
173 getFilterUrl({ subCategory: e.target.value, page: 1 })
174 );
175 }}
176 >
177 <option value="all">Подкатегорија</option>
178
179 {category === "dnevna" && (
180 <option value="agolni-garnituri">Аголни Гарнитури</option>
181 )}
182 {category === "dnevna" && (
183 <option value="sofi">Софи</option>
184 )}
185 {category === "dnevna" && (
186 <option value="fotelji">Фотелји</option>
187 )}
188 {category === "dnevna" && (
189 <option value="taburetki">Табуретки</option>
190 )}
191 {category === "dnevna" && (
192 <option value="klub-masi">Клуб маси</option>
193 )}
194 {category === "dnevna" && (
195 <option value="tv-komodi">ТВ комоди</option>
196 )}
197 {category === "dnevna" && (
198 <option value="komodi">Комоди</option>
199 )}
200 {category === "spalna" && (
201 <option value="spalni-kompleti">Спални Комплети</option>
202 )}
203 {category === "spalna" && (
204 <option value="lezai">Лежаи</option>
205 )}
206 {category === "spalna" && (
207 <option value="kreveti">Кревети</option>
208 )}
209 {category === "spalna" && (
210 <option value="plakari">Плакари</option>
211 )}
212 {category === "spalna" && (
213 <option value="nokni-skafcinja">Ноќни шкафчиња</option>
214 )}
215 {category === "spalna" && (
216 <option value="toaletni-masi">Тоалетни маси</option>
217 )}
218 {category === "kancelarija" && (
219 <option value="biroa">Бироа</option>
220 )}
221 {category === "kancelarija" && (
222 <option value="kancelariski-stolovi">
223 Канцелариски столови
224 </option>
225 )}
226 {category === "kancelarija" && (
227 <option value="gejmerski-stolovi">
228 Гејмерски столови
229 </option>
230 )}
231 {category === "kancelarija" && (
232 <option value="kancelariski-skafovi">
233 Канцелариски шкафови
234 </option>
235 )}
236 {category === "hodnik" && (
237 <option value="skafovi-za-cevli">Шкафови за чевли</option>
238 )}
239 {category === "hodnik" && (
240 <option value="zakacalki-i-ogledala">
241 Закачалки и огледала
242 </option>
243 )}
244 {category === "hodnik" && (
245 <option value="kolekcii-za-hodnik">
246 Колекции за ходник
247 </option>
248 )}
249 {category === "gradina" && (
250 <option value="gradinarski-kompleti">
251 Градинарски комплети
252 </option>
253 )}
254 {category === "gradina" && (
255 <option value="gradinarski-lulki">
256 Градинарски лулки
257 </option>
258 )}
259 {category === "gradina" && (
260 <option value="gradinarski-cadori">
261 Градинарски чадори
262 </option>
263 )}
264 {category === "gradina" && (
265 <option value="gradinarski-masi">Градинарски маси</option>
266 )}
267 {category === "gradina" && (
268 <option value="gradinarski-stolovi">
269 Градинарски столови
270 </option>
271 )}
272 {category === "gradina" && (
273 <option value="gradinarsko-osvetluvanje">
274 Градинарско осветлување
275 </option>
276 )}
277 {category === "trpezarija" && (
278 <option value="trpezariski-masi">Трпезариски маси</option>
279 )}
280 {category === "trpezarija" && (
281 <option value="trpezariski-stolovi">
282 Трпезариски столови
283 </option>
284 )}
285 {category === "trpezarija" && (
286 <option value="kujnski-garnituri">
287 Кујнски гарнитури
288 </option>
289 )}
290 {category === "trpezarija" && (
291 <option value="bar-stolovi-i-masi">
292 Бар столови и маси
293 </option>
294 )}
295 {category === "kujna" && (
296 <option value="kujnski-agolni-garnituri">
297 Кујнски аголни гарнитури
298 </option>
299 )}
300 {category === "kujna" && (
301 <option value="standardni-kujni">Стандардни кујни</option>
302 )}
303 {category === "detska" && (
304 <option value="kolekcii-za-detska-soba">
305 Колекции за детска соба
306 </option>
307 )}
308 {category === "detska" && (
309 <option value="detski-biroa">Детски бироа</option>
310 )}
311 {category === "detska" && (
312 <option value="detski-lezai">Детски лежаи</option>
313 )}
314 </Form.Select>
315 </Form.Group>
316 <Form.Group>
317 <Form.Select
318 id="sortOrder"
319 onChange={(e) => {
320 navigate(getFilterUrl({ order: e.target.value }));
321 }}
322 >
323 <option value={"newest"}>Сортирај по цена</option>
324 <option value={"lowFirst"}>Од ниска кон висока</option>
325 <option value={"highFirst"}>Од висока кон ниска</option>
326 </Form.Select>
327 </Form.Group>
328 </Form>
329 </div>
330 <ListGroup
331 id="filteredProductsContainer"
332 variant="success"
333 style={{ width: "95%", margin: "auto", marginTop: "20px" }}
334 >
335 {products.map((item) => (
336 <ListGroup.Item key={item._id}>
337 <div
338 style={{
339 display: "flex",
340 alignItems: "center",
341 justifyContent: "space-between",
342 }}
343 >
344 <div style={{ display: "flex", alignItems: "center" }}>
345 <img
346 src={item.image}
347 alt={item.name}
348 className="img-fluid rounded img-thumbnail"
349 style={{ margin: "0px" }}
350 ></img>
351 <span style={{ marginLeft: "20px" }}>{item.name}</span>
352 </div>
353 <span>{item.category}</span>
354 <span>{item.subCategory}</span>
355 <span>{item.countInStock}</span>
356
357 <span>{item.price} ден</span>
358 <Button
359 type="button"
360 variant="primary"
361 style={{ height: "50px" }}
362 onClick={() => {
363 navigate(`/admin/product/${item.slug}`);
364 }}
365 >
366 Измени
367 </Button>
368 </div>
369 </ListGroup.Item>
370 ))}
371 </ListGroup>
372 <div style={{ marginTop: "20px" }}>
373 {[...Array(pages).keys()].map((x) => (
374 <LinkContainer
375 key={x + 1}
376 className="mx-1"
377 to={getFilterUrl({ page: x + 1 })}
378 >
379 <Button
380 className={Number(page) === x + 1 ? "text-bold" : ""}
381 variant={Number(page) === x + 1 ? "danger" : "light"}
382 >
383 {x + 1}
384 </Button>
385 </LinkContainer>
386 ))}
387 </div>
388 </div>
389 </div>
390 )}
391 </div>
392 );
393}
394
395export default AdminProductsScreen;
Note: See TracBrowser for help on using the repository browser.