Make price filtering work

This commit is contained in:
Edin Dazdarevic
2017-04-04 04:36:52 +02:00
parent 0af6337132
commit 49e9e2fdfb
6 changed files with 179 additions and 112 deletions

View File

@@ -79,7 +79,7 @@
router.get('/search', function () { router.get('/search', function () {
var _ref = _asyncToGenerator(regeneratorRuntime.mark(function _callee(req, res, next) { var _ref = _asyncToGenerator(regeneratorRuntime.mark(function _callee(req, res, next) {
var bounds, minPrice, maxPrice, minSize, maxSize, rooms, adType, properties, query, _bounds$split$map, _bounds$split$map2, lat1, lng1, lat2, lng2, box, all; var bounds, minPrice, maxPrice, minSize, maxSize, rooms, adType, properties, query, _bounds$split$map, _bounds$split$map2, lat1, lng1, lat2, lng2, box, price, allRooms, or, size, all;
return regeneratorRuntime.wrap(function _callee$(_context) { return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) { while (1) {
@@ -117,77 +117,85 @@
}); });
} }
if (minPrice) { if (minPrice || maxPrice) {
price = {};
if (minPrice) {
price["$gte"] = parseFloat(minPrice);
}
if (maxPrice) {
price["$lte"] = parseFloat(maxPrice);
}
query = Object.assign(query, { query = Object.assign(query, {
price: { price: price
"$gte": parseFloat(minPrice),
"$ne": -1
}
}); });
} }
if (maxPrice) { if (rooms) {
query = Object.assign(query, { allRooms = rooms.split(',');
price: { or = allRooms.map(function (val) {
"$lte": parseFloat(maxPrice), if (val === '4+') {
"$ne": -1 return {
rooms: {
"$gte": 4
}
};
} }
return {
rooms: parseFloat(val)
};
});
query = Object.assign(query, {
"$or": or
}); });
} }
if (rooms === "4+") { if (minSize || maxSize) {
size = {};
if (minSize) {
size["$gte"] = parseFloat(minSize);
}
if (maxSize) {
size["$lte"] = parseFloat(maxSize);
}
query = Object.assign(query, { query = Object.assign(query, {
rooms: { size: size
"$gte": 4
}
});
} else if (rooms) {
query = Object.assign(query, {
rooms: parseFloat(rooms)
}); });
} }
if (minSize) { console.log('QUERY: ', query);
query = Object.assign(query, { _context.next = 18;
size: {
"$gte": parseFloat(minSize)
}
});
}
if (maxSize) {
query = Object.assign(query, {
size: {
"$lte": parseFloat(maxSize)
}
});
}
_context.next = 19;
return properties.find(query).toArray(); return properties.find(query).toArray();
case 19: case 18:
all = _context.sent; all = _context.sent;
res.json(all); res.json(all);
res.end(); res.end();
_context.next = 28; _context.next = 27;
break; break;
case 24: case 23:
_context.prev = 24; _context.prev = 23;
_context.t0 = _context['catch'](0); _context.t0 = _context['catch'](0);
console.log('error:', _context.t0); console.log('error:', _context.t0);
next(_context.t0); next(_context.t0);
case 28: case 27:
case 'end': case 'end':
return _context.stop(); return _context.stop();
} }
} }
}, _callee, undefined, [[0, 24]]); }, _callee, undefined, [[0, 23]]);
})); }));
return function (_x, _x2, _x3) { return function (_x, _x2, _x3) {

View File

@@ -48,52 +48,57 @@ router.get('/search', async (req, res, next) => {
}); });
} }
if (minPrice) { if (minPrice || maxPrice) {
const price = {}
if (minPrice) {
price["$gte"] = parseFloat(minPrice);
}
if (maxPrice) {
price["$lte"] = parseFloat(maxPrice);
}
query = Object.assign(query, { query = Object.assign(query, {
price: { price
"$gte": parseFloat(minPrice),
"$ne": -1
}
}); });
} }
if (maxPrice) { if (rooms) {
query = Object.assign(query, { const allRooms = rooms.split(',');
price: { const or = allRooms.map(val => {
"$lte": parseFloat(maxPrice), if (val === '4+') {
"$ne": -1 return {
rooms: {
"$gte": 4
}
}
} }
return {
rooms: parseFloat(val)
};
});
query = Object.assign(query, {
"$or": or
}); });
} }
if (rooms === "4+") { if (minSize || maxSize) {
const size = {}
if (minSize) {
size["$gte"] = parseFloat(minSize);
}
if (maxSize) {
size["$lte"] = parseFloat(maxSize);
}
query = Object.assign(query, { query = Object.assign(query, {
rooms: { size
"$gte": 4
}
})
} else if (rooms) {
query = Object.assign(query, {
rooms: parseFloat(rooms)
});
}
if (minSize) {
query = Object.assign(query, {
size: {
"$gte": parseFloat(minSize)
}
});
}
if (maxSize) {
query = Object.assign(query, {
size: {
"$lte": parseFloat(maxSize)
}
}); });
} }
console.log('QUERY: ', query);
const all = await properties.find(query).toArray(); const all = await properties.find(query).toArray();
res.json(all); res.json(all);

