refactoring and implementing refreshing items list every 2 seconds
This commit is contained in:
@@ -2,7 +2,7 @@ import React from "react";
|
||||
import Select from "react-select";
|
||||
import { connect } from "react-redux";
|
||||
import { CATEGORY_SELECT, ITEMS_CHANGED } from "constants/actionTypes";
|
||||
import { hoc } from "utils/hoc";
|
||||
import { hoc, areObjectEqual } from "utils/helpers";
|
||||
import { createOlxLink } from "utils/createOlxLink";
|
||||
import axios from "axios";
|
||||
|
||||
@@ -29,21 +29,43 @@ const mapDispatchToProps = dispatch => ({
|
||||
onItemsChanged: items => dispatch({ type: ITEMS_CHANGED, items })
|
||||
});
|
||||
|
||||
let lastUpdateTime = null;
|
||||
let interval = null;
|
||||
class App extends React.Component {
|
||||
componentDidMount() {
|
||||
interval = setInterval(() => {
|
||||
if (lastUpdateTime && Date.now() - lastUpdateTime > 2000) {
|
||||
const { category, options, subcategory, onItemsChanged } = this.props;
|
||||
let url = createOlxLink(category, subcategory, options);
|
||||
url = encodeURI(url);
|
||||
if (url) {
|
||||
axios
|
||||
.get(`/api/${url}`)
|
||||
.then(response => onItemsChanged(response.data))
|
||||
.catch(error => console.log(error));
|
||||
}
|
||||
lastUpdateTime = null;
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
clearInterval(interval);
|
||||
}
|
||||
componentWillReceiveProps(newProps) {
|
||||
const { subcategory, category, options } = this.props;
|
||||
if (
|
||||
newProps.subcategory !== subcategory ||
|
||||
newProps.category !== category ||
|
||||
!areObjectEqual(newProps.options, options)
|
||||
) {
|
||||
lastUpdateTime = Date.now();
|
||||
}
|
||||
}
|
||||
handleChange = selectedOption => {
|
||||
this.props.onCategoryChanged(selectedOption);
|
||||
};
|
||||
|
||||
getDataFromOlx = () => {
|
||||
const { category, options, subcategory, onItemsChanged } = this.props;
|
||||
let url = createOlxLink(category, subcategory, options);
|
||||
url = encodeURI(url);
|
||||
axios
|
||||
.get(`/api/${url}`)
|
||||
.then(response => onItemsChanged(response.data))
|
||||
.catch(error => console.log(error));
|
||||
};
|
||||
|
||||
render() {
|
||||
const { category } = this.props;
|
||||
|
||||
@@ -58,7 +80,6 @@ class App extends React.Component {
|
||||
Vozila: <Vozila />,
|
||||
Nekretnine: <Nekretnine />
|
||||
})}
|
||||
<button onClick={this.getDataFromOlx}>Get Data from OLX </button>
|
||||
<ItemsContainer />
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
import React from "react";
|
||||
import Select from "react-select";
|
||||
import { subcategorywrapper } from "utils/subcategorywrapper";
|
||||
import { hoc } from "utils/hoc";
|
||||
import { hoc } from "utils/helpers";
|
||||
|
||||
import Stanovi from "../subcategories/nekretnine/Stanovi";
|
||||
import Kuce from "../subcategories/nekretnine/Kuce";
|
||||
|
||||
const options = [
|
||||
{ value: "Stanovi", label: "Stanovi" },
|
||||
{ value: "Kuce", label: "Kuce" }
|
||||
];
|
||||
const options = [{ value: 23, label: "Stanovi" }, { value: 24, label: "Kuce" }];
|
||||
|
||||
class Nekretnine extends React.Component {
|
||||
handleChange = selectedOption => {
|
||||
@@ -27,8 +24,8 @@ class Nekretnine extends React.Component {
|
||||
options={options}
|
||||
/>
|
||||
{hoc(subcategory && subcategory.value, {
|
||||
Stanovi: <Stanovi />,
|
||||
Kuce: <Kuce />
|
||||
23: <Stanovi />,
|
||||
24: <Kuce />
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -3,35 +3,35 @@ import Select from "react-select";
|
||||
import Automobili from "../subcategories/vozila/Automobili";
|
||||
import Motocikli from "../subcategories/vozila/Motocikli";
|
||||
import { subcategorywrapper } from "utils/subcategorywrapper";
|
||||
import { hoc } from "utils/hoc";
|
||||
import { hoc } from "utils/helpers";
|
||||
|
||||
const options = [
|
||||
{ value: "Automobili", label: "Automobili" },
|
||||
{ value: "Motocikli", label: "Motocikli" }
|
||||
{ value: 18, label: "Automobili" },
|
||||
{ value: 21, label: "Motocikli" }
|
||||
];
|
||||
|
||||
class Vozila extends React.Component {
|
||||
handleChange = selectedOption => {
|
||||
this.props.onSubCategoryChanged(selectedOption);
|
||||
};
|
||||
handleChange = selectedOption => {
|
||||
this.props.onSubCategoryChanged(selectedOption);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { subcategory } = this.props;
|
||||
render() {
|
||||
const { subcategory } = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Select
|
||||
value={subcategory}
|
||||
onChange={this.handleChange}
|
||||
options={options}
|
||||
/>
|
||||
{hoc(subcategory && subcategory.value, {
|
||||
Automobili: <Automobili />,
|
||||
Motocikli: <Motocikli />
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<Select
|
||||
value={subcategory}
|
||||
onChange={this.handleChange}
|
||||
options={options}
|
||||
/>
|
||||
{hoc(subcategory && subcategory.value, {
|
||||
18: <Automobili />,
|
||||
21: <Motocikli />
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default subcategorywrapper(Vozila);
|
||||
|
||||
@@ -2,5 +2,6 @@ export const rangeOptions = {
|
||||
min: 0,
|
||||
max: 100000,
|
||||
defaultValues: [0, 100000],
|
||||
step: 100
|
||||
step: 100,
|
||||
optionNames: ["od", "do"]
|
||||
};
|
||||
|
||||
@@ -5,42 +5,50 @@ const elements = [
|
||||
{
|
||||
type: "checkbox",
|
||||
name: "Uknjizeno",
|
||||
optionName: "uknjizeno"
|
||||
optionName: "uknjizeno-zk_checkbox",
|
||||
value: "on"
|
||||
},
|
||||
{
|
||||
type: "checkbox",
|
||||
name: "Namjesteno",
|
||||
optionName: "namjesteno"
|
||||
optionName: "namjestena_checkbox",
|
||||
value: "on"
|
||||
},
|
||||
{
|
||||
type: "checkbox",
|
||||
name: "Nedavno adaptirano",
|
||||
optionName: "nedavno_adaptirano"
|
||||
optionName: "nedavno-adaptirana_checkbox",
|
||||
value: "on"
|
||||
},
|
||||
{
|
||||
type: "checkbox",
|
||||
name: "Garaza",
|
||||
optionName: "garaza"
|
||||
optionName: "gara-a_checkbox",
|
||||
value: "on"
|
||||
},
|
||||
{
|
||||
type: "checkbox",
|
||||
name: "Balkon",
|
||||
optionName: "balkon"
|
||||
optionName: "balkon_checkbox",
|
||||
value: "on"
|
||||
},
|
||||
{
|
||||
type: "checkbox",
|
||||
name: "Voda",
|
||||
optionName: "voda"
|
||||
optionName: "voda_checkbox",
|
||||
value: "on"
|
||||
},
|
||||
{
|
||||
type: "checkbox",
|
||||
name: "Plin",
|
||||
optionName: "plin"
|
||||
optionName: "plin_checkbox",
|
||||
value: "on"
|
||||
},
|
||||
{
|
||||
type: "checkbox",
|
||||
name: "Bazen",
|
||||
optionName: "bazen"
|
||||
optionName: "bazen_checkbox",
|
||||
value: "on"
|
||||
}
|
||||
];
|
||||
class KuceFilter extends React.Component {
|
||||
|
||||
@@ -5,47 +5,56 @@ const elements = [
|
||||
{
|
||||
type: "checkbox",
|
||||
name: "Novogradnja",
|
||||
optionName: "novogradnja"
|
||||
optionName: "novogradnja_checkbox",
|
||||
value: "on"
|
||||
},
|
||||
{
|
||||
type: "checkbox",
|
||||
name: "Namjesten",
|
||||
optionName: "namjesten"
|
||||
optionName: "namjesten_checkbox",
|
||||
value: "on"
|
||||
},
|
||||
{
|
||||
type: "checkbox",
|
||||
name: "Nedavno adaptiran",
|
||||
optionName: "Nedavno_adaptiran"
|
||||
optionName: "nedavno-adaptiran_checkbox",
|
||||
value: "on"
|
||||
},
|
||||
{
|
||||
type: "checkbox",
|
||||
name: "Uknjizeno",
|
||||
optionName: "uknjizeno"
|
||||
optionName: "uknjizeno-zk_checkbox",
|
||||
value: "on"
|
||||
},
|
||||
{
|
||||
type: "checkbox",
|
||||
name: "Lift",
|
||||
optionName: "lift"
|
||||
optionName: "lift_checkbox",
|
||||
value: "on"
|
||||
},
|
||||
{
|
||||
type: "checkbox",
|
||||
name: "Balkon",
|
||||
optionName: "balkon"
|
||||
optionName: "balkon_checkbox",
|
||||
value: "on"
|
||||
},
|
||||
{
|
||||
type: "checkbox",
|
||||
name: "Parking",
|
||||
optionName: "parking"
|
||||
optionName: "parking_checkbox",
|
||||
value: "on"
|
||||
},
|
||||
{
|
||||
type: "checkbox",
|
||||
name: "Plin",
|
||||
optionName: "plin"
|
||||
optionName: "plin_checkbox",
|
||||
value: "on"
|
||||
},
|
||||
{
|
||||
type: "checkbox",
|
||||
name: "kablovska",
|
||||
optionName: "kablovska"
|
||||
optionName: "kablovska-tv_checkbox",
|
||||
value: "on"
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -2,5 +2,6 @@ export const rangeOptions = {
|
||||
min: 0,
|
||||
max: 1000,
|
||||
defaultValues: [0, new Date().getFullYear()],
|
||||
step: 1
|
||||
step: 1,
|
||||
optionNames: ["kvadrata_min", "kvadrata_max"]
|
||||
};
|
||||
|
||||
@@ -2,5 +2,6 @@ export const rangeOptions = {
|
||||
min: 0,
|
||||
max: 100000,
|
||||
defaultValues: [0, 100000],
|
||||
step: 100
|
||||
step: 100,
|
||||
optionNames: ["od", "do"]
|
||||
};
|
||||
|
||||
@@ -2,5 +2,6 @@ export const rangeOptions = {
|
||||
min: 1960,
|
||||
max: new Date().getFullYear(),
|
||||
defaultValues: [1960, new Date().getFullYear()],
|
||||
step: 1
|
||||
step: 1,
|
||||
optionNames: ["godiste_min", "godiste_max"]
|
||||
};
|
||||
|
||||
@@ -2,26 +2,31 @@ export const elements = [
|
||||
{
|
||||
name: "Dizel",
|
||||
optionName: "gorivo_select_dizel",
|
||||
type: "checkbox"
|
||||
type: "checkbox",
|
||||
value: "Dizel"
|
||||
},
|
||||
{
|
||||
name: "Benzin",
|
||||
optionName: "gorivo_select_benzin",
|
||||
type: "checkbox"
|
||||
type: "checkbox",
|
||||
value: "Benzin"
|
||||
},
|
||||
{
|
||||
name: "Plin",
|
||||
optionName: "gorivo_select_plin",
|
||||
type: "checkbox"
|
||||
type: "checkbox",
|
||||
value: "Plin"
|
||||
},
|
||||
{
|
||||
name: "Hibrid",
|
||||
optionName: "gorivo_select_hibrid",
|
||||
type: "checkbox"
|
||||
type: "checkbox",
|
||||
value: "Hibrid"
|
||||
},
|
||||
{
|
||||
name: "Elektro",
|
||||
optionName: "gorivo_select_elektro",
|
||||
type: "checkbox"
|
||||
type: "checkbox",
|
||||
value: "Elektro"
|
||||
}
|
||||
];
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
export const kilometrazaOptions = {
|
||||
kilometraMin: {
|
||||
choices: [{ value: 5000, label: "5000" }, { value: 10000, label: "10000" }],
|
||||
value: "kilometrazaMin",
|
||||
optionName: "kilometrazaMin"
|
||||
value: "kilometra-a_min",
|
||||
optionName: "kilometra-a_min"
|
||||
},
|
||||
kilometraMax: {
|
||||
choices: [
|
||||
{ value: 15000, label: "15000" },
|
||||
{ value: 200000, label: "200000" }
|
||||
],
|
||||
value: "kilometrazaMax",
|
||||
optionName: "kilometrazaMax"
|
||||
value: "kilometra-a_max",
|
||||
optionName: "kilometra-a_max"
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export const proizvodacOptions = {
|
||||
choices: [{ value: "1900", label: "Audi" }, { value: "9000", label: "Ford" }],
|
||||
value: "proizvodac",
|
||||
optionName: "proizvodac"
|
||||
value: "v_b",
|
||||
optionName: "v_b"
|
||||
};
|
||||
|
||||
@@ -20,6 +20,7 @@ export const elements = [
|
||||
{
|
||||
type: "checkbox",
|
||||
name: "Udarena vozila",
|
||||
optionName: "udaren_checkbox"
|
||||
optionName: "udaren_checkbox",
|
||||
value: "on"
|
||||
}
|
||||
];
|
||||
|
||||
@@ -19,9 +19,9 @@ class VozilaFilter extends React.Component {
|
||||
elements={Stanje.elements}
|
||||
/>
|
||||
<SelectWrapper {...Proizvodac.proizvodacOptions} />
|
||||
<RangeWrapper {...Cijena.rangeOptions} optionName="cijena" />
|
||||
<RangeWrapper {...Cijena.rangeOptions} />
|
||||
<SelectWrapper {...Lokacija.lokacijaOptions} />
|
||||
<RangeWrapper {...Godiste.rangeOptions} optionName="godiste" />
|
||||
<RangeWrapper {...Godiste.rangeOptions} />
|
||||
<SelectWrapper {...Kilometraza.kilometrazaOptions.kilometraMin} />
|
||||
<SelectWrapper {...Kilometraza.kilometrazaOptions.kilometraMax} />
|
||||
<CheckboxAndRadioWrapper
|
||||
|
||||
@@ -5,7 +5,7 @@ class CheckboxAndRadioWrapper extends React.Component {
|
||||
optionChange = (option, optionName, type) => {
|
||||
const optionTypePicker = {
|
||||
radio: option.target.value,
|
||||
checkbox: option.target.checked
|
||||
checkbox: option.target.checked ? option.target.value : false
|
||||
};
|
||||
const { onOptionChanged } = this.props;
|
||||
onOptionChanged({
|
||||
@@ -15,10 +15,9 @@ class CheckboxAndRadioWrapper extends React.Component {
|
||||
};
|
||||
isChecked = (type, value, optionName) => {
|
||||
const { options } = this.props;
|
||||
return type === "checkbox"
|
||||
? value
|
||||
: options.hasOwnProperty(optionName) &&
|
||||
options[optionName] === String(value);
|
||||
return options.hasOwnProperty(optionName) && type === "checkbox"
|
||||
? options[optionName]
|
||||
: options[optionName] === String(value);
|
||||
};
|
||||
renderElements = (elements, componentName) => {
|
||||
return elements.map(({ type, value, name, optionName } = {}) => (
|
||||
|
||||
@@ -4,22 +4,28 @@ import { optionchangewrapper } from "utils/optionchangewrapper";
|
||||
import "rc-slider/assets/index.css";
|
||||
|
||||
class RangeWrapper extends React.Component {
|
||||
sendAction = (optionName, optionValue) => {
|
||||
this.props.onOptionChanged({
|
||||
optionName,
|
||||
optionValue
|
||||
});
|
||||
};
|
||||
handleRangeChange = ([min, max] = this.props.defaultValues) => {
|
||||
this.inputMin.value = min;
|
||||
this.inputMax.value = max;
|
||||
const { onOptionChanged, optionName } = this.props;
|
||||
onOptionChanged({
|
||||
optionName,
|
||||
optionValue: [min, max]
|
||||
});
|
||||
const { optionNames } = this.props;
|
||||
const optionValues = [min, max];
|
||||
optionNames.forEach((optionName, index) =>
|
||||
this.sendAction(optionName, optionValues[index])
|
||||
);
|
||||
};
|
||||
|
||||
handleInputChange = () => {
|
||||
const { onOptionChanged, optionName } = this.props;
|
||||
onOptionChanged({
|
||||
optionName,
|
||||
optionValue: [this.inputMin.value, this.inputMax.value]
|
||||
});
|
||||
const { optionNames } = this.props;
|
||||
const optionValues = [this.inputMin.value, this.inputMax.value];
|
||||
optionNames.forEach((optionName, index) =>
|
||||
this.sendAction(optionName, optionValues[index])
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
|
||||
Reference in New Issue
Block a user