Add Drop and Send, replace loyalty system with accounts, TODO: save credit card info
This commit is contained in:
parent
d819f11228
commit
671ca65661
BIN
www/assets/images/dropbox-icon.png
Normal file
BIN
www/assets/images/dropbox-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
202
www/assets/images/dropbox-icon.svg
Normal file
202
www/assets/images/dropbox-icon.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 14 KiB |
@ -4,32 +4,66 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
class Map {
|
||||
constructor(mapboxElement) {
|
||||
class MapControl {
|
||||
constructor(mapboxElement, interactive) {
|
||||
this.mapObj = null;
|
||||
this.mapEl = mapboxElement;
|
||||
this.interactiveMap = interactive == true;
|
||||
}
|
||||
|
||||
createMap() {
|
||||
if (mapboxgl.supported()) {
|
||||
$(this.mapEl).css("display", "");
|
||||
this.mapObj = maplibreMap(this.mapEl);
|
||||
this.mapObj = maplibreMap(this.mapEl, this.interactiveMap);
|
||||
} else {
|
||||
console.log("maplibre-gl not supported, disabling map");
|
||||
$(this.mapEl).css("display", "none");
|
||||
}
|
||||
}
|
||||
|
||||
clearOldMarkersAndCenterMapOnNewMarker(classname) {
|
||||
var latitude = $(this.mapEl).data("latitude");
|
||||
var longitude = $(this.mapEl).data("longitude");
|
||||
var accurate = $(this.mapEl).data("accurate") == true;
|
||||
|
||||
/**
|
||||
* Clear all markers from the map, make a new marker, and fly to it.
|
||||
* @param {string} classname CSS class for the marker, for adding icon and stuff. Default will be invisible and 0x0px.
|
||||
* @param {number} latitude
|
||||
* @param {number} longitude
|
||||
* @param {boolean} accurate set true to zoom to street level (z13), false to zoom to general area (z10).
|
||||
* @returns {undefined}
|
||||
*/
|
||||
clearMarkersAndCenterMapOnNewMarker(classname, latitude, longitude, accurate) {
|
||||
this.mapObj.removeMarkers();
|
||||
this.mapObj.addMarker(latitude, longitude, classname);
|
||||
this.mapObj.animateMapIn(latitude, longitude, (accurate ? 13 : 10));
|
||||
}
|
||||
|
||||
loadMarkersFromGeoJson(geojson, iconname, name) {
|
||||
this.mapObj.addSource("markers-" + name, {
|
||||
'type': 'geojson',
|
||||
'data': geojson
|
||||
});
|
||||
this.mapObj.addLayer({
|
||||
id: "marker-layer-" + name,
|
||||
type: "symbol",
|
||||
source: "markers-" + name,
|
||||
layout: {
|
||||
"icon-image": iconname,
|
||||
"icon-anchor": "bottom",
|
||||
'icon-allow-overlap': true
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
loadIcon(url, name, callback) {
|
||||
var mapObj = this.mapObj;
|
||||
this.mapObj.loadImage(
|
||||
url,
|
||||
function (error, image) {
|
||||
if (error)
|
||||
throw error;
|
||||
mapObj.addImage(name, image);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy and re-create the map.
|
||||
* @returns {undefined}
|
||||
@ -57,10 +91,10 @@ class Map {
|
||||
}
|
||||
|
||||
setMapLocation(latitude, longitude) {
|
||||
if (mapObj == null) {
|
||||
if (this.mapObj == null) {
|
||||
return;
|
||||
}
|
||||
mapObj.setMapLocation(latitude, longitude);
|
||||
this.mapObj.setMapLocation(latitude, longitude);
|
||||
}
|
||||
|
||||
animateMapIn(latitude, longitude, zoom, heading) {
|
249
www/assets/js/account.js
Normal file
249
www/assets/js/account.js
Normal file
@ -0,0 +1,249 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
|
||||
function checkAccountStatus(callback) {
|
||||
if (inStorage("phonenumber")) {
|
||||
apirequest(SETTINGS.apis.authorstartverify, {
|
||||
phone: getStorage("phonenumber"),
|
||||
accountkey: (inStorage("accountkey") ? getStorage("accountkey") : "")
|
||||
}, function (resp) {
|
||||
if (resp.status == "OK") {
|
||||
if (resp.authok && resp.accountok) {
|
||||
callback(true);
|
||||
} else if (!resp.authok && resp.accountok) {
|
||||
// verify phone or email
|
||||
// openAccountVerify(resp.verifymsg);
|
||||
callback("noauth", resp.verifymsg);
|
||||
} else if (!resp.authok && !resp.accountok) {
|
||||
callback(false);
|
||||
} else {
|
||||
callback("badstate");
|
||||
}
|
||||
} else {
|
||||
app.dialog.alert(resp.msg, "Error");
|
||||
}
|
||||
}, function (err) {
|
||||
app.dialog.alert("Something went wrong. Try again later.", "Error");
|
||||
});
|
||||
} else {
|
||||
callback(false);
|
||||
}
|
||||
}
|
||||
|
||||
function openAccountVerify(verifymsg) {
|
||||
app.dialog.prompt(verifymsg, "Verify Your Account", function (val) {
|
||||
verifyCode(val);
|
||||
}, function (cancel) {
|
||||
// shrug
|
||||
}, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm auth/login code with server and store login key if successful.
|
||||
* @param {type} code
|
||||
* @returns {undefined}
|
||||
*/
|
||||
function verifyCode(code) {
|
||||
app.dialog.preloader("Verifying...");
|
||||
apirequest(SETTINGS.apis.verifyauthcode, {
|
||||
code: code,
|
||||
phone: getStorage("phonenumber")
|
||||
}, function (resp) {
|
||||
app.dialog.close();
|
||||
if (resp.status == "OK") {
|
||||
setStorage("accountkey", resp.authkey);
|
||||
app.dialog.alert("This device has been successfully linked to your Helena Express account.", "Account verified!");
|
||||
displayAccountInfo();
|
||||
} else if (resp.status == "ERROR") {
|
||||
app.dialog.alert(resp.msg, "Error");
|
||||
}
|
||||
}, function (error) {
|
||||
app.dialog.close();
|
||||
app.dialog.alert("There's a server or network problem. Check your Internet connection or try again later.", "Error");
|
||||
});
|
||||
}
|
||||
|
||||
function displayAccountInfo() {
|
||||
$("#loyaltyBalanceBox").addClass("display-none");
|
||||
$("#loyaltyErrorMessage").html("");
|
||||
if (inStorage("accountkey") && inStorage("phonenumber")) {
|
||||
} else {
|
||||
$("#loyaltyErrorMessage").text("Error: No account connected.");
|
||||
return;
|
||||
}
|
||||
apirequest(SETTINGS.apis.getaccountinfo, {
|
||||
phone: getStorage("phonenumber"),
|
||||
accountkey: getStorage("accountkey")
|
||||
}, function (success) {
|
||||
$("#hasaccountbox").css("display", "");
|
||||
$("#loadingaccountbox").css("display", "none");
|
||||
if (success.status == "OK") {
|
||||
$("#loyaltyCreditBalanceHeading").text(success.credits + " points");
|
||||
$("#loyaltyBalanceBox").removeClass("display-none");
|
||||
|
||||
var canvas = document.createElement('canvas');
|
||||
|
||||
bwipjs.toCanvas(canvas, {
|
||||
bcid: 'code128', // Barcode type
|
||||
text: success.phone, // Text to encode
|
||||
scaleX: 5,
|
||||
scaleY: 1,
|
||||
includetext: false, // Show human-readable text
|
||||
textxalign: 'center', // Always good to set this
|
||||
eclevel: 'M'
|
||||
});
|
||||
$("#accountnumberspan").text("Account number: " + success.phone);
|
||||
document.getElementById("loyaltyBarcodeImg").src = canvas.toDataURL('image/png');
|
||||
|
||||
if (success.payments_setup === false) {
|
||||
$("#addPaymentMethodBox").css("display", "");
|
||||
}
|
||||
|
||||
|
||||
$("#accountupdateform input#name").val(success.name);
|
||||
$("#accountupdateform input#email").val(success.email);
|
||||
$("#accountupdateform input#streetaddress").val(success.streetaddress);
|
||||
$("#accountupdateform input#zipcode").val(success.zipcode);
|
||||
} else {
|
||||
$("#loyaltyBalanceBox").addClass("display-none");
|
||||
$("#loyaltyErrorMessage").text("Error: " + success.msg);
|
||||
}
|
||||
}, function (error) {
|
||||
$("#loyaltyErrorMessage").text("Error: Couldn't get your account info. Try again later.");
|
||||
}, "GET");
|
||||
}
|
||||
|
||||
$("#app").on("click", "#setupAccountBtn", function () {
|
||||
if ($("#accountsetupform input#phonenumber").val() == "") {
|
||||
app.dialog.alert("Add your phone number.", "Error");
|
||||
return;
|
||||
}
|
||||
if ($("#accountsetupform input#name").val() == "") {
|
||||
app.dialog.alert("Add your name.", "Error");
|
||||
return;
|
||||
}
|
||||
if ($("#accountsetupform input#email").val() == "") {
|
||||
app.dialog.alert("Add your email address.", "Error");
|
||||
return;
|
||||
}
|
||||
if ($("#accountsetupform input#streetaddress").val() == "") {
|
||||
app.dialog.alert("Add your street address.", "Error");
|
||||
return;
|
||||
}
|
||||
if ($("#accountsetupform input#zipcode").val() == "") {
|
||||
app.dialog.alert("Add your ZIP Code.", "Error");
|
||||
return;
|
||||
}
|
||||
app.dialog.preloader("Creating Account...");
|
||||
apirequest(SETTINGS.apis.accountregister, {
|
||||
phone: $("#accountsetupform input#phonenumber").val(),
|
||||
name: $("#accountsetupform input#name").val(),
|
||||
email: $("#accountsetupform input#email").val(),
|
||||
address: $("#accountsetupform input#streetaddress").val(),
|
||||
zipcode: $("#accountsetupform input#zipcode").val()
|
||||
}, function (resp) {
|
||||
app.dialog.close();
|
||||
|
||||
if (resp.status == "ERROR") {
|
||||
app.dialog.alert(resp.msg, "Error");
|
||||
return;
|
||||
} else {
|
||||
setStorage("phonenumber", resp.phone);
|
||||
router.refreshPage();
|
||||
}
|
||||
}, function (error) {
|
||||
app.dialog.close();
|
||||
app.dialog.alert("There's a server or network problem. Check your Internet connection or try again later.", "Error");
|
||||
});
|
||||
});
|
||||
|
||||
$("#app").on("click", "#updateAccountBtn", function () {
|
||||
if ($("#accountupdateform input#name").val() == "") {
|
||||
app.dialog.alert("Add your name.", "Error");
|
||||
return;
|
||||
}
|
||||
if ($("#accountupdateform input#email").val() == "") {
|
||||
app.dialog.alert("Add your email address.", "Error");
|
||||
return;
|
||||
}
|
||||
if ($("#accountupdateform input#streetaddress").val() == "") {
|
||||
app.dialog.alert("Add your street address.", "Error");
|
||||
return;
|
||||
}
|
||||
if ($("#accountupdateform input#zipcode").val() == "") {
|
||||
app.dialog.alert("Add your ZIP Code.", "Error");
|
||||
return;
|
||||
}
|
||||
app.dialog.preloader("Updating Account...");
|
||||
apirequest(SETTINGS.apis.accountregister, {
|
||||
phone: getStorage("phonenumber"),
|
||||
accountkey: getStorage("accountkey"),
|
||||
name: $("#accountupdateform input#name").val(),
|
||||
email: $("#accountupdateform input#email").val(),
|
||||
address: $("#accountupdateform input#streetaddress").val(),
|
||||
zipcode: $("#accountupdateform input#zipcode").val()
|
||||
}, function (resp) {
|
||||
app.dialog.close();
|
||||
|
||||
if (resp.status == "ERROR") {
|
||||
app.dialog.alert(resp.msg, "Error");
|
||||
return;
|
||||
} else {
|
||||
app.popup.close("#accountUpdatePopup", true);
|
||||
setStorage("phonenumber", resp.phone);
|
||||
router.refreshPage();
|
||||
app.dialog.alert("Account details updated.", "Account Updated");
|
||||
}
|
||||
}, function (error) {
|
||||
app.dialog.close();
|
||||
app.dialog.alert("There's a server or network problem. Check your Internet connection or try again later.", "Error");
|
||||
});
|
||||
});
|
||||
|
||||
$("#app").on("click", "#connectExistingAccountBtn", function () {
|
||||
app.dialog.prompt("Enter your phone number or account number:", "Connect Your Account", function (val) {
|
||||
var phone = val.replace(/\D/g, '');
|
||||
if (phone.length < 10) {
|
||||
app.dialog.alert("Please enter a full 10-digit phone number.", "Oops!");
|
||||
return;
|
||||
}
|
||||
setStorage("phonenumber", phone);
|
||||
router.refreshPage();
|
||||
}, function (cancel) {
|
||||
// shrug
|
||||
}, "");
|
||||
});
|
||||
|
||||
$("#app").on("popup:open", "#accountUpdatePopup", function () {
|
||||
app.input.checkEmptyState("#accountupdateform input#name");
|
||||
app.input.checkEmptyState("#accountupdateform input#email");
|
||||
app.input.checkEmptyState("#accountupdateform input#streetaddress");
|
||||
app.input.checkEmptyState("#accountupdateform input#zipcode");
|
||||
});
|
||||
|
||||
function initAccountPage() {
|
||||
checkAccountStatus(function (result, msg) {
|
||||
switch (result) {
|
||||
case true:
|
||||
displayAccountInfo();
|
||||
break;
|
||||
case false:
|
||||
$("#setupaccountbox").css("display", "");
|
||||
$("#loadingaccountbox").css("display", "none");
|
||||
break;
|
||||
case "noauth":
|
||||
openAccountVerify(msg);
|
||||
break;
|
||||
case "badstate":
|
||||
app.dialog.alert("Your account is in an unstable state. This shouldn't happen. Please contact us at (406) 389-8988 and we'll fix it.", "Error");
|
||||
break;
|
||||
default:
|
||||
app.dialog.alert("Something went very wrong. Close the app completely (swipe it away from the app switcher) and re-open it. If you continue to get this message, contact us for help: (406) 389-8988", "Error");
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
66
www/assets/js/dropandsend.js
Normal file
66
www/assets/js/dropandsend.js
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
function captureAndSendPickupCode() {
|
||||
scanBarcode(function (result) {
|
||||
var code = "";
|
||||
var coderegex = /^[0-9a-zA-Z]{5,40}$/;
|
||||
if (result.startsWith("https://helena.express/dropandsend#")) {
|
||||
code = result.split("#")[1];
|
||||
} else if (coderegex.test(result)) {
|
||||
code = result;
|
||||
} else {
|
||||
app.dialog.alert("That's not a valid drop box code.", "Error");
|
||||
return;
|
||||
}
|
||||
sendPickupCode(code);
|
||||
}, function () {
|
||||
app.dialog.prompt("Something went wrong while trying to scan the barcode. Type the location number to request a pickup.", "Send Pickup Code", function (code) {
|
||||
if (code == "") {
|
||||
app.dialog.alert("You didn't enter a location number.", "Error");
|
||||
} else {
|
||||
sendPickupCode(code);
|
||||
}
|
||||
}, function (cancel) {
|
||||
|
||||
}, "");
|
||||
});
|
||||
}
|
||||
|
||||
function sendPickupCode(code) {
|
||||
app.dialog.preloader("Loading...");
|
||||
apirequest(SETTINGS.apis.dropandsendpickup, {
|
||||
phone: getStorage("phonenumber"),
|
||||
accountkey: getStorage("accountkey"),
|
||||
locationnumber: code
|
||||
}, function (resp) {
|
||||
app.dialog.close();
|
||||
if (resp.status == "OK") {
|
||||
app.dialog.alert("Thank you for using Helena Express! You'll get an emailed receipt after we pick up and process your package(s).", "Pickup Requested!");
|
||||
} else if (resp.status == "ERROR") {
|
||||
app.dialog.alert(resp.msg, "Error");
|
||||
}
|
||||
}, function (error) {
|
||||
app.dialog.close();
|
||||
app.dialog.alert("There's a server or network problem. Check your Internet connection or try again later.", "Error");
|
||||
});
|
||||
}
|
||||
|
||||
$("#app").on("click", "#pickupCodeQRScanBtn", function () {
|
||||
captureAndSendPickupCode();
|
||||
});
|
||||
|
||||
$("#app").on("click", "#pickupCodeManualEntryBtn", function () {
|
||||
app.dialog.prompt("Enter the location number to request a pickup.", "Send Pickup Code", function (code) {
|
||||
if (code == "") {
|
||||
app.dialog.alert("You didn't enter a location number.", "Error");
|
||||
} else {
|
||||
sendPickupCode(code);
|
||||
}
|
||||
}, function (cancel) {
|
||||
|
||||
}, "");
|
||||
});
|
@ -1,52 +0,0 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
|
||||
function displayLoyaltyPoints() {
|
||||
$("#loyalty-balance-box").addClass("display-none");
|
||||
$("#loyalty-error").html("");
|
||||
if (inStorage("phonenumber")) {
|
||||
var phone = getStorage("phonenumber");
|
||||
} else {
|
||||
$("#loyalty-error").text("Error: No phone number saved.");
|
||||
}
|
||||
app.dialog.preloader("Checking points balance...");
|
||||
apirequest(SETTINGS.apis.loyalty, {phone: phone}, function (success) {
|
||||
app.dialog.close();
|
||||
if (success.status == "OK") {
|
||||
$("#loyalty-credit-balance").text(success.credits + " points");
|
||||
$("#loyalty-balance-box").removeClass("display-none");
|
||||
|
||||
var canvas = document.createElement('canvas');
|
||||
|
||||
bwipjs.toCanvas(canvas, {
|
||||
bcid: 'code128', // Barcode type
|
||||
text: success.phone, // Text to encode
|
||||
scaleX: 5,
|
||||
scaleY: 1,
|
||||
includetext: false, // Show human-readable text
|
||||
textxalign: 'center', // Always good to set this
|
||||
eclevel: 'M'
|
||||
});
|
||||
document.getElementById("loyalty-barcode").src = canvas.toDataURL('image/png');
|
||||
} else {
|
||||
$("#loyalty-balance-box").addClass("display-none");
|
||||
$("#loyalty-error").text("Error: " + success.message);
|
||||
}
|
||||
}, function (error) {
|
||||
$("#loyalty-error").text("Error: Couldn't check your points balance. Try again later.");
|
||||
}, "GET");
|
||||
}
|
||||
|
||||
function savePhoneNumber() {
|
||||
var phone = $("#phonenumber").val().replace(/\D/g, '');
|
||||
if (phone.length < 10) {
|
||||
app.dialog.alert("Please enter a full 10-digit phone number.", "Oops!");
|
||||
return;
|
||||
}
|
||||
setStorage("phonenumber", phone);
|
||||
router.refreshPage();
|
||||
}
|
@ -5,4 +5,4 @@
|
||||
*/
|
||||
|
||||
|
||||
///var trackingMap = new Map(document.getElementById("mapbox-track"));
|
||||
var dropboxMap = null;
|
@ -4,7 +4,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
function maplibreMap(containerEl) {
|
||||
function maplibreMap(containerEl, interactive) {
|
||||
|
||||
var theme = "liberty";
|
||||
if ($("#app").hasClass("theme-dark")) {
|
||||
@ -17,13 +17,39 @@ function maplibreMap(containerEl) {
|
||||
container: containerEl.id,
|
||||
style: SETTINGS.maptileurls[theme].json,
|
||||
//attributionControl: false,
|
||||
interactive: false,
|
||||
interactive: interactive,
|
||||
pitch: 0,
|
||||
zoom: 1,
|
||||
maxZoom: 14,
|
||||
maxZoom: 18,
|
||||
center: [-97, 38]
|
||||
});
|
||||
|
||||
if (interactive) {
|
||||
map.addControl(new mapboxgl.NavigationControl({
|
||||
visualizePitch: false,
|
||||
showCompass: false
|
||||
}), 'top-left');
|
||||
|
||||
map.addControl(
|
||||
new mapboxgl.GeolocateControl({
|
||||
positionOptions: {
|
||||
enableHighAccuracy: true,
|
||||
timeout: 10 * 1000
|
||||
},
|
||||
fitBoundsOptions: {
|
||||
maxZoom: 16
|
||||
},
|
||||
trackUserLocation: false
|
||||
}), 'top-left'
|
||||
);
|
||||
|
||||
map.addControl(
|
||||
new mapboxgl.ScaleControl({
|
||||
unit: "imperial"
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
map.mapEasing = function (t) {
|
||||
return t * (2 - t);
|
||||
};
|
||||
|
@ -179,7 +179,13 @@ function initCordova() {
|
||||
|
||||
// Handle geo: urls
|
||||
$("#app").on("click", "a[href^='geo:']", function (evt) {
|
||||
if (cordova.platformId == "ios") {
|
||||
window.open($(this).attr("href").replace("geo:", "http://maps.apple.com/?q="), "_system");
|
||||
} else if (cordova.platformId == "android") {
|
||||
window.open($(this).attr("href").replace("geo:", "geo:0,0?q="), "_system");
|
||||
} else {
|
||||
window.open($(this).attr("href"), "_system");
|
||||
}
|
||||
evt.preventDefault();
|
||||
});
|
||||
}
|
||||
@ -223,7 +229,7 @@ function initNW() {
|
||||
setupHTML5BarcodeScanner();
|
||||
|
||||
// Handle geo: urls
|
||||
$("#app").on("click", ".geolink", function (evt) {
|
||||
$("#app").on("click", "a[href^='geo:']", function (evt) {
|
||||
require('nw.gui').Shell.openExternal($(this).attr("href"));
|
||||
evt.preventDefault();
|
||||
});
|
||||
|
@ -47,14 +47,15 @@
|
||||
<script src="assets/js/platform.js"></script>
|
||||
|
||||
<script src="assets/js/map_maplibre.js"></script>
|
||||
<script src="assets/js/Map.class.js"></script>
|
||||
<script src="assets/js/MapControl.class.js"></script>
|
||||
<script src="assets/js/map.js"></script>
|
||||
<script src="assets/js/util.js"></script>
|
||||
<script src="assets/js/track.js"></script>
|
||||
<script src="assets/js/dropandsend.js"></script>
|
||||
<script src="assets/js/addresscode.js"></script>
|
||||
<script src="assets/js/rates.js"></script>
|
||||
<script src="assets/js/noticeslip.js"></script>
|
||||
<script src="assets/js/loyalty.js"></script>
|
||||
<script src="assets/js/account.js"></script>
|
||||
|
||||
<script src="routes.js"></script>
|
||||
<script src="assets/js/main.js"></script>
|
178
www/pages/account.html
Normal file
178
www/pages/account.html
Normal file
@ -0,0 +1,178 @@
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<div class="page" data-name="account">
|
||||
|
||||
<div class="navbar">
|
||||
<div class="navbar-bg"></div>
|
||||
<div class="navbar-inner">
|
||||
<div class="left">
|
||||
<a class="link back hapticbtn" href="#">
|
||||
<i class="icon icon-back"></i>
|
||||
<span class="if-not-md">Back</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="title">My Account</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="page-content">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-100 medium-90 xlarge-75 margin-horizontal">
|
||||
<div class="card margin">
|
||||
<div class="card-content text-align-center padding-vertical">
|
||||
|
||||
<div id="loadingaccountbox" style="text-align: center;">
|
||||
<div class="preloader"></div>
|
||||
<br /><br />
|
||||
Loading...
|
||||
</div>
|
||||
|
||||
<div id="hasaccountbox" style="display: none;">
|
||||
<div id="addPaymentMethodBox" style="display: none;">
|
||||
Add a credit or debit card to use Drop and Send. It'll be securely saved for future use.
|
||||
<a class="button hapticbtn button-fill margin" href="/account/managepayment" onclick="alert('TODO')"><i class="fas fa-credit-card"></i> Add Card</a>
|
||||
<hr />
|
||||
</div>
|
||||
<div id="loyaltyBalanceBox" class="card-content-padding">
|
||||
<div>You have earned a total of</div>
|
||||
<h1 id="loyaltyCreditBalanceHeading">...</h1>
|
||||
<img id="loyaltyBarcodeImg" style="width: 90%; max-width: 300px; padding: 1.2em; background: white;" />
|
||||
<br />
|
||||
<span id="accountnumberspan"></span>
|
||||
</div>
|
||||
<div class="block">
|
||||
<div class="button hapticbtn popup-open" data-popup="#accountUpdatePopup"><i class="fas fa-edit"></i> Update account details</div>
|
||||
</div>
|
||||
<div id="loyaltyErrorMessage"></div>
|
||||
<div class="block">
|
||||
Loyalty points have no cash value. All points and associated discounts
|
||||
are offered as a courtesy by and at the discretion of Helena Express
|
||||
and may be revoked, canceled, or modified at any time for any reason.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="setupaccountbox" style="display: none;">
|
||||
<div class="block">
|
||||
Set up an account to use our Drop and Send service, earn rewards points, and more!
|
||||
</div>
|
||||
<div class="block">
|
||||
Already have an account?
|
||||
<div class="button hapticbtn" id="connectExistingAccountBtn">
|
||||
<span class="taptext">Tap</span>
|
||||
<span class="clicktext">Click</span> here</div>
|
||||
to connect it.
|
||||
</div>
|
||||
|
||||
<div class="list">
|
||||
<ul id="accountsetupform">
|
||||
<li class="item-content item-input item-input-outline">
|
||||
<div class="item-inner">
|
||||
<div class="item-title item-floating-label">Name</div>
|
||||
<div class="item-input-wrap">
|
||||
<input type="text" id="name" />
|
||||
<span class="input-clear-button"></span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="item-content item-input item-input-outline">
|
||||
<div class="item-inner">
|
||||
<div class="item-title item-floating-label">Email</div>
|
||||
<div class="item-input-wrap">
|
||||
<input type="email" id="email" autocorrect="off" />
|
||||
<span class="input-clear-button"></span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="item-content item-input item-input-outline">
|
||||
<div class="item-inner">
|
||||
<div class="item-title item-floating-label">Phone Number</div>
|
||||
<div class="item-input-wrap">
|
||||
<input type="tel" id="phonenumber" />
|
||||
<span class="input-clear-button"></span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="item-content item-input item-input-outline">
|
||||
<div class="item-inner">
|
||||
<div class="item-title item-floating-label">House number and street</div>
|
||||
<div class="item-input-wrap">
|
||||
<input type="text" id="streetaddress" placeholder="1234 Notareal Road" autocomplete="off" autocorrect="off"/>
|
||||
<span class="input-clear-button"></span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="item-content item-input item-input-outline">
|
||||
<div class="item-inner">
|
||||
<div class="item-title item-floating-label">ZIP Code</div>
|
||||
<div class="item-input-wrap">
|
||||
<input type="text" id="zipcode" placeholder="59601" autocomplete="off" autocorrect="off" inputmode="numeric"/>
|
||||
<span class="input-clear-button"></span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card-content-padding">
|
||||
<div class="button hapticbtn" id="setupAccountBtn"><i class="far fa-plus"></i> Setup Account</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="popup text-color-black" id="accountUpdatePopup">
|
||||
<div class="list">
|
||||
<ul id="accountupdateform">
|
||||
<li class="item-content item-input item-input-outline">
|
||||
<div class="item-inner">
|
||||
<div class="item-title item-floating-label">Name</div>
|
||||
<div class="item-input-wrap">
|
||||
<input type="text" id="name" />
|
||||
<span class="input-clear-button"></span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="item-content item-input item-input-outline">
|
||||
<div class="item-inner">
|
||||
<div class="item-title item-floating-label">Email</div>
|
||||
<div class="item-input-wrap">
|
||||
<input type="email" id="email" autocorrect="off" />
|
||||
<span class="input-clear-button"></span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="item-content item-input item-input-outline">
|
||||
<div class="item-inner">
|
||||
<div class="item-title item-floating-label">House number and street</div>
|
||||
<div class="item-input-wrap">
|
||||
<input type="text" id="streetaddress" placeholder="1234 Notareal Road" autocomplete="off" autocorrect="off"/>
|
||||
<span class="input-clear-button"></span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="item-content item-input item-input-outline">
|
||||
<div class="item-inner">
|
||||
<div class="item-title item-floating-label">ZIP Code</div>
|
||||
<div class="item-input-wrap">
|
||||
<input type="text" id="zipcode" placeholder="59601" autocomplete="off" autocorrect="off" inputmode="numeric"/>
|
||||
<span class="input-clear-button"></span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card-content-padding">
|
||||
<div class="button button-fill hapticbtn" id="updateAccountBtn"><i class="far fa-edit"></i> Update Account</div>
|
||||
</div>
|
||||
<div class="block text-align-center">
|
||||
<p><a class="button popup-close" href="#">Cancel</a></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
62
www/pages/dropandsend.html
Normal file
62
www/pages/dropandsend.html
Normal file
@ -0,0 +1,62 @@
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<div class="page" data-name="dropandsend">
|
||||
|
||||
<div class="navbar">
|
||||
<div class="navbar-bg"></div>
|
||||
<div class="navbar-inner">
|
||||
<div class="left">
|
||||
<a class="link back" href="#">
|
||||
<i class="icon icon-back"></i>
|
||||
<span class="if-not-md">Back</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="title">Drop and Send</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="page-content">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-100 medium-60 large-50 xlarge-40">
|
||||
<div class="list transparent no-hairlines no-margin-top-sm tablet-inset elevation-tablet media-list">
|
||||
<ul>
|
||||
<li class="padding">
|
||||
Use one of our Drop and Send package drop locations to send mail,
|
||||
packages, and more. No lines, no appointment, no postage, no label
|
||||
printing, no problem!
|
||||
</li>
|
||||
<li class="item-divider">Step 1: Find a Location</li>
|
||||
<li>
|
||||
<div class="mapbox" style="width: 100%; min-height: 300px; max-height: 800px; height: 50vh;" id="mapbox-dropboxes"></div>
|
||||
</li>
|
||||
<li class="item-divider">Step 2: Request Pickup</li>
|
||||
<li>
|
||||
<div class="item-content item-link hapticbtn" id="pickupCodeQRScanBtn">
|
||||
<div class="item-inner">
|
||||
<div class="item-title-row">
|
||||
<div class="item-title"><i class="fas fa-qrcode"></i> Scan Pickup Code</div>
|
||||
</div>
|
||||
<div class="item-text">Scan the pickup code and we'll come get your package.</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="item-content item-link hapticbtn" id="pickupCodeManualEntryBtn">
|
||||
<div class="item-inner">
|
||||
<div class="item-title-row">
|
||||
<div class="item-title"><i class="fas fa-keyboard"></i> Type Location Number</div>
|
||||
</div>
|
||||
<div class="item-text">Type the location number and we'll come get your package.</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
@ -1,135 +0,0 @@
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<div class="page" data-name="loyalty">
|
||||
|
||||
<div class="navbar">
|
||||
<div class="navbar-bg"></div>
|
||||
<div class="navbar-inner">
|
||||
<div class="left">
|
||||
<a class="link back hapticbtn" href="#">
|
||||
<i class="icon icon-back"></i>
|
||||
<span class="if-not-md">Back</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="title">Loyalty Points</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="page-content">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-100 medium-90 xlarge-75 margin-horizontal">
|
||||
<div class="card margin">
|
||||
<div class="card-content text-align-center padding-vertical">
|
||||
{{#if hasphone}}
|
||||
<div id="loyalty-balance-box" class="card-content-padding">
|
||||
<div>You have earned a total of</div>
|
||||
<h1 id="loyalty-credit-balance">...</h1>
|
||||
<img id="loyalty-barcode" style="max-width: 90%; padding: 1.2em; background: white;" />
|
||||
<!-- Timeline -->
|
||||
<div class="timeline">
|
||||
<!-- Timeline item -->
|
||||
<div class="timeline-item">
|
||||
<div class="timeline-item-date">36 Points</div>
|
||||
<div class="timeline-item-divider"></div>
|
||||
<div class="timeline-item-content">
|
||||
<div class="timeline-item-inner">
|
||||
Postcard stamp
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Timeline item with inner -->
|
||||
<div class="timeline-item">
|
||||
<div class="timeline-item-date">50 Points</div>
|
||||
<div class="timeline-item-divider"></div>
|
||||
<div class="timeline-item-content">
|
||||
<div class="timeline-item-inner">
|
||||
Forever stamp
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="timeline-item">
|
||||
<div class="timeline-item-date">100 Points</div>
|
||||
<div class="timeline-item-divider"></div>
|
||||
<div class="timeline-item-content">
|
||||
<div class="timeline-item-inner">
|
||||
$1 pickup discount
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="timeline-item">
|
||||
<div class="timeline-item-date">500 Points</div>
|
||||
<div class="timeline-item-divider"></div>
|
||||
<div class="timeline-item-content">
|
||||
<div class="timeline-item-inner">
|
||||
<div class="timeline-item-text">$5 pickup discount</div>
|
||||
</div>
|
||||
<div class="timeline-item-inner">
|
||||
<div class="timeline-item-text">Sheet of Forever stamps</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="timeline-item">
|
||||
<div class="timeline-item-date">800 Points</div>
|
||||
<div class="timeline-item-divider"></div>
|
||||
<div class="timeline-item-content">
|
||||
<div class="timeline-item-inner">
|
||||
Postage for a Priority Mail envelope or small flat rate box
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="timeline-item">
|
||||
<div class="timeline-item-date">2500 Points</div>
|
||||
<div class="timeline-item-divider"></div>
|
||||
<div class="timeline-item-content">
|
||||
<div class="timeline-item-inner">
|
||||
Postage for a Priority Mail Express envelope
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="loyalty-error"></div>
|
||||
{{else}}
|
||||
<div class="block">
|
||||
Save your phone number to start earning points!
|
||||
</div>
|
||||
<div class="list">
|
||||
<ul id="savephoneform">
|
||||
<li class="item-content item-input item-input-outline">
|
||||
<div class="item-inner">
|
||||
<div class="item-title item-floating-label">Phone Number</div>
|
||||
<div class="item-input-wrap">
|
||||
<input type="tel" id="phonenumber" />
|
||||
<span class="input-clear-button"></span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card-content-padding">
|
||||
<div class="button hapticbtn" onclick="savePhoneNumber()"><i class="far fa-phone-plus"></i> Save Number</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="block">
|
||||
Loyalty points have no cash value. All points and associated discounts
|
||||
are offered as a courtesy by and at the discretion of Helena Express
|
||||
and may be revoked, canceled, or modified at any time for any reason.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="popup text-color-black" id="addresscode-popup">
|
||||
<div class="block text-align-center">
|
||||
<img id="addresscode-barcode" style="max-width: 90%;" />
|
||||
<p>Present this code to the Helena Express agent.</p>
|
||||
<p><a class="button popup-close" href="#">Close</a></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
146
www/routes.js
146
www/routes.js
@ -20,36 +20,42 @@ var routes = [
|
||||
icon: "fad fa-calendar-alt",
|
||||
text: "Get mailing, shipping, and notary services on your schedule anywhere in the Helena area."
|
||||
},
|
||||
{
|
||||
title: "Drop and Send",
|
||||
href: "/dropandsend",
|
||||
icon: "fad fa-box-alt",
|
||||
text: "Bring your package to a secure drop location and we'll ship it for you. No postage or appointment needed."
|
||||
},
|
||||
{
|
||||
title: "Track Package",
|
||||
href: "/track",
|
||||
icon: "fad fa-search",
|
||||
text: "Find the latest location and updates about any shipment."
|
||||
},
|
||||
{
|
||||
title: "Pick Up and Redeliver",
|
||||
href: "/noticeslip",
|
||||
icon: "fad fa-sticky-note",
|
||||
text: "Take a picture of your pink postal notice slip and we'll go get your missed delivery."
|
||||
},
|
||||
{
|
||||
title: "Loyalty Points",
|
||||
href: "/loyalty",
|
||||
icon: "fad fa-badge-dollar",
|
||||
text: "Earn free stamps and discounts."
|
||||
},
|
||||
{
|
||||
title: "Express Pickup",
|
||||
href: "/addresscode",
|
||||
icon: "fal fa-qrcode",
|
||||
text: "Get a faster pickup and a discount by pre-typing the destination address here."
|
||||
},
|
||||
{
|
||||
title: "Get Rates",
|
||||
href: "/rates",
|
||||
icon: "fad fa-calculator",
|
||||
text: "Calculate postage and prices for your item."
|
||||
},
|
||||
{
|
||||
title: "My Account",
|
||||
href: "/account",
|
||||
icon: "fad fa-user-circle",
|
||||
text: "Earn rewards and use Drop and Send with a Helena Express account."
|
||||
},
|
||||
// {
|
||||
// title: "Express Pickup",
|
||||
// href: "/addresscode",
|
||||
// icon: "fal fa-qrcode",
|
||||
// text: "Get a faster pickup and a discount by pre-typing the destination address here."
|
||||
// },
|
||||
{
|
||||
title: "Pick Up and Redeliver",
|
||||
href: "/noticeslip",
|
||||
icon: "fad fa-sticky-note",
|
||||
text: "Take a picture of your pink postal notice slip and we'll go get your missed delivery."
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
@ -99,6 +105,76 @@ var routes = [
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/dropandsend',
|
||||
name: 'dropandsend',
|
||||
templateUrl: './pages/dropandsend.html',
|
||||
on: {
|
||||
pageAfterIn: function () {
|
||||
var mapboxel = document.getElementById("mapbox-dropboxes");
|
||||
dropboxMap = new MapControl(mapboxel, true);
|
||||
dropboxMap.reloadMap();
|
||||
dropboxMap.mapObj.on('load', function () {
|
||||
dropboxMap.mapObj.jumpTo({center: [-112.005, 46.589], zoom: 8});
|
||||
dropboxMap.loadIcon("./assets/images/dropbox-icon.png", "dropbox", function () {
|
||||
apirequest(SETTINGS.apis.dropandsendlocations, {}, function (data) {
|
||||
dropboxMap.loadMarkersFromGeoJson(data, "dropbox", "dropbox");
|
||||
dropboxMap.mapObj.on('click', 'marker-layer-dropbox', function (e) {
|
||||
var coordinates = e.features[0].geometry.coordinates.slice();
|
||||
var name = e.features[0].properties.name;
|
||||
var type = e.features[0].properties.type;
|
||||
var info = e.features[0].properties.info;
|
||||
var hours = e.features[0].properties.hours;
|
||||
var geolink = "geo:" + (Math.round(coordinates[1] * 1000000) / 1000000) + "," + (Math.round(coordinates[0] * 1000000) / 1000000);
|
||||
|
||||
var typedesc = "<i class='fas fa-question-circle'></i> Unknown package size limits";
|
||||
switch (type) {
|
||||
case "micro":
|
||||
typedesc = "<i class='fas fa-envelope'></i> Fits envelopes";
|
||||
break;
|
||||
case "mini":
|
||||
typedesc = "<i class='fas fa-mail-bulk'></i> Fits large envelopes and small packages";
|
||||
break;
|
||||
case "standard":
|
||||
typedesc = "<i class='fas fa-box-alt'></i> Fits up to medium-size packages";
|
||||
break;
|
||||
case "large":
|
||||
typedesc = "<i class='fas fa-boxes-alt'></i> Fits most packages";
|
||||
break;
|
||||
case "business":
|
||||
typedesc = "<i class='fas fa-store-alt'></i> Shipping location, accepts any size package";
|
||||
break;
|
||||
}
|
||||
|
||||
while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
|
||||
coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
|
||||
}
|
||||
|
||||
new mapboxgl.Popup()
|
||||
.setLngLat(coordinates)
|
||||
.setHTML("<b>" + name + "</b><br>" + typedesc
|
||||
+ "<br><b>Hours:</b><br>" + hours
|
||||
+ "<br><b>More Info:</b><br>" + info
|
||||
+ "<br><a class=\"button button-fill button-small\" href=\"" + geolink + "\"><i class=\"fas fa-location-circle\"></i> Directions</a>")
|
||||
.addTo(dropboxMap.mapObj);
|
||||
});
|
||||
|
||||
dropboxMap.mapObj.on('mouseenter', 'marker-layer-dropbox', function () {
|
||||
dropboxMap.mapObj.getCanvas().style.cursor = 'pointer';
|
||||
});
|
||||
|
||||
dropboxMap.mapObj.on('mouseleave', 'marker-layer-dropbox', function () {
|
||||
dropboxMap.mapObj.getCanvas().style.cursor = '';
|
||||
});
|
||||
dropboxMap.animateMapIn(46.589, -112.005, 9, 0);
|
||||
}, function (error) {
|
||||
|
||||
}, "GET");
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/track',
|
||||
url: './pages/track.html',
|
||||
@ -164,23 +240,21 @@ var routes = [
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/loyalty',
|
||||
name: 'loyalty',
|
||||
async: function (routeTo, routeFrom, resolve, reject) {
|
||||
var hasPhone = inStorage("phonenumber");
|
||||
var phone = getStorage("phonenumber");
|
||||
resolve({
|
||||
templateUrl: './pages/loyalty.html'
|
||||
}, {
|
||||
context: {
|
||||
hasphone: hasPhone,
|
||||
phone: phone
|
||||
},
|
||||
path: '/account',
|
||||
name: 'account',
|
||||
templateUrl: './pages/account.html',
|
||||
on: {
|
||||
pageAfterIn: displayLoyaltyPoints
|
||||
pageAfterIn: function () {
|
||||
initAccountPage();
|
||||
}
|
||||
});
|
||||
},
|
||||
routes: [
|
||||
{
|
||||
path: '/managepayment',
|
||||
name: 'managepayment',
|
||||
templateUrl: './pages/managepayment.html'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/track/:code',
|
||||
@ -188,9 +262,13 @@ var routes = [
|
||||
async: trackOpenAsync,
|
||||
on: {
|
||||
pageAfterIn: function () {
|
||||
var trackingMap = new Map(document.getElementById("mapbox-track"));
|
||||
var mapboxel = document.getElementById("mapbox-track");
|
||||
var trackingMap = new MapControl(mapboxel, false);
|
||||
trackingMap.reloadMap();
|
||||
trackingMap.clearOldMarkersAndCenterMapOnNewMarker("package-marker");
|
||||
var latitude = $(mapboxel).data("latitude");
|
||||
var longitude = $(mapboxel).data("longitude");
|
||||
var accurate = $(mapboxel).data("accurate") == true;
|
||||
trackingMap.clearMarkersAndCenterMapOnNewMarker("package-marker", latitude, longitude, accurate);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -6,10 +6,16 @@
|
||||
|
||||
var SETTINGS = {
|
||||
apis: {
|
||||
track: "https://helena.express/tracker/api.php",
|
||||
rates: "https://helena.express/rateapi.php",
|
||||
track: "https://helena.express/apis/track/",
|
||||
rates: "https://helena.express/apis/rates/",
|
||||
pickuprequest: "https://helena.express/pspickup.php",
|
||||
loyalty: "https://helena.express/loyalty.php"
|
||||
dropandsendlocations: "https://helena.express/apis/dropandsend/locations/",
|
||||
dropandsendpickup: "https://helena.express/apis/dropandsend/requestpickup/",
|
||||
getaccountinfo: "https://helena.express/apis/account/getinfo/",
|
||||
authorstartverify: "https://helena.express/apis/account/authorstartverify/",
|
||||
verifyauthcode: "https://helena.express/apis/account/verifyauthcode/",
|
||||
accountregister: "https://helena.express/apis/account/register/",
|
||||
updatepaymentmethod: "https://helena.express/apis/account/updatepaymentmethod/",
|
||||
},
|
||||
stripe_pubkey: "pk_live_RgpadCo1LIIkfyUsY47VhUq6",
|
||||
appointmenturl: "https://appointments.netsyms.com/index.php?hlnexp=1&embed=1&only=1&theme=darkly",
|
||||
|
Loading…
x
Reference in New Issue
Block a user