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 Footer from '../Footer'; import EnhancedTable from '../EnhancedTable'; import LayerMap from '../LayerMap'; import PreviewMap from '../PreviewMap'; // Helpers import Client from '../../utils/feathers'; import { stripProtocol } from '../../utils/url'; import Countries from 'country-list'; // Images import AmbassadorPin from '../../assets/img/map/ambassador_pin.png'; import LoadingGif from '../../assets/img/loading_icon.gif'; // 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: 'nickname', numeric: false, disablePadding: true, label: 'Nickname' }, { id: 'telegram', numeric: false, disablePadding: false, label: 'Telegram Account' }, { id: 'keybase', numeric: false, disablePadding: false, label: 'Keybase' }, { id: 'email', numeric: false, disablePadding: false, label: 'Email' }, { id: 'phone', numeric: false, disablePadding: false, label: 'Phone' }, { id: 'link', numeric: false, disablePadding: false, label: 'URL' }, { id: 'location', numeric: false, disablePadding: true, label: 'Location' }, { id: 'map', numeric: false, disablePadding: false, label: 'Maps', disableSearch: true} ]; /** * Ambassador page component. */ class AmbassadorsPage extends Component { constructor(props, context) { super(props, context); /** @type {ComponentState} */ this.state = { ambassadors: { total: 0, limit: 0, skip: 0, data: [] }, ambassadorsSearch: [], merchantMarkers: [], loading: true, rowsPerPage: [100,200,300], numberOfRows: 100, page: 1, total: undefined, mapsModalIsOpen: false, mapsTitle: '', mapsDescription: '', mapsLat: 0, mapsLon: 0, }; } /** * @description Lifecycle event handler called just after the App loads into the DOM. */ UNSAFE_componentWillMount() { // Get the ambassadors list 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'); this.setState({loading: true}); let result; while(skip < total){ let partialResponse = await ambassadors.find({ query: { $sort: { account: 1 }, $limit: limit, $skip: skip, disabled: false } }); total = partialResponse.total; result === undefined ? result = partialResponse : partialResponse.data.map(this.fillResults(result)); 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 = {stripProtocol(ambassador.url)}; }); // Once both return, update the state 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 }); }; /** * @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 }); } addLocationSearchText(cities){ let searchText = ''; cities.forEach((location) => { searchText += `${(location.name).replace(/(^|\s)\S/g, l => l.toUpperCase())} - ${countries.getName(location.country)} `; }); return searchText; } addLocation(cities){ return ( {(cities.length > 1) && (
)} {cities.map((location, index) => ( {`${(location.name).replace(/(^|\s)\S/g, l => l.toUpperCase())} - ${countries.getName(location.country)}`} {(cities.length > 1) && (

)}
))}
); } addMapButton(nickname, cities){ const app = this; return ( {cities.map((location, index) => (
))}
); } handleSearchChange(data){ this.setState({ ambassadorsSearch: data }); } render() { const { data } = this.state.ambassadors; const { ambassadorsSearch, merchantMarkers } = this.state; 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 (

{ /* Conditional Rendering */} {(this.state.loading) ? ( Loading ): (

this.closeMapsModal()} style={mapsStyles} ariaHideApp={false} contentLabel={this.state.mapsTitle} > {(data.length > 0) ? (

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