diff --git a/web/components/Main.js b/web/components/Main.js
index d937f70..09b0c5b 100644
--- a/web/components/Main.js
+++ b/web/components/Main.js
@@ -14,7 +14,6 @@ class Main extends React.Component {
listings: (new Map()),
imageIndex: 0,
filters: {
- minPrice: 0,
rooms: {}
}
};
@@ -100,40 +99,44 @@ class Main extends React.Component {
refreshListings() {
const map = this.map;
+ const {rooms, minSize, maxSize, minPrice, maxPrice} = this.state.filters;
+
const properties = loadProperties({
bounds: map.getBounds().toUrlValue(),
- minPrice: this.state.filters.minPrice,
- maxPrice: this.state.filters.maxPrice,
- rooms: this.state.filters.rooms
+ rooms,
+ minSize,
+ maxSize,
+ minPrice,
+ maxPrice
});
- 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]};
+ 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
- }
+ 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() {
diff --git a/web/dist/index.html b/web/dist/index.html
index 251c1c5..5666bf3 100644
--- a/web/dist/index.html
+++ b/web/dist/index.html
@@ -1,6 +1,7 @@
+
KIVI - Najbolji način da pronađeš svoj dom
diff --git a/web/dist/main.css b/web/dist/main.css
index 05aa0a3..899f3db 100644
--- a/web/dist/main.css
+++ b/web/dist/main.css
@@ -581,7 +581,7 @@ html {
letter-spacing: .26px;
border-radius: 3px;
background: #fff;
- color: #5ab8f8;
+ color: #51bc6a;
cursor: pointer;
}
@@ -783,3 +783,14 @@ html {
}
}
+
+.fa-refresh-custom {
+ font-size: 1.5em;
+ cursor: pointer;
+ color: #b6d53b;
+ padding: 5px;
+}
+
+.hide {
+ display: none;
+}
diff --git a/web/lib/api.js b/web/lib/api.js
index 6405ded..9e9851f 100644
--- a/web/lib/api.js
+++ b/web/lib/api.js
@@ -4,6 +4,8 @@ export const loadProperties = ({
bounds,
minPrice = '',
maxPrice = '',
+ minSize = '',
+ maxSize = '',
rooms
}) => {
const allRooms = Object
@@ -13,7 +15,7 @@ export const loadProperties = ({
// TODO: handle errors
//return fetch(process.env.API_URL + '/api/search', {
- return fetch(`http://localhost:3001/api/search?bounds=${bounds}&minPrice=${minPrice}&maxPrice=${maxPrice}&rooms=${allRooms}`, {
+ return fetch(`http://localhost:3001/api/search?bounds=${bounds}&minPrice=${minPrice}&maxPrice=${maxPrice}&rooms=${allRooms}&minSize=${minSize}&maxSize=${maxSize}`, {
//credentials: 'include'
});
diff --git a/web/lib/handlers.js b/web/lib/handlers.js
index 4c69f0f..14c1d5f 100644
--- a/web/lib/handlers.js
+++ b/web/lib/handlers.js
@@ -1,125 +1,159 @@
-const setMaxPrice = ({type, action}, component) => {
+const setMaxPrice = ({ type, action }, component) => {
+ const maxPrice = parseFloat(action.maxPrice);
component.setState({
filters: {
...component.state.filters,
- maxPrice: parseFloat(action.maxPrice),
- dirty: true
+ maxPrice: isNaN(maxPrice) ? undefined : maxPrice,
+ priceDirty: true
}
- })
-}
+ });
+};
-const setMinPrice = ({type, action}, component) => {
+const setMinPrice = ({ type, action }, component) => {
+ const minPrice = parseFloat(action.minPrice);
component.setState({
filters: {
...component.state.filters,
- minPrice: parseFloat(action.minPrice),
- dirty: true
+ minPrice: isNaN(minPrice) ? undefined : minPrice,
+ priceDirty: true
}
- })
-}
+ });
+};
-const viewListingDetails= ({type, action}, component) => {
+const setMinSize = ({ type, action }, component) => {
+ const minSize = parseFloat(action.minSize);
+ component.setState({
+ filters: {
+ ...component.state.filters,
+ minSize: isNaN(minSize) ? undefined : minSize,
+ sizeDirty: true
+ }
+ });
+};
+
+const setMaxSize = ({ type, action }, component) => {
+ const maxSize = parseFloat(action.maxSize);
+ component.setState({
+ filters: {
+ ...component.state.filters,
+ maxSize: isNaN(maxSize) ? undefined : maxSize,
+ sizeDirty: true
+ }
+ });
+};
+
+const viewListingDetails = ({ type, action }, component) => {
component.setState({
listingDetails: true,
listingId: action.id,
descriptionExpanded: false,
imageIndex: 0
- })
-}
+ });
+};
-const listingsLoaded = ({type, action}, component) => {
+const listingsLoaded = ({ type, action }, component) => {
const currentListings = new Map(); //component.state.listings;
- for(const listing of action.listings) {
- currentListings.set(listing.url, listing)
+ for (const listing of action.listings) {
+ currentListings.set(listing.url, listing);
}
component.setState({
listings: currentListings
});
-}
+};
-const expandDescription = ({type, action}, component) => {
+const expandDescription = ({ type, action }, component) => {
component.setState({
descriptionExpanded: true
});
-}
+};
-const prevImage = ({type, action}, component) => {
+const prevImage = ({ type, action }, component) => {
const index = component.state.imageIndex;
if (index > 0) {
component.setState({
imageIndex: index - 1
});
}
-}
+};
-const nextImage = ({type, action}, component) => {
+const nextImage = ({ type, action }, component) => {
const index = component.state.imageIndex;
component.setState({
imageIndex: index + 1
});
-}
+};
-const viewImage = ({type, action}, component) => {
+const viewImage = ({ type, action }, component) => {
component.setState({
imageIndex: action.index
});
-}
+};
-const searchPlaceChanged = ({type, action}, component) => {
+const searchPlaceChanged = ({ type, action }, component) => {
component.setState({
listingDetails: false
});
-}
+};
-const setRooms = ({type, action}, component) => {
- const prevRooms = (component.state.filters.rooms || {});
+const setRooms = ({ type, action }, component) => {
+ const prevRooms = component.state.filters.rooms || {};
+ console.log('BERORE ROOMS');
- component.setState({
- filters: {
- ...component.state.filters,
- rooms: {
- ...prevRooms,
- [action.rooms]: !prevRooms[action.rooms]
+ component.setState(
+ {
+ filters: {
+ ...component.state.filters,
+ rooms: {
+ ...prevRooms,
+ [action.rooms]: !prevRooms[action.rooms]
+ }
}
+ },
+ () => {
+ console.log('after rooms');
+ component.refreshListings();
}
- }, () => {
- component.refreshListings();
- });
-}
+ );
+};
-const updateSearch = ({type, action}, component) => {
- console.log('updating search');
- component.setState({
- filters: {
- ...component.state.filters,
- dirty: false
+const updateSearch = ({ type, action }, component) => {
+ console.log("updating search");
+ component.setState(
+ {
+ filters: {
+ ...component.state.filters,
+ sizeDirty: false,
+ priceDirty: false
+ }
+ },
+ () => {
+ component.refreshListings();
}
- }, () => {
- component.refreshListings();
- });
-}
+ );
+};
const handlers = {
- 'SET_MIN_PRICE': setMinPrice,
- 'SET_MAX_PRICE': setMaxPrice,
- 'LISTINGS_LOADED': listingsLoaded,
- 'EXPAND_DESCRIPTION': expandDescription,
- 'PREV_IMAGE': prevImage,
- 'NEXT_IMAGE': nextImage,
- 'VIEW_IMAGE': viewImage,
- 'SEARCH_PLACE_CHANGED': searchPlaceChanged,
- 'SET_ROOMS': setRooms,
- 'VIEW_LISTING_DETAILS': viewListingDetails,
- 'UPDATE_SEARCH': updateSearch
-}
-
-export const handleMessage = ({type, action}, component) => {
+ SET_MIN_PRICE: setMinPrice,
+ SET_MAX_PRICE: setMaxPrice,
+ SET_MIN_SIZE: setMinSize,
+ SET_MAX_SIZE: setMaxSize,
+ LISTINGS_LOADED: listingsLoaded,
+ EXPAND_DESCRIPTION: expandDescription,
+ PREV_IMAGE: prevImage,
+ NEXT_IMAGE: nextImage,
+ VIEW_IMAGE: viewImage,
+ SEARCH_PLACE_CHANGED: searchPlaceChanged,
+ SET_ROOMS: setRooms,
+ VIEW_LISTING_DETAILS: viewListingDetails,
+ UPDATE_SEARCH: updateSearch
+};
+export const handleMessage = ({ type, action }, component) => {
if (!handlers[type]) {
- throw new `Unhandled message: ${type}`;
+ throw new `Unhandled message: ${type}`();
}
- return handlers[type]({type, action}, component);
-}
+ return handlers[type]({ type, action }, component);
+};
diff --git a/web/lib/helpers.js b/web/lib/helpers.js
new file mode 100644
index 0000000..25ddffb
--- /dev/null
+++ b/web/lib/helpers.js
@@ -0,0 +1,14 @@
+export const formatPrice = (p) => {
+ if (p === -1) {
+ return 'Po dogovoru'
+ }
+
+ return p.toLocaleString('bs') + ' KM';
+}
+
+export const formatFilterNumber = (num) => {
+ if (isNaN(num) || num == null) {
+ return ''
+ }
+ return num;
+}
diff --git a/web/package.json b/web/package.json
index 7a8995d..b406aed 100644
--- a/web/package.json
+++ b/web/package.json
@@ -19,6 +19,7 @@
"babel-loader": "^6.2.7",
"babel-preset-es2015": "^6.18.0",
"babel-preset-react": "^6.16.0",
+ "prettier": "^0.22.0",
"webpack": "^1.13.3",
"webpack-dev-server": "^1.16.2"
}
diff --git a/web/yarn.lock b/web/yarn.lock
index c57e84e..17a1e6d 100644
--- a/web/yarn.lock
+++ b/web/yarn.lock
@@ -42,6 +42,12 @@ ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
+ansi-styles@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.0.0.tgz#5404e93a544c4fec7f048262977bebfe3155e0c1"
+ dependencies:
+ color-convert "^1.0.0"
+
anymatch@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507"
@@ -104,6 +110,14 @@ assert@^1.1.1:
dependencies:
util "0.10.3"
+ast-types@0.8.18:
+ version "0.8.18"
+ resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.8.18.tgz#c8b98574898e8914e9d8de74b947564a9fe929af"
+
+ast-types@0.9.4:
+ version "0.9.4"
+ resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.4.tgz#410d1f81890aeb8e0a38621558ba5869ae53c91b"
+
async-each@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d"
@@ -132,7 +146,7 @@ aws4@^1.2.1:
version "1.6.0"
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
-babel-code-frame@^6.22.0:
+babel-code-frame@^6.22.0, babel-code-frame@6.22.0:
version "6.22.0"
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4"
dependencies:
@@ -695,6 +709,10 @@ babylon@^6.11.0, babylon@^6.15.0:
version "6.16.1"
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.16.1.tgz#30c5a22f481978a9e7f8cdfdf496b11d94b404d3"
+babylon@6.15.0:
+ version "6.15.0"
+ resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.15.0.tgz#ba65cfa1a80e1759b0e89fb562e27dccae70348e"
+
balanced-match@^0.4.1:
version "0.4.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
@@ -795,7 +813,7 @@ center-align@^0.1.1:
align-text "^0.1.3"
lazy-cache "^1.0.3"
-chalk@^1.1.0:
+chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3, chalk@1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
dependencies:
@@ -840,6 +858,20 @@ code-point-at@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
+color-convert@^1.0.0:
+ version "1.9.0"
+ resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a"
+ dependencies:
+ color-name "^1.1.1"
+
+color-name@^1.1.1:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.2.tgz#5c8ab72b64bd2215d617ae9559ebb148475cf98d"
+
+colors@>=0.6.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
+
combined-stream@^1.0.5, combined-stream@~1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
@@ -1044,7 +1076,7 @@ escape-string-regexp@^1.0.2:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
-esutils@^2.0.0, esutils@^2.0.2:
+esutils@^2.0.0, esutils@^2.0.2, esutils@2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
@@ -1190,6 +1222,14 @@ find-up@^1.0.0:
path-exists "^2.0.0"
pinkie-promise "^2.0.0"
+flow-parser@0.40.0:
+ version "0.40.0"
+ resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.40.0.tgz#b3444742189093323c4319c4fe9d35391f46bcbc"
+ dependencies:
+ ast-types "0.8.18"
+ colors ">=0.6.2"
+ minimist ">=0.2.0"
+
for-in@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
@@ -1261,6 +1301,10 @@ gauge@~2.7.1:
strip-ansi "^3.0.1"
wide-align "^1.1.0"
+get-stdin@5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398"
+
getpass@^0.1.1:
version "0.1.6"
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.6.tgz#283ffd9fc1256840875311c1b60e8c40187110e6"
@@ -1280,7 +1324,7 @@ glob-parent@^2.0.0:
dependencies:
is-glob "^2.0.0"
-glob@^7.0.5:
+glob@^7.0.5, glob@7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8"
dependencies:
@@ -1533,6 +1577,22 @@ isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
+jest-matcher-utils@^19.0.0:
+ version "19.0.0"
+ resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-19.0.0.tgz#5ecd9b63565d2b001f61fbf7ec4c7f537964564d"
+ dependencies:
+ chalk "^1.1.3"
+ pretty-format "^19.0.0"
+
+jest-validate@19.0.0:
+ version "19.0.0"
+ resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-19.0.0.tgz#8c6318a20ecfeaba0ba5378bfbb8277abded4173"
+ dependencies:
+ chalk "^1.1.1"
+ jest-matcher-utils "^19.0.0"
+ leven "^2.0.0"
+ pretty-format "^19.0.0"
+
jodid25519@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967"
@@ -1600,6 +1660,10 @@ lazy-cache@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e"
+leven@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580"
+
loader-utils@^0.2.11, loader-utils@^0.2.16:
version "0.2.17"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348"
@@ -1691,7 +1755,7 @@ minimatch@^3.0.0, minimatch@^3.0.2:
dependencies:
brace-expansion "^1.0.0"
-minimist@^1.2.0:
+minimist@^1.2.0, minimist@>=0.2.0, minimist@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
@@ -1930,6 +1994,27 @@ preserve@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
+prettier:
+ version "0.22.0"
+ resolved "https://registry.yarnpkg.com/prettier/-/prettier-0.22.0.tgz#7b37c4480d0858180407e5a8e13f0f47da7385d2"
+ dependencies:
+ ast-types "0.9.4"
+ babel-code-frame "6.22.0"
+ babylon "6.15.0"
+ chalk "1.1.3"
+ esutils "2.0.2"
+ flow-parser "0.40.0"
+ get-stdin "5.0.1"
+ glob "7.1.1"
+ jest-validate "19.0.0"
+ minimist "1.2.0"
+
+pretty-format@^19.0.0:
+ version "19.0.0"
+ resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-19.0.0.tgz#56530d32acb98a3fa4851c4e2b9d37b420684c84"
+ dependencies:
+ ansi-styles "^3.0.0"
+
private@^0.1.6:
version "0.1.7"
resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1"