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';
import sortBy from 'sort-by';
// 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 { WHICH_OPTIONS } from '../../utils/constants';
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: 'phone', numeric: false, disablePadding: true, label: 'Phone' },
{ id: 'telegram', numeric: false, disablePadding: true, label: 'Telegram' },
{ id: 'link', numeric: false, disablePadding: false, label: 'Website' },
{ 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: [],
tellersMarkers: [],
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 tellers from the web service
* @param {number} [limit=10] - Max items to be returned.
* @param {number} [skip=0] - Start index search
*/
getTellers = 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 tellers = Client.service('api/v2/tellers');
this.setState({loading: true});
let result;
while(skip < total){
let partialResponse = await tellers.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(tellers){
if(tellers.city !== undefined) tellers.city = (tellers.city).replace(/(^|\s)\S/g, l => l.toUpperCase());
if(tellers.country !== undefined) tellers.country = countries.getName(tellers.country);
});
result.data.map(teller => {
teller.link = {
searchText: stripProtocol(teller.url),
value: (
{stripProtocol(teller.url)}
)
};
teller.location = {
searchText: `${teller.country} - ${teller.city}`,
value: (teller.city) ? `${teller.city} - ${teller.country}`: teller.country
}
teller.map = ;
return teller;
});
// Once both return, update the state
app.setState({
loading: false,
tellersMarkers: result.data
});
};
getTellerMarker = (teller) => {
const which = WHICH_OPTIONS.filter(w => w.id.toLowerCase() === teller.which.toLowerCase());
teller.which_value = ( teller.which && which.length > 0) ?
which[0].value :
'';
const infoDescription = (
Address: {teller.address}
{(teller.which) && (
Which:: {teller.which}
)}
{(teller.bitshares_address) && (
BTS Account:: {teller.bitshares_address}
)}
{(teller.address) && (
Address:: {teller.address}
)}
{(teller.telegram_original) && (
)
}
{(teller.keybase) && (
Keybase: {teller.keybase}
)}
{(teller.whatsapp) && (
Whatsapp: {teller.whatsapp}
)}
{(teller.viber) && (
Viber: {teller.viber}
)}
{(teller.email) && (
Email: {teller.email}
)}
{(teller.phone) && (
Phone: {teller.phone}
)}
{(teller.url) && (
)}
);
const marker = {
lat: teller.lat,
lng: teller.lon,
withInfo: true,
infoTitle: teller.gt_name,
infoDescription: infoDescription,
};
return marker;
};
/**
* @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 => {
if(merchant.telegram){
merchant.telegram_original = merchant.telegram;
merchant.telegram = {
searchText: merchant.telegram,
value: (
{merchant.telegram}
)
};
}
else{
}
merchant.link = {
searchText: stripProtocol(merchant.website),
value: (
{stripProtocol(merchant.website)}
)
};
merchant.location = {
searchText: `${merchant.country} - ${merchant.city}`,
value: (merchant.city) ? `${merchant.city} - ${merchant.country}`: merchant.country
}
merchant.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, marker){
this.setState({
mapsTitle: name,
mapsDescription: marker.infoDescription,
mapsLat: marker.lat,
mapsLon: marker.lng,
mapsModalIsOpen: true
});
}
getMerchantMarker = (merchant) => {
const infoDescription =
Address: {merchant.address}
{(merchant.phone) && (
Phone: {merchant.phone}
)}
{(merchant.telegram_original) && (
)}
{(merchant.website) && (
)}
;
const marker = {
lat: merchant.lat,
lng: merchant.lon,
withInfo: true,
infoTitle: merchant.name,
infoDescription: infoDescription,
};
return marker;
};
handleSearchChange(data){
this.setState({ merchantsSearch: data });
}
render() {
let { data: merchantsData } = this.state.merchants;
const { ambassadorsMarkers, merchantsSearch } = this.state;
const merchantMarkers = merchantsSearch.map(merchant => {
return this.getMerchantMarker(merchant);
});
merchantsData = merchantsData.sort(sortBy('name'));
const textComponent = (
);
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 };