Skip to content

Commit 8d619f1

Browse files
author
WebDeveloperGuide
committed
Front End > Products > Price Filter and Search Filter added
1 parent b6b7f20 commit 8d619f1

File tree

5 files changed

+90
-31
lines changed

5 files changed

+90
-31
lines changed

web_panel/src/components/Filters.js

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,23 @@
1-
import React from 'react';
1+
import React,{useState} from 'react';
22

3-
const Filters = () => {
3+
const Filters = (props) => {
4+
5+
const {priceFilter, changePrice, changeSearch} = props;
6+
47
return(
58
<>
69
<div className="filters">
710
<div className="filters-container">
811
{/* search */}
912
<form className="input-form">
10-
<input type="text" className="search-input" placeholder="search..." />
11-
</form>
12-
{/* categories */}
13-
<h5>Company</h5>
14-
<article className="companies">
15-
<button className="company-btn">all</button>
16-
<button className="company-btn">ikea</button>
17-
<button className="company-btn">marcos</button>
18-
</article>
13+
<input type="text" className="search-input" placeholder="search..." onChange={changeSearch}/>
14+
</form>
1915
{/* price */}
2016
<h5>Price</h5>
2117
<form className="price-form">
22-
<input type="range" className="price-filter" min={0} defaultValue={50} max={100} />
18+
<input type="range" className="price-filter w-100" min={0} defaultValue={priceFilter} max={10000} onChange={changePrice} />
2319
</form>
24-
<span className="price-value">Value : $80</span>
20+
<span className="price-value">Value : ${priceFilter}</span>
2521
</div>
2622
</div>
2723
</>

web_panel/src/components/Products.js

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React,{useEffect} from 'react';
1+
import React,{useEffect,useState} from 'react';
22
import {useSelector,useDispatch} from 'react-redux';
33
import Filters from './Filters';
44
import Product from './Product';
@@ -7,29 +7,65 @@ import Loading from '../components/Loading';
77

88
const Products = () => {
99

10-
const products = useSelector((state)=> state.allProducts.products);
10+
const [currentPage, setCurrentPage] = useState(0);
11+
const [priceFilter,setPriceFilter] = useState(10000);
12+
const [searchTerm, setSearchTerm] = useState('');
13+
const [sortByFilter, setSortByFilter] = useState('');
14+
15+
const changePrice = (e) => {
16+
setPriceFilter(e.target.value)
17+
}
18+
19+
const changeSearch = (e) => {
20+
setSearchTerm(e.target.value)
21+
}
22+
23+
const allProducts = useSelector((state)=> state.allProducts);
24+
const { products, numOfPages, sortBy, searchText, price } = allProducts;
25+
26+
1127
const renderList = products.map((product)=>{
1228
return(
1329
<Product detail={product} key={product._id}/>
1430
)
1531
})
1632

1733
const dispatch = useDispatch();
34+
let pageNum = 0;
35+
let productsPerPage = 9;
36+
1837

1938
useEffect(()=>{
20-
dispatch(getProducts());
39+
dispatch(getProducts(pageNum,productsPerPage, sortBy, searchText, price));
2140
},[])
2241

42+
43+
//Call Function after stop typing text
44+
useEffect(() => {
45+
const delaySearchFunc = setTimeout(() => {
46+
setCurrentPage(0);
47+
dispatch(getProducts(pageNum,productsPerPage, sortByFilter, searchTerm, priceFilter));
48+
}, 1500)
49+
50+
return () => clearTimeout(delaySearchFunc)
51+
}, [searchTerm, priceFilter])
52+
53+
const handleSortBy = (e) => {
54+
const sortByValue = e.target.value;
55+
setCurrentPage(0);
56+
dispatch(getProducts(pageNum,productsPerPage, sortByValue, searchText, price));
57+
}
58+
2359
return(
2460
<>
2561
<section className="products">
26-
<Filters/>
62+
<Filters priceFilter={priceFilter} changePrice={changePrice} changeSearch={changeSearch}/>
2763
{
2864
(Object.keys(products).length === 0) ?
2965
<Loading/> :
3066
<div className="products-container">
3167
{renderList}
32-
</div>
68+
</div>
3369
}
3470
</section>
3571
</>

web_panel/src/redux/actions/productActions.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@ import axios from 'axios';
33
import { toast } from "react-toastify";
44
import {ToastObjects} from "../../util/toastObject";
55

6-
export const getProducts = () => async(dispatch) =>{
6+
export const getProducts = (pageNum,productsPerPage,sortBy,searchText,price) => async(dispatch) =>{
77
try{
8-
const response = await axios.get("products");
8+
const response = await axios.get(`products?page=${pageNum}&limit=${productsPerPage}&sortBy=${sortBy}&searchText=${searchText}&price=${price}`);
99
const responseData = response.data;
10+
11+
responseData['sortBy'] = sortBy;
12+
responseData['searchText'] = searchText;
13+
responseData['price'] = price;
1014

11-
dispatch({ type: ActionTypes.FETCH_PRODUCTS, payload: responseData.data });
15+
dispatch({ type: ActionTypes.FETCH_PRODUCTS, payload: responseData });
1216

1317
} catch (error){
1418

web_panel/src/redux/reducers/productReducer.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@ import { ActionTypes } from '../constants';
22

33
const initialState = {
44
products:[],
5-
productDetail:[]
5+
productDetail:[],
6+
numOfPages:0,
7+
sortBy: '',
8+
searchText:'',
9+
price:'10000'
610
}
711

812
export const productReducer = (state = initialState,{type,payload}) => {
913
switch(type){
1014
case ActionTypes.FETCH_PRODUCTS:
11-
return {...state,products:payload};
15+
return {...state,products:payload.data, numOfPages:payload.numOfPages, sortBy:payload.sortBy, searchText:payload.searchText, price:payload.price};
1216
case ActionTypes.SET_PRODUCT_DETAIL:
1317
return {...state,productDetail:payload};
1418
case ActionTypes.RESET_PRODUCT_DETAIL:

web_services/routes/product.js

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,27 +44,46 @@ router.get("/", async (req,res)=>{
4444
const pageNum = parseInt(req.query.page || "0"); //Products page number
4545
const sortByVal = (req.query.sortBy || "_id"); //Products sort by
4646
const searchText = (req.query.searchText || ""); //Products search text
47+
const priceFilter = (req.query.price || ""); //Products search text
4748

4849

4950
let sortObject = {};
50-
let searchObject = {};
51+
let filterObj = {};
52+
let searchTextObj = {};
53+
let priceObject = {};
5154
sortByField = sortByVal;
5255
if(sortByVal == 'name'){
5356
sortByField = 'title';
5457
}
5558

5659
if(searchText !== ''){
57-
searchObject = {$or:[{ title: { $regex: searchText, $options:'i' }}
58-
,{ description: { $regex: searchText, $options:'i' } }
59-
]};
60+
searchTextObj = {
61+
$or : [
62+
{ title: { $regex: searchText, $options:'i' } },
63+
{ description: { $regex: searchText, $options:'i' } }
64+
]
65+
};
66+
67+
}
68+
69+
if(priceFilter !== ''){
70+
priceObject = {price: {$lte: priceFilter}};
6071
}
6172

62-
sortObject[sortByField] = 1;
73+
74+
filterObj = {
75+
$and : [
76+
searchTextObj,
77+
priceObject
78+
]
79+
};
80+
81+
82+
sortObject[sortByField] = 1;
6383

6484

65-
const totalProducts = await Product.countDocuments(searchObject);
66-
const productData = await Product.find(searchObject).sort(sortObject).limit(itemPerPage).skip(itemPerPage * pageNum);
67-
85+
const totalProducts = await Product.countDocuments(filterObj);
86+
const productData = await Product.find(filterObj).sort(sortObject).limit(itemPerPage).skip(itemPerPage * pageNum);
6887

6988

7089
let numOfPages = parseInt(totalProducts/itemPerPage);

0 commit comments

Comments
 (0)