Compare commits
1 Commits
welcome-po
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aeba6fdc2f |
@@ -752,7 +752,7 @@ router.get('/search/listings', function () {
|
||||
//Get only ads with location
|
||||
|
||||
query = Object.assign(query, {
|
||||
hasMap: true
|
||||
has_map: true
|
||||
});
|
||||
|
||||
//AND
|
||||
|
||||
@@ -97,7 +97,7 @@ router.get ('/search/listings', async (req, res, next) => {
|
||||
|
||||
//Get only ads with location
|
||||
query = Object.assign (query, {
|
||||
hasMap: true,
|
||||
has_map: true,
|
||||
});
|
||||
|
||||
//AND
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export const BASE_URL = '138.68.67.31';
|
||||
@@ -1 +0,0 @@
|
||||
RENTAL_FROM_PAGE=1 RENTAL_TO_PAGE=45 PROSTOR_FROM_PAGE=1 PROSTOR_TO_PAGE=26 MONGO_URL=mongodb://localhost:27017/kivi node /home/bilal/kivi/crawler/build/crawler.js > /home/bilal/crawler.log
|
||||
27652
web/dist/app.bundle.js
vendored
BIN
web/dist/static/images/rent_0.png
vendored
|
Before Width: | Height: | Size: 5.0 KiB |
BIN
web/dist/static/images/rent_0_mobile.png
vendored
|
Before Width: | Height: | Size: 5.0 KiB |
BIN
web/dist/static/images/rent_1.png
vendored
|
Before Width: | Height: | Size: 7.1 KiB |
BIN
web/dist/static/images/rent_1_mobile.png
vendored
|
Before Width: | Height: | Size: 6.7 KiB |
BIN
web/dist/static/images/sale_0.png
vendored
|
Before Width: | Height: | Size: 6.0 KiB |
BIN
web/dist/static/images/sale_0_mobile.png
vendored
|
Before Width: | Height: | Size: 8.4 KiB |
BIN
web/dist/static/images/sale_1.png
vendored
|
Before Width: | Height: | Size: 7.6 KiB |
BIN
web/dist/static/images/sale_1_mobile.png
vendored
|
Before Width: | Height: | Size: 8.3 KiB |
172
web/dist/welcome.css
vendored
@@ -5,25 +5,25 @@
|
||||
/*}*/
|
||||
|
||||
.welcome-container h1 {
|
||||
font-size: 1.2em;
|
||||
font-size: 2em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.welcome-container h2 {
|
||||
|
||||
/*padding-bottom: 25px;*/
|
||||
color: #2d3138;
|
||||
font-size: 1em;
|
||||
font-weight: 200;
|
||||
text-align: center;
|
||||
letter-spacing: .59px;
|
||||
padding-bottom: 25px;
|
||||
color: #2d3138;
|
||||
font-size: 26px;
|
||||
font-weight: 200;
|
||||
text-align: center;
|
||||
letter-spacing: .59px;
|
||||
}
|
||||
|
||||
|
||||
.welcome-container-bg {
|
||||
/*background-color: rgb(92, 192, 99);*/
|
||||
/*background-image: url('static/map.jpg');*/
|
||||
background-image: url('static/images/sa-bg.jpg');
|
||||
background-size: auto 100%;
|
||||
background-image: url('static/map.jpg');
|
||||
/*background-image: url('static/images/sa-bg.jpg');*/
|
||||
/*background-position: center;*/
|
||||
-moz-filter: blur(5px);
|
||||
-o-filter: blur(5px);
|
||||
@@ -40,154 +40,26 @@
|
||||
}
|
||||
|
||||
.welcome-container {
|
||||
position: absolute;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top:0;
|
||||
bottom:0;
|
||||
z-index: 0;
|
||||
/*margin-left: 20px;
|
||||
margin-right: 20px;*/
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
height: 100%;
|
||||
/*padding: 100px;*/
|
||||
padding: 100px;
|
||||
}
|
||||
|
||||
.welcome-content {
|
||||
/*height: 100%;*/
|
||||
/*margin: 0 auto;*/
|
||||
width: 240px;
|
||||
margin: 0 auto;
|
||||
width: 600px;
|
||||
background-color: hsla(0,0%,100%,.95);
|
||||
box-shadow: 0 2px 4px 0 rgba(73,73,73,.1);
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-top:40%;
|
||||
/*padding: 50px;*/
|
||||
}
|
||||
|
||||
.buy-button-active {
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
background:url('static/images/sale_1_mobile.png') no-repeat;
|
||||
background-size: contain;
|
||||
border: none;
|
||||
margin-left: 10%;
|
||||
margin-right: 5%;
|
||||
}
|
||||
|
||||
.buy-button-inactive {
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
background:url('static/images/sale_0_mobile.png') no-repeat;
|
||||
background-size: contain;
|
||||
border: none;
|
||||
margin-left: 10%;
|
||||
margin-right: 5%;
|
||||
}
|
||||
|
||||
.rent-button-active{
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
background:url('static/images/rent_1_mobile.png') no-repeat;
|
||||
background-size: contain;
|
||||
border: none;
|
||||
margin-left: 5%;
|
||||
}
|
||||
|
||||
.rent-button-inactive{
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
background:url('static/images/rent_0_mobile.png') no-repeat;
|
||||
background-size: contain;
|
||||
border: none;
|
||||
margin-left: 5%;
|
||||
}
|
||||
|
||||
.search-button{
|
||||
background-color: #b6d53b;
|
||||
margin: 10px;
|
||||
border: none;
|
||||
text-align: center;
|
||||
font-size: 1em;
|
||||
width: 90%;
|
||||
margin-left:5%;
|
||||
margin-right: 5%;
|
||||
}
|
||||
|
||||
@media (min-width: 550px) {
|
||||
|
||||
.welcome-container h1 {
|
||||
font-size: 2em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.welcome-container h2 {
|
||||
|
||||
/*padding-bottom: 25px;*/
|
||||
color: #2d3138;
|
||||
font-size: 1.4em;
|
||||
font-weight: 200;
|
||||
text-align: center;
|
||||
letter-spacing: .59px;
|
||||
}
|
||||
|
||||
.welcome-content {
|
||||
/*height: 100%;*/
|
||||
/*margin: 0 auto;*/
|
||||
width: 500px;
|
||||
background-color: hsla(0,0%,100%,.95);
|
||||
box-shadow: 0 2px 4px 0 rgba(73,73,73,.1);
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-top:10%;
|
||||
/*padding: 50px;*/
|
||||
}
|
||||
|
||||
.buy-button-active {
|
||||
height: 150px;
|
||||
width: 150px;
|
||||
background:url('static/images/sale_1_mobile.png') no-repeat;
|
||||
background-size: contain;
|
||||
border: none;
|
||||
margin-left: 15%;
|
||||
margin-right: 5%;
|
||||
}
|
||||
|
||||
.buy-button-inactive {
|
||||
height: 150px;
|
||||
width: 150px;
|
||||
background:url('static/images/sale_0_mobile.png') no-repeat;
|
||||
background-size: contain;
|
||||
border: none;
|
||||
margin-left: 15%;
|
||||
margin-right: 5%;
|
||||
}
|
||||
|
||||
.rent-button-active{
|
||||
height: 150px;
|
||||
width: 150px;
|
||||
background:url('static/images/rent_1_mobile.png') no-repeat;
|
||||
background-size: contain;
|
||||
border: none;
|
||||
margin-left: 5%;
|
||||
}
|
||||
|
||||
.rent-button-inactive{
|
||||
height: 150px;
|
||||
width: 150px;
|
||||
background:url('static/images/rent_0_mobile.png') no-repeat;
|
||||
background-size: contain;
|
||||
border: none;
|
||||
margin-left: 5%;
|
||||
}
|
||||
|
||||
.search-button{
|
||||
background-color: #b6d53b;
|
||||
margin: 10px;
|
||||
border: none;
|
||||
text-align: center;
|
||||
font-size: 1.4em;
|
||||
width: 90%;
|
||||
margin-left:5%;
|
||||
margin-right: 5%;
|
||||
}
|
||||
padding: 50px;
|
||||
}
|
||||
|
||||
.welcome-content .gmaps-places-input-welcome {
|
||||
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@@ -22,8 +22,7 @@ class Main extends React.Component {
|
||||
filters: {
|
||||
rooms: {},
|
||||
category: {},
|
||||
status : {},
|
||||
adType: 0
|
||||
status : {}
|
||||
},
|
||||
mobileView: 'MAP',
|
||||
contact: {
|
||||
@@ -35,8 +34,6 @@ class Main extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
console.log("Props : ");
|
||||
console.log(props.initialState);
|
||||
if (props.initialState) {
|
||||
props.initialState.sort = props.initialState.sort || state.sort
|
||||
state.filters.rooms = props.initialState.rooms
|
||||
@@ -52,7 +49,6 @@ class Main extends React.Component {
|
||||
state.filters.maxSize = props.initialState.maxSize
|
||||
state.filters.minPrice = props.initialState.minPrice
|
||||
state.filters.maxPrice = props.initialState.maxPrice
|
||||
state.filters.adType = props.initialState.adType
|
||||
}
|
||||
|
||||
this.state = state
|
||||
@@ -238,8 +234,7 @@ class Main extends React.Component {
|
||||
maxSize,
|
||||
minPrice,
|
||||
maxPrice,
|
||||
category,
|
||||
adType
|
||||
category
|
||||
} = this.state.filters
|
||||
|
||||
const bounds = map.getBounds()
|
||||
@@ -251,7 +246,6 @@ class Main extends React.Component {
|
||||
minPrice,
|
||||
maxPrice,
|
||||
category,
|
||||
adType,
|
||||
page: this.state.page,
|
||||
pins: true
|
||||
})
|
||||
@@ -410,8 +404,7 @@ class Main extends React.Component {
|
||||
maxSize,
|
||||
minPrice,
|
||||
maxPrice,
|
||||
category,
|
||||
adType
|
||||
category
|
||||
} = this.state.filters
|
||||
|
||||
const bounds = map.getBounds()
|
||||
@@ -423,7 +416,6 @@ class Main extends React.Component {
|
||||
minPrice,
|
||||
maxPrice,
|
||||
category,
|
||||
adType,
|
||||
page: this.state.page,
|
||||
sort: this.state.sort
|
||||
})
|
||||
|
||||
@@ -1,25 +1,55 @@
|
||||
import React from 'react'
|
||||
import {AD_TYPE_SALE, AD_TYPE_RENT} from '../../../common/enums';
|
||||
import { pacSelectFirst } from '../helpers/googleMaps'
|
||||
|
||||
export default class Welcome extends React.Component {
|
||||
|
||||
constructor (props) {
|
||||
super(props)
|
||||
|
||||
this.state = {
|
||||
type: AD_TYPE_SALE,
|
||||
type: 'SALE'
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
const options = {
|
||||
componentRestrictions: { country: 'BA' },
|
||||
types: ['geocode']
|
||||
}
|
||||
|
||||
const input = document.getElementById('gmaps-places-input-welcome')
|
||||
const searchBox = new google.maps.places.Autocomplete(input, options)
|
||||
|
||||
pacSelectFirst(input)
|
||||
input.addEventListener('focus', e => {
|
||||
e.target.value = ''
|
||||
})
|
||||
searchBox.addListener('place_changed', () => {
|
||||
const place = searchBox.getPlace()
|
||||
if (place.geometry.viewport) {
|
||||
const bounds = place.geometry.viewport.toUrlValue()
|
||||
this.props.onSearch({
|
||||
bounds,
|
||||
type: this.state.type
|
||||
})
|
||||
} else {
|
||||
const location = place.geometry.location
|
||||
this.props.onSearch({
|
||||
location,
|
||||
type: this.state.type
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onSaleClick () {
|
||||
this.setState({
|
||||
type: AD_TYPE_SALE,
|
||||
type: 'SALE'
|
||||
})
|
||||
}
|
||||
|
||||
onRentClick () {
|
||||
this.setState({
|
||||
type: AD_TYPE_RENT,
|
||||
type: 'RENT'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -33,11 +63,15 @@ export default class Welcome extends React.Component {
|
||||
<div className='welcome-content'>
|
||||
<h1>KIVI</h1>
|
||||
<h2>Pronađi svoj novi dom!</h2>
|
||||
<div>
|
||||
<button className={this.state.type===AD_TYPE_SALE?'buy-button-active':'buy-button-inactive'} onClick={this.onSaleClick.bind(this)}></button>
|
||||
<button className={this.state.type===AD_TYPE_RENT?'rent-button-active':'rent-button-inactive'} onClick={this.onRentClick.bind(this)}></button>
|
||||
</div>
|
||||
<button className='search-button' onClick={()=>this.props.onSearch({adType: this.state.type})} >TRAŽI</button>
|
||||
<button
|
||||
onClick={this.onSaleClick.bind(this)}>Kupovina</button>
|
||||
<button onClick={this.onRentClick.bind(this)}>Iznajmljivanje</button>
|
||||
<input
|
||||
type='text'
|
||||
placeholder='Unesite adresu, naselje ili grad'
|
||||
className='where-to'
|
||||
id='gmaps-places-input-welcome'
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,84 +1,84 @@
|
||||
import React from 'react';
|
||||
import {render} from 'react-dom';
|
||||
import Main from './components/Main';
|
||||
import Welcome from './components/Welcome';
|
||||
import React from 'react'
|
||||
import {render} from 'react-dom'
|
||||
import Main from './components/Main'
|
||||
import Welcome from './components/Welcome'
|
||||
|
||||
const getInitialState = url => {
|
||||
const params = window.location.search.substr (1).split ('&');
|
||||
const params = window.location.search.substr(1).split('&')
|
||||
|
||||
const initialState = {
|
||||
rooms: {},
|
||||
category: {},
|
||||
};
|
||||
category: {}
|
||||
}
|
||||
|
||||
for (const param of params) {
|
||||
const [key, value] = param.split ('=');
|
||||
const [key, value] = param.split('=')
|
||||
if (key === 'rooms' && value !== '') {
|
||||
initialState.rooms = {};
|
||||
value.split (',').forEach (k => {
|
||||
initialState.rooms[parseInt (k)] = true;
|
||||
});
|
||||
initialState.rooms = {}
|
||||
value.split(',').forEach(k => {
|
||||
initialState.rooms[parseInt(k)] = true
|
||||
})
|
||||
}
|
||||
|
||||
if (key === 'category' && value !== '') {
|
||||
initialState.category = {};
|
||||
value.split (',').forEach (k => {
|
||||
initialState.category[parseInt (k)] = true;
|
||||
});
|
||||
initialState.category = {}
|
||||
value.split(',').forEach(k => {
|
||||
initialState.category[parseInt(k)] = true
|
||||
})
|
||||
}
|
||||
|
||||
if (key === 'sort') {
|
||||
initialState.sort = value;
|
||||
initialState.sort = value
|
||||
}
|
||||
|
||||
if (key === 'bounds') {
|
||||
initialState.bounds = value;
|
||||
initialState.bounds = value
|
||||
}
|
||||
|
||||
if (key === 'listingId') {
|
||||
initialState.listingId = value;
|
||||
initialState.listingId = value
|
||||
}
|
||||
|
||||
if (key === 'adType') {
|
||||
initialState.adType = value;
|
||||
if (key === 'type') {
|
||||
initialState.type = value
|
||||
}
|
||||
|
||||
if (key === 'zoom') {
|
||||
initialState.zoom = parseInt (value);
|
||||
initialState.zoom = parseInt(value)
|
||||
}
|
||||
|
||||
if (['minSize', 'maxSize', 'minPrice', 'maxPrice'].includes (key)) {
|
||||
initialState[key] = parseFloat (value);
|
||||
if (['minSize', 'maxSize', 'minPrice', 'maxPrice'].includes(key)) {
|
||||
initialState[key] = parseFloat(value)
|
||||
}
|
||||
}
|
||||
|
||||
return initialState;
|
||||
};
|
||||
return initialState
|
||||
}
|
||||
|
||||
const root = document.getElementById ('root');
|
||||
const initialState = getInitialState (window.location);
|
||||
const root = document.getElementById('root')
|
||||
const initialState = getInitialState(window.location)
|
||||
|
||||
const renderMain = (additionalState = {}) => {
|
||||
const main = <Main initialState={{...initialState, ...additionalState}} />;
|
||||
render (main, root);
|
||||
};
|
||||
const main = <Main initialState={{...initialState, ...additionalState}} />
|
||||
render(main, root)
|
||||
}
|
||||
|
||||
//renderMain ();
|
||||
renderMain()
|
||||
|
||||
// disable temp
|
||||
|
||||
if (
|
||||
Object.keys (initialState).length === 2 &&
|
||||
window.localStorage.getItem ('lastLoad') == null
|
||||
) {
|
||||
const onSearch = ({adType}) => {
|
||||
|
||||
console.log("onSearch()");
|
||||
//window.location = `/?adType=${adType}`;
|
||||
renderMain({adType})
|
||||
};
|
||||
const welcome = <Welcome onSearch={onSearch} />;
|
||||
render (welcome, root);
|
||||
/*
|
||||
if (Object.keys(initialState).length === 2 &&
|
||||
window.localStorage.getItem('lastLoad') == null) {
|
||||
const onSearch = ({bounds, type, location}) => {
|
||||
window.location = `/?bounds=${bounds}&type=${type}`
|
||||
//renderMain({
|
||||
//bounds,
|
||||
//type
|
||||
//})
|
||||
}
|
||||
const welcome = <Welcome onSearch={onSearch} />
|
||||
render(welcome, root)
|
||||
} else {
|
||||
renderMain ();
|
||||
renderMain()
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import fetch from 'isomorphic-fetch'
|
||||
import {BASE_URL} from '../../../common/config'
|
||||
|
||||
const BASE_URL = 'localhost';
|
||||
//const BASE_URL = '192.168.0.13';
|
||||
|
||||
export const saveContactRequest = (listingId, params) => {
|
||||
|
||||
let url = `http://${BASE_URL}/api/contact/${listingId}`
|
||||
let url = `http://${BASE_URL}:3001/api/contact/${listingId}`
|
||||
|
||||
return fetch(url, {
|
||||
method: 'POST',
|
||||
@@ -16,7 +18,7 @@ export const saveContactRequest = (listingId, params) => {
|
||||
}
|
||||
|
||||
export const loadListing = id => {
|
||||
let url = `http://${BASE_URL}/api/search/listings/${id}`
|
||||
let url = `http://${BASE_URL}:3001/api/search/listings/${id}`
|
||||
|
||||
return fetch(
|
||||
url,
|
||||
@@ -35,7 +37,6 @@ export const loadProperties = (
|
||||
maxSize = '',
|
||||
rooms = {},
|
||||
category = {},
|
||||
adType=1,
|
||||
page = 1,
|
||||
pins = false,
|
||||
sort = ''
|
||||
@@ -49,7 +50,7 @@ export const loadProperties = (
|
||||
|
||||
// TODO: handle errors
|
||||
//return fetch(process.env.API_URL + '/api/search', {
|
||||
let url = `http://${BASE_URL}/api/search/listings?bounds=${bounds}&minPrice=${minPrice}&maxPrice=${maxPrice}&rooms=${allRooms}&minSize=${minSize}&maxSize=${maxSize}&adType=${adType}&category=${allCategories}&page=${page}&pins=${pins}&sort=${sort}`
|
||||
let url = `http://${BASE_URL}: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,
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import {BASE_URL} from '../../../common/config'
|
||||
|
||||
export const formatPrice = p => {
|
||||
if (isNaN(p)) {
|
||||
return 'Po dogovoru'
|
||||
@@ -35,7 +33,8 @@ S poštovanjem
|
||||
}
|
||||
|
||||
export const listingUrl = (id) => {
|
||||
return `http://${BASE_URL}/?listingId=${id}`
|
||||
// TODO: fix this once removing hardcoded values
|
||||
return `http://localhost:8080/?listingId=${id}`
|
||||
}
|
||||
|
||||
export const isMobile = () => window.matchMedia("(max-width: 768px)").matches
|
||||
|
||||
@@ -59,15 +59,13 @@ export default class Router {
|
||||
sort,
|
||||
rooms = {},
|
||||
category = {},
|
||||
zoom,
|
||||
adType
|
||||
zoom
|
||||
} = this.state
|
||||
|
||||
if (listingId) {
|
||||
params.push(`listingId=${listingId}`)
|
||||
}
|
||||
|
||||
params.push(`adType=${adType}`);
|
||||
params.push(`sort=${sort}`)
|
||||
params.push(`bounds=${bounds}`)
|
||||
params.push(`zoom=${zoom}`)
|
||||
|
||||
@@ -3,13 +3,7 @@ module.exports = {
|
||||
output: {
|
||||
path: __dirname + "/dist",
|
||||
filename: "app.bundle.js",
|
||||
publicPath: "http://138.68.67.31:8080/"
|
||||
},
|
||||
devServer: {
|
||||
// .. rest of devserver options
|
||||
|
||||
host: '0.0.0.0',
|
||||
disableHostCheck: true
|
||||
publicPath: "http://0.0.0.0:8080/"
|
||||
},
|
||||
module: {
|
||||
loaders: [
|
||||
|
||||