Images compress - header

mx
Letícia Camara 2018-10-15 22:51:00 -03:00
commit 0fa3eda540
8 changed files with 299 additions and 157 deletions

View File

@ -1,6 +1,6 @@
# PalmPay.io Website files
Feel free to copy any/all of these files if you are creating a clone site such as PalmPay.se, PalmPay.pt, PalmPay.mx, PalmPay.my, PalmPay.ca, PalmPay.pro, etc
Feel free to copy any/all of these files if you are creating a clone site such as PalmPay.se, PalmPay.pt, PalmPay.mx, PalmPay.my, PalmPay.ca, PalmPay.pro, PalmPay.solutions, PalmPay.ch, etc
Any questions, feel free to ping us on..
Telegram: https://t.me/Agorise

View File

@ -42,7 +42,6 @@ const propTypes = {
onEdit: PropTypes.func,
onDelete: PropTypes.func,
onMultipleDelete: PropTypes.func,
};
/**
@ -142,14 +141,46 @@ class EnhancedTable extends Component {
* @param {string} query - The search term.
*/
updateQuery = (query) => {
query = query.trim();
// If query is empty or undefined
if (!query) {
this.setState({searchQuery: ''});
this.props.onSearchChange(this.props.data);
return;
}
// 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);
};
/*
@ -177,10 +208,14 @@ class EnhancedTable extends Component {
// Iterate over the search column select boxes
searchColumns.map(column => {
try {
if( column.checked &&
(item[column.name] !== undefined) &&
((item[column.name].toLowerCase()).indexOf(searchQuery.toLowerCase()) !== -1) ){
insert = true;
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) {
@ -196,6 +231,8 @@ class EnhancedTable extends Component {
});
}
return (
<div style={styles.root}>
<EnhancedSearch
@ -238,8 +275,14 @@ class EnhancedTable extends Component {
key={this.props.name + '-data-' + column.id}
component="th" scope="row" padding="none"
style={{margin: 'auto 0', textAlign: 'center', padding: 0}}
>
{n[column.id]}
>{
((n[column.id]) !== undefined && (n[column.id]) !== null) ?
( (n[column.id]).hasOwnProperty('value') ?
n[column.id].value : n[column.id]
)
:
n[column.id]
}
</TableCell>
))}
{this.props.isAdmin &&

View File

@ -117,22 +117,6 @@ function Footer() {
<div
style={{ fontSize: "0.8em" }}
className="text-white col-md-2">
<small>
Site by:
<a
target="_blank"
rel="noopener noreferrer"
href="https://about.me/poqdavid">
poqdavid
</a>
{" "} & {" "}
<a
target="_blank"
rel="noopener noreferrer"
href="http://leticiacamara.com">
Leticia Camara
</a>
</small>
</div>
</div>

View File

@ -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';
@ -33,6 +32,8 @@ const propTypes = {
showControls: PropTypes.bool
};
/**
* This object sets default values to the optional props.
*/
@ -156,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 {
@ -170,83 +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/v1/ambassadors');
this.setState({loading: true});
ambassadors.find().then( (results) => {
const markers = results.data.map(ambassador => {
const marker = {
lat: ambassador.lat,
lng: ambassador.lon,
withInfo: true,
infoTitle: ambassador.nickname,
infoDescription: `${ambassador.city} - ${ambassador.country}`,
};
return 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() {
@ -265,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%` }} />}

View File

@ -52,12 +52,12 @@ const mapsStyles = {
const columnData = [
{ id: 'nickname', numeric: false, disablePadding: true, label: 'Nickname' },
{ id: 'location', numeric: false, disablePadding: true, label: 'Location' },
{ 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}
];
@ -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) {
@ -107,17 +110,64 @@ class AmbassadorsPage extends Component {
* @param {number} [limit=10] - Max items to be returned.
* @param {number} [skip=0] - Start index search
*/
getAmbassadors = async (limit = 10, skip = 0) => {
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/v1/ambassadors');
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 = <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,
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,
@ -129,15 +179,26 @@ class AmbassadorsPage extends Component {
skip = skip + limit;
}
result.data.forEach(function(ambassador){
if(ambassador.city !== undefined) ambassador.city = (ambassador.city).replace(/(^|\s)\S/g, l => l.toUpperCase());
if(ambassador.country !== undefined) ambassador.country = countries.getName(ambassador.country);
// Setup disabled to be string
ambassador.disabled = (ambassador.disabled) ? 'yes': '';
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({loading: false, ambassadors: result});
app.setState({
merchantMarkers: markers
});
};
/**
@ -161,29 +222,78 @@ class AmbassadorsPage extends Component {
});
}
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 (
<span>
{(cities.length > 1) && (<span><br /></span>)}
{cities.map((location, index) => (
<span key={index}>
{`${(location.name).replace(/(^|\s)\S/g, l => l.toUpperCase())} - ${countries.getName(location.country)}`}
{(cities.length > 1) && (<span><br /><br /></span>)}
</span>
))}
</span>
);
}
addMapButton(nickname, cities){
const app = this;
return (
<span>
{cities.map((location, index) => (
<div key={index}>
<Button
className="App-button"
variant="contained"
style={{
backgroundColor: "#2069b3",
color: 'white',
marginTop: 5,
marginBottom: 5
}}
onClick={() => app.openMaps(
nickname,
`${(location.name).replace(/(^|\s)\S/g, l => l.toUpperCase())} - ${countries.getName(location.country)}`,
location.lat,
location.lon
)}
>Show on Map
</Button>
</div>
))}
</span>
);
}
handleSearchChange(data){
this.setState({ ambassadorsSearch: data });
}
render() {
const { data } = this.state.ambassadors;
const { ambassadorsSearch, merchantMarkers } = this.state;
data.map(ambassador => {
ambassador.location = `${ambassador.city} - ${ambassador.country}`;
ambassador.link = <a target="_blank" rel="noopener noreferrer"
href={ambassador.url}>{stripProtocol(ambassador.url)}</a>;
ambassador.map = <Button
className="App-button"
variant="contained"
style={{
backgroundColor: "#2069b3",
color: 'white'
}}
onClick={() => this.openMaps(
ambassador.nickname,
`${ambassador.city} - ${ambassador.country}`,
ambassador.lat,
ambassador.lon
)}
>Show on Map
</Button>;
return ambassador;
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 (
@ -238,6 +348,7 @@ class AmbassadorsPage extends Component {
showSearchColumns={false}
rowsPerPage={10}
isAdmin={false}
onSearchChange={(data) => this.handleSearchChange(data)}
/>
</div>
) : (
@ -245,6 +356,8 @@ class AmbassadorsPage extends Component {
)}
<div className="map">
<LayerMap
ambassadors={ambassadorsMarkers}
merchants={merchantMarkers}
ambassadorsLayer={true}
merchantsLayer={false}
mapHeight={'600px'}

View File

@ -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'}

View File

@ -4,6 +4,7 @@ const app = feathers();
// Change to your production ambassador web service
// const restClient = feathers.rest('http://localhost:3030');
const restClient = feathers.rest('https://palmpaybackend.leticiacamara.com');
// Configure an Fetch AJAX library with that client. For fetch details see https://facebook.github.io/react-native/docs/network.html
// For rest details see https://docs.feathersjs.com/api/client/rest.html
app.configure(restClient.fetch(window.fetch));

View File

@ -7,10 +7,12 @@ function addProtocol(url, protocol) {
}
function stripProtocol(url){
if(!url) return '';
return url.replace(/(^\w+:|^)\/\//, '');
}
function getProtocol(url){
if(!url) return '';
const values = url.match(/(^\w+:|^)\/\//);
return values && (values.length > 0) ? values[0] : '';