diff --git a/snippets/checkout.html b/snippets/checkout.html index c71ab06..d1c0446 100644 --- a/snippets/checkout.html +++ b/snippets/checkout.html @@ -1,5 +1,5 @@ {{define "header_additions"}} - + {{end}} {{define "body_content"}}

Checkout

@@ -15,88 +15,5 @@ - + {{end}} diff --git a/snippets/graph.html b/snippets/graph.html index 1695001..0ef671c 100644 --- a/snippets/graph.html +++ b/snippets/graph.html @@ -7,7 +7,7 @@ - +
@@ -45,103 +45,7 @@
- +
@@ -149,170 +53,9 @@ $(function() {
- + - + {{ else }}

Bitte zuerst einloggen

diff --git a/snippets/scales.html b/snippets/scales.html index ec3c798..a943620 100644 --- a/snippets/scales.html +++ b/snippets/scales.html @@ -192,317 +192,7 @@ Sie erhalten eine E-Mail, sobald die Zahlung erfolgreich abgeschlossen ist. - + {{ else }}

Bitte zuerst einloggen

diff --git a/static/js/chart.js b/static/js/chart.js new file mode 100644 index 0000000..65d5484 --- /dev/null +++ b/static/js/chart.js @@ -0,0 +1,159 @@ +var chart; + +function drawGraph(deveui, alias, property, start, stop, create_graph) { + range = "" + range = range + "&start=" + start; + range = range + "&stop=" + stop; + + var label; + var labels = {}; + var forceNiceScale = true; + $(".button").removeClass("is-success"); + if (property=="t") { + $("#btn_t").addClass("is-success"); + label = 'Temperatur'; + mysubtitle = 'Temperatur in °C'; + minfunc = function(min) { if (min > 0) { return 0 } else { return min } } + maxfunc = function(max) { return max + 5 } + } else if (property=="vp") { + $("#btn_vp").addClass("is-success"); + label = 'Akkuladung'; + mysubtitle = 'Akkuladung in Prozent'; + minfunc = function(min) { return 0 } + maxfunc = function(max) { return 100 } + forceNiceScale = false; + } else if (property=="w") { + $("#btn_w").addClass("is-success"); + label = 'Gewicht'; + mysubtitle = 'Gewicht in Kilogramm'; + minfunc = function(min) { if (min > 5000) { return min - 2000 } else { return 0 } } + maxfunc = function(max) { return max + 2000 } + labels = { + formatter: function(val, index) { + return (val / 1000.0).toFixed(3); + } + }; + } else if (property==="h") { + $("#btn_h").addClass("is-success"); + label = 'Luftfeuchtigkeit'; + mysubtitle = 'Luftfeuchtigkeit in Prozent'; + minfunc = function(min) { return 0 } + maxfunc = function(max) { return 100 } + forceNiceScale = false; + } else if (property=="p") { + $("#btn_p").addClass("is-success"); + label = 'Luftdruck'; + mysubtitle = 'Luftdruck in Hektopascal'; + minfunc = function(min) { return 900 } + maxfunc = function(max) { return 1060 } + } else { + label = 'Unknown'; + mysubtitle = 'Unknown'; + } + + $.getJSON('https://mini-beieli.ch/metrics?deveui=' + deveui + '&alias=' + alias + '&property=' + property + range, function(mydata) { + if ("msg" in mydata) { + if (mydata.msg.includes("expired")) { + $('#chart').html(`
+
+ Abo ist abgelaufen +
+
`); + } else if (mydata.msg.includes("error:")) { + $('#myselectors').hide(); + $('#chart').html(`
+
+ Fehler im Aufruf +
+
`); + } else { + location.reload(true); + } + return; + } + var options = { + chart: { + type: 'line', + animations: { + enabled: false + } + }, + stroke: { + curve: 'smooth' + }, + title: { + text: urlParams.get('alias'), + align: 'center', + offsetY: 20, + style: { + fontSize: '32px' + } + }, + subtitle: { + text: mysubtitle, + align: 'center', + offsetY: 60, + style: { + fontSize: '12px' + } + }, + xaxis: { + type: "datetime", + labels: { + rotate: 0, + datetimeUTC: false + } + }, + yaxis: { + min: minfunc, + max: maxfunc, + forceNiceScale: forceNiceScale, + labels: labels + }, + tooltip: { + x: { + format: 'dd.MM.yyyy HH:mm' + } + }, + series: [{ + name: label, + data: mydata + }] + } + + if (create_graph) { + chart = new ApexCharts(document.querySelector("#chart"), options); + } else { + chart.destroy(); + chart = new ApexCharts(document.querySelector("#chart"), options); + //chart.updateOptions(options); + //chart.updateSeries(mydata); + } + + chart.render(); + }); +} + +var urlParams = new URLSearchParams(window.location.search); +var deveui = urlParams.get('deveui'); +var alias = urlParams.get('alias'); +var property = urlParams.get('property'); +var start = urlParams.get('start'); +var stop = urlParams.get('stop'); + +range=""; +if (start == null) { + var dstart = moment({hour: 0}); + var start = dstart.utc().format('YYYY-MM-DDTHH:mm:ss[Z]'); + range = range + "&start=" + start; +} + +if (stop == null) { + var dstop = moment(); + var stop = dstop.utc().format('YYYY-MM-DDTHH:mm:ss[Z]'); + range = range + "&stop=" + stop; +} + +$('#reportrange span').html(moment(start).locale('de').format('D. MMM YYYY') + ' - ' + moment(stop).locale('de').format('D. MMM YYYY')); + +drawGraph(deveui, alias, property, start, stop, true); diff --git a/static/js/chekout.js b/static/js/chekout.js new file mode 100644 index 0000000..af9d3ef --- /dev/null +++ b/static/js/chekout.js @@ -0,0 +1,81 @@ +// Set your publishable key: remember to change this to your live publishable key in production +// See your keys here: https://dashboard.stripe.com/account/apikeys +var stripe = Stripe('pk_test_YkSGqH3Tk9WKK9HrlY63GhAg'); +var elements = stripe.elements(); + +// Set up Stripe.js and Elements to use in checkout form +var style = { + base: { + color: "#32325d", + } +}; + +var card = elements.create("card", { style: style }); +card.mount("#card-element"); + + +card.addEventListener('change', ({error}) => { + const displayError = document.getElementById('card-errors'); + if (error) { + displayError.textContent = error.message; + } else { + displayError.textContent = ''; + } +}); + + +var submitButton = document.getElementById('submit'); + +function GetClientSecret() { + var result = ""; + $.ajax({ + async: false, + url: "getstripepaymentintent", + type: "get", //send it through get method + dataType: "json", + data: { + charge_data: $("#charge_data").html() + }, + success: function(response) { + console.log('pay success'); + console.log(response.stripesessionid); + console.log('rc: '+response.rc); + if (response.rc == 0) { + result = response.stripeclientsecret; + } + }, + error: function(xhr) { + console.log('getstripepaymentintent error'); + //Do Something to handle error + } + }); + + return result; +} + +submitButton.addEventListener('click', function(ev) { + var clientSecret = GetClientSecret(); + stripe.confirmCardPayment(clientSecret, { + payment_method: { + card: card, + billing_details: { + name: 'Jenny Rosen' + } + } + }).then(function(result) { + if (result.error) { + // Show error to your customer (e.g., insufficient funds) + console.log(result.error.message); + } else { + // The payment has been processed! + if (result.paymentIntent.status === 'succeeded') { + // Show a success message to your customer + // There's a risk of the customer closing the window before callback + // execution. Set up a webhook or plugin to listen for the + // payment_intent.succeeded event that handles any business critical + // post-payment actions. + alert("Payment succeeded!!!"); + } + } + }); +}); diff --git a/static/js/graph.js b/static/js/graph.js new file mode 100644 index 0000000..63881b5 --- /dev/null +++ b/static/js/graph.js @@ -0,0 +1,94 @@ +$(function() { + + var start = moment({hour: 0}); + var end = moment(); + var s_start = start.utc().format('YYYY-MM-DDTHH:mm:ss[Z]'); + var s_end = end.utc().format('YYYY-MM-DDTHH:mm:ss[Z]'); + + console.log("XXX: "+start.format()); + + function cb(start, end) { + $('#reportrange span').html(start.locale('de').format('D. MMM YYYY') + ' - ' + end.locale('de').format('D. MMM YYYY')); + console.log("A new date selection was made: " + start.format() + ' to ' + end.format()); + s_start = start.utc().format('YYYY-MM-DDTHH:mm:ss[Z]'); + s_end = end.utc().format('YYYY-MM-DDTHH:mm:ss[Z]'); + console.log("Start: " + s_start + ' End: ' + s_end + ' Property: '+ property); + drawGraph(deveui, alias, property, s_start,s_end, false); + } + + $('#btn_w').on("click", function() { + property = 'w'; + drawGraph(deveui, alias, property, s_start, s_end, false); + }); + + $('#btn_t').on("click", function() { + property = 't'; + drawGraph(deveui, alias, property, s_start, s_end, false); + }); + + $('#btn_h').on("click", function() { + property = 'h'; + drawGraph(deveui, alias, property, s_start, s_end, false); + }); + + $('#btn_p').on("click", function() { + property = 'p'; + drawGraph(deveui, alias, property, s_start, s_end, false); + }); + + $('#btn_vp').on("click", function() { + property = 'vp'; + drawGraph(deveui, alias, property, s_start, s_end, false); + }); + + $('#reportrange').daterangepicker({ + startDate: start.local(), + endDate: end.local(), + regional: [ "de" ], + "locale": { + format: 'DD.MM.YYYY', + "separator": " - ", + "applyLabel": "Anwenden", + "cancelLabel": "Abbrechen", + "fromLabel": "Von", + "toLabel": "Bis", + customRangeLabel: 'Benutzerdefiniert', + "weekLabel": "W", + "daysOfWeek": [ + "So", + "Mo", + "Di", + "Mi", + "Do", + "Fr", + "Sa" + ], + "monthNames": [ + "Jan", + "Feb", + "Mär", + "Apr", + "Mai", + "Jun", + "Jul", + "Aug", + "Sep", + "Okt", + "Nov", + "Dez" + ], + "firstDay": 1 + }, + ranges: { + 'Heute': [moment(), moment()], + 'Gestern': [moment().subtract(1, 'days'), moment().subtract(1, 'days')], + 'Letzte 7 Tage': [moment().subtract(6, 'days'), moment()], + 'Letzte 30 Tage': [moment().subtract(29, 'days'), moment()], + 'Diesen Monat': [moment().startOf('month'), moment().endOf('month')], + 'Letzten Monat': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')] + } + }, cb); + + //cb(start, end); + +}); diff --git a/static/js/scales.js b/static/js/scales.js new file mode 100644 index 0000000..eee8894 --- /dev/null +++ b/static/js/scales.js @@ -0,0 +1,308 @@ +function validate(what, text) { + if (what == 'alias') { + var re = /^[a-zA-Z0-9 ]{1,25}$/; + } else if (what == 'smsnumber') { + var re = /^\+[0-9]{11,11}$/; + } + return re.test(text); +} + +// A $( document ).ready() block. +$( document ).ready(function() { +$(".show-modal").click(function() { + $("#alias_exclamation").hide(); + $("#smsnumber_exclamation").hide(); + var alias = $(this).prev().html(); + var deveui = $(this).prev().attr('id').replace("alias_",""); + $('#deveui').html(deveui); + var alarmactive = $('#alarmactive_'+deveui).html(); + var smsnumber = $('#smsnumber_'+deveui).html(); + + $("#alias").val(alias); + console.log(alarmactive); + if (alarmactive == "1") { + $('#checkbox').prop('checked', true); + } else { + $('#checkbox').prop('checked', false); + } + $("#smsnumber").val(smsnumber); + $("#modal").addClass("is-active"); +}); + +$("#cart-close").click(function() { + $("#cart").removeClass("is-active"); +}); + +$("#payment_notifier_close").click(function() { + $("#payment_notifier").removeClass("is-active"); + location.reload(true); +}); + +$(".abo_plus").click(function() { + console.log("abo_plus"); + el = $(this).parent().find(".abo_add_years"); + el_text = $(this).parent().parent().find(".abo_add_years_text"); + counter = Number(el.html()); + if (counter < 3) { + counter = counter + 1; + el.html(counter); + if (counter == 1) { + el_text.html("+" + counter + " Jahr"); + } else { + el_text.html("+" + counter + " Jahre"); + } + } +}); + +$(".abo_minus").click(function() { + console.log("abo_minus"); + el = $(this).parent().find(".abo_add_years"); + el_text = $(this).parent().parent().find(".abo_add_years_text"); + counter = Number(el.html()); + if (counter > 0) { + counter = counter - 1; + el.html(counter); + if (counter == 0) { + el_text.html(" "); + } else if (counter == 1) { + el_text.html("+" + counter + " Jahr"); + } else { + el_text.html("+" + counter + " Jahre"); + } + } +}); + +function add_years(dt,n) +{ + return new Date(dt.setFullYear(dt.getFullYear() + n)); +} + +$(".abo_pay").click(function() { + console.log("pay..."); + loadStripeLibrary(); + counter = 0; + charge_data = ''; + abo_table = ''; + abo_table += ''; + $(".waage").each(function( index ) { + console.log( index + ": " + $( this ).find(".alias").html() ); + this_count = Number($( this ).find(".abo_add_years").html()); + if (this_count > 0) { + counter += this_count; + paid_until = $( this ).find(".paid_until").html(); + if (moment(paid_until,'DD.MM.YYYY') < moment()) { + this_date = moment().format('DD.MM.YYYY'); + } else { + this_date = paid_until; + } + abo_table += ''; + if (charge_data == '') { + charge_data = $( this ).find("div").first().attr('id') + ":" + this_count; + } else { + charge_data += "," + $( this ).find("div").first().attr('id') + ":" + this_count; + } + } + console.log( counter ); + }); + abo_table += ''; + console.log("Counter: "+counter); + abo_table += "
Aliasverlängern bisBetrag
' + $( this ).find('.alias').html() + '' + moment(this_date,'DD.MM.YYYY').add('years', this_count).format('DD.MM.YYYY') + '' + (this_count * 24).toFixed(2) + '
Total CHF' + (counter * 24).toFixed(2) + '
"; + if (counter > 0) { + console.log(abo_table); + console.log("charge_data: "+charge_data); + $("#abos_verlaengern").html(abo_table); + $("#charge_data").html(charge_data); + $("#cart").addClass("is-active"); + } +}); + +$("#modal-close").click(function() { + console.log("blabla"); + $("#modal").removeClass("is-active"); +}); + +$("#modal-save").click(function() { + var alarmactive = "0"; + if ($('#checkbox').prop('checked')) { + alarmactive = "1"; + } + + // Validation Code + var is_valid = true; + if (!validate('alias',$('#alias').val())) { + $('#alias_errormsg').html('Ungültige Bezeichnung; erlaubte Zeichen A-Z, 0-9 und Leerschlag'); + $("#alias").addClass("is-danger"); + $("#alias_exclamation").show(); + is_valid = false; + } else { + $('#alias_errormsg').html(''); + $("#alias").removeClass("is-danger"); + $("#alias_exclamation").hide(); + } + + if (!validate('smsnumber',$('#smsnumber').val())) { + $('#smsnumber_errormsg').html('Beispiel einer gültigen SMS Nummer: +41761234567'); + $("#smsnumber").addClass("is-danger"); + $("#smsnumber_exclamation").show(); + is_valid = false; + } else { + $('#smsnumber_errormsg').html(''); + $("#smsnumber").removeClass("is-danger"); + $("#smsnumber_exclamation").hide(); + } + + if (!(is_valid)) { + return; + } + + $.ajax({ + url: "save_scale_settings", + type: "get", //send it through get method + dataType: "json", + data: { + deveui: $('#deveui').html(), + alias: $('#alias').val(), + smsnumber: $("#smsnumber").val(), + alarmactive: alarmactive + }, + success: function(response) { + console.log('save success'); + if (response.rc == 0) { + $('#alias_'+$('#deveui').html()).html($('#alias').val()); + var alarmactive = "0"; + if ($('#checkbox').prop('checked')) { + alarmactive = "1"; + } + $('#alarmactive_'+$('#deveui').html()).html(alarmactive); + $('#smsnumber_'+$('#deveui').html()).html($('#smsnumber').val()); + } + }, + error: function(xhr) { + console.log('save error'); + //Do Something to handle error + } + }); + + console.log("save"); + $("#modal").removeClass("is-active"); +}); + +}); + +function loadStripeLibrary() { + $.ajax({ + url: "https://js.stripe.com/v3/", + dataType: "script", + async: false, // <-- This is the key + success: function () { + // all good... + console.log("loadStripeLibrary called..."); + SetupStripe(); + }, + error: function () { + throw new Error("Could not load script " + script); + } + }); +} + +function SetupStripe() { + console.log("SetupStripe"); + // Set your publishable key: remember to change this to your live publishable key in production + // See your keys here: https://dashboard.stripe.com/account/apikeys + stripe = Stripe('pk_test_YkSGqH3Tk9WKK9HrlY63GhAg'); + elements = stripe.elements({ locale: "de" }); + + // Set up Stripe.js and Elements to use in checkout form + style = { + base: { + color: "#32325d", + } + }; + + card = elements.create("card", { style: style }); + card.mount("#card-element"); + $("#card-errors-article").hide(); + + card.addEventListener('change', ({error}) => { + if (error) { + $("#card-errors").text(error.message); + $("#card-errors-article").show(); + } else { + $("#card-errors").text(""); + $("#card-errors-article").hide(); + } + }); +} + +function ConfirmPayment(clientSecret) { + stripe.confirmCardPayment(clientSecret, { + payment_method: { + card: card, + billing_details: { + name: '{{ .UserName }}' + } + } + }).then(function(result) { + if (result.error) { + // Show error to your customer (e.g., insufficient funds) + console.log(result.error.message); + $('#card-errors').text(result.error.message); + $('#card-errors-article').show(); + //Do Something to handle error + EndPaymentProgress(); + } else { + // The payment has been processed! + if (result.paymentIntent.status === 'succeeded') { + // Show a success message to your customer + // There's a risk of the customer closing the window before callback + // execution. Set up a webhook or plugin to listen for the + // payment_intent.succeeded event that handles any business critical + // post-payment actions. + console.log("Payment succeeded!!!"); + $('#card-errors').text(""); + $('#card-errors-article').hide(); + $("#cart").removeClass("is-active"); + EndPaymentProgress(); + $('#payment_notifier').addClass('is-active'); + } + } + }); +} + +function StartPaymentProgress() { + $("#cart-pay").attr("disabled", true).addClass("is-loading"); + $("#cart-close").attr("disabled", true); +} + +function EndPaymentProgress() { + $("#cart-pay").attr("disabled", false).removeClass("is-loading"); + $("#cart-close").attr("disabled", false); +} + +function PayMe() { + $.ajax({ + url: "getstripepaymentintent", + type: "get", //send it through get method + dataType: "json", + data: { + charge_data: $("#charge_data").html() + }, + success: function(response) { + console.log('pay success'); + console.log('rc: '+response.rc); + if (response.rc == 0) { + ConfirmPayment(response.stripeclientsecret); + } + }, + error: function(xhr) { + console.log('getstripepaymentintent error'); + //Do Something to handle error + EndPaymentProgress(); + } + }); +} + +$('#cart-pay').on('click', function(ev) { + StartPaymentProgress(); + PayMe(); +}); diff --git a/templates/layout.html b/templates/layout.html index c968d87..6885692 100644 --- a/templates/layout.html +++ b/templates/layout.html @@ -9,8 +9,8 @@ - - + + {{template "header_additions" . }} @@ -83,7 +83,7 @@ {{template "body_content" . }} - + {{end}}