Filters view on mobile

This commit is contained in:
Edin Dazdarevic
2017-04-17 12:02:02 +02:00
parent 880f7a3f65
commit 746d28d0fd
8 changed files with 138 additions and 23 deletions

2
web/dist/index.html vendored
View File

@@ -4,7 +4,7 @@
<title>KIVI - Najbolji način da pronađeš svoj dom</title> <title>KIVI - Najbolji način da pronađeš svoj dom</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<!--<meta name="viewport" content="width=device-width, initial-scale=1">--> <!--<meta name="viewport" content="width=device-width, initial-scale=1">-->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css"> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">

45
web/dist/main.css vendored
View File

@@ -170,6 +170,12 @@ html {
border-radius: 5px 0 0 5px; border-radius: 5px 0 0 5px;
} }
.view-type-right.selected,
.view-type-left.selected {
background-color: #b6d53b;
color: #fff;
}
.view-type-right { .view-type-right {
border-radius: 0px 5px 5px 0; border-radius: 0px 5px 5px 0;
margin-left: -1px; margin-left: -1px;
@@ -179,8 +185,13 @@ html {
position: fixed; position: fixed;
bottom: 0; bottom: 0;
left: 0; left: 0;
width: 100%; width: 99%;
height: 50px; height: 50px;
display: flex;
text-align: center;
padding-left: 10px;
padding-right: 0;
align-items: baseline;
} }
.filter-title { .filter-title {
@@ -256,7 +267,7 @@ html {
} }
.filter-btn.more-filters { .filter-btn.more-filters {
float: right; /*float: right;*/
width: 145px; width: 145px;
} }
@@ -459,11 +470,39 @@ html {
} }
} }
.listings-filter {
display: none;
}
@media (max-width : 768px) { @media (max-width : 768px) {
.listings-count { .listings-count {
display: none; display: none;
} }
.listings-filter {
right: 5px;
min-width: 150px;
/*text-align: right;*/
/*display: block;*/
display: inline-block;
border: 1px solid #b6d53b;
padding: 8px 12px;
cursor: pointer;
margin: 0 6px 6px 0;
color: #2d3138;
font-size: 14px;
letter-spacing: .4px;
border-radius: 3px;
user-select: none;
touch-action: manipulation;
vertical-align: middle;
text-align: center;
flex-grow: 1;
text-overflow: ellipsis;
overflow: hidden;
}
#right { #right {
width: 100%; width: 100%;
float: none; float: none;
@@ -540,7 +579,7 @@ html {
.filter-row { .filter-row {
display: block; display: block;
padding: 11px 0; padding: 5px 0;
border: 0; border: 0;
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -68,8 +68,14 @@ export default class Filters extends React.Component {
this.props.dispatch({type: 'SET_CATEGORY', action: {category}}) this.props.dispatch({type: 'SET_CATEGORY', action: {category}})
} }
onRefreshClick () { onRefreshClick (closeFilters) {
this.updateSearch() this.updateSearch()
if (closeFilters) {
this.props.dispatch({
type: 'CLOSE_FILTERS'
})
}
} }
onKeyPress (e) { onKeyPress (e) {
@@ -95,6 +101,25 @@ export default class Filters extends React.Component {
this.props.dispatch({type: 'UPDATE_SEARCH'}) this.props.dispatch({type: 'UPDATE_SEARCH'})
} }
onResetSearch (e) {
this.props.dispatch({
type: 'UPDATE_ROUTE',
action: {
params: {
minPrice: '',
maxPrice: '',
minSize: '',
maxSize: '',
rooms: '',
category: ''
}
}
})
this.props.dispatch({
type: 'RESET_FILTERS'
})
}
render () { render () {
const {filters} = this.props const {filters} = this.props
const selectedRooms = val => filters.rooms[val] ? 'selected' : '' const selectedRooms = val => filters.rooms[val] ? 'selected' : ''
@@ -249,7 +274,11 @@ export default class Filters extends React.Component {
</div> </div>
</div> </div>
<div className="clear-both" /> <div className="clear-both" />
<div className="filter-bottom" /> <div className="filter-bottom">
<div onClick={this.onResetSearch.bind(this)} className="filter-btn">Poništi</div>
<div onClick={this.onRefreshClick.bind(this, true)} className="filter-btn">Potvrdi</div>
</div>
</div> </div>
) )
} }

View File

@@ -157,6 +157,14 @@ export default class Listings extends React.Component {
}) })
} }
onFiltersClick (e) {
e.preventDefault()
this.props.dispatch({
type: 'OPEN_FILTERS'
})
}
render () { render () {
const {listings = new Map(), totalCount, sort} = this.props const {listings = new Map(), totalCount, sort} = this.props
@@ -181,6 +189,12 @@ export default class Listings extends React.Component {
<div className="listings-count"> <div className="listings-count">
{totalCount} rezultata {totalCount} rezultata
</div> </div>
<div
onClick={this.onFiltersClick.bind(this)}
className="listings-filter">
Filteri
</div>
</div> </div>
<div className="listings-items"> <div className="listings-items">

View File

@@ -166,8 +166,12 @@ class Main extends React.Component {
}) })
control.addEventListener('click', e => { control.addEventListener('click', e => {
this.setState({ //this.setState({
mapClicked: true //mapClicked: true
//})
this.dispatch({
type: 'OPEN_FILTERS'
}) })
}) })
@@ -183,18 +187,22 @@ class Main extends React.Component {
} }
onCloseClick (e) { onCloseClick (e) {
if (this.state.mapClicked) { if (this.state.filtersOpen) {
setTimeout( console.log('FILTERS WERE OPEN')
() => { //setTimeout(
google.maps.event.trigger(this.map, 'resize') //() => {
}, //google.maps.event.trigger(this.map, 'resize')
100 //},
) //100
//)
} }
this.setState({ this.dispatch({
mapClicked: false type: 'CLOSE_FILTERS'
}) })
//this.setState({
//mapClicked: false
//})
} }
findMarker (id) { findMarker (id) {
@@ -578,12 +586,13 @@ class Main extends React.Component {
let leftClass = 'left-base' let leftClass = 'left-base'
let rightClass = 'right-base' let rightClass = 'right-base'
if (this.state.listingId || this.state.mapClicked) { if (this.state.listingId || this.state.filtersOpen) {
leftClass = this.addAbsoluteLeftInRender ? 'left-absolute' : '' leftClass = this.addAbsoluteLeftInRender ? 'left-absolute' : ''
rightClass = 'right-shown' rightClass = 'right-shown'
} }
const {contactFormOpen} = this.state const {contactFormOpen} = this.state
const isMapView = this.state.mobileView === 'MAP'
return ( return (
<div id="container"> <div id="container">
@@ -601,10 +610,10 @@ class Main extends React.Component {
type="text" type="text"
/> />
<div className="view-types"> <div className="view-types">
<a onClick={this.onMobileListViewClick.bind(this)}className="view-type-left"> <a onClick={this.onMobileListViewClick.bind(this)} className={!isMapView ? "view-type-left selected": "view-type-left"}>
<i className="btn-select-map fa fa-list" /> <i className="btn-select-map fa fa-list" />
</a> </a>
<a onClick={this.onMobileMapViewClick.bind(this)} className="view-type-right"> <a onClick={this.onMobileMapViewClick.bind(this)} className={isMapView ? "view-type-right selected": "view-type-right"}>
<i className="view-type-map-icon fa fa-map-marker" /> <i className="view-type-map-icon fa fa-map-marker" />
</a> </a>
</div> </div>
@@ -616,7 +625,7 @@ class Main extends React.Component {
<div id="left" style={leftStyle} className={leftClass}> <div id="left" style={leftStyle} className={leftClass}>
{this.state.mobileView === 'LIST' && !this.state.listingDetails && {this.state.mobileView === 'LIST' && !this.state.listingDetails &&
<div className="map-list-view"> <div className={ this.state.filtersOpen ? "map-list-view hide": "map-list-view" }>
<Listings <Listings
sort={this.state.sort} sort={this.state.sort}
totalCount={this.state.totalCount} totalCount={this.state.totalCount}

View File

@@ -1,7 +1,7 @@
import fetch from 'isomorphic-fetch' import fetch from 'isomorphic-fetch'
//const BASE_URL = 'localhost'; //const BASE_URL = 'localhost';
const BASE_URL = '192.168.0.13'; const BASE_URL = '192.168.1.117';
export const saveContactRequest = (listingId, params) => { export const saveContactRequest = (listingId, params) => {

View File

@@ -372,6 +372,27 @@ const mobileListView = ({type, action}, component) => {
}) })
} }
const openFilters = ({type, action}, component) => {
component.setState({
filtersOpen: true
})
}
const closeFilters = ({type, action}, component) => {
component.setState({
filtersOpen: false
})
}
const resetFilters = ({type, action}, component) => {
component.setState({
filters: {
rooms: {},
category: {}
}
})
}
const handlers = { const handlers = {
SET_MIN_PRICE: setMinPrice, SET_MIN_PRICE: setMinPrice,
SET_MAX_PRICE: setMaxPrice, SET_MAX_PRICE: setMaxPrice,
@@ -401,7 +422,10 @@ const handlers = {
SUBMIT_CONTACT_END: submitContactEnd, SUBMIT_CONTACT_END: submitContactEnd,
INVALID_CONTACT: invalidContact, INVALID_CONTACT: invalidContact,
MOBILE_MAP_VIEW: mobileMapView, MOBILE_MAP_VIEW: mobileMapView,
MOBILE_LIST_VIEW: mobileListView MOBILE_LIST_VIEW: mobileListView,
OPEN_FILTERS: openFilters,
CLOSE_FILTERS: closeFilters,
RESET_FILTERS: resetFilters
} }
export const handleMessage = ({type, action}, component) => { export const handleMessage = ({type, action}, component) => {