Changeset a2e5735
- Timestamp:
- 12/13/22 22:38:11 (2 years ago)
- Branches:
- master
- Parents:
- 113029b
- Files:
-
- 19 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
backend/models/productModel.js
r113029b ra2e5735 5 5 name: { type: String, required: true, unique: true }, 6 6 slug: { type: String, required: true, unique: true }, 7 height: { type: Number, required: true }, 8 width: { type: Number, required: true }, 9 length: { type: Number, required: true }, 7 10 image: { type: String, required: true }, 8 11 sideImage: { type: String, required: true }, -
backend/routes/productRoutes.js
r113029b ra2e5735 42 42 priceMontaza: req.body.priceMontaza, 43 43 countInStock: req.body.countInStock, 44 height: req.body.H, 45 width: req.body.W, 46 length: req.body.L, 44 47 }); 45 48 … … 52 55 53 56 const PAGE_SIZE = 7; 57 58 productRouter.get( 59 "/search", 60 expressAsyncHandler(async (req, res) => { 61 const { query } = req; 62 const pageSize = query.pageSize || PAGE_SIZE; 63 const page = query.page || 1; 64 const searchQuery = query.text; 65 console.log("HEEEY: " + searchQuery); 66 const queryFilter = 67 searchQuery && searchQuery !== "all" 68 ? { name: { $regex: searchQuery, $options: "i" } } 69 : {}; 70 const descriptionFilter = 71 searchQuery && searchQuery !== "all" 72 ? { description: { $regex: searchQuery, $options: "i" } } 73 : {}; 74 const slug = 75 searchQuery && searchQuery !== "all" 76 ? { slug: { $regex: searchQuery, $options: "i" } } 77 : {}; 78 const products = await Product.find({ 79 $or: [ 80 { name: { $regex: searchQuery, $options: "i" } }, 81 { slug: { $regex: searchQuery, $options: "i" } }, 82 { description: { $regex: searchQuery, $options: "i" } }, 83 ], 84 }) 85 .skip(pageSize * (page - 1)) 86 .limit(pageSize); 87 const countProducts = await Product.countDocuments({ 88 $or: [ 89 { name: { $regex: searchQuery, $options: "i" } }, 90 { slug: { $regex: searchQuery, $options: "i" } }, 91 { description: { $regex: searchQuery, $options: "i" } }, 92 ], 93 }); 94 res.send({ 95 products, 96 countProducts, 97 page, 98 pages: Math.ceil(countProducts / pageSize), 99 }); 100 }) 101 ); 102 54 103 productRouter.get( 55 104 "/", … … 62 111 const order = query.order || ""; 63 112 const searchQuery = query.query || ""; 113 const HF = query.HF || 0; 114 const HT = query.HT || 1000; 115 const WF = query.WF || 0; 116 const WT = query.WT || 1000; 117 const LF = query.LF || 0; 118 const LT = query.LT || 1000; 64 119 65 120 const queryFilter = … … 80 135 ...categoryFilter, 81 136 ...subCategoryFilter, 137 $and: [ 138 { height: { $gte: HF } }, 139 { height: { $lte: HT } }, 140 { width: { $gte: WF } }, 141 { width: { $lte: WT } }, 142 { length: { $gte: LF } }, 143 { length: { $lte: LT } }, 144 ], 82 145 }) 83 146 .sort(sortOrder) -
backend/server.js
r113029b ra2e5735 7 7 import userRouter from "./routes/userRoutes.js"; 8 8 import orderRouter from "./routes/orderRoutes.js"; 9 import categoryRouter from "./routes/categoryRoutes.js"; 9 10 10 11 dotenv.config(); … … 28 29 app.use("/api/users", userRouter); 29 30 app.use("/api/orders", orderRouter); 31 app.use("/api/category", categoryRouter); 30 32 31 33 app.use((err, req, res, next) => { -
frontend/src/App.js
r113029b ra2e5735 28 28 import AdminOrdersScreen from "./screens/AdminOrdersScreen"; 29 29 import AdminOrderScreen from "./screens/AdminOrderScreen"; 30 import AdminAddCategoryScreen from "./screens/AdminAddCategoryScreen"; 31 import SearchScreen from "./screens/SearchScreen"; 30 32 function App() { 31 33 const { state } = useContext(Store); … … 54 56 element={<CategoryScreen />} 55 57 /> 58 <Route path="/products/search" element={<SearchScreen />} /> 56 59 <Route path="/admin/dashboard" element={<AdminDashboardScreen />} /> 57 60 <Route path="/admin/addProduct" element={<AdminAddProductScreen />} /> 61 <Route 62 path="/admin/addCategory" 63 element={<AdminAddCategoryScreen />} 64 ></Route> 58 65 <Route path="/admin/products" element={<AdminProductsScreen />} /> 59 66 <Route path="/admin/orders" element={<AdminOrdersScreen />} /> -
frontend/src/components/Header.js
r113029b ra2e5735 1 import React from "react";1 import React, { useEffect, useState } from "react"; 2 2 import logo from "../Images/logo.png"; 3 3 import "../styles/Header.css"; … … 24 24 import NavDropdown from "react-bootstrap/NavDropdown"; 25 25 import { height } from "@mui/system"; 26 import Axios from "axios"; 27 import CategoryMenu from "./CategoryMenu"; 26 28 27 29 const toggleMenu = (event) => { … … 76 78 const navigate = useNavigate(); 77 79 80 const [categories, setCategories] = useState([]); 81 //const [] 82 78 83 const signoutHandler = () => { 79 84 ctxDispatch({ type: "USER_SIGNOUT" }); … … 83 88 window.location.href = "/signin"; 84 89 }; 90 91 const searchHandler = () => { 92 let text = document.querySelector(".header__searchInput").value; 93 console.log(text); 94 navigate(`/products/search?text=${text}`); 95 }; 96 97 useEffect(() => { 98 const fetchData = async () => { 99 const cat = await Axios.get(`/api/category/getCategories`); 100 categories.splice(0, categories.length); 101 for (let i = 0; i < cat.data.length; i++) { 102 categories.push(cat.data[i]); 103 } 104 console.log(categories[0]); 105 }; 106 fetchData(); 107 }, [categories]); 108 const results = []; 109 const results1 = []; 110 const results2 = []; 111 const results3 = []; 112 if (categories) createMenu(categories); 113 function createMenu(categories) { 114 /* 115 let ul = document.getElementById("category-ul-1"); 116 for(let i=0;i<categories.length;i++){ 117 ul.appendChild() 118 }*/ 119 results.splice(0, results.length); 120 categories.forEach((category) => { 121 results.push(<CategoryMenu category={category} />); 122 }); 123 for (let i = 0; i < categories.length; i++) { 124 if (i < 3) { 125 results1.push(<CategoryMenu category={categories[i]} />); 126 } else if (i < 5) { 127 results2.push(<CategoryMenu category={categories[i]} />); 128 } else { 129 results3.push(<CategoryMenu category={categories[i]} />); 130 } 131 } 132 console.log("Results:"); 133 console.log(categories); 134 } 85 135 86 136 return ( … … 839 889 <div className="header__dropdown"> 840 890 <div className="header__dropdownColumn"> 841 <ul> 891 <ul id="category-ul-1"> 892 <li>{categories[0] && results1}</li> 893 {/* 842 894 <li> 843 895 <Link to="/products/dnevna/all"> … … 916 968 </li> 917 969 </ul> 918 </li>970 </li>*/} 919 971 </ul> 920 972 </div> 921 973 <div className="header__dropdownColumn"> 922 974 <ul> 975 <li>{categories[0] && results2}</li> 976 {/* 923 977 <li> 924 978 <Link to="/products/spalna/all"> … … 998 1052 </ul> 999 1053 </li> 1054 */} 1000 1055 </ul> 1001 1056 </div> 1002 1057 <div className="header__dropdownColumn"> 1003 1058 <ul> 1059 <li>{categories[0] && results3}</li> 1060 {/* 1004 1061 <li> 1005 1062 <Link to="/products/kancelarija/all"> … … 1083 1140 </ul> 1084 1141 </li> 1142 */} 1085 1143 </ul> 1086 1144 </div> … … 1201 1259 </div> 1202 1260 <div className="header__search"> 1203 <input className="header__searchInput" type="text" /> 1204 <SearchIcon className="header__searchIcon" fontSize="large" /> 1261 <input className="header__searchInput" type="text" name="text" /> 1262 <button onClick={searchHandler}> 1263 <SearchIcon className="header__searchIcon" fontSize="large" /> 1264 </button> 1205 1265 </div> 1206 1266 </div> -
frontend/src/components/Product.js
r113029b ra2e5735 54 54 <div 55 55 style={{ 56 width: "100%",57 56 display: "flex", 58 justifyContent: " center",57 justifyContent: "space-around", 59 58 alignItems: "center", 60 59 }} 61 60 > 62 {product.countInStock > 0 ? ( 63 <span style={{ color: "green" }}> 64 <CheckIcon></CheckIcon>Залиха 65 </span> 66 ) : ( 67 <span style={{ color: "red" }}> 68 <ClearIcon></ClearIcon>Залиха 69 </span> 70 )} 61 <h5>H: {product.height}</h5> 62 <h5>W: {product.width}</h5> 63 <h5>L: {product.length}</h5> 71 64 </div> 72 <div className="product__addToCart" style={{ marginTop: "15px" }}> 65 <div 66 className="product__addToCart" 67 style={{ marginTop: "15px", display: "flex", justifyContent: "center" }} 68 > 73 69 <button onClick={addToCartHandler}> 74 70 <ShoppingBasketIcon /> 75 71 </button> 72 <div 73 style={{ 74 //width: "100%", 75 display: "flex", 76 justifyContent: "center", 77 alignItems: "center", 78 marginLeft: "10px", 79 }} 80 > 81 {product.countInStock > 0 ? ( 82 <span style={{ color: "green" }}> 83 <CheckIcon></CheckIcon>Залиха 84 </span> 85 ) : ( 86 <span style={{ color: "red" }}> 87 <ClearIcon></ClearIcon>Залиха 88 </span> 89 )} 90 </div> 76 91 </div> 77 92 </div> -
frontend/src/screens/AdminAddProductScreen.js
r113029b ra2e5735 20 20 const [dimension, setDimension] = useState(""); 21 21 const [scheme, setScheme] = useState(""); 22 const [H, setH] = useState(""); 23 const [W, setW] = useState(""); 24 const [L, setL] = useState(""); 22 25 const [message, setMessage] = useState(""); 23 26 … … 56 59 formData.append("dimension", dimension); 57 60 formData.append("scheme", scheme); 58 61 formData.append("H", H); 62 formData.append("W", W); 63 formData.append("L", L); 59 64 try { 60 65 const result = await axios.post("/api/products/add", formData); … … 76 81 Додади нов производ 77 82 </div> 83 </Link> 84 <Link 85 to={"/admin/addCategory"} 86 style={{ textDecoration: "none", width: "100%" }} 87 > 88 <div className="dashboard-btn">Додади категорија</div> 78 89 </Link> 79 90 <Link … … 351 362 </div> 352 363 <div> 364 <Form.Group 365 style={{ display: "flex", justifyContent: "space-around" }} 366 > 367 <div 368 style={{ 369 display: "flex", 370 flexDirection: "row", 371 alignItems: "center", 372 }} 373 > 374 <Form.Label>H:</Form.Label> 375 <Form.Control 376 type="text" 377 name="dimension" 378 style={{ width: "60px" }} 379 value={H} 380 onChange={(e) => setH(e.target.value)} 381 required 382 ></Form.Control> 383 </div> 384 <div 385 style={{ 386 display: "flex", 387 flexDirection: "row", 388 alignItems: "center", 389 }} 390 > 391 <Form.Label>W:</Form.Label> 392 <Form.Control 393 type="text" 394 name="dimension" 395 value={W} 396 onChange={(e) => setW(e.target.value)} 397 style={{ width: "60px" }} 398 required 399 ></Form.Control> 400 </div> 401 <div 402 style={{ 403 display: "flex", 404 flexDirection: "row", 405 alignItems: "center", 406 }} 407 > 408 <Form.Label>L:</Form.Label> 409 <Form.Control 410 type="text" 411 name="dimension" 412 style={{ width: "60px" }} 413 value={L} 414 onChange={(e) => setL(e.target.value)} 415 required 416 ></Form.Control> 417 </div> 418 </Form.Group> 353 419 <Form.Group> 354 420 <Form.Label>Слика со димензии</Form.Label> -
frontend/src/screens/AdminDashboardScreen.js
r113029b ra2e5735 6 6 import { useNavigate, Link } from "react-router-dom"; 7 7 import ListProducts from "../components/ListProducts"; 8 import { Helmet } from "react-helmet-async"; 8 9 9 10 function AdminDashboardScreen() { … … 19 20 return ( 20 21 <div id="pgContainer"> 22 <Helmet> 23 <title>Dashboard</title> 24 </Helmet> 21 25 <div id="sidebarMenu"> 22 26 <Link … … 27 31 Додади нов производ 28 32 </div> 33 </Link> 34 <Link 35 to={"/admin/addCategory"} 36 style={{ textDecoration: "none", width: "100%" }} 37 > 38 <div className="dashboard-btn">Додади категорија</div> 29 39 </Link> 30 40 <Link -
frontend/src/screens/AdminEditProductScreen.js
r113029b ra2e5735 83 83 Додади нов производ 84 84 </div> 85 </Link> 86 <Link 87 to={"/admin/addCategory"} 88 style={{ textDecoration: "none", width: "100%" }} 89 > 90 <div className="dashboard-btn">Додади категорија</div> 85 91 </Link> 86 92 <Link -
frontend/src/screens/AdminOrdersScreen.js
r113029b ra2e5735 82 82 Додади нов производ 83 83 </div> 84 </Link> 85 <Link 86 to={"/admin/addCategory"} 87 style={{ textDecoration: "none", width: "100%" }} 88 > 89 <div className="dashboard-btn">Додади категорија</div> 84 90 </Link> 85 91 <Link -
frontend/src/screens/AdminProductsScreen.js
r113029b ra2e5735 96 96 Додади нов производ 97 97 </div> 98 </Link> 99 <Link 100 to={"/admin/addCategory"} 101 style={{ textDecoration: "none", width: "100%" }} 102 > 103 <div className="dashboard-btn">Додади категорија</div> 98 104 </Link> 99 105 <Link -
frontend/src/screens/CategoryScreen.js
r113029b ra2e5735 1 import React, { useEffect, useReducer } from "react";1 import React, { useEffect, useReducer, useState } from "react"; 2 2 import "../styles/Home.css"; 3 3 // import data from "./data"; … … 34 34 const params = useParams(); 35 35 const { category, subCategory } = params; 36 var HF = 0; 37 var HT = 1000; 38 var WF = 0; 39 var WT = 1000; 40 var LF = 0; 41 var LT = 1000; 42 //const [HT, setHT] = useState(1000); 43 //const [WF, setWF] = useState(0); 44 //const [WT, setWT] = useState(1000); 45 //const [LF, setLF] = useState(0); 46 //const [LT, setLT] = useState(1000); 36 47 const navigate = useNavigate(); 37 48 const { search } = useLocation(); … … 43 54 const order = sp.get("order") || "newest"; 44 55 const page = sp.get("page") || 1; 45 46 56 const [{ loading, error, products, pages, countProducts }, dispatch] = 47 57 useReducer(reducer, { loading: true, error: "" }); … … 56 66 );*/ 57 67 const { data } = await axios.get( 58 `/api/products?page=${page}&query=${query}&category=${category}&subCategory=${subCategory}&order=${order} `68 `/api/products?page=${page}&query=${query}&category=${category}&subCategory=${subCategory}&order=${order}&HF=${HF}&HT=${HT}&WF=${WF}&WT=${WT}&LF=${LF}<=${LT}` 59 69 ); 60 70 dispatch({ type: "FETCH_SUCCESS", payload: data }); … … 64 74 }; 65 75 fetchData(); 66 }, [category, page, query, order, subCategory, error]); 76 }, [ 77 category, 78 page, 79 query, 80 order, 81 subCategory, 82 error, 83 HF, 84 HT, 85 WF, 86 WT, 87 LF, 88 LT, 89 ]); 67 90 68 91 const getFilterUrl = (filter) => { … … 72 95 const filterSubCategory = filter.subCategory || subCategory; 73 96 const sortOrder = filter.order || order; 74 return `?category=${filterCategorry}&query=${filterQuery}&subCategory=${filterSubCategory}&page=${filterPage}&order=${sortOrder}`; 97 const filterHF = filter.HF || HF; 98 const filterHT = filter.HT || HT; 99 const filterWF = filter.WF || WF; 100 const filterWT = filter.WT || WT; 101 const filterLF = filter.LF || LF; 102 const filterLT = filter.LT || LT; 103 return `?category=${filterCategorry}&query=${filterQuery}&subCategory=${filterSubCategory}&page=${filterPage}&order=${sortOrder}&HF=${filterHF}&HT=${filterHT}&WF=${filterWF}&WT=${filterWT}&LF=${filterLF}<=${filterLT}`; 104 }; 105 106 const filterHandler = (e) => { 107 e.preventDefault(); 108 HF = document.getElementById("HF").value; 109 HT = document.getElementById("HT").value; 110 WF = document.getElementById("WF").value; 111 WT = document.getElementById("WT").value; 112 LF = document.getElementById("LF").value; 113 LT = document.getElementById("LT").value; 114 console.log(HT); 115 const fetchData = async () => { 116 try { 117 dispatch({ type: "FETCH_REQUEST" }); 118 /* 119 const { data } = await axios.get( 120 `/api/products/search?page=${page}&query=${query}&category=${category}&subCategory=${subCategory}&order=${order}` 121 );*/ 122 const { data } = await axios.get( 123 `/api/products?page=${page}&query=${query}&category=${category}&subCategory=${subCategory}&order=${order}&HF=${HF}&HT=${HT}&WF=${WF}&WT=${WT}&LF=${LF}<=${LT}` 124 ); 125 dispatch({ type: "FETCH_SUCCESS", payload: data }); 126 } catch (err) { 127 dispatch({ type: "FETCH_FAIL", payload: getError(err) }); 128 } 129 }; 130 fetchData(); 75 131 }; 76 132 … … 124 180 > 125 181 <Form 182 onSubmit={filterHandler} 126 183 style={{ 127 184 width: "100%", 128 185 display: "flex", 129 justifyContent: " end",186 justifyContent: "space-around", 130 187 marginRight: "40px", 131 188 alignItems: "center", 132 189 }} 133 190 > 191 <Form.Group style={{ display: "flex", alignItems: "center" }}> 192 <Form.Label style={{ margin: "0px" }}>H:</Form.Label> 193 <Form.Control 194 style={{ width: "60px" }} 195 id="HF" 196 //onChange={(e) => setHF(e.target.value)} 197 /> 198 <Form.Label style={{ margin: "0px" }}>-</Form.Label> 199 <Form.Control 200 style={{ width: "60px" }} 201 id="HT" 202 //onChange={(e) => setHT(e.target.value)} 203 /> 204 </Form.Group> 205 <Form.Group style={{ display: "flex", alignItems: "center" }}> 206 <Form.Label style={{ margin: "0px" }}>W:</Form.Label> 207 <Form.Control 208 style={{ width: "60px" }} 209 id="WF" 210 //onChange={(e) => setWF(e.target.value)} 211 /> 212 <Form.Label style={{ margin: "0px" }}>-</Form.Label> 213 <Form.Control 214 style={{ width: "60px" }} 215 id="WT" 216 //onChange={(e) => setWT(e.target.value)} 217 /> 218 </Form.Group> 219 <Form.Group style={{ display: "flex", alignItems: "center" }}> 220 <Form.Label style={{ margin: "0px" }}>L:</Form.Label> 221 <Form.Control 222 id="LF" 223 style={{ width: "60px" }} 224 //onChange={(e) => setLF(e.target.value)} 225 /> 226 <Form.Label style={{ margin: "0px" }}>-</Form.Label> 227 <Form.Control 228 id="LT" 229 style={{ width: "60px" }} 230 //onChange={(e) => setLT(e.target.value)} 231 /> 232 </Form.Group> 134 233 {/*} 135 234 <Form.Group> … … 292 391 <option value={"highFirst"}>Од висока кон ниска</option> 293 392 </Form.Select> 393 </Form.Group> 394 <Form.Group> 395 <Button variant="danger" size="lg" type="submit"> 396 Филтрирај 397 </Button> 294 398 </Form.Group> 295 399 </Form>
Note:
See TracChangeset
for help on using the changeset viewer.