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) && (
Telegram: {ambassador.telegram}
)} {(ambassador.keybase) && (
Keybase: {ambassador.keybase}
)} {(ambassador.email) && (
Email: {ambassador.email}
)} {(ambassador.phone) && (
Phone: {ambassador.phone}
)} {(ambassador.url) && (
URL:: {stripProtocol(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) && (
Telegram: {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) && (
URL:: {stripProtocol(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) && (
Telegram: {merchant.telegram_original}
)} {(merchant.website) && (
Website:: {stripProtocol(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) ? ( Loading ): (
this.closeMapsModal()} style={mapsStyles} ariaHideApp={false} contentLabel={this.state.mapsTitle} > {(merchantsData.length > 0) ? (

this.handleSearchChange(data)} />
) : (
No Data found
)}
)}
); } } export { MerchantsPage };