215 lines
5.1 KiB
JavaScript
215 lines
5.1 KiB
JavaScript
import React from 'react'
|
|
import {findDOMNode} from 'react-dom'
|
|
import {formatPrice, listingImageUrl} from '../lib/helpers'
|
|
import {loadListing} from '../lib/api'
|
|
|
|
export default class Listings extends React.Component {
|
|
constructor (props) {
|
|
super(props)
|
|
|
|
this.handleTouchMove = e => {
|
|
const node = e.target
|
|
const offset = node.scrollHeight - node.scrollTop - node.clientHeight
|
|
console.log('HANDLE TOUCH MOVE OFFSET', offset)
|
|
}
|
|
|
|
this.handleScroll = e => {
|
|
console.log('scrolling');
|
|
const node = e.target
|
|
const offset = node.scrollHeight - node.scrollTop - node.clientHeight
|
|
|
|
if (this.props && this.props.loadingMore) {
|
|
return
|
|
}
|
|
|
|
if (offset < 50) {
|
|
this.props.dispatch({type: 'LOAD_MORE_LISTINGS'})
|
|
}
|
|
}
|
|
}
|
|
|
|
onListingClick (id) {
|
|
loadListing(id).then(l => l.text()).then(l => {
|
|
this.props.dispatch({
|
|
type: 'UPDATE_ROUTE',
|
|
action: {
|
|
toDispatch: {
|
|
type: 'VIEW_LISTING_DETAILS',
|
|
action: {
|
|
id,
|
|
listing: JSON.parse(l)
|
|
}
|
|
},
|
|
params: {
|
|
listingId: id
|
|
}
|
|
}
|
|
})
|
|
|
|
this.props.dispatch({
|
|
type: 'VIEW_LISTING_DETAILS',
|
|
action: {
|
|
id,
|
|
listing: JSON.parse(l)
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
onMouseEnter (id) {
|
|
this.props.dispatch({
|
|
type: 'ON_LISTING_MOUSE_OVER',
|
|
action: {
|
|
id
|
|
}
|
|
})
|
|
}
|
|
|
|
renderListings () {
|
|
const {listings = new Map()} = this.props
|
|
|
|
if (listings.size === 0) {
|
|
return (
|
|
<div className="listings-no-results">
|
|
<i className="fa fa-frown-o fa-frown-o-custom" aria-hidden="true" />
|
|
|
|
<h4>Nema rezultata</h4>
|
|
<h5>
|
|
Nema oglasa koji ispunjavaju vaše uslove pretrage.
|
|
</h5>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
const rendered = []
|
|
|
|
for (const l of listings.values()) {
|
|
const {images} = l
|
|
|
|
rendered.push(
|
|
<div
|
|
key={l._id}
|
|
onMouseEnter={this.onMouseEnter.bind(this, l._id)}
|
|
className="property-list-item"
|
|
onClick={this.onListingClick.bind(this, l._id)}
|
|
>
|
|
<div className="pli-image">
|
|
<img src={listingImageUrl(images[0])} alt="" />
|
|
</div>
|
|
<div className="pli-details">
|
|
<div className="price">{formatPrice(l.price)}</div>
|
|
<div className="description">
|
|
{l.rooms ? `${l.rooms} sobe, ` : null}
|
|
{l.size ? `${l.size}m2` : null}
|
|
</div>
|
|
<div className="address">
|
|
<div className="street">
|
|
{l.address}
|
|
</div>
|
|
<div className="location">
|
|
{l.location}
|
|
</div>
|
|
</div>
|
|
<div className="hours-ago">Prije {l.time}</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
return rendered
|
|
}
|
|
|
|
componentDidMount () {
|
|
this.attachScrollListener()
|
|
}
|
|
|
|
componentWillUnmount () {
|
|
this.removeScrollListener()
|
|
}
|
|
|
|
attachScrollListener () {
|
|
const listings = findDOMNode(this.refs.listings)
|
|
listings.parentNode.addEventListener('scroll', this.handleScroll)
|
|
listings.parentNode.addEventListener('touchmove', this.handleTouchMove)
|
|
}
|
|
|
|
removeScrollListener () {
|
|
const listings = findDOMNode(this.refs.listings)
|
|
listings.parentNode.removeEventListener('scroll', this.handleScroll)
|
|
listings.parentNode.removeEventListener('touchmove', this.handleTouchMove)
|
|
}
|
|
|
|
onSortChange (e) {
|
|
this.props.dispatch({
|
|
type: 'UPDATE_ROUTE',
|
|
action: {
|
|
params: {
|
|
sort: e.target.value
|
|
}
|
|
}
|
|
})
|
|
|
|
this.props.dispatch({
|
|
type: 'SORT_CHANGE',
|
|
action: {
|
|
sort: e.target.value
|
|
}
|
|
})
|
|
}
|
|
|
|
onFiltersClick (e) {
|
|
e.preventDefault()
|
|
|
|
this.props.dispatch({
|
|
type: 'OPEN_FILTERS'
|
|
})
|
|
}
|
|
|
|
resultsString (count) {
|
|
if (count == "1") {
|
|
return "rezultat"
|
|
}
|
|
|
|
return "rezultata"
|
|
}
|
|
|
|
render () {
|
|
const {listings = new Map(), totalCount, sort} = this.props
|
|
|
|
return (
|
|
<div ref="listings" className="listings">
|
|
<div className="listings-header">
|
|
<div className="select-container">
|
|
<div className="select-group">
|
|
<select
|
|
value={sort}
|
|
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>
|
|
</div>
|
|
</div>
|
|
<div className="listings-count">
|
|
{totalCount} {this.resultsString(totalCount)}
|
|
</div>
|
|
|
|
<div
|
|
onClick={this.onFiltersClick.bind(this)}
|
|
className="listings-filter">
|
|
Filteri
|
|
</div>
|
|
</div>
|
|
|
|
<div className="listings-items">
|
|
{this.renderListings()}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
}
|