Sorting & showing date
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -17,6 +17,7 @@
|
|||||||
"babel-preset-es2017": "^6.22.0",
|
"babel-preset-es2017": "^6.22.0",
|
||||||
"body-parser": "^1.17.1",
|
"body-parser": "^1.17.1",
|
||||||
"cookie-parser": "^1.4.3",
|
"cookie-parser": "^1.4.3",
|
||||||
|
"date-fns": "^1.28.2",
|
||||||
"express": "^4.15.2",
|
"express": "^4.15.2",
|
||||||
"isomorphic-fetch": "^2.2.1",
|
"isomorphic-fetch": "^2.2.1",
|
||||||
"mongodb": "^2.2.25"
|
"mongodb": "^2.2.25"
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
import express from 'express'
|
import express from 'express'
|
||||||
import bodyParser from 'body-parser';
|
import bodyParser from 'body-parser';
|
||||||
|
import distanceInWordsToNow from 'date-fns/distance_in_words_to_now';
|
||||||
|
var hr = require('date-fns/locale/hr');
|
||||||
|
|
||||||
var MongoClient = require('mongodb').MongoClient;
|
var MongoClient = require('mongodb').MongoClient;
|
||||||
var ObjectID = require('mongodb').ObjectID;
|
var ObjectID = require('mongodb').ObjectID;
|
||||||
|
|
||||||
@@ -140,9 +143,22 @@ router.get('/search/listings', async (req, res, next) => {
|
|||||||
|
|
||||||
res.header('X-Total-Count', cnt);
|
res.header('X-Total-Count', cnt);
|
||||||
|
|
||||||
|
const getSort = () => {
|
||||||
|
if (sort === 'price-min') {
|
||||||
|
return [['price', 'asc']];
|
||||||
|
} else if (sort === 'price-max') {
|
||||||
|
return [['price', 'desc']];
|
||||||
|
} else if (sort === 'newest') {
|
||||||
|
return [['_id', 'desc']];
|
||||||
|
} else if (sort === 'relevance') {
|
||||||
|
// TODO: figure out what the relevance is
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let all = properties.find(query, {
|
let all = properties.find(query, {
|
||||||
//"sort": [['field1','asc'], ['field2','desc']]
|
//"sort": [['field1','asc'], ['field2','desc']]
|
||||||
"sort": [['price','asc']]
|
"sort": getSort()
|
||||||
});
|
});
|
||||||
|
|
||||||
const isPins = pins === "true";
|
const isPins = pins === "true";
|
||||||
@@ -179,7 +195,10 @@ router.get('/search/listings', async (req, res, next) => {
|
|||||||
price,
|
price,
|
||||||
rooms,
|
rooms,
|
||||||
size,
|
size,
|
||||||
time
|
time: distanceInWordsToNow(
|
||||||
|
new Date(time),
|
||||||
|
{locale: hr}
|
||||||
|
)
|
||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -562,6 +562,10 @@ core-util-is@~1.0.0:
|
|||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||||
|
|
||||||
|
date-fns:
|
||||||
|
version "1.28.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.28.2.tgz#19e4192d68875c0bf7c9537e3f296a8ec64853ef"
|
||||||
|
|
||||||
debug@^2.1.1, debug@^2.2.0, debug@2.6.3:
|
debug@^2.1.1, debug@^2.2.0, debug@2.6.3:
|
||||||
version "2.6.3"
|
version "2.6.3"
|
||||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.3.tgz#0f7eb8c30965ec08c72accfa0130c8b79984141d"
|
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.3.tgz#0f7eb8c30965ec08c72accfa0130c8b79984141d"
|
||||||
|
|||||||
@@ -11,29 +11,17 @@ export default class Listings extends React.Component {
|
|||||||
const node = e.target;
|
const node = e.target;
|
||||||
const offset = node.scrollHeight - node.scrollTop - node.clientHeight;
|
const offset = node.scrollHeight - node.scrollTop - node.clientHeight;
|
||||||
|
|
||||||
//console.log('-----------------');
|
|
||||||
//console.log('node.scrollHeight', node.scrollHeight);
|
|
||||||
//console.log('node.parentNode.scrollTop', node.scrollTop);
|
|
||||||
//console.log('node.parentNode.clientHeight', node.clientHeight);
|
|
||||||
|
|
||||||
if (this.props && this.props.loadingMore) {
|
if (this.props && this.props.loadingMore) {
|
||||||
|
|
||||||
console.log('still loading!');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('scrolling', node.scrollTop, node.scrollHeight, offset);
|
|
||||||
if (offset < 50) {
|
if (offset < 50) {
|
||||||
|
|
||||||
console.log('load more');
|
|
||||||
//this.removeScrollListener();
|
|
||||||
this.props.dispatch({type: 'LOAD_MORE_LISTINGS'});
|
this.props.dispatch({type: 'LOAD_MORE_LISTINGS'});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onListingClick(id) {
|
onListingClick(id) {
|
||||||
|
|
||||||
loadListing(id).then(l => l.text()).then(l => {
|
loadListing(id).then(l => l.text()).then(l => {
|
||||||
console.log('listing loaded', l);
|
console.log('listing loaded', l);
|
||||||
this.props.dispatch({type: 'VIEW_LISTING_DETAILS', action: {
|
this.props.dispatch({type: 'VIEW_LISTING_DETAILS', action: {
|
||||||
@@ -41,14 +29,6 @@ export default class Listings extends React.Component {
|
|||||||
listing: JSON.parse(l)
|
listing: JSON.parse(l)
|
||||||
}});
|
}});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
//this.props.dispatch({
|
|
||||||
//type: 'VIEW_LISTING_DETAILS',
|
|
||||||
//action: {
|
|
||||||
//id
|
|
||||||
//}
|
|
||||||
//});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onMouseEnter (id) {
|
onMouseEnter (id) {
|
||||||
@@ -60,17 +40,6 @@ export default class Listings extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate (prevProps) {
|
|
||||||
console.log('RECEIVING PROPS: ', prevProps, 'new are', this.props);
|
|
||||||
|
|
||||||
//if (this.props.loadingMore != null) {
|
|
||||||
//if (!this.props.loadingMore && prevProps.loadingMore) {
|
|
||||||
//this.attachScrollListener();
|
|
||||||
//console.log('ATTACHING AGAIN', this);
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
renderListings () {
|
renderListings () {
|
||||||
const {listings = (new Map())} = this.props;
|
const {listings = (new Map())} = this.props;
|
||||||
|
|
||||||
@@ -110,7 +79,7 @@ export default class Listings extends React.Component {
|
|||||||
{l.location}
|
{l.location}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="hours-ago">Prije 2 sata</div>
|
<div className="hours-ago">Prije {l.time}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -138,23 +107,30 @@ export default class Listings extends React.Component {
|
|||||||
listings.parentNode.removeEventListener('scroll', this.handleScroll);
|
listings.parentNode.removeEventListener('scroll', this.handleScroll);
|
||||||
}
|
}
|
||||||
|
|
||||||
//componentDidUpdate() {
|
onSortChange (e) {
|
||||||
//console.log('componentDidUpdate');
|
this.props.dispatch({type: 'SORT_CHANGE', action: {
|
||||||
////this.attachScrollListener();
|
sort: e.target.value
|
||||||
//}
|
}});
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
|
||||||
const {listings = (new Map()), totalCount} = this.props;
|
const {listings = (new Map()), totalCount, sort} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref="listings" className="listings">
|
<div ref="listings" className="listings">
|
||||||
<div className="listings-header">
|
<div className="listings-header">
|
||||||
<div className="select-container">
|
<div className="select-container">
|
||||||
<div className="select-group">
|
<div className="select-group">
|
||||||
<select name="listings-type" id="listings-type">
|
<select
|
||||||
<option value="cijena">Cijena: od najmanje</option>
|
value={sort}
|
||||||
<option value="cijena">Cijena: od najvece</option>
|
onChange={this.onSortChange.bind(this)}
|
||||||
|
name="listings-type"
|
||||||
|
id="listings-type">
|
||||||
|
<option value="relevance">Relevantno</option>
|
||||||
|
<option value="newest">Najnovije</option>
|
||||||
|
<option value="price-min">Cijena: od najmanje</option>
|
||||||
|
<option value="price-max">Cijena: od najvece</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ class Main extends React.Component {
|
|||||||
listings: (new Map()),
|
listings: (new Map()),
|
||||||
imageIndex: 0,
|
imageIndex: 0,
|
||||||
page: 0,
|
page: 0,
|
||||||
|
sort: 'relevance',
|
||||||
filters: {
|
filters: {
|
||||||
rooms: {},
|
rooms: {},
|
||||||
category: {}
|
category: {}
|
||||||
@@ -91,7 +92,6 @@ class Main extends React.Component {
|
|||||||
map.addListener('idle', () => {
|
map.addListener('idle', () => {
|
||||||
console.log('idle');
|
console.log('idle');
|
||||||
this.dispatch({type: 'MAP_IDLE'});
|
this.dispatch({type: 'MAP_IDLE'});
|
||||||
//this.refreshListings();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,7 +289,8 @@ class Main extends React.Component {
|
|||||||
minPrice,
|
minPrice,
|
||||||
maxPrice,
|
maxPrice,
|
||||||
category,
|
category,
|
||||||
page: this.state.page
|
page: this.state.page,
|
||||||
|
sort: this.state.sort
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -419,6 +420,7 @@ class Main extends React.Component {
|
|||||||
} else {
|
} else {
|
||||||
children.push(<Filters filters={this.state.filters} dispatch={this.dispatch.bind(this)} onClose={this.onCloseClick.bind(this)}/>);
|
children.push(<Filters filters={this.state.filters} dispatch={this.dispatch.bind(this)} onClose={this.onCloseClick.bind(this)}/>);
|
||||||
children.push(<Listings
|
children.push(<Listings
|
||||||
|
sort={this.state.sort}
|
||||||
totalCount={this.state.totalCount}
|
totalCount={this.state.totalCount}
|
||||||
loadingMore={this.state.loadingMore}
|
loadingMore={this.state.loadingMore}
|
||||||
listings={this.state.listings}
|
listings={this.state.listings}
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ export const loadProperties = ({
|
|||||||
rooms = {},
|
rooms = {},
|
||||||
category = {},
|
category = {},
|
||||||
page = 1,
|
page = 1,
|
||||||
pins = false
|
pins = false,
|
||||||
|
sort = ''
|
||||||
}) => {
|
}) => {
|
||||||
const allRooms = Object
|
const allRooms = Object
|
||||||
.keys(rooms)
|
.keys(rooms)
|
||||||
@@ -31,7 +32,7 @@ export const loadProperties = ({
|
|||||||
|
|
||||||
// TODO: handle errors
|
// TODO: handle errors
|
||||||
//return fetch(process.env.API_URL + '/api/search', {
|
//return fetch(process.env.API_URL + '/api/search', {
|
||||||
let url = `http://localhost:3001/api/search/listings?bounds=${bounds}&minPrice=${minPrice}&maxPrice=${maxPrice}&rooms=${allRooms}&minSize=${minSize}&maxSize=${maxSize}&category=${allCategories}&page=${page}&pins=${pins}`
|
let url = `http://localhost:3001/api/search/listings?bounds=${bounds}&minPrice=${minPrice}&maxPrice=${maxPrice}&rooms=${allRooms}&minSize=${minSize}&maxSize=${maxSize}&category=${allCategories}&page=${page}&pins=${pins}&sort=${sort}`
|
||||||
|
|
||||||
return fetch(url, {
|
return fetch(url, {
|
||||||
//credentials: 'include'
|
//credentials: 'include'
|
||||||
|
|||||||
@@ -246,6 +246,15 @@ const mapIdle = ({type, action}, component) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sortChange = ({type, action}, component) => {
|
||||||
|
component.setState({
|
||||||
|
sort: action.sort,
|
||||||
|
page: 0
|
||||||
|
}, () => {
|
||||||
|
component.refreshListings();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const handlers = {
|
const handlers = {
|
||||||
SET_MIN_PRICE: setMinPrice,
|
SET_MIN_PRICE: setMinPrice,
|
||||||
SET_MAX_PRICE: setMaxPrice,
|
SET_MAX_PRICE: setMaxPrice,
|
||||||
@@ -265,7 +274,8 @@ const handlers = {
|
|||||||
BACK_TO_RESULTS: backToResults,
|
BACK_TO_RESULTS: backToResults,
|
||||||
LOAD_MORE_LISTINGS: loadMoreListings,
|
LOAD_MORE_LISTINGS: loadMoreListings,
|
||||||
MAP_IDLE: mapIdle,
|
MAP_IDLE: mapIdle,
|
||||||
PINS_LOADED: pinsLoaded
|
PINS_LOADED: pinsLoaded,
|
||||||
|
SORT_CHANGE: sortChange
|
||||||
};
|
};
|
||||||
|
|
||||||
export const handleMessage = ({ type, action }, component) => {
|
export const handleMessage = ({ type, action }, component) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user