Update maps to include search logic
This commit is contained in:
parent
0495704e9b
commit
6d291ecf95
4 changed files with 222 additions and 118 deletions
|
@ -148,6 +148,38 @@ class EnhancedTable extends Component {
|
|||
}
|
||||
// Update the search field as soon as the character is typed
|
||||
this.setState({searchQuery: query});
|
||||
|
||||
const searchQuery = query;
|
||||
const searchColumns = this.state.searchColumns;
|
||||
const data = this.props.data.filter((item) => {
|
||||
let insert = false;
|
||||
|
||||
// Iterate over the search column select boxes
|
||||
searchColumns.map(column => {
|
||||
try {
|
||||
if( column.checked && (item[column.name] !== undefined) ) {
|
||||
|
||||
if(item[column.name].hasOwnProperty('searchText') && item[column.name].searchText.toLowerCase().indexOf(searchQuery.toLowerCase().trim()) !== -1){
|
||||
insert = true;
|
||||
}
|
||||
else if(item[column.name].toLowerCase().indexOf(searchQuery.toLowerCase().trim()) !== -1){
|
||||
insert = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(error) {
|
||||
//console.error(error);
|
||||
}
|
||||
return column;
|
||||
});
|
||||
|
||||
if(insert){
|
||||
return item;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
this.props.onSearchChange(data);
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -198,6 +230,8 @@ class EnhancedTable extends Component {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div style={styles.root}>
|
||||
<EnhancedSearch
|
||||
|
|
|
@ -15,7 +15,6 @@ import LayerMapSwitches from './LayerMapSwitches';
|
|||
|
||||
// Helpers
|
||||
import GOOGLE_MAPS_API from '../utils/constants';
|
||||
import Client from '../utils/feathers';
|
||||
|
||||
// Images
|
||||
import MerchantPin from '../assets/img/map/merchant_pin.png';
|
||||
|
@ -158,7 +157,9 @@ const propTypesLayerMap = {
|
|||
ambassadorsLayer: PropTypes.bool,
|
||||
merchantsLayer: PropTypes.bool,
|
||||
showControls: PropTypes.bool,
|
||||
mapHeight: PropTypes.string
|
||||
mapHeight: PropTypes.string,
|
||||
ambassadors: PropTypes.array,
|
||||
merchants: PropTypes.array,
|
||||
};
|
||||
|
||||
class LayerMap extends Component {
|
||||
|
@ -172,86 +173,8 @@ class LayerMap extends Component {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Lifecycle event handler called just after the App loads into the DOM.
|
||||
*/
|
||||
UNSAFE_componentWillMount() {
|
||||
this.getAmbassadors();
|
||||
this.getMerchants();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Get the ambassadors list from the web service.
|
||||
* @param {string} id - Merchant ID.
|
||||
*/
|
||||
getAmbassadors = () => {
|
||||
const app = this;
|
||||
const ambassadors = Client.service('api/v2/ambassadors');
|
||||
|
||||
this.setState({loading: true});
|
||||
|
||||
ambassadors.find().then( (results) => {
|
||||
const markers = [];
|
||||
results.data.forEach(ambassador => {
|
||||
ambassador.cities.forEach(function(city) {
|
||||
const marker = {
|
||||
lat: city.lat,
|
||||
lng: city.lon,
|
||||
withInfo: true,
|
||||
infoTitle: ambassador.nickname,
|
||||
infoDescription: `${city.name} - ${city.country}`,
|
||||
};
|
||||
markers.push(marker);
|
||||
});
|
||||
});
|
||||
|
||||
// Once both return, update the state
|
||||
app.setState({
|
||||
ambassadors: markers,
|
||||
loading: false
|
||||
});
|
||||
}).catch( error => {
|
||||
app.setState({responseError: error.message, loading: false});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @description Get the merchants list from the web service.
|
||||
* @param {string} id - Merchant ID.
|
||||
*/
|
||||
getMerchants = () => {
|
||||
const app = this;
|
||||
const merchants = Client.service('api/v1/merchants');
|
||||
|
||||
this.setState({loading: true});
|
||||
|
||||
merchants.find().then( (results) => {
|
||||
const markers = results.data.map(merchant => {
|
||||
const marker = {
|
||||
lat: merchant.lat,
|
||||
lng: merchant.lon,
|
||||
withInfo: true,
|
||||
infoTitle: merchant.name,
|
||||
infoDescription: `${merchant.address}, ${merchant.city} - ${merchant.country}`,
|
||||
};
|
||||
return marker;
|
||||
});
|
||||
|
||||
// Once both return, update the state
|
||||
app.setState({
|
||||
merchants: markers,
|
||||
loading: false
|
||||
});
|
||||
}).catch( error => {
|
||||
app.setState({responseError: error.message, loading: false});
|
||||
});
|
||||
};
|
||||
|
||||
handleLayerChange = name => event => {
|
||||
this.setState({ [name]: event.target.checked });
|
||||
// Update any time changes
|
||||
this.getAmbassadors();
|
||||
this.getMerchants();
|
||||
};
|
||||
|
||||
render() {
|
||||
|
@ -270,8 +193,8 @@ class LayerMap extends Component {
|
|||
<div style={{ height: 56 }}></div>
|
||||
)}
|
||||
<CustomLayerMap
|
||||
ambassadors={this.state.ambassadorLayer ? this.state.ambassadors: []}
|
||||
merchants={this.state.merchantLayer ? this.state.merchants: []}
|
||||
ambassadors={this.state.ambassadorLayer ? this.props.ambassadors: []}
|
||||
merchants={this.state.merchantLayer ? this.props.merchants: []}
|
||||
mapZoom={3}
|
||||
mapCenter={{ lat: 0, lng: 0 }}
|
||||
loadingElement={<div style={{ height: `100%` }} />}
|
||||
|
|
|
@ -76,6 +76,8 @@ class AmbassadorsPage extends Component {
|
|||
skip: 0,
|
||||
data: []
|
||||
},
|
||||
ambassadorsSearch: [],
|
||||
merchantMarkers: [],
|
||||
loading: true,
|
||||
rowsPerPage: [100,200,300],
|
||||
numberOfRows: 100,
|
||||
|
@ -95,6 +97,7 @@ class AmbassadorsPage extends Component {
|
|||
UNSAFE_componentWillMount() {
|
||||
// Get the ambassadors list
|
||||
this.getAmbassadors();
|
||||
this.getMerchants();
|
||||
}
|
||||
|
||||
fillResults(result) {
|
||||
|
@ -129,8 +132,72 @@ class AmbassadorsPage extends Component {
|
|||
skip = skip + limit;
|
||||
}
|
||||
|
||||
// Add location and maps button
|
||||
result.data.forEach(function(ambassador){
|
||||
ambassador.location = {
|
||||
searchText: app.addLocationSearchText(ambassador.cities),
|
||||
value: app.addLocation(ambassador.cities)
|
||||
}
|
||||
ambassador.map = app.addMapButton(ambassador.nickname, ambassador.cities);
|
||||
ambassador.link = <a target="_blank" rel="noopener noreferrer"
|
||||
href={ambassador.url}>{stripProtocol(ambassador.url)}</a>;
|
||||
});
|
||||
|
||||
// Once both return, update the state
|
||||
app.setState({loading: false, ambassadors: result});
|
||||
app.setState({
|
||||
loading: false,
|
||||
ambassadors: result,
|
||||
ambassadorsSearch: result.data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @description Get merchants from the web service
|
||||
* @param {number} [limit=10] - Max items to be returned.
|
||||
* @param {number} [skip=0] - Start index search
|
||||
*/
|
||||
getMerchants = async (limit = 50, skip = 0) => {
|
||||
const app = this;
|
||||
// Initially we don't know how much the total value is, so to make sure we enter the loop
|
||||
// at least once we're just setting it to be 1
|
||||
let total = 1;
|
||||
|
||||
const merchants = Client.service('api/v1/merchants');
|
||||
|
||||
let result;
|
||||
while(skip < total){
|
||||
let partialResponse = await merchants.find({
|
||||
query: {
|
||||
$sort: { account: 1 },
|
||||
$limit: limit,
|
||||
$skip: skip
|
||||
}
|
||||
});
|
||||
total = partialResponse.total;
|
||||
result === undefined ? result = partialResponse : partialResponse.data.map(this.fillResults(result));
|
||||
skip = skip + limit;
|
||||
}
|
||||
|
||||
result.data.forEach(function(merchants){
|
||||
if(merchants.city !== undefined) merchants.city = (merchants.city).replace(/(^|\s)\S/g, l => l.toUpperCase());
|
||||
if(merchants.country !== undefined) merchants.country = countries.getName(merchants.country);
|
||||
});
|
||||
|
||||
const markers = result.data.map(merchant => {
|
||||
const marker = {
|
||||
lat: merchant.lat,
|
||||
lng: merchant.lon,
|
||||
withInfo: true,
|
||||
infoTitle: merchant.name,
|
||||
infoDescription: `${merchant.address}, ${merchant.city} - ${merchant.country}`,
|
||||
};
|
||||
return marker;
|
||||
});
|
||||
|
||||
// Once both return, update the state
|
||||
app.setState({
|
||||
merchantMarkers: markers
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -206,20 +273,26 @@ class AmbassadorsPage extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
handleSearchChange(data){
|
||||
this.setState({ ambassadorsSearch: data });
|
||||
}
|
||||
|
||||
render() {
|
||||
const { data } = this.state.ambassadors;
|
||||
const { ambassadorsSearch, merchantMarkers } = this.state;
|
||||
|
||||
const app = this;
|
||||
|
||||
// Add location and maps button
|
||||
data.forEach(function(ambassador){
|
||||
ambassador.location = {
|
||||
searchText: app.addLocationSearchText(ambassador.cities),
|
||||
value: app.addLocation(ambassador.cities)
|
||||
}
|
||||
ambassador.map = app.addMapButton(ambassador.nickname, ambassador.cities);
|
||||
ambassador.link = <a target="_blank" rel="noopener noreferrer"
|
||||
href={ambassador.url}>{stripProtocol(ambassador.url)}</a>;
|
||||
const ambassadorsMarkers = [];
|
||||
ambassadorsSearch.forEach(ambassador => {
|
||||
ambassador.cities.forEach(function(city) {
|
||||
const marker = {
|
||||
lat: city.lat,
|
||||
lng: city.lon,
|
||||
withInfo: true,
|
||||
infoTitle: ambassador.nickname,
|
||||
infoDescription: `${city.name} - ${city.country}`,
|
||||
};
|
||||
ambassadorsMarkers.push(marker);
|
||||
});
|
||||
});
|
||||
|
||||
return (
|
||||
|
@ -274,6 +347,7 @@ class AmbassadorsPage extends Component {
|
|||
showSearchColumns={false}
|
||||
rowsPerPage={10}
|
||||
isAdmin={false}
|
||||
onSearchChange={(data) => this.handleSearchChange(data)}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
|
@ -281,6 +355,8 @@ class AmbassadorsPage extends Component {
|
|||
)}
|
||||
<div className="map">
|
||||
<LayerMap
|
||||
ambassadors={ambassadorsMarkers}
|
||||
merchants={merchantMarkers}
|
||||
ambassadorsLayer={true}
|
||||
merchantsLayer={false}
|
||||
mapHeight={'600px'}
|
||||
|
|
|
@ -74,6 +74,8 @@ class MerchantsPage extends Component {
|
|||
skip: 0,
|
||||
data: []
|
||||
},
|
||||
merchantsSearch: [],
|
||||
ambassadorsMarkers: [],
|
||||
loading: true,
|
||||
rowsPerPage: [100,200,300],
|
||||
numberOfRows: 100,
|
||||
|
@ -94,7 +96,7 @@ class MerchantsPage extends Component {
|
|||
* @description Lifecycle event handler called just after the App loads into the DOM.
|
||||
*/
|
||||
UNSAFE_componentWillMount() {
|
||||
// Get the ambassadors list
|
||||
this.getAmbassadors();
|
||||
this.getMerchants();
|
||||
}
|
||||
|
||||
|
@ -103,12 +105,57 @@ class MerchantsPage extends Component {
|
|||
return (item) => data.data.push(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Get ambassadors from the web service
|
||||
* @param {number} [limit=10] - Max items to be returned.
|
||||
* @param {number} [skip=0] - Start index search
|
||||
*/
|
||||
getAmbassadors = async (limit = 50, skip = 0) => {
|
||||
const app = this;
|
||||
// Initially we don't know how much the total value is, so to make sure we enter the loop
|
||||
// at least once we're just setting it to be 1
|
||||
let total = 1;
|
||||
|
||||
const ambassadors = Client.service('api/v2/ambassadors');
|
||||
|
||||
let result;
|
||||
while(skip < total){
|
||||
let partialResponse = await ambassadors.find({
|
||||
query: {
|
||||
$sort: { account: 1 },
|
||||
$limit: limit,
|
||||
$skip: skip
|
||||
}
|
||||
});
|
||||
total = partialResponse.total;
|
||||
result === undefined ? result = partialResponse : partialResponse.data.map(this.fillResults(result));
|
||||
skip = skip + limit;
|
||||
}
|
||||
|
||||
const markers = [];
|
||||
result.data.forEach(ambassador => {
|
||||
ambassador.cities.forEach(function(city) {
|
||||
const marker = {
|
||||
lat: city.lat,
|
||||
lng: city.lon,
|
||||
withInfo: true,
|
||||
infoTitle: ambassador.nickname,
|
||||
infoDescription: `${city.name} - ${city.country}`,
|
||||
};
|
||||
markers.push(marker);
|
||||
});
|
||||
});
|
||||
|
||||
// Once both return, update the state
|
||||
app.setState({ ambassadorsMarkers: markers });
|
||||
};
|
||||
|
||||
/**
|
||||
* @description Get merchants from the web service
|
||||
* @param {number} [limit=10] - Max items to be returned.
|
||||
* @param {number} [skip=0] - Start index search
|
||||
*/
|
||||
getMerchants = async (limit = 10, skip = 0) => {
|
||||
getMerchants = async (limit = 50, skip = 0) => {
|
||||
const app = this;
|
||||
// Initially we don't know how much the total value is, so to make sure we enter the loop
|
||||
// at least once we're just setting it to be 1
|
||||
|
@ -135,8 +182,31 @@ class MerchantsPage extends Component {
|
|||
if(merchants.country !== undefined) merchants.country = countries.getName(merchants.country);
|
||||
});
|
||||
|
||||
result.data.map(merchant => {
|
||||
merchant.map = <Button
|
||||
className="App-button"
|
||||
variant="contained"
|
||||
style={{
|
||||
backgroundColor: "#139657",
|
||||
color: 'white'
|
||||
}}
|
||||
onClick={() => this.openMaps(
|
||||
merchant.name,
|
||||
`${merchant.address}, ${merchant.city} - ${merchant.country}`,
|
||||
merchant.lat,
|
||||
merchant.lon
|
||||
)}
|
||||
>Show on Map
|
||||
</Button>;
|
||||
return merchant;
|
||||
});
|
||||
|
||||
// Once both return, update the state
|
||||
app.setState({loading: false, merchants: result});
|
||||
app.setState({
|
||||
loading: false,
|
||||
merchants: result,
|
||||
merchantsSearch: result.data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -160,28 +230,26 @@ class MerchantsPage extends Component {
|
|||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { data } = this.state.merchants;
|
||||
handleSearchChange(data){
|
||||
this.setState({ merchantsSearch: data });
|
||||
}
|
||||
|
||||
data.map(merchant => {
|
||||
merchant.map = <Button
|
||||
className="App-button"
|
||||
variant="contained"
|
||||
style={{
|
||||
backgroundColor: "#139657",
|
||||
color: 'white'
|
||||
}}
|
||||
onClick={() => this.openMaps(
|
||||
merchant.name,
|
||||
`${merchant.address}, ${merchant.city} - ${merchant.country}`,
|
||||
merchant.lat,
|
||||
merchant.lon
|
||||
)}
|
||||
>Show on Map
|
||||
</Button>;
|
||||
return merchant;
|
||||
render() {
|
||||
const { data: merchantsData } = this.state.merchants;
|
||||
const { ambassadorsMarkers, merchantsSearch } = this.state;
|
||||
|
||||
const merchantMarkers = merchantsSearch.map(merchant => {
|
||||
const marker = {
|
||||
lat: merchant.lat,
|
||||
lng: merchant.lon,
|
||||
withInfo: true,
|
||||
infoTitle: merchant.name,
|
||||
infoDescription: `${merchant.address}, ${merchant.city} - ${merchant.country}`,
|
||||
};
|
||||
return marker;
|
||||
});
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
<AppHeader />
|
||||
|
@ -223,16 +291,17 @@ class MerchantsPage extends Component {
|
|||
/>
|
||||
</Modal>
|
||||
|
||||
{(data.length > 0) ? (
|
||||
{(merchantsData.length > 0) ? (
|
||||
<div>
|
||||
<br />
|
||||
<EnhancedTable
|
||||
columnData={columnData}
|
||||
data={data}
|
||||
data={merchantsData}
|
||||
orderBy="account"
|
||||
rowsPerPage={10}
|
||||
showSearchColumns={false}
|
||||
isAdmin={false}
|
||||
onSearchChange={(data) => this.handleSearchChange(data)}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
|
@ -240,6 +309,8 @@ class MerchantsPage extends Component {
|
|||
)}
|
||||
<div className="map">
|
||||
<LayerMap
|
||||
ambassadors={ambassadorsMarkers}
|
||||
merchants={merchantMarkers}
|
||||
ambassadorsLayer={false}
|
||||
merchantsLayer={true}
|
||||
mapHeight={'600px'}
|
||||
|
|
Loading…
Reference in a new issue