import React, { Component } from 'react';
import { FormattedMessage, FormattedHTMLMessage } from 'react-intl';
import Modal from 'react-modal';
import { Link } from 'react-router-dom';
import Button from '@material-ui/core/Button';
// Custom components
import AppHeader from '../AppHeader';
import EnhancedTable from '../EnhancedTable';
import Footer from '../Footer';
import LayerMap from '../LayerMap';
import PreviewMap from '../PreviewMap';
import { stripProtocol } from '../../utils/url';
// Helpers
import Client from '../../utils/feathers';
import Countries from 'country-list';
// Images
import LoadingGif from '../../assets/img/loading_icon.gif';
import MerchantPin from '../../assets/img/map/merchant_pin.png';
import "./MerchantsPage.css";
// List of countries
const countries = Countries();
const centerStyle = {
marginTop: 20,
marginBottom: 20
};
const loadingStyle = {
textAlign: 'center',
marginTop: 20,
marginBottom: 20,
display: 'block',
marginLeft: 'auto',
marginRight: 'auto'
};
const mapsStyles = {
content : {
top : '50%',
left : '50%',
right : 'auto',
bottom : 'auto',
marginRight : '-50%',
transform : 'translate(-50%, -50%)',
minWidth : '300px'
}
};
const columnData = [
{ id: 'name', numeric: false, disablePadding: true, label: 'Name' },
{ id: 'address', numeric: false, disablePadding: true, label: 'Address' },
{ id: 'location', numeric: false, disablePadding: false, label: 'Location' },
{ id: 'map', numeric: false, disablePadding: false, label: 'Maps', disableSearch: true}
];
/**
* Merchant page component.
*/
class MerchantsPage extends Component {
constructor(props, context) {
super(props, context);
/** @type {ComponentState} */
this.state = {
merchants: {
total: 0,
limit: 0,
skip: 0,
data: []
},
merchantsSearch: [],
ambassadorsMarkers: [],
loading: true,
rowsPerPage: [100,200,300],
numberOfRows: 100,
page: 1,
total: undefined,
dialogOpen: false,
dialogMultipleOpen: false,
modalIsOpen: false,
mapsModalIsOpen: false,
mapsTitle: '',
mapsDescription: '',
mapsLat: 0,
mapsLon: 0
};
}
/**
* @description Lifecycle event handler called just after the App loads into the DOM.
*/
UNSAFE_componentWillMount() {
this.getAmbassadors();
this.getMerchants();
}
fillResults(result) {
const data = result;
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 infoDescription =
Location : {(city.name).replace(/(^|\s)\S/g, l => l.toUpperCase())} - {countries.getName(city.country)}
{(ambassador.nickname) && (
Nickname : {ambassador.nickname}
)}
{(ambassador.telegram) && (
)}
{(ambassador.keybase) && (
Keybase : {ambassador.keybase}
)}
{(ambassador.email) && (
Email : {ambassador.email}
)}
{(ambassador.phone) && (
Phone : {ambassador.phone}
)}
{(ambassador.url) && (
)}
;
const marker = {
lat: city.lat,
lng: city.lon,
withInfo: true,
infoTitle: ambassador.nickname,
infoDescription: infoDescription,
};
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 = 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');
this.setState({loading: true});
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);
});
result.data.map(merchant => {
const infoDescription =
Address : {merchant.address}
{(merchant.phone) && (
Phone : {merchant.phone}
)}
;
merchant.location = {
searchText: `${merchant.country} - ${merchant.city}`,
value: (merchant.city) ? `${merchant.city} - ${merchant.country}`: merchant.country
}
merchant.map = this.openMaps(
merchant.name,
infoDescription,
merchant.lat,
merchant.lon
)}
>Show on Map
;
return merchant;
});
// Once both return, update the state
app.setState({
loading: false,
merchants: result,
merchantsSearch: result.data
});
};
/**
* @description Close Maps modal.
*/
closeMapsModal() {
this.setState({
mapsLat: 0,
mapsLon: 0,
mapsModalIsOpen: false
});
}
openMaps(name, address, lat, lon){
this.setState({
mapsTitle: name,
mapsDescription: address,
mapsLat: lat,
mapsLon: lon,
mapsModalIsOpen: true
});
}
handleSearchChange(data){
this.setState({ merchantsSearch: data });
}
render() {
const { data: merchantsData } = this.state.merchants;
const { ambassadorsMarkers, merchantsSearch } = this.state;
const merchantMarkers = merchantsSearch.map(merchant => {
const infoDescription =
Address : {merchant.address}
{(merchant.phone) && (
Phone : {merchant.phone}
)}
;
const marker = {
lat: merchant.lat,
lng: merchant.lon,
withInfo: true,
infoTitle: merchant.name,
infoDescription: infoDescription,
};
return marker;
});
return (
{ /* Conditional Rendering */}
{(this.state.loading) ? (
): (
this.closeMapsModal()}
style={mapsStyles}
ariaHideApp={false}
contentLabel={this.state.mapsTitle}
>
{(merchantsData.length > 0) ? (
this.handleSearchChange(data)}
/>
) : (
No Data found
)}
)}
);
}
}
export { MerchantsPage };