View File

@@ -8,6 +8,10 @@ export default class Filters extends React.Component {
} }
} }
onMaxPriceChange (e) {
this.props.dispatch({type: 'SET_MAX_PRICE', action: {maxPrice: e.target.value}})
}
onMinPriceChange (e) { onMinPriceChange (e) {
this.props.dispatch({type: 'SET_MIN_PRICE', action: {minPrice: e.target.value}}) this.props.dispatch({type: 'SET_MIN_PRICE', action: {minPrice: e.target.value}})
} }
@@ -17,6 +21,10 @@ export default class Filters extends React.Component {
this.props.dispatch({type: 'SET_ROOMS', action: {rooms}}); this.props.dispatch({type: 'SET_ROOMS', action: {rooms}});
} }
onRefreshClick () {
this.props.dispatch({type: 'UPDATE_SEARCH'});
}
render() { render() {
const {filters} = this.props; const {filters} = this.props;
@@ -38,7 +46,8 @@ export default class Filters extends React.Component {
</div> </div>
<div className="filter-content value-between-box"> <div className="filter-content value-between-box">
izmedju <input value={`${this.props.filters.minPrice}`} onChange={this.onMinPriceChange.bind(this)}></input> KM i <input></input> izmedju <input value={`${this.props.filters.minPrice}`} onChange={this.onMinPriceChange.bind(this)}></input> KM i <input onChange={this.onMaxPriceChange.bind(this)}></input>
{this.props.filters.dirty? <button onClick={this.onRefreshClick.bind(this)}>Refresh</button>: null}
</div> </div>
</div> </div>

View File

@@ -82,37 +82,7 @@ class Main extends React.Component {
this.map = map; this.map = map;
map.addListener('idle', () => { map.addListener('idle', () => {
const properties = loadProperties({ this.refreshListings();
bounds: map.getBounds().toUrlValue(),
minPrice: this.state.filters.minPrice});
properties.then(p=> p.text()).then(p => {
const data = JSON.parse(p);
console.log('props', data)
for(const [index, prop] of data.entries()) {
const myLatLng = {lat: prop.loc[0], lng: prop.loc[1]};
const marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: prop.title
});
marker.addListener('click', () => {
console.log('clicking...')
this.dispatch({type: 'VIEW_LISTING_DETAILS', action: {
id: prop.url
}})
});
}
this.dispatch({
type: 'LISTINGS_LOADED',
action: {
listings: data
}
});
})
}); });
} }
@@ -128,6 +98,44 @@ class Main extends React.Component {
}); });
} }
refreshListings() {
const map = this.map;
const properties = loadProperties({
bounds: map.getBounds().toUrlValue(),
minPrice: this.state.filters.minPrice,
maxPrice: this.state.filters.maxPrice,
rooms: this.state.filters.rooms
});
properties.then(p=> p.text()).then(p => {
const data = JSON.parse(p);
console.log('props', data)
for(const [index, prop] of data.entries()) {
const myLatLng = {lat: prop.loc[0], lng: prop.loc[1]};
const marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: prop.title
});
marker.addListener('click', () => {
console.log('clicking...')
this.dispatch({type: 'VIEW_LISTING_DETAILS', action: {
id: prop.url
}})
});
}
this.dispatch({
type: 'LISTINGS_LOADED',
action: {
listings: data
}
});
})
}
onListingClick() { onListingClick() {
this.setState({ this.setState({
listingDetails: true listingDetails: true

View File

@@ -1,9 +1,19 @@
import fetch from 'isomorphic-fetch'; import fetch from 'isomorphic-fetch';
export const loadProperties = ({bounds, minPrice = 0}) => { export const loadProperties = ({
bounds,
minPrice = '',
maxPrice = '',
rooms
}) => {
const allRooms = Object
.keys(rooms)
.filter((v) => rooms[v])
.join(',');
// TODO: handle errors // TODO: handle errors
//return fetch(process.env.API_URL + '/api/search', { //return fetch(process.env.API_URL + '/api/search', {
return fetch(`http://localhost:3001/api/search?bounds=${bounds}&minPrice=${minPrice}`, { return fetch(`http://localhost:3001/api/search?bounds=${bounds}&minPrice=${minPrice}&maxPrice=${maxPrice}&rooms=${allRooms}`, {
//credentials: 'include' //credentials: 'include'
}); });

View File

@@ -1,8 +1,19 @@
const setMaxPrice = ({type, action}, component) => {
component.setState({
filters: {
...component.state.filters,
maxPrice: parseFloat(action.maxPrice),
dirty: true
}
})
}
const setMinPrice = ({type, action}, component) => { const setMinPrice = ({type, action}, component) => {
component.setState({ component.setState({
filters: { filters: {
...component.state.filters, ...component.state.filters,
minPrice: parseFloat(action.minPrice) || 0 minPrice: parseFloat(action.minPrice),
dirty: true
} }
}) })
} }
@@ -73,11 +84,26 @@ const setRooms = ({type, action}, component) => {
[action.rooms]: !prevRooms[action.rooms] [action.rooms]: !prevRooms[action.rooms]
} }
} }
}, () => {
component.refreshListings();
});
}
const updateSearch = ({type, action}, component) => {
console.log('updating search');
component.setState({
filters: {
...component.state.filters,
dirty: false
}
}, () => {
component.refreshListings();
}); });
} }
const handlers = { const handlers = {
'SET_MIN_PRICE': setMinPrice, 'SET_MIN_PRICE': setMinPrice,
'SET_MAX_PRICE': setMaxPrice,
'LISTINGS_LOADED': listingsLoaded, 'LISTINGS_LOADED': listingsLoaded,
'EXPAND_DESCRIPTION': expandDescription, 'EXPAND_DESCRIPTION': expandDescription,
'PREV_IMAGE': prevImage, 'PREV_IMAGE': prevImage,
@@ -85,7 +111,8 @@ const handlers = {
'VIEW_IMAGE': viewImage, 'VIEW_IMAGE': viewImage,
'SEARCH_PLACE_CHANGED': searchPlaceChanged, 'SEARCH_PLACE_CHANGED': searchPlaceChanged,
'SET_ROOMS': setRooms, 'SET_ROOMS': setRooms,
'VIEW_LISTING_DETAILS': viewListingDetails 'VIEW_LISTING_DETAILS': viewListingDetails,
'UPDATE_SEARCH': updateSearch
} }
export const handleMessage = ({type, action}, component) => { export const handleMessage = ({type, action}, component) => {