From 49e9e2fdfb8189c123120bc3a567525f6e039264 Mon Sep 17 00:00:00 2001 From: Edin Dazdarevic Date: Tue, 4 Apr 2017 04:36:52 +0200 Subject: [PATCH] Make price filtering work --- backend/build/server.js | 92 +++++++++++++++++++++------------------ backend/server.js | 73 ++++++++++++++++--------------- web/components/Filters.js | 11 ++++- web/components/Main.js | 70 ++++++++++++++++------------- web/lib/api.js | 14 +++++- web/lib/handlers.js | 31 ++++++++++++- 6 files changed, 179 insertions(+), 112 deletions(-) diff --git a/backend/build/server.js b/backend/build/server.js index f585d34..f6aa941 100644 --- a/backend/build/server.js +++ b/backend/build/server.js @@ -79,7 +79,7 @@ router.get('/search', function () { 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) { 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, { - price: { - "$gte": parseFloat(minPrice), - "$ne": -1 - } + price: price }); } - if (maxPrice) { - query = Object.assign(query, { - price: { - "$lte": parseFloat(maxPrice), - "$ne": -1 + if (rooms) { + allRooms = rooms.split(','); + or = allRooms.map(function (val) { + if (val === '4+') { + 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, { - rooms: { - "$gte": 4 - } - }); - } else if (rooms) { - query = Object.assign(query, { - rooms: parseFloat(rooms) + size: size }); } - if (minSize) { - query = Object.assign(query, { - size: { - "$gte": parseFloat(minSize) - } - }); - } - - if (maxSize) { - query = Object.assign(query, { - size: { - "$lte": parseFloat(maxSize) - } - }); - } - - _context.next = 19; + console.log('QUERY: ', query); + _context.next = 18; return properties.find(query).toArray(); - case 19: + case 18: all = _context.sent; res.json(all); res.end(); - _context.next = 28; + _context.next = 27; break; - case 24: - _context.prev = 24; + case 23: + _context.prev = 23; _context.t0 = _context['catch'](0); console.log('error:', _context.t0); next(_context.t0); - case 28: + case 27: case 'end': return _context.stop(); } } - }, _callee, undefined, [[0, 24]]); + }, _callee, undefined, [[0, 23]]); })); return function (_x, _x2, _x3) { diff --git a/backend/server.js b/backend/server.js index 093b5e6..79ad61d 100644 --- a/backend/server.js +++ b/backend/server.js @@ -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, { - price: { - "$gte": parseFloat(minPrice), - "$ne": -1 - } + price }); } - if (maxPrice) { - query = Object.assign(query, { - price: { - "$lte": parseFloat(maxPrice), - "$ne": -1 + if (rooms) { + const allRooms = rooms.split(','); + const or = allRooms.map(val => { + if (val === '4+') { + 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, { - rooms: { - "$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) - } + size }); } + console.log('QUERY: ', query); const all = await properties.find(query).toArray(); res.json(all); diff --git a/web/components/Filters.js b/web/components/Filters.js index 2a427c1..269fa1f 100644 --- a/web/components/Filters.js +++ b/web/components/Filters.js @@ -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) { 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}}); } + onRefreshClick () { + this.props.dispatch({type: 'UPDATE_SEARCH'}); + } + render() { const {filters} = this.props; @@ -38,7 +46,8 @@ export default class Filters extends React.Component {
- izmedju KM i + izmedju KM i + {this.props.filters.dirty? : null}
diff --git a/web/components/Main.js b/web/components/Main.js index a8f5ae8..d937f70 100644 --- a/web/components/Main.js +++ b/web/components/Main.js @@ -82,37 +82,7 @@ class Main extends React.Component { this.map = map; map.addListener('idle', () => { - const properties = loadProperties({ - 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 - } - }); - }) + this.refreshListings(); }); } @@ -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() { this.setState({ listingDetails: true diff --git a/web/lib/api.js b/web/lib/api.js index ae37b75..6405ded 100644 --- a/web/lib/api.js +++ b/web/lib/api.js @@ -1,9 +1,19 @@ 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 //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' }); diff --git a/web/lib/handlers.js b/web/lib/handlers.js index 6f2dcb7..4c69f0f 100644 --- a/web/lib/handlers.js +++ b/web/lib/handlers.js @@ -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) => { component.setState({ 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] } } + }, () => { + component.refreshListings(); + }); +} + +const updateSearch = ({type, action}, component) => { + console.log('updating search'); + component.setState({ + filters: { + ...component.state.filters, + dirty: false + } + }, () => { + component.refreshListings(); }); } const handlers = { 'SET_MIN_PRICE': setMinPrice, + 'SET_MAX_PRICE': setMaxPrice, 'LISTINGS_LOADED': listingsLoaded, 'EXPAND_DESCRIPTION': expandDescription, 'PREV_IMAGE': prevImage, @@ -85,7 +111,8 @@ const handlers = { 'VIEW_IMAGE': viewImage, 'SEARCH_PLACE_CHANGED': searchPlaceChanged, 'SET_ROOMS': setRooms, - 'VIEW_LISTING_DETAILS': viewListingDetails + 'VIEW_LISTING_DETAILS': viewListingDetails, + 'UPDATE_SEARCH': updateSearch } export const handleMessage = ({type, action}, component) => {