apply prettier to everything.
This commit is contained in:
parent
083f7a0a8d
commit
4730500ed7
33 changed files with 4988 additions and 3871 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -27,3 +27,5 @@ venv
|
||||||
.pyre*
|
.pyre*
|
||||||
|
|
||||||
__bundle__
|
__bundle__
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
|
|
||||||
12
.prettierrc
Normal file
12
.prettierrc
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"semi": false,
|
||||||
|
"arrowParens": "avoid",
|
||||||
|
"insertPragma": false,
|
||||||
|
"printWidth": 80,
|
||||||
|
"proseWrap": "preserve",
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "none",
|
||||||
|
"useTabs": false,
|
||||||
|
"jsxBracketSameLine": false,
|
||||||
|
"bracketSpacing": false
|
||||||
|
}
|
||||||
2
Makefile
Normal file
2
Makefile
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
prettier:
|
||||||
|
./node_modules/.bin/prettier --write lnbits/static/js/** lnbits/core/static/js/** lnbits/extensions/*/templates/**
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
new Vue({
|
new Vue({
|
||||||
el: '#vue',
|
el: '#vue',
|
||||||
mixins: [windowMixin]
|
mixins: [windowMixin]
|
||||||
});
|
})
|
||||||
|
|
|
||||||
|
|
@ -8,18 +8,18 @@ new Vue({
|
||||||
data: {}
|
data: {}
|
||||||
},
|
},
|
||||||
walletName: ''
|
walletName: ''
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
createWallet: function () {
|
createWallet: function () {
|
||||||
LNbits.href.createWallet(this.walletName);
|
LNbits.href.createWallet(this.walletName)
|
||||||
},
|
},
|
||||||
processing: function () {
|
processing: function () {
|
||||||
this.$q.notify({
|
this.$q.notify({
|
||||||
timeout: 0,
|
timeout: 0,
|
||||||
message: 'Processing...',
|
message: 'Processing...',
|
||||||
icon: null
|
icon: null
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,39 +1,49 @@
|
||||||
Vue.component(VueQrcode.name, VueQrcode);
|
Vue.component(VueQrcode.name, VueQrcode)
|
||||||
Vue.use(VueQrcodeReader);
|
Vue.use(VueQrcodeReader)
|
||||||
|
|
||||||
|
|
||||||
function generateChart(canvas, payments) {
|
function generateChart(canvas, payments) {
|
||||||
var txs = [];
|
var txs = []
|
||||||
var n = 0;
|
var n = 0
|
||||||
var data = {
|
var data = {
|
||||||
labels: [],
|
labels: [],
|
||||||
income: [],
|
income: [],
|
||||||
outcome: [],
|
outcome: [],
|
||||||
cumulative: []
|
cumulative: []
|
||||||
};
|
}
|
||||||
|
|
||||||
_.each(payments.slice(0).sort(function (a, b) {
|
_.each(
|
||||||
return a.time - b.time;
|
payments.slice(0).sort(function (a, b) {
|
||||||
}), function (tx) {
|
return a.time - b.time
|
||||||
|
}),
|
||||||
|
function (tx) {
|
||||||
txs.push({
|
txs.push({
|
||||||
hour: Quasar.utils.date.formatDate(tx.date, 'YYYY-MM-DDTHH:00'),
|
hour: Quasar.utils.date.formatDate(tx.date, 'YYYY-MM-DDTHH:00'),
|
||||||
sat: tx.sat,
|
sat: tx.sat
|
||||||
});
|
})
|
||||||
});
|
}
|
||||||
|
)
|
||||||
|
|
||||||
_.each(_.groupBy(txs, 'hour'), function (value, day) {
|
_.each(_.groupBy(txs, 'hour'), function (value, day) {
|
||||||
var income = _.reduce(value, function(memo, tx) {
|
var income = _.reduce(
|
||||||
return (tx.sat >= 0) ? memo + tx.sat : memo;
|
value,
|
||||||
}, 0);
|
function (memo, tx) {
|
||||||
var outcome = _.reduce(value, function(memo, tx) {
|
return tx.sat >= 0 ? memo + tx.sat : memo
|
||||||
return (tx.sat < 0) ? memo + Math.abs(tx.sat) : memo;
|
},
|
||||||
}, 0);
|
0
|
||||||
n = n + income - outcome;
|
)
|
||||||
data.labels.push(day);
|
var outcome = _.reduce(
|
||||||
data.income.push(income);
|
value,
|
||||||
data.outcome.push(outcome);
|
function (memo, tx) {
|
||||||
data.cumulative.push(n);
|
return tx.sat < 0 ? memo + Math.abs(tx.sat) : memo
|
||||||
});
|
},
|
||||||
|
0
|
||||||
|
)
|
||||||
|
n = n + income - outcome
|
||||||
|
data.labels.push(day)
|
||||||
|
data.income.push(income)
|
||||||
|
data.outcome.push(outcome)
|
||||||
|
data.cumulative.push(n)
|
||||||
|
})
|
||||||
|
|
||||||
new Chart(canvas.getContext('2d'), {
|
new Chart(canvas.getContext('2d'), {
|
||||||
type: 'bar',
|
type: 'bar',
|
||||||
|
|
@ -72,10 +82,11 @@ function generateChart(canvas, payments) {
|
||||||
},
|
},
|
||||||
tooltips: {
|
tooltips: {
|
||||||
mode: 'index',
|
mode: 'index',
|
||||||
intersect:false
|
intersect: false
|
||||||
},
|
},
|
||||||
scales: {
|
scales: {
|
||||||
xAxes: [{
|
xAxes: [
|
||||||
|
{
|
||||||
type: 'time',
|
type: 'time',
|
||||||
display: true,
|
display: true,
|
||||||
offset: true,
|
offset: true,
|
||||||
|
|
@ -83,7 +94,8 @@ function generateChart(canvas, payments) {
|
||||||
minUnit: 'hour',
|
minUnit: 'hour',
|
||||||
stepSize: 3
|
stepSize: 3
|
||||||
}
|
}
|
||||||
}],
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
// performance tweaks
|
// performance tweaks
|
||||||
animation: {
|
animation: {
|
||||||
|
|
@ -95,10 +107,9 @@ function generateChart(canvas, payments) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
el: '#vue',
|
el: '#vue',
|
||||||
mixins: [windowMixin],
|
mixins: [windowMixin],
|
||||||
|
|
@ -128,8 +139,20 @@ new Vue({
|
||||||
paymentsTable: {
|
paymentsTable: {
|
||||||
columns: [
|
columns: [
|
||||||
{name: 'memo', align: 'left', label: 'Memo', field: 'memo'},
|
{name: 'memo', align: 'left', label: 'Memo', field: 'memo'},
|
||||||
{name: 'date', align: 'left', label: 'Date', field: 'date', sortable: true},
|
{
|
||||||
{name: 'sat', align: 'right', label: 'Amount (sat)', field: 'sat', sortable: true}
|
name: 'date',
|
||||||
|
align: 'left',
|
||||||
|
label: 'Date',
|
||||||
|
field: 'date',
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'sat',
|
||||||
|
align: 'right',
|
||||||
|
label: 'Amount (sat)',
|
||||||
|
field: 'sat',
|
||||||
|
sortable: true
|
||||||
|
}
|
||||||
],
|
],
|
||||||
pagination: {
|
pagination: {
|
||||||
rowsPerPage: 10
|
rowsPerPage: 10
|
||||||
|
|
@ -143,46 +166,50 @@ new Vue({
|
||||||
show: false,
|
show: false,
|
||||||
location: window.location
|
location: window.location
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
filteredPayments: function () {
|
filteredPayments: function () {
|
||||||
var q = this.paymentsTable.filter;
|
var q = this.paymentsTable.filter
|
||||||
if (!q || q == '') return this.payments;
|
if (!q || q == '') return this.payments
|
||||||
|
|
||||||
return LNbits.utils.search(this.payments, q);
|
return LNbits.utils.search(this.payments, q)
|
||||||
},
|
},
|
||||||
balance: function () {
|
balance: function () {
|
||||||
if (this.payments.length) {
|
if (this.payments.length) {
|
||||||
return _.pluck(this.payments, 'amount').reduce(function (a, b) { return a + b; }, 0) / 1000;
|
return (
|
||||||
|
_.pluck(this.payments, 'amount').reduce(function (a, b) {
|
||||||
|
return a + b
|
||||||
|
}, 0) / 1000
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return this.g.wallet.sat;
|
return this.g.wallet.sat
|
||||||
},
|
},
|
||||||
fbalance: function () {
|
fbalance: function () {
|
||||||
return LNbits.utils.formatSat(this.balance)
|
return LNbits.utils.formatSat(this.balance)
|
||||||
},
|
},
|
||||||
canPay: function () {
|
canPay: function () {
|
||||||
if (!this.send.invoice) return false;
|
if (!this.send.invoice) return false
|
||||||
return this.send.invoice.sat <= this.balance;
|
return this.send.invoice.sat <= this.balance
|
||||||
},
|
},
|
||||||
pendingPaymentsExist: function () {
|
pendingPaymentsExist: function () {
|
||||||
return (this.payments)
|
return this.payments
|
||||||
? _.where(this.payments, {pending: 1}).length > 0
|
? _.where(this.payments, {pending: 1}).length > 0
|
||||||
: false;
|
: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
closeCamera: function () {
|
closeCamera: function () {
|
||||||
this.sendCamera.show = false;
|
this.sendCamera.show = false
|
||||||
},
|
},
|
||||||
showCamera: function () {
|
showCamera: function () {
|
||||||
this.sendCamera.show = true;
|
this.sendCamera.show = true
|
||||||
},
|
},
|
||||||
showChart: function () {
|
showChart: function () {
|
||||||
this.paymentsChart.show = true;
|
this.paymentsChart.show = true
|
||||||
this.$nextTick(function () {
|
this.$nextTick(function () {
|
||||||
generateChart(this.$refs.canvas, this.payments);
|
generateChart(this.$refs.canvas, this.payments)
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
showReceiveDialog: function () {
|
showReceiveDialog: function () {
|
||||||
this.receive = {
|
this.receive = {
|
||||||
|
|
@ -194,7 +221,7 @@ new Vue({
|
||||||
memo: ''
|
memo: ''
|
||||||
},
|
},
|
||||||
paymentChecker: null
|
paymentChecker: null
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
showSendDialog: function () {
|
showSendDialog: function () {
|
||||||
this.send = {
|
this.send = {
|
||||||
|
|
@ -204,57 +231,64 @@ new Vue({
|
||||||
bolt11: ''
|
bolt11: ''
|
||||||
},
|
},
|
||||||
paymentChecker: null
|
paymentChecker: null
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
closeReceiveDialog: function () {
|
closeReceiveDialog: function () {
|
||||||
var checker = this.receive.paymentChecker;
|
var checker = this.receive.paymentChecker
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
clearInterval(checker);
|
clearInterval(checker)
|
||||||
}, 10000);
|
}, 10000)
|
||||||
},
|
},
|
||||||
closeSendDialog: function () {
|
closeSendDialog: function () {
|
||||||
this.sendCamera.show = false;
|
this.sendCamera.show = false
|
||||||
var checker = this.send.paymentChecker;
|
var checker = this.send.paymentChecker
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
clearInterval(checker);
|
clearInterval(checker)
|
||||||
}, 1000);
|
}, 1000)
|
||||||
},
|
},
|
||||||
createInvoice: function () {
|
createInvoice: function () {
|
||||||
var self = this;
|
var self = this
|
||||||
this.receive.status = 'loading';
|
this.receive.status = 'loading'
|
||||||
LNbits.api.createInvoice(this.g.wallet, this.receive.data.amount, this.receive.data.memo)
|
LNbits.api
|
||||||
|
.createInvoice(
|
||||||
|
this.g.wallet,
|
||||||
|
this.receive.data.amount,
|
||||||
|
this.receive.data.memo
|
||||||
|
)
|
||||||
.then(function (response) {
|
.then(function (response) {
|
||||||
self.receive.status = 'success';
|
self.receive.status = 'success'
|
||||||
self.receive.paymentReq = response.data.payment_request;
|
self.receive.paymentReq = response.data.payment_request
|
||||||
|
|
||||||
self.receive.paymentChecker = setInterval(function () {
|
self.receive.paymentChecker = setInterval(function () {
|
||||||
LNbits.api.getPayment(self.g.wallet, response.data.checking_id).then(function (response) {
|
LNbits.api
|
||||||
|
.getPayment(self.g.wallet, response.data.checking_id)
|
||||||
|
.then(function (response) {
|
||||||
if (response.data.paid) {
|
if (response.data.paid) {
|
||||||
self.fetchPayments();
|
self.fetchPayments()
|
||||||
self.receive.show = false;
|
self.receive.show = false
|
||||||
clearInterval(self.receive.paymentChecker);
|
clearInterval(self.receive.paymentChecker)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}, 2000);
|
}, 2000)
|
||||||
|
})
|
||||||
}).catch(function (error) {
|
.catch(function (error) {
|
||||||
LNbits.utils.notifyApiError(error);
|
LNbits.utils.notifyApiError(error)
|
||||||
self.receive.status = 'pending';
|
self.receive.status = 'pending'
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
decodeQR: function (res) {
|
decodeQR: function (res) {
|
||||||
this.send.data.bolt11 = res;
|
this.send.data.bolt11 = res
|
||||||
this.decodeInvoice();
|
this.decodeInvoice()
|
||||||
this.sendCamera.show = false;
|
this.sendCamera.show = false
|
||||||
},
|
},
|
||||||
decodeInvoice: function () {
|
decodeInvoice: function () {
|
||||||
if (this.send.data.bolt11.startsWith('lightning:')) {
|
if (this.send.data.bolt11.startsWith('lightning:')) {
|
||||||
this.send.data.bolt11 = this.send.data.bolt11.slice(10);
|
this.send.data.bolt11 = this.send.data.bolt11.slice(10)
|
||||||
}
|
}
|
||||||
|
|
||||||
let invoice;
|
let invoice
|
||||||
try {
|
try {
|
||||||
invoice = decode(this.send.data.bolt11);
|
invoice = decode(this.send.data.bolt11)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.$q.notify({
|
this.$q.notify({
|
||||||
timeout: 3000,
|
timeout: 3000,
|
||||||
|
|
@ -262,101 +296,120 @@ new Vue({
|
||||||
message: error + '.',
|
message: error + '.',
|
||||||
caption: '400 BAD REQUEST',
|
caption: '400 BAD REQUEST',
|
||||||
icon: null
|
icon: null
|
||||||
});
|
})
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let cleanInvoice = {
|
let cleanInvoice = {
|
||||||
msat: invoice.human_readable_part.amount,
|
msat: invoice.human_readable_part.amount,
|
||||||
sat: invoice.human_readable_part.amount / 1000,
|
sat: invoice.human_readable_part.amount / 1000,
|
||||||
fsat: LNbits.utils.formatSat(invoice.human_readable_part.amount / 1000)
|
fsat: LNbits.utils.formatSat(invoice.human_readable_part.amount / 1000)
|
||||||
};
|
}
|
||||||
|
|
||||||
_.each(invoice.data.tags, function (tag) {
|
_.each(invoice.data.tags, function (tag) {
|
||||||
if (_.isObject(tag) && _.has(tag, 'description')) {
|
if (_.isObject(tag) && _.has(tag, 'description')) {
|
||||||
if (tag.description == 'payment_hash') { cleanInvoice.hash = tag.value; }
|
if (tag.description == 'payment_hash') {
|
||||||
else if (tag.description == 'description') { cleanInvoice.description = tag.value; }
|
cleanInvoice.hash = tag.value
|
||||||
else if (tag.description == 'expiry') {
|
} else if (tag.description == 'description') {
|
||||||
var expireDate = new Date((invoice.data.time_stamp + tag.value) * 1000);
|
cleanInvoice.description = tag.value
|
||||||
cleanInvoice.expireDate = Quasar.utils.date.formatDate(expireDate, 'YYYY-MM-DDTHH:mm:ss.SSSZ');
|
} else if (tag.description == 'expiry') {
|
||||||
cleanInvoice.expired = false; // TODO
|
var expireDate = new Date(
|
||||||
|
(invoice.data.time_stamp + tag.value) * 1000
|
||||||
|
)
|
||||||
|
cleanInvoice.expireDate = Quasar.utils.date.formatDate(
|
||||||
|
expireDate,
|
||||||
|
'YYYY-MM-DDTHH:mm:ss.SSSZ'
|
||||||
|
)
|
||||||
|
cleanInvoice.expired = false // TODO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
this.send.invoice = Object.freeze(cleanInvoice);
|
this.send.invoice = Object.freeze(cleanInvoice)
|
||||||
},
|
},
|
||||||
payInvoice: function () {
|
payInvoice: function () {
|
||||||
var self = this;
|
var self = this
|
||||||
|
|
||||||
dismissPaymentMsg = this.$q.notify({
|
dismissPaymentMsg = this.$q.notify({
|
||||||
timeout: 0,
|
timeout: 0,
|
||||||
message: 'Processing payment...',
|
message: 'Processing payment...',
|
||||||
icon: null
|
icon: null
|
||||||
});
|
})
|
||||||
|
|
||||||
LNbits.api.payInvoice(this.g.wallet, this.send.data.bolt11).then(function (response) {
|
LNbits.api
|
||||||
|
.payInvoice(this.g.wallet, this.send.data.bolt11)
|
||||||
|
.then(function (response) {
|
||||||
self.send.paymentChecker = setInterval(function () {
|
self.send.paymentChecker = setInterval(function () {
|
||||||
LNbits.api.getPayment(self.g.wallet, response.data.checking_id).then(function (res) {
|
LNbits.api
|
||||||
|
.getPayment(self.g.wallet, response.data.checking_id)
|
||||||
|
.then(function (res) {
|
||||||
if (res.data.paid) {
|
if (res.data.paid) {
|
||||||
self.send.show = false;
|
self.send.show = false
|
||||||
clearInterval(self.send.paymentChecker);
|
clearInterval(self.send.paymentChecker)
|
||||||
dismissPaymentMsg();
|
dismissPaymentMsg()
|
||||||
self.fetchPayments();
|
self.fetchPayments()
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}, 2000);
|
}, 2000)
|
||||||
}).catch(function (error) {
|
})
|
||||||
dismissPaymentMsg();
|
.catch(function (error) {
|
||||||
LNbits.utils.notifyApiError(error);
|
dismissPaymentMsg()
|
||||||
});
|
LNbits.utils.notifyApiError(error)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
deleteWallet: function (walletId, user) {
|
deleteWallet: function (walletId, user) {
|
||||||
LNbits.utils.confirmDialog(
|
LNbits.utils
|
||||||
'Are you sure you want to delete this wallet?'
|
.confirmDialog('Are you sure you want to delete this wallet?')
|
||||||
).onOk(function () {
|
.onOk(function () {
|
||||||
LNbits.href.deleteWallet(walletId, user);
|
LNbits.href.deleteWallet(walletId, user)
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
fetchPayments: function (checkPending) {
|
fetchPayments: function (checkPending) {
|
||||||
var self = this;
|
var self = this
|
||||||
|
|
||||||
return LNbits.api.getPayments(this.g.wallet, checkPending).then(function (response) {
|
return LNbits.api
|
||||||
self.payments = response.data.map(function (obj) {
|
.getPayments(this.g.wallet, checkPending)
|
||||||
return LNbits.map.payment(obj);
|
.then(function (response) {
|
||||||
}).sort(function (a, b) {
|
self.payments = response.data
|
||||||
return b.time - a.time;
|
.map(function (obj) {
|
||||||
});
|
return LNbits.map.payment(obj)
|
||||||
});
|
})
|
||||||
|
.sort(function (a, b) {
|
||||||
|
return b.time - a.time
|
||||||
|
})
|
||||||
|
})
|
||||||
},
|
},
|
||||||
checkPendingPayments: function () {
|
checkPendingPayments: function () {
|
||||||
var dismissMsg = this.$q.notify({
|
var dismissMsg = this.$q.notify({
|
||||||
timeout: 0,
|
timeout: 0,
|
||||||
message: 'Checking pending transactions...',
|
message: 'Checking pending transactions...',
|
||||||
icon: null
|
icon: null
|
||||||
});
|
})
|
||||||
|
|
||||||
this.fetchPayments(true).then(function () {
|
this.fetchPayments(true).then(function () {
|
||||||
dismissMsg();
|
dismissMsg()
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
exportCSV: function () {
|
exportCSV: function () {
|
||||||
LNbits.utils.exportCSV(this.paymentsTable.columns, this.payments);
|
LNbits.utils.exportCSV(this.paymentsTable.columns, this.payments)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'payments': function () {
|
payments: function () {
|
||||||
EventHub.$emit('update-wallet-balance', [this.g.wallet.id, this.balance]);
|
EventHub.$emit('update-wallet-balance', [this.g.wallet.id, this.balance])
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
this.fetchPayments();
|
this.fetchPayments()
|
||||||
setTimeout(this.checkPendingPayments(), 1200);
|
setTimeout(this.checkPendingPayments(), 1200)
|
||||||
},
|
},
|
||||||
mounted: function () {
|
mounted: function () {
|
||||||
if (this.$refs.disclaimer && !this.$q.localStorage.getItem('lnbits.disclaimerShown')) {
|
if (
|
||||||
this.disclaimerDialog.show = true;
|
this.$refs.disclaimer &&
|
||||||
this.$q.localStorage.set('lnbits.disclaimerShown', true);
|
!this.$q.localStorage.getItem('lnbits.disclaimerShown')
|
||||||
|
) {
|
||||||
|
this.disclaimerDialog.show = true
|
||||||
|
this.$q.localStorage.set('lnbits.disclaimerShown', true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,24 @@
|
||||||
|
<q-expansion-item
|
||||||
<q-expansion-item
|
|
||||||
group="extras"
|
group="extras"
|
||||||
icon="swap_vertical_circle"
|
icon="swap_vertical_circle"
|
||||||
label="Info"
|
label="Info"
|
||||||
:content-inset-level="0.5"
|
:content-inset-level="0.5"
|
||||||
>
|
>
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<h5 class="text-subtitle1 q-my-none">Assistant Faucet Milker</h5>
|
<h5 class="text-subtitle1 q-my-none">Assistant Faucet Milker</h5>
|
||||||
<p>Milking faucets with software, known as "assmilking", seems at first to be black-hat, although in fact there might be some unexplored use cases. An LNURL withdraw gives someone the right to pull funds, which can be done over time. An LNURL withdraw could be used outside of just faucets, to provide money streaming and repeat payments.<br/>Paste or scan an LNURL withdraw, enter the amount for the AMilk to pull and the frequency for it to be pulled.<br/>
|
<p>
|
||||||
<small> Created by, <a href="https://github.com/benarc">Ben Arc</a></small></p>
|
Milking faucets with software, known as "assmilking", seems at first to
|
||||||
</q-card>
|
be black-hat, although in fact there might be some unexplored use cases.
|
||||||
|
An LNURL withdraw gives someone the right to pull funds, which can be
|
||||||
|
done over time. An LNURL withdraw could be used outside of just faucets,
|
||||||
|
to provide money streaming and repeat payments.<br />Paste or scan an
|
||||||
|
LNURL withdraw, enter the amount for the AMilk to pull and the frequency
|
||||||
|
for it to be pulled.<br />
|
||||||
|
<small>
|
||||||
|
Created by, <a href="https://github.com/benarc">Ben Arc</a></small
|
||||||
|
>
|
||||||
|
</p>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
|
</q-card>
|
||||||
</q-card-section></q-expansion-item>
|
</q-expansion-item>
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,12 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %} {% from "macros.jinja" import window_vars with context
|
||||||
|
%} {% block page %}
|
||||||
{% from "macros.jinja" import window_vars with context %}
|
<div class="row q-col-gutter-md">
|
||||||
|
|
||||||
|
|
||||||
{% block page %}
|
|
||||||
<div class="row q-col-gutter-md">
|
|
||||||
<div class="col-12 col-md-8 col-lg-7 q-gutter-y-md">
|
<div class="col-12 col-md-8 col-lg-7 q-gutter-y-md">
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<q-btn unelevated color="deep-purple" @click="amilkDialog.show = true">New AMilk</q-btn>
|
<q-btn unelevated color="deep-purple" @click="amilkDialog.show = true"
|
||||||
|
>New AMilk</q-btn
|
||||||
|
>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|
||||||
|
|
@ -22,38 +20,36 @@
|
||||||
<q-btn flat color="grey" @click="exportCSV">Export to CSV</q-btn>
|
<q-btn flat color="grey" @click="exportCSV">Export to CSV</q-btn>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<q-table dense flat
|
<q-table
|
||||||
|
dense
|
||||||
|
flat
|
||||||
:data="amilks"
|
:data="amilks"
|
||||||
row-key="id"
|
row-key="id"
|
||||||
:columns="amilksTable.columns"
|
:columns="amilksTable.columns"
|
||||||
:pagination.sync="amilksTable.pagination">
|
:pagination.sync="amilksTable.pagination"
|
||||||
|
>
|
||||||
{% raw %}
|
{% raw %}
|
||||||
<template v-slot:header="props">
|
<template v-slot:header="props">
|
||||||
<q-tr :props="props">
|
<q-tr :props="props">
|
||||||
|
<q-th v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
<q-th
|
|
||||||
v-for="col in props.cols"
|
|
||||||
:key="col.name"
|
|
||||||
:props="props"
|
|
||||||
>
|
|
||||||
{{ col.label }}
|
{{ col.label }}
|
||||||
</q-th>
|
</q-th>
|
||||||
|
|
||||||
</q-tr>
|
</q-tr>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:body="props">
|
<template v-slot:body="props">
|
||||||
<q-tr :props="props">
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
<q-td
|
|
||||||
v-for="col in props.cols"
|
|
||||||
:key="col.name"
|
|
||||||
:props="props"
|
|
||||||
|
|
||||||
>
|
|
||||||
{{ col.value }}
|
{{ col.value }}
|
||||||
</q-td>
|
</q-td>
|
||||||
<q-td auto-width>
|
<q-td auto-width>
|
||||||
<q-btn flat dense size="xs" @click="deleteAMilk(props.row.id)" icon="cancel" color="pink"></q-btn>
|
<q-btn
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
size="xs"
|
||||||
|
@click="deleteAMilk(props.row.id)"
|
||||||
|
icon="cancel"
|
||||||
|
color="pink"
|
||||||
|
></q-btn>
|
||||||
</q-td>
|
</q-td>
|
||||||
</q-tr>
|
</q-tr>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -66,7 +62,9 @@
|
||||||
<div class="col-12 col-md-4 col-lg-5 q-gutter-y-md">
|
<div class="col-12 col-md-4 col-lg-5 q-gutter-y-md">
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<h6 class="text-subtitle1 q-my-none">LNbits Assistant Faucet Milker Extension</h6>
|
<h6 class="text-subtitle1 q-my-none">
|
||||||
|
LNbits Assistant Faucet Milker Extension
|
||||||
|
</h6>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-section class="q-pa-none">
|
<q-card-section class="q-pa-none">
|
||||||
<q-separator></q-separator>
|
<q-separator></q-separator>
|
||||||
|
|
@ -80,40 +78,59 @@
|
||||||
<q-dialog v-model="amilkDialog.show" position="top">
|
<q-dialog v-model="amilkDialog.show" position="top">
|
||||||
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
|
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
|
||||||
<q-form @submit="createAMilk" class="q-gutter-md">
|
<q-form @submit="createAMilk" class="q-gutter-md">
|
||||||
<q-select filled dense emit-value v-model="amilkDialog.data.wallet" :options="g.user.walletOptions" label="Wallet *">
|
<q-select
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
emit-value
|
||||||
|
v-model="amilkDialog.data.wallet"
|
||||||
|
:options="g.user.walletOptions"
|
||||||
|
label="Wallet *"
|
||||||
|
>
|
||||||
</q-select>
|
</q-select>
|
||||||
<q-input filled dense
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
v-model.trim="amilkDialog.data.lnurl"
|
v-model.trim="amilkDialog.data.lnurl"
|
||||||
type="url"
|
type="url"
|
||||||
label="LNURL Withdraw"></q-input>
|
label="LNURL Withdraw"
|
||||||
<q-input filled dense
|
></q-input>
|
||||||
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
v-model.number="amilkDialog.data.amount"
|
v-model.number="amilkDialog.data.amount"
|
||||||
type="number"
|
type="number"
|
||||||
label="Amount *"></q-input>
|
label="Amount *"
|
||||||
<q-input filled dense
|
></q-input>
|
||||||
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
v-model.trim="amilkDialog.data.atime"
|
v-model.trim="amilkDialog.data.atime"
|
||||||
type="number"
|
type="number"
|
||||||
label="Hit frequency (secs)"
|
label="Hit frequency (secs)"
|
||||||
placeholder="Frequency to be hit"></q-input>
|
placeholder="Frequency to be hit"
|
||||||
<q-btn unelevated
|
></q-input>
|
||||||
|
<q-btn
|
||||||
|
unelevated
|
||||||
color="deep-purple"
|
color="deep-purple"
|
||||||
:disable="amilkDialog.data.amount == null || amilkDialog.data.amount < 0 || amilkDialog.data.lnurl == null"
|
:disable="amilkDialog.data.amount == null || amilkDialog.data.amount < 0 || amilkDialog.data.lnurl == null"
|
||||||
type="submit">Create amilk</q-btn>
|
type="submit"
|
||||||
|
>Create amilk</q-btn
|
||||||
|
>
|
||||||
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Cancel</q-btn>
|
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Cancel</q-btn>
|
||||||
</q-form>
|
</q-form>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %} {% block scripts %} {{ window_vars(user) }}
|
||||||
|
<script>
|
||||||
{% block scripts %}
|
|
||||||
{{ window_vars(user) }}
|
|
||||||
<script>
|
|
||||||
var mapAMilk = function (obj) {
|
var mapAMilk = function (obj) {
|
||||||
obj.date = Quasar.utils.date.formatDate(new Date(obj.time * 1000), 'YYYY-MM-DD HH:mm');
|
obj.date = Quasar.utils.date.formatDate(
|
||||||
obj.fsat = new Intl.NumberFormat(LOCALE).format(obj.amount);
|
new Date(obj.time * 1000),
|
||||||
obj.wall = ['/amilk/', obj.id].join('');
|
'YYYY-MM-DD HH:mm'
|
||||||
return obj;
|
)
|
||||||
|
obj.fsat = new Intl.NumberFormat(LOCALE).format(obj.amount)
|
||||||
|
obj.wall = ['/amilk/', obj.id].join('')
|
||||||
|
return obj
|
||||||
}
|
}
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
|
|
@ -137,94 +154,99 @@
|
||||||
show: false,
|
show: false,
|
||||||
data: {}
|
data: {}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
getAMilks: function () {
|
getAMilks: function () {
|
||||||
var self = this;
|
var self = this
|
||||||
|
|
||||||
LNbits.api.request(
|
LNbits.api
|
||||||
|
.request(
|
||||||
'GET',
|
'GET',
|
||||||
'/amilk/api/v1/amilk?all_wallets',
|
'/amilk/api/v1/amilk?all_wallets',
|
||||||
this.g.user.wallets[0].inkey
|
this.g.user.wallets[0].inkey
|
||||||
).then(function (response) {
|
)
|
||||||
|
.then(function (response) {
|
||||||
self.amilks = response.data.map(function (obj) {
|
self.amilks = response.data.map(function (obj) {
|
||||||
response.data.forEach(MILK);
|
response.data.forEach(MILK)
|
||||||
function MILK(item){
|
function MILK(item) {
|
||||||
|
window.setInterval(function () {
|
||||||
window.setInterval(function(){
|
LNbits.api
|
||||||
|
.request(
|
||||||
|
|
||||||
LNbits.api.request(
|
|
||||||
'GET',
|
'GET',
|
||||||
'/amilk/api/v1/amilk/milk/' + item.id,
|
'/amilk/api/v1/amilk/milk/' + item.id,
|
||||||
"Lorem"
|
'Lorem'
|
||||||
).then(function (response) {
|
)
|
||||||
|
.then(function (response) {
|
||||||
self.amilks = response.data.map(function (obj) {
|
self.amilks = response.data.map(function (obj) {
|
||||||
return mapAMilk(obj);
|
return mapAMilk(obj)
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
},
|
}, item.atime * 1000)
|
||||||
item.atime*1000);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return mapAMilk(obj);
|
return mapAMilk(obj)
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
createAMilk: function () {
|
createAMilk: function () {
|
||||||
var data = {
|
var data = {
|
||||||
lnurl: this.amilkDialog.data.lnurl,
|
lnurl: this.amilkDialog.data.lnurl,
|
||||||
atime: parseInt(this.amilkDialog.data.atime),
|
atime: parseInt(this.amilkDialog.data.atime),
|
||||||
amount: this.amilkDialog.data.amount
|
amount: this.amilkDialog.data.amount
|
||||||
};
|
}
|
||||||
var self = this;
|
var self = this
|
||||||
|
|
||||||
console.log(this.amilkDialog.data.wallet);
|
console.log(this.amilkDialog.data.wallet)
|
||||||
|
|
||||||
LNbits.api.request(
|
LNbits.api
|
||||||
|
.request(
|
||||||
'POST',
|
'POST',
|
||||||
'/amilk/api/v1/amilk',
|
'/amilk/api/v1/amilk',
|
||||||
_.findWhere(this.g.user.wallets, {id: this.amilkDialog.data.wallet}).inkey,
|
_.findWhere(this.g.user.wallets, {id: this.amilkDialog.data.wallet})
|
||||||
|
.inkey,
|
||||||
data
|
data
|
||||||
).then(function (response) {
|
)
|
||||||
self.amilks.push(mapAMilk(response.data));
|
.then(function (response) {
|
||||||
self.amilkDialog.show = false;
|
self.amilks.push(mapAMilk(response.data))
|
||||||
self.amilkDialog.data = {};
|
self.amilkDialog.show = false
|
||||||
}).catch(function (error) {
|
self.amilkDialog.data = {}
|
||||||
LNbits.utils.notifyApiError(error);
|
})
|
||||||
});
|
.catch(function (error) {
|
||||||
|
LNbits.utils.notifyApiError(error)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
deleteAMilk: function (amilkId) {
|
deleteAMilk: function (amilkId) {
|
||||||
var self = this;
|
var self = this
|
||||||
var amilk = _.findWhere(this.amilks, {id: amilkId});
|
var amilk = _.findWhere(this.amilks, {id: amilkId})
|
||||||
|
|
||||||
LNbits.utils.confirmDialog(
|
LNbits.utils
|
||||||
'Are you sure you want to delete this AMilk link?'
|
.confirmDialog('Are you sure you want to delete this AMilk link?')
|
||||||
).onOk(function () {
|
.onOk(function () {
|
||||||
LNbits.api.request(
|
LNbits.api
|
||||||
|
.request(
|
||||||
'DELETE',
|
'DELETE',
|
||||||
'/amilk/api/v1/amilks/' + amilkId,
|
'/amilk/api/v1/amilks/' + amilkId,
|
||||||
_.findWhere(self.g.user.wallets, {id: amilk.wallet}).inkey
|
_.findWhere(self.g.user.wallets, {id: amilk.wallet}).inkey
|
||||||
).then(function (response) {
|
)
|
||||||
self.amilks = _.reject(self.amilks, function (obj) { return obj.id == amilkId; });
|
.then(function (response) {
|
||||||
}).catch(function (error) {
|
self.amilks = _.reject(self.amilks, function (obj) {
|
||||||
LNbits.utils.notifyApiError(error);
|
return obj.id == amilkId
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
LNbits.utils.notifyApiError(error)
|
||||||
|
})
|
||||||
|
})
|
||||||
},
|
},
|
||||||
exportCSV: function () {
|
exportCSV: function () {
|
||||||
LNbits.utils.exportCSV(this.amilksTable.columns, this.amilks);
|
LNbits.utils.exportCSV(this.amilksTable.columns, this.amilks)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
if (this.g.user.wallets.length) {
|
if (this.g.user.wallets.length) {
|
||||||
this.getAMilks();
|
this.getAMilks()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,29 @@
|
||||||
|
<q-expansion-item
|
||||||
<q-expansion-item
|
|
||||||
group="extras"
|
group="extras"
|
||||||
icon="swap_vertical_circle"
|
icon="swap_vertical_circle"
|
||||||
label="Info"
|
label="Info"
|
||||||
:content-inset-level="0.5"
|
:content-inset-level="0.5"
|
||||||
>
|
>
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<h5 class="text-subtitle1 q-my-none">Diagon Alley: Decentralised Market-Stalls</h5>
|
<h5 class="text-subtitle1 q-my-none">
|
||||||
<p>Make a list of products to sell, point your list of products at a public indexer. Buyers browse your products on the indexer, and pay you directly. Ratings are managed by the indexer. Your stall can be listed in multiple indexers, even over TOR, if you wish to be anonymous.<br/>
|
Diagon Alley: Decentralised Market-Stalls
|
||||||
More information on the <a href="https://github.com/lnbits/Diagon-Alley">Diagon Alley Protocol</a><br/>
|
</h5>
|
||||||
<small> Created by, <a href="https://github.com/benarc">Ben Arc</a></small></p>
|
<p>
|
||||||
|
Make a list of products to sell, point your list of products at a public
|
||||||
|
indexer. Buyers browse your products on the indexer, and pay you
|
||||||
|
directly. Ratings are managed by the indexer. Your stall can be listed
|
||||||
|
in multiple indexers, even over TOR, if you wish to be anonymous.<br />
|
||||||
|
More information on the
|
||||||
|
<a href="https://github.com/lnbits/Diagon-Alley"
|
||||||
|
>Diagon Alley Protocol</a
|
||||||
|
><br />
|
||||||
|
<small>
|
||||||
|
Created by, <a href="https://github.com/benarc">Ben Arc</a></small
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-card-section>
|
|
||||||
|
|
||||||
</q-card-section>
|
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
<q-expansion-item
|
<q-expansion-item
|
||||||
group="extras"
|
group="extras"
|
||||||
|
|
@ -22,43 +31,91 @@
|
||||||
label="API info"
|
label="API info"
|
||||||
:content-inset-level="0.5"
|
:content-inset-level="0.5"
|
||||||
>
|
>
|
||||||
|
<q-expansion-item
|
||||||
<q-expansion-item group="api" dense expand-separator label="Get prodcuts, categorised by wallet">
|
group="api"
|
||||||
|
dense
|
||||||
|
expand-separator
|
||||||
|
label="Get prodcuts, categorised by wallet"
|
||||||
|
>
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<code><span class="text-light-blue">GET</span> /api/v1/diagonalley/stall/products/<indexer_id></code>
|
<code
|
||||||
|
><span class="text-light-blue">GET</span>
|
||||||
|
/api/v1/diagonalley/stall/products/<indexer_id></code
|
||||||
|
>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Returns 201 CREATED (application/json)</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||||
|
Returns 201 CREATED (application/json)
|
||||||
|
</h5>
|
||||||
<code>Product JSON list</code>
|
<code>Product JSON list</code>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||||
<code>curl -X GET {{ request.url_root }}diagonalley/api/v1/diagonalley/stall/products/<indexer_id></code>
|
<code
|
||||||
|
>curl -X GET {{ request.url_root
|
||||||
|
}}diagonalley/api/v1/diagonalley/stall/products/<indexer_id></code
|
||||||
|
>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
<q-expansion-item group="api" dense expand-separator label="Get invoice for product">
|
<q-expansion-item
|
||||||
|
group="api"
|
||||||
|
dense
|
||||||
|
expand-separator
|
||||||
|
label="Get invoice for product"
|
||||||
|
>
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<code><span class="text-light-green">POST</span> /api/v1/diagonalley/stall/order/<indexer_id></code>
|
<code
|
||||||
|
><span class="text-light-green">POST</span>
|
||||||
|
/api/v1/diagonalley/stall/order/<indexer_id></code
|
||||||
|
>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
|
||||||
<code>{"id": <string>, "address": <string>, "shippingzone": <integer>, "email": <string>, "quantity": <integer>}</code>
|
<code
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Returns 201 CREATED (application/json)</h5>
|
>{"id": <string>, "address": <string>, "shippingzone":
|
||||||
<code>{"checking_id": <string>,"payment_request": <string>}</code>
|
<integer>, "email": <string>, "quantity":
|
||||||
|
<integer>}</code
|
||||||
|
>
|
||||||
|
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||||
|
Returns 201 CREATED (application/json)
|
||||||
|
</h5>
|
||||||
|
<code
|
||||||
|
>{"checking_id": <string>,"payment_request":
|
||||||
|
<string>}</code
|
||||||
|
>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||||
<code>curl -X POST {{ request.url_root }}diagonalley/api/v1/diagonalley/stall/order/<indexer_id> -d '{"id": <product_id&>, "email": <customer_email>, "address": <customer_address>, "quantity": 2, "shippingzone": 1}' -H "Content-type: application/json"
|
<code
|
||||||
|
>curl -X POST {{ request.url_root
|
||||||
|
}}diagonalley/api/v1/diagonalley/stall/order/<indexer_id> -d
|
||||||
|
'{"id": <product_id&>, "email": <customer_email>,
|
||||||
|
"address": <customer_address>, "quantity": 2, "shippingzone":
|
||||||
|
1}' -H "Content-type: application/json"
|
||||||
</code>
|
</code>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
<q-expansion-item group="api" dense expand-separator label="Check a product has been shipped"
|
<q-expansion-item
|
||||||
class="q-mb-md">
|
group="api"
|
||||||
|
dense
|
||||||
|
expand-separator
|
||||||
|
label="Check a product has been shipped"
|
||||||
|
class="q-mb-md"
|
||||||
|
>
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<code><span class="text-light-blue">GET</span> /diagonalley/api/v1/diagonalley/stall/checkshipped/<checking_id></code>
|
<code
|
||||||
|
><span class="text-light-blue">GET</span>
|
||||||
|
/diagonalley/api/v1/diagonalley/stall/checkshipped/<checking_id></code
|
||||||
|
>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Returns 200 OK (application/json)</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||||
|
Returns 200 OK (application/json)
|
||||||
|
</h5>
|
||||||
<code>{"shipped": <boolean>}</code>
|
<code>{"shipped": <boolean>}</code>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||||
<code>curl -X GET {{ request.url_root }}diagonalley/api/v1/diagonalley/stall/checkshipped/<checking_id> -H "Content-type: application/json"</code>
|
<code
|
||||||
|
>curl -X GET {{ request.url_root
|
||||||
|
}}diagonalley/api/v1/diagonalley/stall/checkshipped/<checking_id>
|
||||||
|
-H "Content-type: application/json"</code
|
||||||
|
>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1 +1,3 @@
|
||||||
<script>console.log("{{ stall }}")</script>
|
<script>
|
||||||
|
console.log('{{ stall }}')
|
||||||
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<!-- @format -->
|
<!-- @format -->
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
|
@ -202,204 +202,183 @@
|
||||||
type="text/javascript"
|
type="text/javascript"
|
||||||
></script>
|
></script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
||||||
//GOOFY CSS HACK TO GO DARK
|
//GOOFY CSS HACK TO GO DARK
|
||||||
|
|
||||||
.skin-blue .wrapper {
|
.skin-blue .wrapper {
|
||||||
background:
|
background: #1f2234;
|
||||||
#1f2234;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.skin-blue .sidebar-menu > li.active > a {
|
.skin-blue .sidebar-menu > li.active > a {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background:#1f2234;
|
background: #1f2234;
|
||||||
border-left-color:#8964a9;
|
border-left-color: #8964a9;
|
||||||
}
|
}
|
||||||
|
|
||||||
.skin-blue .main-header .navbar {
|
.skin-blue .main-header .navbar {
|
||||||
background-color:
|
background-color: #2e507d;
|
||||||
#2e507d;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.content-wrapper, .right-side {
|
|
||||||
background-color:
|
|
||||||
#1f2234;
|
|
||||||
}
|
|
||||||
.skin-blue .main-header .logo {
|
|
||||||
background-color:
|
|
||||||
#1f2234;
|
|
||||||
color:
|
|
||||||
#fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.skin-blue .sidebar-menu > li.header {
|
|
||||||
color:
|
|
||||||
#4b646f;
|
|
||||||
background:
|
|
||||||
#1f2234;
|
|
||||||
}
|
|
||||||
.skin-blue .wrapper, .skin-blue .main-sidebar, .skin-blue .left-side {
|
|
||||||
background:
|
|
||||||
#1f2234;
|
|
||||||
}
|
|
||||||
|
|
||||||
.skin-blue .sidebar-menu > li > .treeview-menu {
|
|
||||||
margin: 0 1px;
|
|
||||||
background:
|
|
||||||
#1f2234;
|
|
||||||
}
|
|
||||||
|
|
||||||
.skin-blue .sidebar-menu > li > a {
|
|
||||||
border-left: 3px solid
|
|
||||||
transparent;
|
|
||||||
margin-right: 1px;
|
|
||||||
}
|
|
||||||
.skin-blue .sidebar-menu > li > a:hover, .skin-blue .sidebar-menu > li.active > a {
|
|
||||||
|
|
||||||
|
.content-wrapper,
|
||||||
|
.right-side {
|
||||||
|
background-color: #1f2234;
|
||||||
|
}
|
||||||
|
.skin-blue .main-header .logo {
|
||||||
|
background-color: #1f2234;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background:#3e355a;
|
}
|
||||||
border-left-color:#8964a9;
|
|
||||||
|
|
||||||
}
|
.skin-blue .sidebar-menu > li.header {
|
||||||
|
color: #4b646f;
|
||||||
|
background: #1f2234;
|
||||||
|
}
|
||||||
|
.skin-blue .wrapper,
|
||||||
|
.skin-blue .main-sidebar,
|
||||||
|
.skin-blue .left-side {
|
||||||
|
background: #1f2234;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skin-blue .sidebar-menu > li > .treeview-menu {
|
||||||
|
margin: 0 1px;
|
||||||
|
background: #1f2234;
|
||||||
|
}
|
||||||
|
|
||||||
.skin-blue .main-header .logo:hover {
|
.skin-blue .sidebar-menu > li > a {
|
||||||
background:
|
border-left: 3px solid transparent;
|
||||||
#3e355a;
|
margin-right: 1px;
|
||||||
}
|
}
|
||||||
|
.skin-blue .sidebar-menu > li > a:hover,
|
||||||
|
.skin-blue .sidebar-menu > li.active > a {
|
||||||
|
color: #fff;
|
||||||
|
background: #3e355a;
|
||||||
|
border-left-color: #8964a9;
|
||||||
|
}
|
||||||
|
|
||||||
.skin-blue .main-header .navbar .sidebar-toggle:hover {
|
.skin-blue .main-header .logo:hover {
|
||||||
background-color:
|
background: #3e355a;
|
||||||
#3e355a;
|
}
|
||||||
}
|
|
||||||
.main-footer {
|
.skin-blue .main-header .navbar .sidebar-toggle:hover {
|
||||||
|
background-color: #3e355a;
|
||||||
|
}
|
||||||
|
.main-footer {
|
||||||
background-color: #1f2234;
|
background-color: #1f2234;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
border-top: 0px;
|
border-top: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.skin-blue .main-header .navbar {
|
.skin-blue .main-header .navbar {
|
||||||
background-color: #1f2234;
|
background-color: #1f2234;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-red, .callout.callout-danger, .alert-danger, .alert-error, .label-danger, .modal-danger .modal-body {
|
|
||||||
background-color:
|
|
||||||
#1f2234 !important;
|
|
||||||
}
|
|
||||||
.alert-danger, .alert-error {
|
|
||||||
|
|
||||||
|
.bg-red,
|
||||||
|
.callout.callout-danger,
|
||||||
|
.alert-danger,
|
||||||
|
.alert-error,
|
||||||
|
.label-danger,
|
||||||
|
.modal-danger .modal-body {
|
||||||
|
background-color: #1f2234 !important;
|
||||||
|
}
|
||||||
|
.alert-danger,
|
||||||
|
.alert-error {
|
||||||
border-color: #fff;
|
border-color: #fff;
|
||||||
border: 1px solid
|
border: 1px solid #fff;
|
||||||
|
|
||||||
#fff;
|
|
||||||
border-radius: 7px;
|
border-radius: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
.skin-blue .main-header .navbar .nav > li > a:hover,
|
||||||
|
.skin-blue .main-header .navbar .nav > li > a:active,
|
||||||
.skin-blue .main-header .navbar .nav > li > a:hover, .skin-blue .main-header .navbar .nav > li > a:active, .skin-blue .main-header .navbar .nav > li > a:focus, .skin-blue .main-header .navbar .nav .open > a, .skin-blue .main-header .navbar .nav .open > a:hover, .skin-blue .main-header .navbar .nav .open > a:focus {
|
.skin-blue .main-header .navbar .nav > li > a:focus,
|
||||||
color:
|
.skin-blue .main-header .navbar .nav .open > a,
|
||||||
#f6f6f6;
|
.skin-blue .main-header .navbar .nav .open > a:hover,
|
||||||
|
.skin-blue .main-header .navbar .nav .open > a:focus {
|
||||||
|
color: #f6f6f6;
|
||||||
background-color: #3e355a;
|
background-color: #3e355a;
|
||||||
}
|
}
|
||||||
.bg-aqua, .callout.callout-info, .alert-info, .label-info, .modal-info .modal-body {
|
.bg-aqua,
|
||||||
background-color:
|
.callout.callout-info,
|
||||||
#3e355a !important;
|
.alert-info,
|
||||||
}
|
.label-info,
|
||||||
|
.modal-info .modal-body {
|
||||||
|
background-color: #3e355a !important;
|
||||||
|
}
|
||||||
|
|
||||||
.box {
|
.box {
|
||||||
position: relative;
|
position: relative;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
background-color: #333646;
|
background-color: #333646;
|
||||||
border-top: 3px solid #8964a9;
|
border-top: 3px solid #8964a9;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
}
|
||||||
|
.table-striped > tbody > tr:nth-of-type(2n + 1) {
|
||||||
|
background-color: #333646;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
.box-header {
|
||||||
.table-striped > tbody > tr:nth-of-type(2n+1) {
|
|
||||||
background-color:
|
|
||||||
#333646;
|
|
||||||
}
|
|
||||||
|
|
||||||
.box-header {
|
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
.box.box-danger {
|
||||||
|
|
||||||
|
|
||||||
.box.box-danger {
|
|
||||||
border-top-color: #8964a9;
|
border-top-color: #8964a9;
|
||||||
}
|
}
|
||||||
.box.box-primary {
|
.box.box-primary {
|
||||||
border-top-color: #8964a9;
|
border-top-color: #8964a9;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: #8964a9;
|
color: #8964a9;
|
||||||
}
|
}
|
||||||
.box-header.with-border {
|
.box-header.with-border {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover, a:active, a:focus {
|
a:hover,
|
||||||
|
a:active,
|
||||||
|
a:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
// .modal.in .modal-dialog{
|
// .modal.in .modal-dialog{
|
||||||
// color:#000;
|
// color:#000;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
.form-control {
|
|
||||||
|
|
||||||
background-color:#333646;
|
|
||||||
color: #fff;
|
|
||||||
|
|
||||||
}
|
|
||||||
.box-footer {
|
|
||||||
|
|
||||||
|
.form-control {
|
||||||
|
background-color: #333646;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.box-footer {
|
||||||
border-top: none;
|
border-top: none;
|
||||||
|
|
||||||
background-color:
|
|
||||||
#333646;
|
|
||||||
}
|
|
||||||
.modal-footer {
|
|
||||||
|
|
||||||
border-top: none;
|
|
||||||
|
|
||||||
}
|
|
||||||
.modal-content {
|
|
||||||
|
|
||||||
background-color:
|
|
||||||
#333646;
|
|
||||||
}
|
|
||||||
.modal.in .modal-dialog {
|
|
||||||
|
|
||||||
background-color: #333646;
|
background-color: #333646;
|
||||||
|
}
|
||||||
|
.modal-footer {
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
.modal-content {
|
||||||
|
background-color: #333646;
|
||||||
|
}
|
||||||
|
.modal.in .modal-dialog {
|
||||||
|
background-color: #333646;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
.layout-boxed {
|
||||||
|
|
||||||
.layout-boxed {
|
|
||||||
background: none;
|
background: none;
|
||||||
background-color: rgba(0, 0, 0, 0);
|
background-color: rgba(0, 0, 0, 0);
|
||||||
background-color:
|
background-color: #3e355a;
|
||||||
#3e355a;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.skin-blue .sidebar-menu > li > a:hover, .skin-blue .sidebar-menu > li.active > a {
|
|
||||||
|
|
||||||
|
.skin-blue .sidebar-menu > li > a:hover,
|
||||||
|
.skin-blue .sidebar-menu > li.active > a {
|
||||||
background: none;
|
background: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body class="skin-blue layout-boxed sidebar-collapse sidebar-open">
|
<body class="skin-blue layout-boxed sidebar-collapse sidebar-open">
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
|
|
@ -421,7 +400,6 @@ background-color:
|
||||||
<ul class="nav navbar-nav">
|
<ul class="nav navbar-nav">
|
||||||
<!-- Messages: style can be found in dropdown.less-->
|
<!-- Messages: style can be found in dropdown.less-->
|
||||||
<li class="dropdown messages-menu">
|
<li class="dropdown messages-menu">
|
||||||
|
|
||||||
{% block messages %}{% endblock %}
|
{% block messages %}{% endblock %}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
@ -431,9 +409,7 @@ background-color:
|
||||||
|
|
||||||
<aside class="main-sidebar">
|
<aside class="main-sidebar">
|
||||||
<!-- sidebar: style can be found in sidebar.less -->
|
<!-- sidebar: style can be found in sidebar.less -->
|
||||||
<section class="sidebar" style="height: auto;">
|
<section class="sidebar" style="height: auto;"></section>
|
||||||
|
|
||||||
</section>
|
|
||||||
<!-- /.sidebar -->
|
<!-- /.sidebar -->
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
|
|
@ -445,46 +421,68 @@ background-color:
|
||||||
LNBits Events
|
LNBits Events
|
||||||
<small>Lightning powered tickets</small>
|
<small>Lightning powered tickets</small>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Main content -->
|
<!-- Main content -->
|
||||||
<section class="content"><br/><br/>
|
<section class="content">
|
||||||
<center><h1 style="font-size:500%">{{ nme }}</h1></center>
|
<br /><br />
|
||||||
<center><h2 style="width:55%;word-wrap: break-word;" >{{ descr }}</h2></center>
|
<center><h1 style="font-size: 500%;">{{ nme }}</h1></center>
|
||||||
<div id="theform">
|
|
||||||
<br/><br/><br/>
|
|
||||||
<center>
|
<center>
|
||||||
|
<h2 style="width: 55%; word-wrap: break-word;">{{ descr }}</h2>
|
||||||
<form role="form">
|
|
||||||
|
|
||||||
<div class="form-group" style="width:300px;">
|
|
||||||
|
|
||||||
<input id="Nam" type="text" class="form-control" placeholder="Name"></input>
|
|
||||||
<input id="Ema" type="text" class="form-control" placeholder="Email"></input>
|
|
||||||
</div>
|
|
||||||
<button onclick="submitforticket()" type="button" class="btn btn-info">Go to payment</button><p style="color:red;" id="error"></p>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</center>
|
</center>
|
||||||
|
<div id="theform">
|
||||||
<center><br/><br/> <div id="qrcode" style="width: 340px;"></div><br/><br/>
|
<br /><br /><br />
|
||||||
<div style="width:55%;word-wrap: break-word;" id="qrcodetxt"></div> <br/></center>
|
<center>
|
||||||
|
<form role="form">
|
||||||
</section><!-- /.content -->
|
<div class="form-group" style="width: 300px;">
|
||||||
</div><!-- /.content-wrapper -->
|
<input
|
||||||
|
id="Nam"
|
||||||
|
type="text"
|
||||||
|
class="form-control"
|
||||||
|
placeholder="Name"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
id="Ema"
|
||||||
|
type="text"
|
||||||
|
class="form-control"
|
||||||
|
placeholder="Email"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
onclick="submitforticket()"
|
||||||
|
type="button"
|
||||||
|
class="btn btn-info"
|
||||||
|
>
|
||||||
|
Go to payment
|
||||||
|
</button>
|
||||||
|
<p style="color: red;" id="error"></p>
|
||||||
|
</form>
|
||||||
|
</center>
|
||||||
|
</div>
|
||||||
|
<center>
|
||||||
|
<br /><br />
|
||||||
|
<div id="qrcode" style="width: 340px;"></div>
|
||||||
|
<br /><br />
|
||||||
|
<div
|
||||||
|
style="width: 55%; word-wrap: break-word;"
|
||||||
|
id="qrcodetxt"
|
||||||
|
></div>
|
||||||
|
<br />
|
||||||
|
</center>
|
||||||
|
</section>
|
||||||
|
<!-- /.content -->
|
||||||
|
</div>
|
||||||
|
<!-- /.content-wrapper -->
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
function postAjax(url, data, thekey, success) {
|
||||||
|
|
||||||
function postAjax(url, data, thekey, success) {
|
|
||||||
var params =
|
var params =
|
||||||
typeof data == 'string'
|
typeof data == 'string'
|
||||||
? data
|
? data
|
||||||
: Object.keys(data)
|
: Object.keys(data)
|
||||||
.map(function(k) {
|
.map(function (k) {
|
||||||
return encodeURIComponent(k) + '=' + encodeURIComponent(data[k])
|
return encodeURIComponent(k) + '=' + encodeURIComponent(data[k])
|
||||||
})
|
})
|
||||||
.join('&')
|
.join('&')
|
||||||
|
|
@ -492,7 +490,7 @@ function postAjax(url, data, thekey, success) {
|
||||||
? new XMLHttpRequest()
|
? new XMLHttpRequest()
|
||||||
: new ActiveXObject('Microsoft.XMLHTTP')
|
: new ActiveXObject('Microsoft.XMLHTTP')
|
||||||
xhr.open('POST', url)
|
xhr.open('POST', url)
|
||||||
xhr.onreadystatechange = function() {
|
xhr.onreadystatechange = function () {
|
||||||
if (xhr.readyState > 3 && xhr.status == 200) {
|
if (xhr.readyState > 3 && xhr.status == 200) {
|
||||||
success(xhr.responseText)
|
success(xhr.responseText)
|
||||||
}
|
}
|
||||||
|
|
@ -501,14 +499,14 @@ function postAjax(url, data, thekey, success) {
|
||||||
xhr.setRequestHeader('Content-Type', 'application/json')
|
xhr.setRequestHeader('Content-Type', 'application/json')
|
||||||
xhr.send(params)
|
xhr.send(params)
|
||||||
return xhr
|
return xhr
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAjax(url, thekey, success) {
|
function getAjax(url, thekey, success) {
|
||||||
var xhr = window.XMLHttpRequest
|
var xhr = window.XMLHttpRequest
|
||||||
? new XMLHttpRequest()
|
? new XMLHttpRequest()
|
||||||
: new ActiveXObject('Microsoft.XMLHTTP')
|
: new ActiveXObject('Microsoft.XMLHTTP')
|
||||||
xhr.open('GET', url, true)
|
xhr.open('GET', url, true)
|
||||||
xhr.onreadystatechange = function() {
|
xhr.onreadystatechange = function () {
|
||||||
if (xhr.readyState > 3 && xhr.status == 200) {
|
if (xhr.readyState > 3 && xhr.status == 200) {
|
||||||
success(xhr.responseText)
|
success(xhr.responseText)
|
||||||
}
|
}
|
||||||
|
|
@ -518,19 +516,18 @@ function postAjax(url, data, thekey, success) {
|
||||||
|
|
||||||
xhr.send()
|
xhr.send()
|
||||||
return xhr
|
return xhr
|
||||||
}
|
}
|
||||||
|
|
||||||
function submitforticket(){
|
|
||||||
|
|
||||||
|
function submitforticket() {
|
||||||
nam = document.getElementById('Nam').value
|
nam = document.getElementById('Nam').value
|
||||||
ema = document.getElementById('Ema').value
|
ema = document.getElementById('Ema').value
|
||||||
|
|
||||||
postAjax(
|
postAjax(
|
||||||
"{{ url_for('events.api_getticket') }}?ema=" + ema,
|
"{{ url_for('events.api_getticket') }}?ema=" + ema,
|
||||||
JSON.stringify({"unireg": "{{wave }}", "name": nam}),
|
JSON.stringify({unireg: '{{wave }}', name: nam}),
|
||||||
"filla",
|
'filla',
|
||||||
|
|
||||||
function(data) {
|
function (data) {
|
||||||
theinvoice = JSON.parse(data).pay_req
|
theinvoice = JSON.parse(data).pay_req
|
||||||
thehash = JSON.parse(data).payment_hash
|
thehash = JSON.parse(data).payment_hash
|
||||||
|
|
||||||
|
|
@ -542,29 +539,29 @@ function submitforticket(){
|
||||||
colorLight: '#ffffff',
|
colorLight: '#ffffff',
|
||||||
correctLevel: QRCode.CorrectLevel.M
|
correctLevel: QRCode.CorrectLevel.M
|
||||||
})
|
})
|
||||||
document.getElementById('theform').innerHTML = ""
|
document.getElementById('theform').innerHTML = ''
|
||||||
|
|
||||||
document.getElementById("qrcode").style.backgroundColor = "white";
|
document.getElementById('qrcode').style.backgroundColor = 'white'
|
||||||
document.getElementById("qrcode").style.padding = "20px";
|
document.getElementById('qrcode').style.padding = '20px'
|
||||||
|
|
||||||
|
document.getElementById('qrcodetxt').innerHTML =
|
||||||
|
theinvoice + '<br/><br/>'
|
||||||
|
|
||||||
document.getElementById('qrcodetxt').innerHTML = theinvoice + "<br/><br/>"
|
var refreshId = setInterval(function () {
|
||||||
|
getAjax('/api/v1/invoice/' + thehash, '{{wave}}', function (datab) {
|
||||||
var refreshId = setInterval(function(){
|
|
||||||
|
|
||||||
getAjax('/api/v1/invoice/' + thehash, "{{wave}}", function(datab) {
|
|
||||||
console.log(JSON.parse(datab).PAID)
|
console.log(JSON.parse(datab).PAID)
|
||||||
if (JSON.parse(datab).PAID == 'TRUE') {
|
if (JSON.parse(datab).PAID == 'TRUE') {
|
||||||
location.replace("{{ url_for('events.ticket') }}?hash="+thehash + "&unireg={{wave}}")
|
location.replace(
|
||||||
|
"{{ url_for('events.ticket') }}?hash=" +
|
||||||
|
thehash +
|
||||||
|
'&unireg={{wave}}'
|
||||||
|
)
|
||||||
clearInterval(refreshId)
|
clearInterval(refreshId)
|
||||||
}
|
}
|
||||||
})}, 3000);
|
})
|
||||||
|
}, 3000)
|
||||||
|
}
|
||||||
})
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,8 @@
|
||||||
<li class="header"><b>Instant wallet, bookmark to save</b></li>
|
<li class="header"><b>Instant wallet, bookmark to save</b></li>
|
||||||
<li></li>
|
<li></li>
|
||||||
</ul>
|
</ul>
|
||||||
{% endblock %}
|
{% endblock %} {% block menuitems %}
|
||||||
|
<li class="treeview">
|
||||||
{% block menuitems %}
|
|
||||||
<li class="treeview">
|
|
||||||
<a href="#">
|
<a href="#">
|
||||||
<i class="fa fa-bitcoin"></i> <span>Wallets</span>
|
<i class="fa fa-bitcoin"></i> <span>Wallets</span>
|
||||||
<i class="fa fa-angle-left pull-right"></i>
|
<i class="fa fa-angle-left pull-right"></i>
|
||||||
|
|
@ -21,34 +19,34 @@
|
||||||
<ul class="treeview-menu">
|
<ul class="treeview-menu">
|
||||||
{% for w in user_wallets %}
|
{% for w in user_wallets %}
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ url_for('wallet') }}?wal={{ w.id }}&usr={{ w.user }}"><i class="fa fa-bolt"></i> {{ w.name }}</a>
|
<a href="{{ url_for('wallet') }}?wal={{ w.id }}&usr={{ w.user }}"
|
||||||
|
><i class="fa fa-bolt"></i> {{ w.name }}</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<li><a onclick="sidebarmake()">Add a wallet +</a></li>
|
<li><a onclick="sidebarmake()">Add a wallet +</a></li>
|
||||||
<div id="sidebarmake"></div>
|
<div id="sidebarmake"></div>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="active treeview">
|
<li class="active treeview">
|
||||||
<a href="#">
|
<a href="#">
|
||||||
<i class="fa fa-th"></i> <span>Extensions</span>
|
<i class="fa fa-th"></i> <span>Extensions</span>
|
||||||
<i class="fa fa-angle-left pull-right"></i>
|
<i class="fa fa-angle-left pull-right"></i>
|
||||||
</a>
|
</a>
|
||||||
<ul class="treeview-menu">
|
<ul class="treeview-menu">
|
||||||
{% for extension in EXTENSIONS %}
|
{% for extension in EXTENSIONS %} {% if extension.code in user_ext %}
|
||||||
{% if extension.code in user_ext %}
|
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ url_for(extension.code + '.index') }}?usr={{ user }}"><i class="fa fa-plus"></i> {{ extension.name }}</a>
|
<a href="{{ url_for(extension.code + '.index') }}?usr={{ user }}"
|
||||||
|
><i class="fa fa-plus"></i> {{ extension.name }}</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %} {% endfor %}
|
||||||
{% endfor %}
|
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ url_for('core.extensions') }}?usr={{ user }}">Manager</a></li>
|
<a href="{{ url_for('core.extensions') }}?usr={{ user }}">Manager</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
{% endblock %}
|
{% endblock %} {% block body %}
|
||||||
|
|
||||||
|
|
||||||
{% block body %}
|
|
||||||
<!-- Right side column. Contains the navbar and content of the page -->
|
<!-- Right side column. Contains the navbar and content of the page -->
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
<!-- Content Header (Page header) -->
|
<!-- Content Header (Page header) -->
|
||||||
|
|
@ -56,14 +54,17 @@
|
||||||
<h1>
|
<h1>
|
||||||
Events
|
Events
|
||||||
<small>bitcoin tickets</small>
|
<small>bitcoin tickets</small>
|
||||||
|
|
||||||
</h1>
|
</h1>
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ url_for('wallet') }}?usr={{ user }}"><i class="fa fa-dashboard"></i> Home</a>
|
<a href="{{ url_for('wallet') }}?usr={{ user }}"
|
||||||
|
><i class="fa fa-dashboard"></i> Home</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ url_for('core.extensions') }}?usr={{ user }}"><li class="fa fa-dashboard">Extensions</li></a>
|
<a href="{{ url_for('core.extensions') }}?usr={{ user }}"
|
||||||
|
><li class="fa fa-dashboard">Extensions</li></a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<i class="active" class="fa fa-dashboard">Lightning tickets</i>
|
<i class="active" class="fa fa-dashboard">Lightning tickets</i>
|
||||||
|
|
@ -71,35 +72,34 @@
|
||||||
</ol>
|
</ol>
|
||||||
<br /><br />
|
<br /><br />
|
||||||
</section>
|
</section>
|
||||||
<style>
|
<style>
|
||||||
.datepicker-days{
|
.datepicker-days {
|
||||||
|
|
||||||
background-color: #1f2234;
|
background-color: #1f2234;
|
||||||
}
|
}
|
||||||
|
</style>
|
||||||
</style>
|
|
||||||
<!-- Main content -->
|
<!-- Main content -->
|
||||||
<section class="content">
|
<section class="content">
|
||||||
<!-- Small boxes (Stat box) -->
|
<!-- Small boxes (Stat box) -->
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<!-- general form elements -->
|
<!-- general form elements -->
|
||||||
<div class="box box-primary">
|
<div class="box box-primary">
|
||||||
|
|
||||||
|
|
||||||
<div class="box-header">
|
<div class="box-header">
|
||||||
<h3 class="box-title"> Make a ticket wave</h3>
|
<h3 class="box-title">Make a ticket wave</h3>
|
||||||
</div><!-- /.box-header -->
|
</div>
|
||||||
|
<!-- /.box-header -->
|
||||||
|
|
||||||
<!-- form start -->
|
<!-- form start -->
|
||||||
<form role="form">
|
<form role="form">
|
||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="exampleInputEmail1">Ticket title</label>
|
<label for="exampleInputEmail1">Ticket title</label>
|
||||||
<input id="tit" type="text" pattern="^[A-Za-z]+$" class="form-control" >
|
<input
|
||||||
|
id="tit"
|
||||||
|
type="text"
|
||||||
|
pattern="^[A-Za-z]+$"
|
||||||
|
class="form-control"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
@ -118,65 +118,86 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="nooftickets">No. of tickets</label>
|
<label for="nooftickets">No. of tickets</label>
|
||||||
<input id="notickets" type="number" class="form-control" placeholder="10" max="86400"></input>
|
<input
|
||||||
|
id="notickets"
|
||||||
|
type="number"
|
||||||
|
class="form-control"
|
||||||
|
placeholder="10"
|
||||||
|
max="86400"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Close date:</label>
|
<label>Close date:</label>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="text" class="form-control" id="datepicker"></input>
|
<input type="text" class="form-control" id="datepicker" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="prpertick">Price per ticket</label>
|
<label for="prpertick">Price per ticket</label>
|
||||||
<input id="prtickets" type="number" class="form-control" placeholder="10"></input>
|
<input
|
||||||
|
id="prtickets"
|
||||||
|
type="number"
|
||||||
|
class="form-control"
|
||||||
|
placeholder="10"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div><!-- /.box-body -->
|
|
||||||
|
|
||||||
<div class="box-footer">
|
<div class="box-footer">
|
||||||
|
<button onclick="postev()" type="button" class="btn btn-info">
|
||||||
<button onclick="postev()" type="button" class="btn btn-info">Create Wave</button><p style="color:red;" id="error"></p>
|
Create Wave
|
||||||
|
</button>
|
||||||
|
<p style="color: red;" id="error"></p>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div></div></div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<!-- general form elements -->
|
<!-- general form elements -->
|
||||||
<div class="box box-primary">
|
<div class="box box-primary">
|
||||||
<div class="box-header">
|
<div class="box-header">
|
||||||
<h3 class="box-title">Select a link</h3>
|
<h3 class="box-title">Select a link</h3>
|
||||||
</div><!-- /.box-header -->
|
</div>
|
||||||
|
<!-- /.box-header -->
|
||||||
<form role="form">
|
<form role="form">
|
||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
<select
|
||||||
<select class="form-control" id="waveselect" onchange="drawwithdraw()">
|
class="form-control"
|
||||||
|
id="waveselect"
|
||||||
|
onchange="drawwithdraw()"
|
||||||
|
>
|
||||||
<option value="none" selected>
|
<option value="none" selected>
|
||||||
Select an Option
|
Select an Option
|
||||||
</option>
|
</option>
|
||||||
{% for w in user_ev %}
|
{% for w in user_ev %}
|
||||||
<option id="{{w.uni}}" value="{{w.tit}}-{{w.unireg}}-{{w.uni}}">{{w.tit}}-{{w.unireg}}-{{w.uni}}</option>
|
<option id="{{w.uni}}" value="{{w.tit}}-{{w.unireg}}-{{w.uni}}"
|
||||||
|
>{{w.tit}}-{{w.unireg}}-{{w.uni}}</option
|
||||||
|
>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<center> <br/><div id="qrcode" style="width:340px" ></div><br/><div style="width:75%;word-wrap: break-word;" id="qrcodetxt" ></div></center>
|
<center>
|
||||||
|
<br />
|
||||||
|
<div id="qrcode" style="width: 340px;"></div>
|
||||||
|
<br />
|
||||||
|
<div
|
||||||
|
style="width: 75%; word-wrap: break-word;"
|
||||||
|
id="qrcodetxt"
|
||||||
|
></div>
|
||||||
|
</center>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</div><!-- /.box -->
|
|
||||||
</div>
|
</div>
|
||||||
|
<!-- /.box -->
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
@ -187,16 +208,19 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- /.box-header -->
|
<!-- /.box-header -->
|
||||||
<div class="box-body no-padding">
|
<div class="box-body no-padding">
|
||||||
<table id="pagnation" class="table table-bswearing anchorordered table-striped">
|
<table
|
||||||
|
id="pagnation"
|
||||||
|
class="table table-bswearing anchorordered table-striped"
|
||||||
|
>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Title</th>
|
<th>Title</th>
|
||||||
<th style="width:15%">Amt</th>
|
<th style="width: 15%;">Amt</th>
|
||||||
<th style="width:15%">Sold</th>
|
<th style="width: 15%;">Sold</th>
|
||||||
<th style="width:15%">Closing</th>
|
<th style="width: 15%;">Closing</th>
|
||||||
<th style="width:15%">Price</th>
|
<th style="width: 15%;">Price</th>
|
||||||
<th style="width:15%">Wallet</th>
|
<th style="width: 15%;">Wallet</th>
|
||||||
<th style="width:10%">Edit</th>
|
<th style="width: 10%;">Edit</th>
|
||||||
<th style="width:10%">Del</th>
|
<th style="width: 10%;">Del</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tbody id="ticketwaves"></tbody>
|
<tbody id="ticketwaves"></tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
@ -207,9 +231,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="editlink"></div>
|
||||||
|
|
||||||
<div id="editlink"></div>
|
|
||||||
|
|
||||||
<!-- /.content -->
|
<!-- /.content -->
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -232,7 +254,7 @@
|
||||||
console.log(user_ev)
|
console.log(user_ev)
|
||||||
|
|
||||||
|
|
||||||
function drawChart(user_ev) {
|
function drawChart(user_ev) {
|
||||||
var transactionsHTML = ''
|
var transactionsHTML = ''
|
||||||
|
|
||||||
for (var i = 0; i < user_ev.length; i++) {
|
for (var i = 0; i < user_ev.length; i++) {
|
||||||
|
|
@ -262,11 +284,11 @@ function drawChart(user_ev) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user_ev.length) {
|
if (user_ev.length) {
|
||||||
drawChart(user_ev)
|
drawChart(user_ev)
|
||||||
}
|
}
|
||||||
|
|
||||||
function postev(){
|
function postev(){
|
||||||
|
|
||||||
wal = document.getElementById('wal').value
|
wal = document.getElementById('wal').value
|
||||||
tit = document.getElementById('tit').value
|
tit = document.getElementById('tit').value
|
||||||
|
|
@ -305,28 +327,28 @@ function postev(){
|
||||||
function(data) { location.replace("{{ url_for('events.index') }}?usr=" + user)
|
function(data) { location.replace("{{ url_for('events.index') }}?usr=" + user)
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function editlink(evnum){
|
function editlink(evnum){
|
||||||
|
|
||||||
evdetails = user_ev[evnum]
|
evdetails = user_ev[evnum]
|
||||||
|
|
||||||
console.log(evdetails.descr)
|
console.log(evdetails.descr)
|
||||||
wallpick = ""
|
wallpick = ""
|
||||||
|
|
||||||
checkbox = ""
|
checkbox = ""
|
||||||
if (evdetails.uniq == 1){
|
if (evdetails.uniq == 1){
|
||||||
checkbox = "checked"}
|
checkbox = "checked"}
|
||||||
|
|
||||||
document.getElementById('editlink').innerHTML = "<div class='row'>"+
|
document.getElementById('editlink').innerHTML = "<div class='row'>"+
|
||||||
"<div class='col-md-6'>"+
|
"<div class='col-md-6'>"+
|
||||||
" <!-- general form elements -->"+
|
" <!-- general form elements -->"+
|
||||||
"<div class='box box-primary' style='min-height: 300px;'>"+
|
"<div class='box box-primary' style='min-height: 300px;'>"+
|
||||||
"<div class='box-header'>"+
|
"<div class='box-header'>"+
|
||||||
"<h3 class='box-title'> Edit: <i id='unid'>" + evdetails.tit + "-" + evdetails.uni + "-" + evdetails.unireg + "</i> </h3>"+
|
"<h3 class='box-title'> Edit: <i id='unid'>" + evdetails.tit + "-" + evdetails.uni + "-" + evdetails.unireg + "</i> </h3>"+
|
||||||
"<div class='box-tools pull-right'>" +
|
"<div class='box-tools pull-right'>" +
|
||||||
"<button class='btn btn-box-tool' data-widget='remove'><i class='fa fa-times'></i></button>" +
|
"<button class='btn btn-box-tool' data-widget='remove'><i class='fa fa-times'></i></button>" +
|
||||||
"</div>" +
|
"</div>" +
|
||||||
" </div><!-- /.box-header -->"+
|
" </div><!-- /.box-header -->"+
|
||||||
" <!-- form start -->"+
|
" <!-- form start -->"+
|
||||||
|
|
@ -338,7 +360,7 @@ document.getElementById('editlink').innerHTML = "<div class='row'>"+
|
||||||
"<label for='exampleInputEmail1'>Link title</label>"+
|
"<label for='exampleInputEmail1'>Link title</label>"+
|
||||||
"<input id='edittit' type='text' class='form-control' value='"+
|
"<input id='edittit' type='text' class='form-control' value='"+
|
||||||
evdetails.tit +
|
evdetails.tit +
|
||||||
"'></input> </div>"+
|
"'> </div>"+
|
||||||
" </div>"+
|
" </div>"+
|
||||||
|
|
||||||
"<div class='col-sm-1 col-md-8'>"+
|
"<div class='col-sm-1 col-md-8'>"+
|
||||||
|
|
@ -367,7 +389,7 @@ document.getElementById('editlink').innerHTML = "<div class='row'>"+
|
||||||
" <label for='exampleInputPassword1'>No of tickets:</label>"+
|
" <label for='exampleInputPassword1'>No of tickets:</label>"+
|
||||||
" <input id='editnooftickets' type='number' class='form-control' placeholder='0' max='86400' value='"+
|
" <input id='editnooftickets' type='number' class='form-control' placeholder='0' max='86400' value='"+
|
||||||
evdetails.notickets +
|
evdetails.notickets +
|
||||||
"'></input>"+
|
"'>"+
|
||||||
"</div> </div>"+
|
"</div> </div>"+
|
||||||
|
|
||||||
" <div class='col-sm-3 col-md-4'>"+
|
" <div class='col-sm-3 col-md-4'>"+
|
||||||
|
|
@ -375,14 +397,14 @@ document.getElementById('editlink').innerHTML = "<div class='row'>"+
|
||||||
"<label for='exampleInputEmail1'>Price per ticket:</label>"+
|
"<label for='exampleInputEmail1'>Price per ticket:</label>"+
|
||||||
" <input id='editprtick' type='number' class='form-control' placeholder='1' value='"+
|
" <input id='editprtick' type='number' class='form-control' placeholder='1' value='"+
|
||||||
evdetails.prtick +
|
evdetails.prtick +
|
||||||
"'></input>"+
|
"'>"+
|
||||||
" </div></div>"+
|
" </div></div>"+
|
||||||
" <div class='col-sm-3 col-md-4'>"+
|
" <div class='col-sm-3 col-md-4'>"+
|
||||||
" <div class='input-group date'>"+
|
" <div class='input-group date'>"+
|
||||||
" <label for='exampleInputEmail1'>Close date:</label>"+
|
" <label for='exampleInputEmail1'>Close date:</label>"+
|
||||||
" <input id='datepicker2' type='text' class='form-control' placeholder='1' value='"+
|
" <input id='datepicker2' type='text' class='form-control' placeholder='1' value='"+
|
||||||
evdetails.cldate +
|
evdetails.cldate +
|
||||||
"'></input>"+
|
"'>"+
|
||||||
" </div></div>"+
|
" </div></div>"+
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -398,14 +420,14 @@ document.getElementById('editlink').innerHTML = "<div class='row'>"+
|
||||||
" </div></form></div><!-- /.box --></div></div>"
|
" </div></form></div><!-- /.box --></div></div>"
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Date picker
|
//Date picker
|
||||||
$('#datepicker2').datepicker({
|
$('#datepicker2').datepicker({
|
||||||
autoclose: true
|
autoclose: true
|
||||||
})
|
})
|
||||||
|
|
||||||
function editlinkcont(){
|
function editlinkcont(){
|
||||||
|
|
||||||
unid = document.getElementById('unid').innerHTML
|
unid = document.getElementById('unid').innerHTML
|
||||||
wal = document.getElementById('editwal').value
|
wal = document.getElementById('editwal').value
|
||||||
|
|
@ -442,12 +464,12 @@ function editlinkcont(){
|
||||||
"filla",
|
"filla",
|
||||||
|
|
||||||
function(data) { location.replace("{{ url_for('events.index') }}?usr=" + user)
|
function(data) { location.replace("{{ url_for('events.index') }}?usr=" + user)
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//draws withdraw QR code
|
//draws withdraw QR code
|
||||||
function drawwithdraw() {
|
function drawwithdraw() {
|
||||||
|
|
||||||
document.getElementById("qrcode").innerHTML = "";
|
document.getElementById("qrcode").innerHTML = "";
|
||||||
walname = document.getElementById("waveselect").value
|
walname = document.getElementById("waveselect").value
|
||||||
|
|
@ -473,8 +495,7 @@ function drawwithdraw() {
|
||||||
document.getElementById("qrcode").style.backgroundColor = "white";
|
document.getElementById("qrcode").style.backgroundColor = "white";
|
||||||
document.getElementById("qrcode").style.padding = "20px";
|
document.getElementById("qrcode").style.padding = "20px";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<!-- @format -->
|
<!-- @format -->
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
|
@ -202,204 +202,183 @@
|
||||||
type="text/javascript"
|
type="text/javascript"
|
||||||
></script>
|
></script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
||||||
//GOOFY CSS HACK TO GO DARK
|
//GOOFY CSS HACK TO GO DARK
|
||||||
|
|
||||||
.skin-blue .wrapper {
|
.skin-blue .wrapper {
|
||||||
background:
|
background: #1f2234;
|
||||||
#1f2234;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.skin-blue .sidebar-menu > li.active > a {
|
.skin-blue .sidebar-menu > li.active > a {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background:#1f2234;
|
background: #1f2234;
|
||||||
border-left-color:#8964a9;
|
border-left-color: #8964a9;
|
||||||
}
|
}
|
||||||
|
|
||||||
.skin-blue .main-header .navbar {
|
.skin-blue .main-header .navbar {
|
||||||
background-color:
|
background-color: #2e507d;
|
||||||
#2e507d;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.content-wrapper, .right-side {
|
|
||||||
background-color:
|
|
||||||
#1f2234;
|
|
||||||
}
|
|
||||||
.skin-blue .main-header .logo {
|
|
||||||
background-color:
|
|
||||||
#1f2234;
|
|
||||||
color:
|
|
||||||
#fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.skin-blue .sidebar-menu > li.header {
|
|
||||||
color:
|
|
||||||
#4b646f;
|
|
||||||
background:
|
|
||||||
#1f2234;
|
|
||||||
}
|
|
||||||
.skin-blue .wrapper, .skin-blue .main-sidebar, .skin-blue .left-side {
|
|
||||||
background:
|
|
||||||
#1f2234;
|
|
||||||
}
|
|
||||||
|
|
||||||
.skin-blue .sidebar-menu > li > .treeview-menu {
|
|
||||||
margin: 0 1px;
|
|
||||||
background:
|
|
||||||
#1f2234;
|
|
||||||
}
|
|
||||||
|
|
||||||
.skin-blue .sidebar-menu > li > a {
|
|
||||||
border-left: 3px solid
|
|
||||||
transparent;
|
|
||||||
margin-right: 1px;
|
|
||||||
}
|
|
||||||
.skin-blue .sidebar-menu > li > a:hover, .skin-blue .sidebar-menu > li.active > a {
|
|
||||||
|
|
||||||
|
.content-wrapper,
|
||||||
|
.right-side {
|
||||||
|
background-color: #1f2234;
|
||||||
|
}
|
||||||
|
.skin-blue .main-header .logo {
|
||||||
|
background-color: #1f2234;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background:#3e355a;
|
}
|
||||||
border-left-color:#8964a9;
|
|
||||||
|
|
||||||
}
|
.skin-blue .sidebar-menu > li.header {
|
||||||
|
color: #4b646f;
|
||||||
|
background: #1f2234;
|
||||||
|
}
|
||||||
|
.skin-blue .wrapper,
|
||||||
|
.skin-blue .main-sidebar,
|
||||||
|
.skin-blue .left-side {
|
||||||
|
background: #1f2234;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skin-blue .sidebar-menu > li > .treeview-menu {
|
||||||
|
margin: 0 1px;
|
||||||
|
background: #1f2234;
|
||||||
|
}
|
||||||
|
|
||||||
.skin-blue .main-header .logo:hover {
|
.skin-blue .sidebar-menu > li > a {
|
||||||
background:
|
border-left: 3px solid transparent;
|
||||||
#3e355a;
|
margin-right: 1px;
|
||||||
}
|
}
|
||||||
|
.skin-blue .sidebar-menu > li > a:hover,
|
||||||
|
.skin-blue .sidebar-menu > li.active > a {
|
||||||
|
color: #fff;
|
||||||
|
background: #3e355a;
|
||||||
|
border-left-color: #8964a9;
|
||||||
|
}
|
||||||
|
|
||||||
.skin-blue .main-header .navbar .sidebar-toggle:hover {
|
.skin-blue .main-header .logo:hover {
|
||||||
background-color:
|
background: #3e355a;
|
||||||
#3e355a;
|
}
|
||||||
}
|
|
||||||
.main-footer {
|
.skin-blue .main-header .navbar .sidebar-toggle:hover {
|
||||||
|
background-color: #3e355a;
|
||||||
|
}
|
||||||
|
.main-footer {
|
||||||
background-color: #1f2234;
|
background-color: #1f2234;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
border-top: 0px;
|
border-top: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.skin-blue .main-header .navbar {
|
.skin-blue .main-header .navbar {
|
||||||
background-color: #1f2234;
|
background-color: #1f2234;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-red, .callout.callout-danger, .alert-danger, .alert-error, .label-danger, .modal-danger .modal-body {
|
|
||||||
background-color:
|
|
||||||
#1f2234 !important;
|
|
||||||
}
|
|
||||||
.alert-danger, .alert-error {
|
|
||||||
|
|
||||||
|
.bg-red,
|
||||||
|
.callout.callout-danger,
|
||||||
|
.alert-danger,
|
||||||
|
.alert-error,
|
||||||
|
.label-danger,
|
||||||
|
.modal-danger .modal-body {
|
||||||
|
background-color: #1f2234 !important;
|
||||||
|
}
|
||||||
|
.alert-danger,
|
||||||
|
.alert-error {
|
||||||
border-color: #fff;
|
border-color: #fff;
|
||||||
border: 1px solid
|
border: 1px solid #fff;
|
||||||
|
|
||||||
#fff;
|
|
||||||
border-radius: 7px;
|
border-radius: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
.skin-blue .main-header .navbar .nav > li > a:hover,
|
||||||
|
.skin-blue .main-header .navbar .nav > li > a:active,
|
||||||
.skin-blue .main-header .navbar .nav > li > a:hover, .skin-blue .main-header .navbar .nav > li > a:active, .skin-blue .main-header .navbar .nav > li > a:focus, .skin-blue .main-header .navbar .nav .open > a, .skin-blue .main-header .navbar .nav .open > a:hover, .skin-blue .main-header .navbar .nav .open > a:focus {
|
.skin-blue .main-header .navbar .nav > li > a:focus,
|
||||||
color:
|
.skin-blue .main-header .navbar .nav .open > a,
|
||||||
#f6f6f6;
|
.skin-blue .main-header .navbar .nav .open > a:hover,
|
||||||
|
.skin-blue .main-header .navbar .nav .open > a:focus {
|
||||||
|
color: #f6f6f6;
|
||||||
background-color: #3e355a;
|
background-color: #3e355a;
|
||||||
}
|
}
|
||||||
.bg-aqua, .callout.callout-info, .alert-info, .label-info, .modal-info .modal-body {
|
.bg-aqua,
|
||||||
background-color:
|
.callout.callout-info,
|
||||||
#3e355a !important;
|
.alert-info,
|
||||||
}
|
.label-info,
|
||||||
|
.modal-info .modal-body {
|
||||||
|
background-color: #3e355a !important;
|
||||||
|
}
|
||||||
|
|
||||||
.box {
|
.box {
|
||||||
position: relative;
|
position: relative;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
background-color: #333646;
|
background-color: #333646;
|
||||||
border-top: 3px solid #8964a9;
|
border-top: 3px solid #8964a9;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
}
|
||||||
|
.table-striped > tbody > tr:nth-of-type(2n + 1) {
|
||||||
|
background-color: #333646;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
.box-header {
|
||||||
.table-striped > tbody > tr:nth-of-type(2n+1) {
|
|
||||||
background-color:
|
|
||||||
#333646;
|
|
||||||
}
|
|
||||||
|
|
||||||
.box-header {
|
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
.box.box-danger {
|
||||||
|
|
||||||
|
|
||||||
.box.box-danger {
|
|
||||||
border-top-color: #8964a9;
|
border-top-color: #8964a9;
|
||||||
}
|
}
|
||||||
.box.box-primary {
|
.box.box-primary {
|
||||||
border-top-color: #8964a9;
|
border-top-color: #8964a9;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: #8964a9;
|
color: #8964a9;
|
||||||
}
|
}
|
||||||
.box-header.with-border {
|
.box-header.with-border {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover, a:active, a:focus {
|
a:hover,
|
||||||
|
a:active,
|
||||||
|
a:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
// .modal.in .modal-dialog{
|
// .modal.in .modal-dialog{
|
||||||
// color:#000;
|
// color:#000;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
.form-control {
|
|
||||||
|
|
||||||
background-color:#333646;
|
|
||||||
color: #fff;
|
|
||||||
|
|
||||||
}
|
|
||||||
.box-footer {
|
|
||||||
|
|
||||||
|
.form-control {
|
||||||
|
background-color: #333646;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.box-footer {
|
||||||
border-top: none;
|
border-top: none;
|
||||||
|
|
||||||
background-color:
|
|
||||||
#333646;
|
|
||||||
}
|
|
||||||
.modal-footer {
|
|
||||||
|
|
||||||
border-top: none;
|
|
||||||
|
|
||||||
}
|
|
||||||
.modal-content {
|
|
||||||
|
|
||||||
background-color:
|
|
||||||
#333646;
|
|
||||||
}
|
|
||||||
.modal.in .modal-dialog {
|
|
||||||
|
|
||||||
background-color: #333646;
|
background-color: #333646;
|
||||||
|
}
|
||||||
|
.modal-footer {
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
.modal-content {
|
||||||
|
background-color: #333646;
|
||||||
|
}
|
||||||
|
.modal.in .modal-dialog {
|
||||||
|
background-color: #333646;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
.layout-boxed {
|
||||||
|
|
||||||
.layout-boxed {
|
|
||||||
background: none;
|
background: none;
|
||||||
background-color: rgba(0, 0, 0, 0);
|
background-color: rgba(0, 0, 0, 0);
|
||||||
background-color:
|
background-color: #3e355a;
|
||||||
#3e355a;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.skin-blue .sidebar-menu > li > a:hover, .skin-blue .sidebar-menu > li.active > a {
|
|
||||||
|
|
||||||
|
.skin-blue .sidebar-menu > li > a:hover,
|
||||||
|
.skin-blue .sidebar-menu > li.active > a {
|
||||||
background: none;
|
background: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body class="skin-blue layout-boxed sidebar-collapse sidebar-open">
|
<body class="skin-blue layout-boxed sidebar-collapse sidebar-open">
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
|
|
@ -421,7 +400,6 @@ background-color:
|
||||||
<ul class="nav navbar-nav">
|
<ul class="nav navbar-nav">
|
||||||
<!-- Messages: style can be found in dropdown.less-->
|
<!-- Messages: style can be found in dropdown.less-->
|
||||||
<li class="dropdown messages-menu">
|
<li class="dropdown messages-menu">
|
||||||
|
|
||||||
{% block messages %}{% endblock %}
|
{% block messages %}{% endblock %}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
@ -433,8 +411,6 @@ background-color:
|
||||||
<!-- sidebar: style can be found in sidebar.less -->
|
<!-- sidebar: style can be found in sidebar.less -->
|
||||||
<section class="sidebar" style="height: auto;">
|
<section class="sidebar" style="height: auto;">
|
||||||
<!-- Sidebar user panel -->
|
<!-- Sidebar user panel -->
|
||||||
|
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
<!-- /.sidebar -->
|
<!-- /.sidebar -->
|
||||||
</aside>
|
</aside>
|
||||||
|
|
@ -447,21 +423,26 @@ background-color:
|
||||||
LNBits Events
|
LNBits Events
|
||||||
<small>Lightning powered tickets</small>
|
<small>Lightning powered tickets</small>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Main content -->
|
<!-- Main content -->
|
||||||
<section class="content"><br/><br/>
|
<section class="content">
|
||||||
<center><h1 style="font-size:500%">{{ user_ev[0][6] }}</h1></center>
|
<br /><br />
|
||||||
|
<center><h1 style="font-size: 500%;">{{ user_ev[0][6] }}</h1></center>
|
||||||
|
|
||||||
|
<br /><br /><br />
|
||||||
|
|
||||||
<br/><br/><br/>
|
<div
|
||||||
|
class="modal fade sends"
|
||||||
<div class='modal fade sends' tabindex='-1' role='dialog' aria-labelledby='myLargeModalLabel' aria-hidden='true'>
|
tabindex="-1"
|
||||||
<div class='modal-dialog' >
|
role="dialog"
|
||||||
<div id='scantickets' style='padding: 0 10px 0 10px;'>
|
aria-labelledby="myLargeModalLabel"
|
||||||
</div></div></div>
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div id="scantickets" style="padding: 0 10px 0 10px;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<center>
|
<center>
|
||||||
<button
|
<button
|
||||||
|
|
@ -469,43 +450,44 @@ background-color:
|
||||||
class="btn btn-block btn-primary btn-lg"
|
class="btn btn-block btn-primary btn-lg"
|
||||||
data-toggle="modal"
|
data-toggle="modal"
|
||||||
data-target=".sends"
|
data-target=".sends"
|
||||||
style="width:300px;"
|
style="width: 300px;"
|
||||||
>
|
>
|
||||||
Scan ticket
|
Scan ticket
|
||||||
</button>
|
</button>
|
||||||
</center>
|
</center>
|
||||||
|
|
||||||
|
|
||||||
<div id="scantickets"></div>
|
<div id="scantickets"></div>
|
||||||
<br/><br/><br/>
|
<br /><br /><br />
|
||||||
<div id="qrcodetxt"></div> <br/></center>
|
<div id="qrcodetxt"></div>
|
||||||
<br/><br/><br/>
|
<br />
|
||||||
|
<br /><br /><br />
|
||||||
|
|
||||||
<center>
|
<center>
|
||||||
<div class="row" style="width:80%;margin-top:80px">
|
<div class="row" style="width: 80%; margin-top: 80px;">
|
||||||
|
<style>
|
||||||
|
.ema,
|
||||||
<style>
|
button:focus .txt {
|
||||||
.ema, button:focus .txt {
|
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
button:focus .ema {
|
button:focus .ema {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
</style>
|
||||||
</style>
|
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="box-header">
|
<div class="box-header">
|
||||||
<h3 class="box-title">Attendees<b id="withdraws"></b></h3>
|
<h3 class="box-title">Attendees<b id="withdraws"></b></h3>
|
||||||
</div>
|
</div>
|
||||||
<!-- /.box-header -->
|
<!-- /.box-header -->
|
||||||
<div class="box-body no-padding">
|
<div class="box-body no-padding">
|
||||||
<table id="pagnation" class="table table-bswearing anchorordered table-striped">
|
<table
|
||||||
|
id="pagnation"
|
||||||
|
class="table table-bswearing anchorordered table-striped"
|
||||||
|
>
|
||||||
<tr>
|
<tr>
|
||||||
<th style="width:20%">Name</th>
|
<th style="width: 20%;">Name</th>
|
||||||
<th style="width:20%">Email</th>
|
<th style="width: 20%;">Email</th>
|
||||||
<th style="width:50%">Ticket</th>
|
<th style="width: 50%;">Ticket</th>
|
||||||
<th style="width:10%">Registered</th>
|
<th style="width: 10%;">Registered</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tbody id="ticketwaves"></tbody>
|
<tbody id="ticketwaves"></tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
@ -513,25 +495,25 @@ button:focus .ema {
|
||||||
<!-- /.box-body -->
|
<!-- /.box-body -->
|
||||||
</div>
|
</div>
|
||||||
<!-- /.box -->
|
<!-- /.box -->
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</center>
|
</center>
|
||||||
|
</section>
|
||||||
</section><!-- /.content -->
|
<!-- /.content -->
|
||||||
</div><!-- /.content-wrapper -->
|
</div>
|
||||||
|
<!-- /.content-wrapper -->
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
|
||||||
window.user_ev = {{ user_ev | tojson | safe }}
|
window.user_ev = {{ user_ev | tojson | safe }}
|
||||||
window.user_ev_sold = {{ user_ev_sold | tojson | safe }}
|
window.user_ev_sold = {{ user_ev_sold | tojson | safe }}
|
||||||
console.log(user_ev)
|
console.log(user_ev)
|
||||||
console.log(user_ev_sold)
|
console.log(user_ev_sold)
|
||||||
|
|
||||||
|
|
||||||
function drawChart(user_ev_sold) {
|
function drawChart(user_ev_sold) {
|
||||||
var transactionsHTML = ''
|
var transactionsHTML = ''
|
||||||
|
|
||||||
for (var i = 0; i < user_ev_sold.length; i++) {
|
for (var i = 0; i < user_ev_sold.length; i++) {
|
||||||
|
|
@ -554,13 +536,13 @@ function drawChart(user_ev_sold) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user_ev_sold.length) {
|
if (user_ev_sold.length) {
|
||||||
drawChart(user_ev_sold)
|
drawChart(user_ev_sold)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function postAjax(url, data, thekey, success) {
|
function postAjax(url, data, thekey, success) {
|
||||||
var params =
|
var params =
|
||||||
typeof data == 'string'
|
typeof data == 'string'
|
||||||
? data
|
? data
|
||||||
|
|
@ -582,7 +564,7 @@ function postAjax(url, data, thekey, success) {
|
||||||
xhr.setRequestHeader('Content-Type', 'application/json')
|
xhr.setRequestHeader('Content-Type', 'application/json')
|
||||||
xhr.send(params)
|
xhr.send(params)
|
||||||
return xhr
|
return xhr
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAjax(url, thekey, success) {
|
function getAjax(url, thekey, success) {
|
||||||
var xhr = window.XMLHttpRequest
|
var xhr = window.XMLHttpRequest
|
||||||
|
|
@ -599,9 +581,9 @@ function postAjax(url, data, thekey, success) {
|
||||||
|
|
||||||
xhr.send()
|
xhr.send()
|
||||||
return xhr
|
return xhr
|
||||||
}
|
}
|
||||||
|
|
||||||
function scanQRsend() {
|
function scanQRsend() {
|
||||||
document.getElementById('scantickets').innerHTML =
|
document.getElementById('scantickets').innerHTML =
|
||||||
"<div class='modal-content'>"+
|
"<div class='modal-content'>"+
|
||||||
"<br/><div id='registered'><div id='loadingMessage'>🎥 Unable to access video stream (please make sure you have a webcam enabled)</div>" +
|
"<br/><div id='registered'><div id='loadingMessage'>🎥 Unable to access video stream (please make sure you have a webcam enabled)</div>" +
|
||||||
|
|
@ -663,28 +645,26 @@ function scanQRsend() {
|
||||||
}
|
}
|
||||||
requestAnimationFrame(tick)
|
requestAnimationFrame(tick)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function cancelsend() {
|
function cancelsend() {
|
||||||
location.reload();
|
location.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function getUrlVars() {
|
function getUrlVars() {
|
||||||
var vars = {};
|
var vars = {};
|
||||||
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
|
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
|
||||||
vars[key] = value;
|
vars[key] = value;
|
||||||
});
|
});
|
||||||
return vars;
|
return vars;
|
||||||
}
|
}
|
||||||
var name = getUrlVars()["name"];
|
var name = getUrlVars()["name"];
|
||||||
var thehash = getUrlVars()["thehash"];
|
var thehash = getUrlVars()["thehash"];
|
||||||
console.log(thehash)
|
console.log(thehash)
|
||||||
if(thehash != null){
|
if(thehash != null){
|
||||||
document.getElementById('qrcodetxt').innerHTML = "<center><h1>" + name + " is registered!</h1></center>"
|
document.getElementById('qrcodetxt').innerHTML = "<center><h1>" + name + " is registered!</h1></center>"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<!-- @format -->
|
<!-- @format -->
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
|
@ -202,204 +202,183 @@
|
||||||
type="text/javascript"
|
type="text/javascript"
|
||||||
></script>
|
></script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
||||||
//GOOFY CSS HACK TO GO DARK
|
//GOOFY CSS HACK TO GO DARK
|
||||||
|
|
||||||
.skin-blue .wrapper {
|
.skin-blue .wrapper {
|
||||||
background:
|
background: #1f2234;
|
||||||
#1f2234;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.skin-blue .sidebar-menu > li.active > a {
|
.skin-blue .sidebar-menu > li.active > a {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background:#1f2234;
|
background: #1f2234;
|
||||||
border-left-color:#8964a9;
|
border-left-color: #8964a9;
|
||||||
}
|
}
|
||||||
|
|
||||||
.skin-blue .main-header .navbar {
|
.skin-blue .main-header .navbar {
|
||||||
background-color:
|
background-color: #2e507d;
|
||||||
#2e507d;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.content-wrapper, .right-side {
|
|
||||||
background-color:
|
|
||||||
#1f2234;
|
|
||||||
}
|
|
||||||
.skin-blue .main-header .logo {
|
|
||||||
background-color:
|
|
||||||
#1f2234;
|
|
||||||
color:
|
|
||||||
#fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.skin-blue .sidebar-menu > li.header {
|
|
||||||
color:
|
|
||||||
#4b646f;
|
|
||||||
background:
|
|
||||||
#1f2234;
|
|
||||||
}
|
|
||||||
.skin-blue .wrapper, .skin-blue .main-sidebar, .skin-blue .left-side {
|
|
||||||
background:
|
|
||||||
#1f2234;
|
|
||||||
}
|
|
||||||
|
|
||||||
.skin-blue .sidebar-menu > li > .treeview-menu {
|
|
||||||
margin: 0 1px;
|
|
||||||
background:
|
|
||||||
#1f2234;
|
|
||||||
}
|
|
||||||
|
|
||||||
.skin-blue .sidebar-menu > li > a {
|
|
||||||
border-left: 3px solid
|
|
||||||
transparent;
|
|
||||||
margin-right: 1px;
|
|
||||||
}
|
|
||||||
.skin-blue .sidebar-menu > li > a:hover, .skin-blue .sidebar-menu > li.active > a {
|
|
||||||
|
|
||||||
|
.content-wrapper,
|
||||||
|
.right-side {
|
||||||
|
background-color: #1f2234;
|
||||||
|
}
|
||||||
|
.skin-blue .main-header .logo {
|
||||||
|
background-color: #1f2234;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background:#3e355a;
|
}
|
||||||
border-left-color:#8964a9;
|
|
||||||
|
|
||||||
}
|
.skin-blue .sidebar-menu > li.header {
|
||||||
|
color: #4b646f;
|
||||||
|
background: #1f2234;
|
||||||
|
}
|
||||||
|
.skin-blue .wrapper,
|
||||||
|
.skin-blue .main-sidebar,
|
||||||
|
.skin-blue .left-side {
|
||||||
|
background: #1f2234;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skin-blue .sidebar-menu > li > .treeview-menu {
|
||||||
|
margin: 0 1px;
|
||||||
|
background: #1f2234;
|
||||||
|
}
|
||||||
|
|
||||||
.skin-blue .main-header .logo:hover {
|
.skin-blue .sidebar-menu > li > a {
|
||||||
background:
|
border-left: 3px solid transparent;
|
||||||
#3e355a;
|
margin-right: 1px;
|
||||||
}
|
}
|
||||||
|
.skin-blue .sidebar-menu > li > a:hover,
|
||||||
|
.skin-blue .sidebar-menu > li.active > a {
|
||||||
|
color: #fff;
|
||||||
|
background: #3e355a;
|
||||||
|
border-left-color: #8964a9;
|
||||||
|
}
|
||||||
|
|
||||||
.skin-blue .main-header .navbar .sidebar-toggle:hover {
|
.skin-blue .main-header .logo:hover {
|
||||||
background-color:
|
background: #3e355a;
|
||||||
#3e355a;
|
}
|
||||||
}
|
|
||||||
.main-footer {
|
.skin-blue .main-header .navbar .sidebar-toggle:hover {
|
||||||
|
background-color: #3e355a;
|
||||||
|
}
|
||||||
|
.main-footer {
|
||||||
background-color: #1f2234;
|
background-color: #1f2234;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
border-top: 0px;
|
border-top: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.skin-blue .main-header .navbar {
|
.skin-blue .main-header .navbar {
|
||||||
background-color: #1f2234;
|
background-color: #1f2234;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-red, .callout.callout-danger, .alert-danger, .alert-error, .label-danger, .modal-danger .modal-body {
|
|
||||||
background-color:
|
|
||||||
#1f2234 !important;
|
|
||||||
}
|
|
||||||
.alert-danger, .alert-error {
|
|
||||||
|
|
||||||
|
.bg-red,
|
||||||
|
.callout.callout-danger,
|
||||||
|
.alert-danger,
|
||||||
|
.alert-error,
|
||||||
|
.label-danger,
|
||||||
|
.modal-danger .modal-body {
|
||||||
|
background-color: #1f2234 !important;
|
||||||
|
}
|
||||||
|
.alert-danger,
|
||||||
|
.alert-error {
|
||||||
border-color: #fff;
|
border-color: #fff;
|
||||||
border: 1px solid
|
border: 1px solid #fff;
|
||||||
|
|
||||||
#fff;
|
|
||||||
border-radius: 7px;
|
border-radius: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
.skin-blue .main-header .navbar .nav > li > a:hover,
|
||||||
|
.skin-blue .main-header .navbar .nav > li > a:active,
|
||||||
.skin-blue .main-header .navbar .nav > li > a:hover, .skin-blue .main-header .navbar .nav > li > a:active, .skin-blue .main-header .navbar .nav > li > a:focus, .skin-blue .main-header .navbar .nav .open > a, .skin-blue .main-header .navbar .nav .open > a:hover, .skin-blue .main-header .navbar .nav .open > a:focus {
|
.skin-blue .main-header .navbar .nav > li > a:focus,
|
||||||
color:
|
.skin-blue .main-header .navbar .nav .open > a,
|
||||||
#f6f6f6;
|
.skin-blue .main-header .navbar .nav .open > a:hover,
|
||||||
|
.skin-blue .main-header .navbar .nav .open > a:focus {
|
||||||
|
color: #f6f6f6;
|
||||||
background-color: #3e355a;
|
background-color: #3e355a;
|
||||||
}
|
}
|
||||||
.bg-aqua, .callout.callout-info, .alert-info, .label-info, .modal-info .modal-body {
|
.bg-aqua,
|
||||||
background-color:
|
.callout.callout-info,
|
||||||
#3e355a !important;
|
.alert-info,
|
||||||
}
|
.label-info,
|
||||||
|
.modal-info .modal-body {
|
||||||
|
background-color: #3e355a !important;
|
||||||
|
}
|
||||||
|
|
||||||
.box {
|
.box {
|
||||||
position: relative;
|
position: relative;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
background-color: #333646;
|
background-color: #333646;
|
||||||
border-top: 3px solid #8964a9;
|
border-top: 3px solid #8964a9;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
}
|
||||||
|
.table-striped > tbody > tr:nth-of-type(2n + 1) {
|
||||||
|
background-color: #333646;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
.box-header {
|
||||||
.table-striped > tbody > tr:nth-of-type(2n+1) {
|
|
||||||
background-color:
|
|
||||||
#333646;
|
|
||||||
}
|
|
||||||
|
|
||||||
.box-header {
|
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
.box.box-danger {
|
||||||
|
|
||||||
|
|
||||||
.box.box-danger {
|
|
||||||
border-top-color: #8964a9;
|
border-top-color: #8964a9;
|
||||||
}
|
}
|
||||||
.box.box-primary {
|
.box.box-primary {
|
||||||
border-top-color: #8964a9;
|
border-top-color: #8964a9;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: #8964a9;
|
color: #8964a9;
|
||||||
}
|
}
|
||||||
.box-header.with-border {
|
.box-header.with-border {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover, a:active, a:focus {
|
a:hover,
|
||||||
|
a:active,
|
||||||
|
a:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
// .modal.in .modal-dialog{
|
// .modal.in .modal-dialog{
|
||||||
// color:#000;
|
// color:#000;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
.form-control {
|
|
||||||
|
|
||||||
background-color:#333646;
|
|
||||||
color: #fff;
|
|
||||||
|
|
||||||
}
|
|
||||||
.box-footer {
|
|
||||||
|
|
||||||
|
.form-control {
|
||||||
|
background-color: #333646;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.box-footer {
|
||||||
border-top: none;
|
border-top: none;
|
||||||
|
|
||||||
background-color:
|
|
||||||
#333646;
|
|
||||||
}
|
|
||||||
.modal-footer {
|
|
||||||
|
|
||||||
border-top: none;
|
|
||||||
|
|
||||||
}
|
|
||||||
.modal-content {
|
|
||||||
|
|
||||||
background-color:
|
|
||||||
#333646;
|
|
||||||
}
|
|
||||||
.modal.in .modal-dialog {
|
|
||||||
|
|
||||||
background-color: #333646;
|
background-color: #333646;
|
||||||
|
}
|
||||||
|
.modal-footer {
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
.modal-content {
|
||||||
|
background-color: #333646;
|
||||||
|
}
|
||||||
|
.modal.in .modal-dialog {
|
||||||
|
background-color: #333646;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
.layout-boxed {
|
||||||
|
|
||||||
.layout-boxed {
|
|
||||||
background: none;
|
background: none;
|
||||||
background-color: rgba(0, 0, 0, 0);
|
background-color: rgba(0, 0, 0, 0);
|
||||||
background-color:
|
background-color: #3e355a;
|
||||||
#3e355a;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.skin-blue .sidebar-menu > li > a:hover, .skin-blue .sidebar-menu > li.active > a {
|
|
||||||
|
|
||||||
|
.skin-blue .sidebar-menu > li > a:hover,
|
||||||
|
.skin-blue .sidebar-menu > li.active > a {
|
||||||
background: none;
|
background: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body class="skin-blue layout-boxed sidebar-collapse sidebar-open">
|
<body class="skin-blue layout-boxed sidebar-collapse sidebar-open">
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
|
|
@ -421,7 +400,6 @@ background-color:
|
||||||
<ul class="nav navbar-nav">
|
<ul class="nav navbar-nav">
|
||||||
<!-- Messages: style can be found in dropdown.less-->
|
<!-- Messages: style can be found in dropdown.less-->
|
||||||
<li class="dropdown messages-menu">
|
<li class="dropdown messages-menu">
|
||||||
|
|
||||||
{% block messages %}{% endblock %}
|
{% block messages %}{% endblock %}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
@ -431,9 +409,7 @@ background-color:
|
||||||
|
|
||||||
<aside class="main-sidebar">
|
<aside class="main-sidebar">
|
||||||
<!-- sidebar: style can be found in sidebar.less -->
|
<!-- sidebar: style can be found in sidebar.less -->
|
||||||
<section class="sidebar" style="height: auto;">
|
<section class="sidebar" style="height: auto;"></section>
|
||||||
|
|
||||||
</section>
|
|
||||||
<!-- /.sidebar -->
|
<!-- /.sidebar -->
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
|
|
@ -445,30 +421,37 @@ background-color:
|
||||||
LNBits Events
|
LNBits Events
|
||||||
<small>Lightning powered tickets</small>
|
<small>Lightning powered tickets</small>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Main content -->
|
<!-- Main content -->
|
||||||
<section class="content"><br/><br/>
|
<section class="content">
|
||||||
|
<br /><br />
|
||||||
|
|
||||||
<center><h2 style="width:70%;font-size:400%" >Bookmark/Screenshot this page. <br/>It is your ticket!</h2></center>
|
<center>
|
||||||
<center> <div style="width:340px;background-color:white;padding:20px"id="qrcode"></div></center>
|
<h2 style="width: 70%; font-size: 400%;">
|
||||||
|
Bookmark/Screenshot this page. <br />It is your ticket!
|
||||||
|
</h2>
|
||||||
</section><!-- /.content -->
|
</center>
|
||||||
</div><!-- /.content-wrapper -->
|
<center>
|
||||||
|
<div
|
||||||
|
style="width: 340px; background-color: white; padding: 20px;"
|
||||||
|
id="qrcode"
|
||||||
|
></div>
|
||||||
|
</center>
|
||||||
|
</section>
|
||||||
|
<!-- /.content -->
|
||||||
|
</div>
|
||||||
|
<!-- /.content-wrapper -->
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
<script>
|
<script>
|
||||||
new QRCode(document.getElementById('qrcode'), {
|
new QRCode(document.getElementById('qrcode'), {
|
||||||
text: "{{ticket}}",
|
text: '{{ticket}}',
|
||||||
width: 300,
|
width: 300,
|
||||||
height: 300,
|
height: 300,
|
||||||
colorDark: '#000000',
|
colorDark: '#000000',
|
||||||
colorLight: '#ffffff',
|
colorLight: '#ffffff',
|
||||||
correctLevel: QRCode.CorrectLevel.M
|
correctLevel: QRCode.CorrectLevel.M
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,18 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %} {% from "macros.jinja" import window_vars with context
|
||||||
|
%} {% block page %}
|
||||||
{% from "macros.jinja" import window_vars with context %}
|
<q-card>
|
||||||
|
|
||||||
|
|
||||||
{% block page %}
|
|
||||||
<q-card>
|
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<h5 class="text-subtitle1 q-mt-none q-mb-md">Frameworks used by LNbits</h5>
|
<h5 class="text-subtitle1 q-mt-none q-mb-md">Frameworks used by LNbits</h5>
|
||||||
<q-list>
|
<q-list>
|
||||||
<q-item v-for="tool in tools" :key="tool.name" tag="a" :href="tool.url" target="_blank">
|
<q-item
|
||||||
{% raw %} <!-- with raw Flask won't try to interpret the Vue moustaches -->
|
v-for="tool in tools"
|
||||||
|
:key="tool.name"
|
||||||
|
tag="a"
|
||||||
|
:href="tool.url"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
{% raw %}
|
||||||
|
<!-- with raw Flask won't try to interpret the Vue moustaches -->
|
||||||
<q-item-section>
|
<q-item-section>
|
||||||
<q-item-label>{{ tool.name }}</q-item-label>
|
<q-item-label>{{ tool.name }}</q-item-label>
|
||||||
<q-item-label caption>{{ tool.language }}</q-item-label>
|
<q-item-label caption>{{ tool.language }}</q-item-label>
|
||||||
|
|
@ -18,25 +21,25 @@
|
||||||
</q-item>
|
</q-item>
|
||||||
</q-list>
|
</q-list>
|
||||||
<q-separator class="q-my-lg"></q-separator>
|
<q-separator class="q-my-lg"></q-separator>
|
||||||
<p>A magical "g" is always available, with info about the user, wallets and extensions:</p>
|
<p>
|
||||||
|
A magical "g" is always available, with info about the user, wallets and
|
||||||
|
extensions:
|
||||||
|
</p>
|
||||||
<code class="text-caption">{% raw %}{{ g }}{% endraw %}</code>
|
<code class="text-caption">{% raw %}{{ g }}{% endraw %}</code>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
{% endblock %}
|
{% endblock %} {% block scripts %} {{ window_vars(user) }}
|
||||||
|
<script>
|
||||||
{% block scripts %}
|
|
||||||
{{ window_vars(user) }}
|
|
||||||
<script>
|
|
||||||
new Vue({
|
new Vue({
|
||||||
el: '#vue',
|
el: '#vue',
|
||||||
mixins: [windowMixin],
|
mixins: [windowMixin],
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
tools: []
|
tools: []
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
var self = this;
|
var self = this
|
||||||
|
|
||||||
// axios is available for making requests
|
// axios is available for making requests
|
||||||
axios({
|
axios({
|
||||||
|
|
@ -46,9 +49,9 @@
|
||||||
'X-example-header': 'not-used'
|
'X-example-header': 'not-used'
|
||||||
}
|
}
|
||||||
}).then(function (response) {
|
}).then(function (response) {
|
||||||
self.tools = response.data;
|
self.tools = response.data
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -6,23 +6,23 @@
|
||||||
>
|
>
|
||||||
<q-expansion-item group="api" dense expand-separator label="List paywalls">
|
<q-expansion-item group="api" dense expand-separator label="List paywalls">
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section> </q-card-section>
|
||||||
|
|
||||||
</q-card-section>
|
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
<q-expansion-item group="api" dense expand-separator label="Create a paywall">
|
<q-expansion-item group="api" dense expand-separator label="Create a paywall">
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section> </q-card-section>
|
||||||
|
|
||||||
</q-card-section>
|
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
<q-expansion-item group="api" dense expand-separator label="Delete a paywall" class="q-pb-md">
|
<q-expansion-item
|
||||||
|
group="api"
|
||||||
|
dense
|
||||||
|
expand-separator
|
||||||
|
label="Delete a paywall"
|
||||||
|
class="q-pb-md"
|
||||||
|
>
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section> </q-card-section>
|
||||||
|
|
||||||
</q-card-section>
|
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,39 @@
|
||||||
{% extends "public.html" %}
|
{% extends "public.html" %} {% block page %}
|
||||||
|
<div class="row q-col-gutter-md justify-center">
|
||||||
|
|
||||||
{% block page %}
|
|
||||||
<div class="row q-col-gutter-md justify-center">
|
|
||||||
<div class="col-12 col-sm-6 col-md-5 col-lg-4">
|
<div class="col-12 col-sm-6 col-md-5 col-lg-4">
|
||||||
<q-card class="q-pa-lg">
|
<q-card class="q-pa-lg">
|
||||||
<q-card-section class="q-pa-none">
|
<q-card-section class="q-pa-none">
|
||||||
<h5 class="text-subtitle1 q-my-none">{{ paywall.memo }}</h5>
|
<h5 class="text-subtitle1 q-my-none">{{ paywall.memo }}</h5>
|
||||||
<strong class="text-purple">Price: <lnbits-fsat :amount="{{ paywall.amount }}"></lnbits-fsat> sat</strong>
|
<strong class="text-purple"
|
||||||
|
>Price:
|
||||||
|
<lnbits-fsat :amount="{{ paywall.amount }}"></lnbits-fsat> sat</strong
|
||||||
|
>
|
||||||
<q-separator class="q-my-lg"></q-separator>
|
<q-separator class="q-my-lg"></q-separator>
|
||||||
<div v-if="paymentReq">
|
<div v-if="paymentReq">
|
||||||
<a :href="'lightning:' + paymentReq">
|
<a :href="'lightning:' + paymentReq">
|
||||||
<q-responsive :ratio="1" class="q-mx-xl q-mb-md">
|
<q-responsive :ratio="1" class="q-mx-xl q-mb-md">
|
||||||
<qrcode :value="paymentReq" :options="{width: 800}" class="rounded-borders"></qrcode>
|
<qrcode
|
||||||
|
:value="paymentReq"
|
||||||
|
:options="{width: 800}"
|
||||||
|
class="rounded-borders"
|
||||||
|
></qrcode>
|
||||||
</q-responsive>
|
</q-responsive>
|
||||||
</a>
|
</a>
|
||||||
<div class="row q-mt-lg">
|
<div class="row q-mt-lg">
|
||||||
<q-btn outline color="grey" @click="copyText(paymentReq)">Copy invoice</q-btn>
|
<q-btn outline color="grey" @click="copyText(paymentReq)"
|
||||||
|
>Copy invoice</q-btn
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="redirectUrl">
|
<div v-if="redirectUrl">
|
||||||
<p>You can access the URL behind this paywall:<br>
|
<p>
|
||||||
<strong>{% raw %}{{ redirectUrl }}{% endraw %}</strong></p>
|
You can access the URL behind this paywall:<br />
|
||||||
|
<strong>{% raw %}{{ redirectUrl }}{% endraw %}</strong>
|
||||||
|
</p>
|
||||||
<div class="row q-mt-lg">
|
<div class="row q-mt-lg">
|
||||||
<q-btn outline color="grey" type="a" :href="redirectUrl">Open URL</q-btn>
|
<q-btn outline color="grey" type="a" :href="redirectUrl"
|
||||||
|
>Open URL</q-btn
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
|
|
@ -36,13 +46,11 @@
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %} {% block scripts %}
|
||||||
|
<script src="{{ url_for('static', filename='vendor/vue-qrcode@1.0.2/vue-qrcode.min.js') }}"></script>
|
||||||
{% block scripts %}
|
<script>
|
||||||
<script src="{{ url_for('static', filename='vendor/vue-qrcode@1.0.2/vue-qrcode.min.js') }}"></script>
|
Vue.component(VueQrcode.name, VueQrcode)
|
||||||
<script>
|
|
||||||
Vue.component(VueQrcode.name, VueQrcode);
|
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
el: '#vue',
|
el: '#vue',
|
||||||
|
|
@ -51,57 +59,64 @@
|
||||||
return {
|
return {
|
||||||
paymentReq: null,
|
paymentReq: null,
|
||||||
redirectUrl: null
|
redirectUrl: null
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getInvoice: function () {
|
getInvoice: function () {
|
||||||
var self = this;
|
var self = this
|
||||||
|
|
||||||
axios.get(
|
axios
|
||||||
'/paywall/api/v1/paywalls/{{ paywall.id }}/invoice'
|
.get('/paywall/api/v1/paywalls/{{ paywall.id }}/invoice')
|
||||||
).then(function (response) {
|
.then(function (response) {
|
||||||
self.paymentReq = response.data.payment_request;
|
self.paymentReq = response.data.payment_request
|
||||||
|
|
||||||
dismissMsg = self.$q.notify({
|
dismissMsg = self.$q.notify({
|
||||||
timeout: 0,
|
timeout: 0,
|
||||||
message: 'Waiting for payment...'
|
message: 'Waiting for payment...'
|
||||||
});
|
})
|
||||||
|
|
||||||
paymentChecker = setInterval(function () {
|
paymentChecker = setInterval(function () {
|
||||||
axios.post(
|
axios
|
||||||
|
.post(
|
||||||
'/paywall/api/v1/paywalls/{{ paywall.id }}/check_invoice',
|
'/paywall/api/v1/paywalls/{{ paywall.id }}/check_invoice',
|
||||||
{checking_id: response.data.checking_id}
|
{checking_id: response.data.checking_id}
|
||||||
).then(function (res) {
|
)
|
||||||
|
.then(function (res) {
|
||||||
if (res.data.paid) {
|
if (res.data.paid) {
|
||||||
clearInterval(paymentChecker);
|
clearInterval(paymentChecker)
|
||||||
dismissMsg();
|
dismissMsg()
|
||||||
self.redirectUrl = res.data.url;
|
self.redirectUrl = res.data.url
|
||||||
self.$q.localStorage.set('lnbits.paywall.{{ paywall.id }}', res.data.url);
|
self.$q.localStorage.set(
|
||||||
|
'lnbits.paywall.{{ paywall.id }}',
|
||||||
|
res.data.url
|
||||||
|
)
|
||||||
|
|
||||||
self.$q.notify({
|
self.$q.notify({
|
||||||
type: 'positive',
|
type: 'positive',
|
||||||
message: 'Payment received!',
|
message: 'Payment received!',
|
||||||
icon: null
|
icon: null
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}).catch(function (error) {
|
})
|
||||||
LNbits.utils.notifyApiError(error);
|
.catch(function (error) {
|
||||||
});
|
LNbits.utils.notifyApiError(error)
|
||||||
}, 2000);
|
})
|
||||||
}).catch(function (error) {
|
}, 2000)
|
||||||
LNbits.utils.notifyApiError(error);
|
})
|
||||||
});
|
.catch(function (error) {
|
||||||
|
LNbits.utils.notifyApiError(error)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
var url = this.$q.localStorage.getItem('lnbits.paywall.{{ paywall.id }}');
|
var url = this.$q.localStorage.getItem('lnbits.paywall.{{ paywall.id }}')
|
||||||
|
|
||||||
if (url) {
|
if (url) {
|
||||||
this.redirectUrl = url;
|
this.redirectUrl = url
|
||||||
} else {
|
} else {
|
||||||
this.getInvoice();
|
this.getInvoice()
|
||||||
};
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
</script>
|
})
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,12 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %} {% from "macros.jinja" import window_vars with context
|
||||||
|
%} {% block page %}
|
||||||
{% from "macros.jinja" import window_vars with context %}
|
<div class="row q-col-gutter-md">
|
||||||
|
|
||||||
|
|
||||||
{% block page %}
|
|
||||||
<div class="row q-col-gutter-md">
|
|
||||||
<div class="col-12 col-md-8 col-lg-7 q-gutter-y-md">
|
<div class="col-12 col-md-8 col-lg-7 q-gutter-y-md">
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<q-btn unelevated color="deep-purple" @click="formDialog.show = true">New paywall</q-btn>
|
<q-btn unelevated color="deep-purple" @click="formDialog.show = true"
|
||||||
|
>New paywall</q-btn
|
||||||
|
>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|
||||||
|
|
@ -22,20 +20,19 @@
|
||||||
<q-btn flat color="grey" @click="exportCSV">Export to CSV</q-btn>
|
<q-btn flat color="grey" @click="exportCSV">Export to CSV</q-btn>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<q-table dense flat
|
<q-table
|
||||||
|
dense
|
||||||
|
flat
|
||||||
:data="paywalls"
|
:data="paywalls"
|
||||||
row-key="id"
|
row-key="id"
|
||||||
:columns="paywallsTable.columns"
|
:columns="paywallsTable.columns"
|
||||||
:pagination.sync="paywallsTable.pagination">
|
:pagination.sync="paywallsTable.pagination"
|
||||||
|
>
|
||||||
{% raw %}
|
{% raw %}
|
||||||
<template v-slot:header="props">
|
<template v-slot:header="props">
|
||||||
<q-tr :props="props">
|
<q-tr :props="props">
|
||||||
<q-th auto-width></q-th>
|
<q-th auto-width></q-th>
|
||||||
<q-th
|
<q-th v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
v-for="col in props.cols"
|
|
||||||
:key="col.name"
|
|
||||||
:props="props"
|
|
||||||
>
|
|
||||||
{{ col.label }}
|
{{ col.label }}
|
||||||
</q-th>
|
</q-th>
|
||||||
<q-th auto-width></q-th>
|
<q-th auto-width></q-th>
|
||||||
|
|
@ -44,18 +41,39 @@
|
||||||
<template v-slot:body="props">
|
<template v-slot:body="props">
|
||||||
<q-tr :props="props">
|
<q-tr :props="props">
|
||||||
<q-td auto-width>
|
<q-td auto-width>
|
||||||
<q-btn unelevated dense size="xs" icon="launch" :color="($q.dark.isActive) ? 'grey-7' : 'grey-5'" type="a" :href="props.row.displayUrl" target="_blank"></q-btn>
|
<q-btn
|
||||||
<q-btn unelevated dense size="xs" icon="link" :color="($q.dark.isActive) ? 'grey-7' : 'grey-5'" type="a" :href="props.row.url" target="_blank"></q-btn>
|
unelevated
|
||||||
|
dense
|
||||||
|
size="xs"
|
||||||
|
icon="launch"
|
||||||
|
:color="($q.dark.isActive) ? 'grey-7' : 'grey-5'"
|
||||||
|
type="a"
|
||||||
|
:href="props.row.displayUrl"
|
||||||
|
target="_blank"
|
||||||
|
></q-btn>
|
||||||
|
<q-btn
|
||||||
|
unelevated
|
||||||
|
dense
|
||||||
|
size="xs"
|
||||||
|
icon="link"
|
||||||
|
:color="($q.dark.isActive) ? 'grey-7' : 'grey-5'"
|
||||||
|
type="a"
|
||||||
|
:href="props.row.url"
|
||||||
|
target="_blank"
|
||||||
|
></q-btn>
|
||||||
</q-td>
|
</q-td>
|
||||||
<q-td
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
v-for="col in props.cols"
|
|
||||||
:key="col.name"
|
|
||||||
:props="props"
|
|
||||||
>
|
|
||||||
{{ col.value }}
|
{{ col.value }}
|
||||||
</q-td>
|
</q-td>
|
||||||
<q-td auto-width>
|
<q-td auto-width>
|
||||||
<q-btn flat dense size="xs" @click="deletePaywall(props.row.id)" icon="cancel" color="pink"></q-btn>
|
<q-btn
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
size="xs"
|
||||||
|
@click="deletePaywall(props.row.id)"
|
||||||
|
icon="cancel"
|
||||||
|
color="pink"
|
||||||
|
></q-btn>
|
||||||
</q-td>
|
</q-td>
|
||||||
</q-tr>
|
</q-tr>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -82,41 +100,62 @@
|
||||||
<q-dialog v-model="formDialog.show" position="top">
|
<q-dialog v-model="formDialog.show" position="top">
|
||||||
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
|
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
|
||||||
<q-form @submit="createPaywall" class="q-gutter-md">
|
<q-form @submit="createPaywall" class="q-gutter-md">
|
||||||
<q-select filled dense emit-value v-model="formDialog.data.wallet" :options="g.user.walletOptions" label="Wallet *">
|
<q-select
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
emit-value
|
||||||
|
v-model="formDialog.data.wallet"
|
||||||
|
:options="g.user.walletOptions"
|
||||||
|
label="Wallet *"
|
||||||
|
>
|
||||||
</q-select>
|
</q-select>
|
||||||
<q-input filled dense
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
v-model.trim="formDialog.data.url"
|
v-model.trim="formDialog.data.url"
|
||||||
type="url"
|
type="url"
|
||||||
label="Target URL *"></q-input>
|
label="Target URL *"
|
||||||
<q-input filled dense
|
></q-input>
|
||||||
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
v-model.number="formDialog.data.amount"
|
v-model.number="formDialog.data.amount"
|
||||||
type="number"
|
type="number"
|
||||||
label="Amount (sat) *"></q-input>
|
label="Amount (sat) *"
|
||||||
<q-input filled dense
|
></q-input>
|
||||||
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
v-model.trim="formDialog.data.memo"
|
v-model.trim="formDialog.data.memo"
|
||||||
label="Memo"
|
label="Memo"
|
||||||
placeholder="LNbits invoice"></q-input>
|
placeholder="LNbits invoice"
|
||||||
|
></q-input>
|
||||||
<div class="row q-mt-lg">
|
<div class="row q-mt-lg">
|
||||||
<q-btn unelevated
|
<q-btn
|
||||||
|
unelevated
|
||||||
color="deep-purple"
|
color="deep-purple"
|
||||||
:disable="formDialog.data.amount == null || formDialog.data.amount < 0 || formDialog.data.url == null"
|
:disable="formDialog.data.amount == null || formDialog.data.amount < 0 || formDialog.data.url == null"
|
||||||
type="submit">Create paywall</q-btn>
|
type="submit"
|
||||||
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Cancel</q-btn>
|
>Create paywall</q-btn
|
||||||
|
>
|
||||||
|
<q-btn v-close-popup flat color="grey" class="q-ml-auto"
|
||||||
|
>Cancel</q-btn
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</q-form>
|
</q-form>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %} {% block scripts %} {{ window_vars(user) }}
|
||||||
|
<script>
|
||||||
{% block scripts %}
|
|
||||||
{{ window_vars(user) }}
|
|
||||||
<script>
|
|
||||||
var mapPaywall = function (obj) {
|
var mapPaywall = function (obj) {
|
||||||
obj.date = Quasar.utils.date.formatDate(new Date(obj.time * 1000), 'YYYY-MM-DD HH:mm');
|
obj.date = Quasar.utils.date.formatDate(
|
||||||
obj.fsat = new Intl.NumberFormat(LOCALE).format(obj.amount);
|
new Date(obj.time * 1000),
|
||||||
obj.displayUrl = ['/paywall/', obj.id].join('');
|
'YYYY-MM-DD HH:mm'
|
||||||
return obj;
|
)
|
||||||
|
obj.fsat = new Intl.NumberFormat(LOCALE).format(obj.amount)
|
||||||
|
obj.displayUrl = ['/paywall/', obj.id].join('')
|
||||||
|
return obj
|
||||||
}
|
}
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
|
|
@ -129,11 +168,21 @@
|
||||||
columns: [
|
columns: [
|
||||||
{name: 'id', align: 'left', label: 'ID', field: 'id'},
|
{name: 'id', align: 'left', label: 'ID', field: 'id'},
|
||||||
{name: 'memo', align: 'left', label: 'Memo', field: 'memo'},
|
{name: 'memo', align: 'left', label: 'Memo', field: 'memo'},
|
||||||
{name: 'date', align: 'left', label: 'Date', field: 'date', sortable: true},
|
|
||||||
{
|
{
|
||||||
name: 'amount', align: 'right', label: 'Amount (sat)', field: 'fsat', sortable: true,
|
name: 'date',
|
||||||
|
align: 'left',
|
||||||
|
label: 'Date',
|
||||||
|
field: 'date',
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'amount',
|
||||||
|
align: 'right',
|
||||||
|
label: 'Amount (sat)',
|
||||||
|
field: 'fsat',
|
||||||
|
sortable: true,
|
||||||
sort: function (a, b, rowA, rowB) {
|
sort: function (a, b, rowA, rowB) {
|
||||||
return rowA.amount - rowB.amount;
|
return rowA.amount - rowB.amount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
@ -145,70 +194,81 @@
|
||||||
show: false,
|
show: false,
|
||||||
data: {}
|
data: {}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getPaywalls: function () {
|
getPaywalls: function () {
|
||||||
var self = this;
|
var self = this
|
||||||
|
|
||||||
LNbits.api.request(
|
LNbits.api
|
||||||
|
.request(
|
||||||
'GET',
|
'GET',
|
||||||
'/paywall/api/v1/paywalls?all_wallets',
|
'/paywall/api/v1/paywalls?all_wallets',
|
||||||
this.g.user.wallets[0].inkey
|
this.g.user.wallets[0].inkey
|
||||||
).then(function (response) {
|
)
|
||||||
|
.then(function (response) {
|
||||||
self.paywalls = response.data.map(function (obj) {
|
self.paywalls = response.data.map(function (obj) {
|
||||||
return mapPaywall(obj);
|
return mapPaywall(obj)
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
createPaywall: function () {
|
createPaywall: function () {
|
||||||
var data = {
|
var data = {
|
||||||
url: this.formDialog.data.url,
|
url: this.formDialog.data.url,
|
||||||
memo: this.formDialog.data.memo,
|
memo: this.formDialog.data.memo,
|
||||||
amount: this.formDialog.data.amount
|
amount: this.formDialog.data.amount
|
||||||
};
|
}
|
||||||
var self = this;
|
var self = this
|
||||||
|
|
||||||
LNbits.api.request(
|
LNbits.api
|
||||||
|
.request(
|
||||||
'POST',
|
'POST',
|
||||||
'/paywall/api/v1/paywalls',
|
'/paywall/api/v1/paywalls',
|
||||||
_.findWhere(this.g.user.wallets, {id: this.formDialog.data.wallet}).inkey,
|
_.findWhere(this.g.user.wallets, {id: this.formDialog.data.wallet})
|
||||||
|
.inkey,
|
||||||
data
|
data
|
||||||
).then(function (response) {
|
)
|
||||||
self.paywalls.push(mapPaywall(response.data));
|
.then(function (response) {
|
||||||
self.formDialog.show = false;
|
self.paywalls.push(mapPaywall(response.data))
|
||||||
self.formDialog.data = {};
|
self.formDialog.show = false
|
||||||
}).catch(function (error) {
|
self.formDialog.data = {}
|
||||||
LNbits.utils.notifyApiError(error);
|
})
|
||||||
});
|
.catch(function (error) {
|
||||||
|
LNbits.utils.notifyApiError(error)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
deletePaywall: function (paywallId) {
|
deletePaywall: function (paywallId) {
|
||||||
var self = this;
|
var self = this
|
||||||
var paywall = _.findWhere(this.paywalls, {id: paywallId});
|
var paywall = _.findWhere(this.paywalls, {id: paywallId})
|
||||||
|
|
||||||
LNbits.utils.confirmDialog(
|
LNbits.utils
|
||||||
'Are you sure you want to delete this paywall link?'
|
.confirmDialog('Are you sure you want to delete this paywall link?')
|
||||||
).onOk(function () {
|
.onOk(function () {
|
||||||
LNbits.api.request(
|
LNbits.api
|
||||||
|
.request(
|
||||||
'DELETE',
|
'DELETE',
|
||||||
'/paywall/api/v1/paywalls/' + paywallId,
|
'/paywall/api/v1/paywalls/' + paywallId,
|
||||||
_.findWhere(self.g.user.wallets, {id: paywall.wallet}).inkey
|
_.findWhere(self.g.user.wallets, {id: paywall.wallet}).inkey
|
||||||
).then(function (response) {
|
)
|
||||||
self.paywalls = _.reject(self.paywalls, function (obj) { return obj.id == paywallId; });
|
.then(function (response) {
|
||||||
}).catch(function (error) {
|
self.paywalls = _.reject(self.paywalls, function (obj) {
|
||||||
LNbits.utils.notifyApiError(error);
|
return obj.id == paywallId
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
LNbits.utils.notifyApiError(error)
|
||||||
|
})
|
||||||
|
})
|
||||||
},
|
},
|
||||||
exportCSV: function () {
|
exportCSV: function () {
|
||||||
LNbits.utils.exportCSV(this.paywallsTable.columns, this.paywalls);
|
LNbits.utils.exportCSV(this.paywallsTable.columns, this.paywalls)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
if (this.g.user.wallets.length) {
|
if (this.g.user.wallets.length) {
|
||||||
this.getPaywalls();
|
this.getPaywalls()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -4,49 +4,84 @@
|
||||||
label="API info"
|
label="API info"
|
||||||
:content-inset-level="0.5"
|
:content-inset-level="0.5"
|
||||||
>
|
>
|
||||||
<q-expansion-item group="api" dense expand-separator label="List all users TPoS">
|
<q-expansion-item
|
||||||
|
group="api"
|
||||||
|
dense
|
||||||
|
expand-separator
|
||||||
|
label="List all users TPoS"
|
||||||
|
>
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<code><span class="text-light-blue">GET</span> /tpos/api/v1/tposs</code>
|
<code><span class="text-light-blue">GET</span> /tpos/api/v1/tposs</code>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
||||||
<code>{"X-Api-Key": <invoice_key>}</code><br />
|
<code>{"X-Api-Key": <invoice_key>}</code><br />
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Returns 201 CREATED (application/json)</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||||
<code>{"currency": <string>, "id": <string>, "name": <string>, "wallet": <string>}</code>
|
Returns 201 CREATED (application/json)
|
||||||
|
</h5>
|
||||||
|
<code
|
||||||
|
>{"currency": <string>, "id": <string>, "name":
|
||||||
|
<string>, "wallet": <string>}</code
|
||||||
|
>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||||
<code>curl -X GET {{ request.url_root }}tpos/api/v1/tposs -H "X-Api-Key: <invoice_key>" </code>
|
<code
|
||||||
|
>curl -X GET {{ request.url_root }}tpos/api/v1/tposs -H "X-Api-Key:
|
||||||
|
<invoice_key>"
|
||||||
|
</code>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
<q-expansion-item group="api" dense expand-separator label="Create a TPoS">
|
<q-expansion-item group="api" dense expand-separator label="Create a TPoS">
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<code><span class="text-light-green">POST</span> /tpos/api/v1/tposs</code>
|
<code
|
||||||
|
><span class="text-light-green">POST</span> /tpos/api/v1/tposs</code
|
||||||
|
>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
||||||
<code>{"X-Api-Key": <invoice_key>}</code><br />
|
<code>{"X-Api-Key": <invoice_key>}</code><br />
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
|
||||||
<code>{"name": <string>, "currency": <string*ie USD*>}</code>
|
<code
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Returns 201 CREATED (application/json)</h5>
|
>{"name": <string>, "currency": <string*ie USD*>}</code
|
||||||
<code>{"currency": <string>, "id": <string>, "name": <string>, "wallet": <string>}</code>
|
>
|
||||||
|
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||||
|
Returns 201 CREATED (application/json)
|
||||||
|
</h5>
|
||||||
|
<code
|
||||||
|
>{"currency": <string>, "id": <string>, "name":
|
||||||
|
<string>, "wallet": <string>}</code
|
||||||
|
>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||||
<code>curl -X POST {{ request.url_root }}tpos/api/v1/tposs -d '{"name": <string>, "currency": <string>}' -H "Content-type: application/json" -H "X-Api-Key: <admin_key>"
|
<code
|
||||||
|
>curl -X POST {{ request.url_root }}tpos/api/v1/tposs -d '{"name":
|
||||||
|
<string>, "currency": <string>}' -H "Content-type:
|
||||||
|
application/json" -H "X-Api-Key: <admin_key>"
|
||||||
</code>
|
</code>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
|
|
||||||
<q-expansion-item group="api" dense expand-separator label="Delete a TPoS" class="q-pb-md">
|
<q-expansion-item
|
||||||
|
group="api"
|
||||||
|
dense
|
||||||
|
expand-separator
|
||||||
|
label="Delete a TPoS"
|
||||||
|
class="q-pb-md"
|
||||||
|
>
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<code><span class="text-light-green">DELETE</span> /tpos/api/v1/tposs/<tpos_id></code>
|
<code
|
||||||
|
><span class="text-light-green">DELETE</span>
|
||||||
|
/tpos/api/v1/tposs/<tpos_id></code
|
||||||
|
>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
||||||
<code>{"X-Api-Key": <admin_key>}</code><br />
|
<code>{"X-Api-Key": <admin_key>}</code><br />
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Returns 201 NO_CONTENT</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Returns 201 NO_CONTENT</h5>
|
||||||
<code></code>
|
<code></code>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||||
<code>curl -X DELETE {{ request.url_root }}tpos/api/v1/tposs/<tpos_id> -H "X-Api-Key: <admin_key>"
|
<code
|
||||||
|
>curl -X DELETE {{ request.url_root
|
||||||
|
}}tpos/api/v1/tposs/<tpos_id> -H "X-Api-Key: <admin_key>"
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,18 @@
|
||||||
<q-expansion-item
|
<q-expansion-item group="extras" icon="info" label="About TPoS">
|
||||||
group="extras"
|
|
||||||
icon="info"
|
|
||||||
label="About TPoS">
|
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<p>Thiago's Point of Sale is a secure, mobile-ready, instant and shareable point of sale terminal (PoS) for merchants. The PoS is linked to your LNbits wallet but completely air-gapped so users can ONLY create invoices. To share the TPoS hit the hash on the terminal.</p>
|
<p>
|
||||||
<small>Created by <a href="https://github.com/talvasconcelos" target="_blank">Tiago Vasconcelos</a>.</small>
|
Thiago's Point of Sale is a secure, mobile-ready, instant and shareable
|
||||||
|
point of sale terminal (PoS) for merchants. The PoS is linked to your
|
||||||
|
LNbits wallet but completely air-gapped so users can ONLY create
|
||||||
|
invoices. To share the TPoS hit the hash on the terminal.
|
||||||
|
</p>
|
||||||
|
<small
|
||||||
|
>Created by
|
||||||
|
<a href="https://github.com/talvasconcelos" target="_blank"
|
||||||
|
>Tiago Vasconcelos</a
|
||||||
|
>.</small
|
||||||
|
>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,12 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %} {% from "macros.jinja" import window_vars with context
|
||||||
|
%} {% block page %}
|
||||||
{% from "macros.jinja" import window_vars with context %}
|
<div class="row q-col-gutter-md">
|
||||||
|
|
||||||
|
|
||||||
{% block page %}
|
|
||||||
<div class="row q-col-gutter-md">
|
|
||||||
<div class="col-12 col-md-8 col-lg-7 q-gutter-y-md">
|
<div class="col-12 col-md-8 col-lg-7 q-gutter-y-md">
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<q-btn unelevated color="deep-purple" @click="formDialog.show = true">New TPoS</q-btn>
|
<q-btn unelevated color="deep-purple" @click="formDialog.show = true"
|
||||||
|
>New TPoS</q-btn
|
||||||
|
>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|
||||||
|
|
@ -22,20 +20,19 @@
|
||||||
<q-btn flat color="grey" @click="exportCSV">Export to CSV</q-btn>
|
<q-btn flat color="grey" @click="exportCSV">Export to CSV</q-btn>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<q-table dense flat
|
<q-table
|
||||||
|
dense
|
||||||
|
flat
|
||||||
:data="tposs"
|
:data="tposs"
|
||||||
row-key="id"
|
row-key="id"
|
||||||
:columns="tpossTable.columns"
|
:columns="tpossTable.columns"
|
||||||
:pagination.sync="tpossTable.pagination">
|
:pagination.sync="tpossTable.pagination"
|
||||||
|
>
|
||||||
{% raw %}
|
{% raw %}
|
||||||
<template v-slot:header="props">
|
<template v-slot:header="props">
|
||||||
<q-tr :props="props">
|
<q-tr :props="props">
|
||||||
<q-th auto-width></q-th>
|
<q-th auto-width></q-th>
|
||||||
<q-th
|
<q-th v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
v-for="col in props.cols"
|
|
||||||
:key="col.name"
|
|
||||||
:props="props"
|
|
||||||
>
|
|
||||||
{{ col.label }}
|
{{ col.label }}
|
||||||
</q-th>
|
</q-th>
|
||||||
<q-th auto-width></q-th>
|
<q-th auto-width></q-th>
|
||||||
|
|
@ -45,17 +42,29 @@
|
||||||
<template v-slot:body="props">
|
<template v-slot:body="props">
|
||||||
<q-tr :props="props">
|
<q-tr :props="props">
|
||||||
<q-td auto-width>
|
<q-td auto-width>
|
||||||
<q-btn unelevated dense size="xs" icon="launch" :color="($q.dark.isActive) ? 'grey-7' : 'grey-5'" type="a" :href="props.row.tpos" target="_blank"></q-btn>
|
<q-btn
|
||||||
|
unelevated
|
||||||
|
dense
|
||||||
|
size="xs"
|
||||||
|
icon="launch"
|
||||||
|
:color="($q.dark.isActive) ? 'grey-7' : 'grey-5'"
|
||||||
|
type="a"
|
||||||
|
:href="props.row.tpos"
|
||||||
|
target="_blank"
|
||||||
|
></q-btn>
|
||||||
</q-td>
|
</q-td>
|
||||||
<q-td
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
v-for="col in props.cols"
|
|
||||||
:key="col.name"
|
|
||||||
:props="props"
|
|
||||||
>
|
|
||||||
{{ col.value }}
|
{{ col.value }}
|
||||||
</q-td>
|
</q-td>
|
||||||
<q-td auto-width>
|
<q-td auto-width>
|
||||||
<q-btn flat dense size="xs" @click="deleteTPoS(props.row.id)" icon="cancel" color="pink"></q-btn>
|
<q-btn
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
size="xs"
|
||||||
|
@click="deleteTPoS(props.row.id)"
|
||||||
|
icon="cancel"
|
||||||
|
color="pink"
|
||||||
|
></q-btn>
|
||||||
</q-td>
|
</q-td>
|
||||||
</q-tr>
|
</q-tr>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -81,43 +90,58 @@
|
||||||
</q-card>
|
</q-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<q-dialog v-model="formDialog.show" position="top" @hide="closeFormDialog">
|
<q-dialog v-model="formDialog.show" position="top" @hide="closeFormDialog">
|
||||||
<q-card class="q-pa-lg q-pt-xl" style="width: 500px">
|
<q-card class="q-pa-lg q-pt-xl" style="width: 500px;">
|
||||||
<q-form @submit="createTPoS" class="q-gutter-md">
|
<q-form @submit="createTPoS" class="q-gutter-md">
|
||||||
<q-input filled dense
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
v-model.trim="formDialog.data.name"
|
v-model.trim="formDialog.data.name"
|
||||||
label="Name"
|
label="Name"
|
||||||
placeholder="Tiago's PoS"></q-input>
|
placeholder="Tiago's PoS"
|
||||||
<q-select filled dense
|
></q-input>
|
||||||
emit-value v-model="formDialog.data.wallet"
|
<q-select
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
emit-value
|
||||||
|
v-model="formDialog.data.wallet"
|
||||||
:options="g.user.walletOptions"
|
:options="g.user.walletOptions"
|
||||||
label="Wallet *"></q-select>
|
label="Wallet *"
|
||||||
<q-select filled dense
|
></q-select>
|
||||||
emit-value v-model="formDialog.data.currency"
|
<q-select
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
emit-value
|
||||||
|
v-model="formDialog.data.currency"
|
||||||
:options="currencyOptions"
|
:options="currencyOptions"
|
||||||
label="Currency *"></q-select>
|
label="Currency *"
|
||||||
|
></q-select>
|
||||||
<div class="row q-mt-lg">
|
<div class="row q-mt-lg">
|
||||||
<q-btn unelevated
|
<q-btn
|
||||||
|
unelevated
|
||||||
color="deep-purple"
|
color="deep-purple"
|
||||||
:disable="formDialog.data.currency == null || formDialog.data.name == null"
|
:disable="formDialog.data.currency == null || formDialog.data.name == null"
|
||||||
type="submit">Create TPoS</q-btn>
|
type="submit"
|
||||||
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Cancel</q-btn>
|
>Create TPoS</q-btn
|
||||||
|
>
|
||||||
|
<q-btn v-close-popup flat color="grey" class="q-ml-auto"
|
||||||
|
>Cancel</q-btn
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</q-form>
|
</q-form>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %} {% block scripts %} {{ window_vars(user) }}
|
||||||
|
<script>
|
||||||
{% block scripts %}
|
|
||||||
{{ window_vars(user) }}
|
|
||||||
<script>
|
|
||||||
var mapTPoS = function (obj) {
|
var mapTPoS = function (obj) {
|
||||||
obj.date = Quasar.utils.date.formatDate(new Date(obj.time * 1000), 'YYYY-MM-DD HH:mm');
|
obj.date = Quasar.utils.date.formatDate(
|
||||||
obj.fsat = new Intl.NumberFormat(LOCALE).format(obj.amount);
|
new Date(obj.time * 1000),
|
||||||
obj.tpos = ['/tpos/', obj.id].join('');
|
'YYYY-MM-DD HH:mm'
|
||||||
return obj;
|
)
|
||||||
|
obj.fsat = new Intl.NumberFormat(LOCALE).format(obj.amount)
|
||||||
|
obj.tpos = ['/tpos/', obj.id].join('')
|
||||||
|
return obj
|
||||||
}
|
}
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
|
|
@ -127,21 +151,188 @@
|
||||||
return {
|
return {
|
||||||
tposs: [],
|
tposs: [],
|
||||||
currencyOptions: [
|
currencyOptions: [
|
||||||
'USD','EUR','GBP','AED','AFN','ALL','AMD','ANG','AOA','ARS','AUD','AWG','AZN','BAM','BBD','BDT','BGN','BHD',
|
'USD',
|
||||||
'BIF','BMD','BND','BOB','BRL','BSD','BTN','BWP','BYN','BZD','CAD','CDF','CHF','CLF','CLP','CNH','CNY','COP',
|
'EUR',
|
||||||
'CRC','CUC','CUP','CVE','CZK','DJF','DKK','DOP','DZD','EGP','ERN','ETB','EUR','FJD','FKP','GBP','GEL','GGP',
|
'GBP',
|
||||||
'GHS','GIP','GMD','GNF','GTQ','GYD','HKD','HNL','HRK','HTG','HUF','IDR','ILS','IMP','INR','IQD','IRR','ISK',
|
'AED',
|
||||||
'JEP','JMD','JOD','JPY','KES','KGS','KHR','KMF','KPW','KRW','KWD','KYD','KZT','LAK','LBP','LKR','LRD','LSL',
|
'AFN',
|
||||||
'LYD','MAD','MDL','MGA','MKD','MMK','MNT','MOP','MRO','MUR','MVR','MWK','MXN','MYR','MZN','NAD','NGN','NIO','NOK','NPR','NZD','OMR','PAB','PEN','PGK','PHP','PKR','PLN','PYG','QAR','RON','RSD','RUB','RWF','SAR','SBD',
|
'ALL',
|
||||||
'SCR','SDG','SEK','SGD','SHP','SLL','SOS','SRD','SSP','STD','SVC','SYP','SZL','THB','TJS','TMT','TND','TOP',
|
'AMD',
|
||||||
'TRY','TTD','TWD','TZS','UAH','UGX','USD','UYU','UZS','VEF','VES','VND','VUV','WST','XAF','XAG','XAU','XCD',
|
'ANG',
|
||||||
'XDR','XOF','XPD','XPF','XPT','YER','ZAR','ZMW','ZWL'
|
'AOA',
|
||||||
|
'ARS',
|
||||||
|
'AUD',
|
||||||
|
'AWG',
|
||||||
|
'AZN',
|
||||||
|
'BAM',
|
||||||
|
'BBD',
|
||||||
|
'BDT',
|
||||||
|
'BGN',
|
||||||
|
'BHD',
|
||||||
|
'BIF',
|
||||||
|
'BMD',
|
||||||
|
'BND',
|
||||||
|
'BOB',
|
||||||
|
'BRL',
|
||||||
|
'BSD',
|
||||||
|
'BTN',
|
||||||
|
'BWP',
|
||||||
|
'BYN',
|
||||||
|
'BZD',
|
||||||
|
'CAD',
|
||||||
|
'CDF',
|
||||||
|
'CHF',
|
||||||
|
'CLF',
|
||||||
|
'CLP',
|
||||||
|
'CNH',
|
||||||
|
'CNY',
|
||||||
|
'COP',
|
||||||
|
'CRC',
|
||||||
|
'CUC',
|
||||||
|
'CUP',
|
||||||
|
'CVE',
|
||||||
|
'CZK',
|
||||||
|
'DJF',
|
||||||
|
'DKK',
|
||||||
|
'DOP',
|
||||||
|
'DZD',
|
||||||
|
'EGP',
|
||||||
|
'ERN',
|
||||||
|
'ETB',
|
||||||
|
'EUR',
|
||||||
|
'FJD',
|
||||||
|
'FKP',
|
||||||
|
'GBP',
|
||||||
|
'GEL',
|
||||||
|
'GGP',
|
||||||
|
'GHS',
|
||||||
|
'GIP',
|
||||||
|
'GMD',
|
||||||
|
'GNF',
|
||||||
|
'GTQ',
|
||||||
|
'GYD',
|
||||||
|
'HKD',
|
||||||
|
'HNL',
|
||||||
|
'HRK',
|
||||||
|
'HTG',
|
||||||
|
'HUF',
|
||||||
|
'IDR',
|
||||||
|
'ILS',
|
||||||
|
'IMP',
|
||||||
|
'INR',
|
||||||
|
'IQD',
|
||||||
|
'IRR',
|
||||||
|
'ISK',
|
||||||
|
'JEP',
|
||||||
|
'JMD',
|
||||||
|
'JOD',
|
||||||
|
'JPY',
|
||||||
|
'KES',
|
||||||
|
'KGS',
|
||||||
|
'KHR',
|
||||||
|
'KMF',
|
||||||
|
'KPW',
|
||||||
|
'KRW',
|
||||||
|
'KWD',
|
||||||
|
'KYD',
|
||||||
|
'KZT',
|
||||||
|
'LAK',
|
||||||
|
'LBP',
|
||||||
|
'LKR',
|
||||||
|
'LRD',
|
||||||
|
'LSL',
|
||||||
|
'LYD',
|
||||||
|
'MAD',
|
||||||
|
'MDL',
|
||||||
|
'MGA',
|
||||||
|
'MKD',
|
||||||
|
'MMK',
|
||||||
|
'MNT',
|
||||||
|
'MOP',
|
||||||
|
'MRO',
|
||||||
|
'MUR',
|
||||||
|
'MVR',
|
||||||
|
'MWK',
|
||||||
|
'MXN',
|
||||||
|
'MYR',
|
||||||
|
'MZN',
|
||||||
|
'NAD',
|
||||||
|
'NGN',
|
||||||
|
'NIO',
|
||||||
|
'NOK',
|
||||||
|
'NPR',
|
||||||
|
'NZD',
|
||||||
|
'OMR',
|
||||||
|
'PAB',
|
||||||
|
'PEN',
|
||||||
|
'PGK',
|
||||||
|
'PHP',
|
||||||
|
'PKR',
|
||||||
|
'PLN',
|
||||||
|
'PYG',
|
||||||
|
'QAR',
|
||||||
|
'RON',
|
||||||
|
'RSD',
|
||||||
|
'RUB',
|
||||||
|
'RWF',
|
||||||
|
'SAR',
|
||||||
|
'SBD',
|
||||||
|
'SCR',
|
||||||
|
'SDG',
|
||||||
|
'SEK',
|
||||||
|
'SGD',
|
||||||
|
'SHP',
|
||||||
|
'SLL',
|
||||||
|
'SOS',
|
||||||
|
'SRD',
|
||||||
|
'SSP',
|
||||||
|
'STD',
|
||||||
|
'SVC',
|
||||||
|
'SYP',
|
||||||
|
'SZL',
|
||||||
|
'THB',
|
||||||
|
'TJS',
|
||||||
|
'TMT',
|
||||||
|
'TND',
|
||||||
|
'TOP',
|
||||||
|
'TRY',
|
||||||
|
'TTD',
|
||||||
|
'TWD',
|
||||||
|
'TZS',
|
||||||
|
'UAH',
|
||||||
|
'UGX',
|
||||||
|
'USD',
|
||||||
|
'UYU',
|
||||||
|
'UZS',
|
||||||
|
'VEF',
|
||||||
|
'VES',
|
||||||
|
'VND',
|
||||||
|
'VUV',
|
||||||
|
'WST',
|
||||||
|
'XAF',
|
||||||
|
'XAG',
|
||||||
|
'XAU',
|
||||||
|
'XCD',
|
||||||
|
'XDR',
|
||||||
|
'XOF',
|
||||||
|
'XPD',
|
||||||
|
'XPF',
|
||||||
|
'XPT',
|
||||||
|
'YER',
|
||||||
|
'ZAR',
|
||||||
|
'ZMW',
|
||||||
|
'ZWL'
|
||||||
],
|
],
|
||||||
tpossTable: {
|
tpossTable: {
|
||||||
columns: [
|
columns: [
|
||||||
{name: 'id', align: 'left', label: 'ID', field: 'id'},
|
{name: 'id', align: 'left', label: 'ID', field: 'id'},
|
||||||
{name: 'name', align: 'left', label: 'Name', field: 'name'},
|
{name: 'name', align: 'left', label: 'Name', field: 'name'},
|
||||||
{name: 'currency', align: 'left', label: 'Currency', field: 'currency'}
|
{
|
||||||
|
name: 'currency',
|
||||||
|
align: 'left',
|
||||||
|
label: 'Currency',
|
||||||
|
field: 'currency'
|
||||||
|
}
|
||||||
],
|
],
|
||||||
pagination: {
|
pagination: {
|
||||||
rowsPerPage: 10
|
rowsPerPage: 10
|
||||||
|
|
@ -151,71 +342,82 @@
|
||||||
show: false,
|
show: false,
|
||||||
data: {}
|
data: {}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
closeFormDialog: function () {
|
closeFormDialog: function () {
|
||||||
this.formDialog.data = {};
|
this.formDialog.data = {}
|
||||||
},
|
},
|
||||||
getTPoSs: function () {
|
getTPoSs: function () {
|
||||||
var self = this;
|
var self = this
|
||||||
|
|
||||||
LNbits.api.request(
|
LNbits.api
|
||||||
|
.request(
|
||||||
'GET',
|
'GET',
|
||||||
'/tpos/api/v1/tposs?all_wallets',
|
'/tpos/api/v1/tposs?all_wallets',
|
||||||
this.g.user.wallets[0].inkey
|
this.g.user.wallets[0].inkey
|
||||||
).then(function (response) {
|
)
|
||||||
|
.then(function (response) {
|
||||||
self.tposs = response.data.map(function (obj) {
|
self.tposs = response.data.map(function (obj) {
|
||||||
return mapTPoS(obj);
|
return mapTPoS(obj)
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
createTPoS: function () {
|
createTPoS: function () {
|
||||||
var data = {
|
var data = {
|
||||||
name: this.formDialog.data.name,
|
name: this.formDialog.data.name,
|
||||||
currency: this.formDialog.data.currency
|
currency: this.formDialog.data.currency
|
||||||
};
|
}
|
||||||
var self = this;
|
var self = this
|
||||||
|
|
||||||
LNbits.api.request(
|
LNbits.api
|
||||||
|
.request(
|
||||||
'POST',
|
'POST',
|
||||||
'/tpos/api/v1/tposs',
|
'/tpos/api/v1/tposs',
|
||||||
_.findWhere(this.g.user.wallets, {id: this.formDialog.data.wallet}).inkey,
|
_.findWhere(this.g.user.wallets, {id: this.formDialog.data.wallet})
|
||||||
|
.inkey,
|
||||||
data
|
data
|
||||||
).then(function (response) {
|
)
|
||||||
self.tposs.push(mapTPoS(response.data));
|
.then(function (response) {
|
||||||
self.formDialog.show = false;
|
self.tposs.push(mapTPoS(response.data))
|
||||||
}).catch(function (error) {
|
self.formDialog.show = false
|
||||||
LNbits.utils.notifyApiError(error);
|
})
|
||||||
});
|
.catch(function (error) {
|
||||||
|
LNbits.utils.notifyApiError(error)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
deleteTPoS: function (tposId) {
|
deleteTPoS: function (tposId) {
|
||||||
var self = this;
|
var self = this
|
||||||
var tpos = _.findWhere(this.tposs, {id: tposId});
|
var tpos = _.findWhere(this.tposs, {id: tposId})
|
||||||
|
|
||||||
LNbits.utils.confirmDialog(
|
LNbits.utils
|
||||||
'Are you sure you want to delete this TPoS?'
|
.confirmDialog('Are you sure you want to delete this TPoS?')
|
||||||
).onOk(function () {
|
.onOk(function () {
|
||||||
LNbits.api.request(
|
LNbits.api
|
||||||
|
.request(
|
||||||
'DELETE',
|
'DELETE',
|
||||||
'/tpos/api/v1/tposs/' + tposId,
|
'/tpos/api/v1/tposs/' + tposId,
|
||||||
_.findWhere(self.g.user.wallets, {id: tpos.wallet}).adminkey
|
_.findWhere(self.g.user.wallets, {id: tpos.wallet}).adminkey
|
||||||
).then(function (response) {
|
)
|
||||||
self.tposs = _.reject(self.tposs, function (obj) { return obj.id == tposId; });
|
.then(function (response) {
|
||||||
}).catch(function (error) {
|
self.tposs = _.reject(self.tposs, function (obj) {
|
||||||
LNbits.utils.notifyApiError(error);
|
return obj.id == tposId
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
LNbits.utils.notifyApiError(error)
|
||||||
|
})
|
||||||
|
})
|
||||||
},
|
},
|
||||||
exportCSV: function () {
|
exportCSV: function () {
|
||||||
LNbits.utils.exportCSV(this.tpossTable.columns, this.tposs);
|
LNbits.utils.exportCSV(this.tpossTable.columns, this.tposs)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
if (this.g.user.wallets.length) {
|
if (this.g.user.wallets.length) {
|
||||||
this.getTPoSs();
|
this.getTPoSs()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,6 @@
|
||||||
{% extends "public.html" %}
|
{% extends "public.html" %} {% block toolbar_title %}{{ tpos.name }}{% endblock
|
||||||
|
%} {% block footer %}{% endblock %} {% block page_container %}
|
||||||
|
<q-page-container>
|
||||||
{% block toolbar_title %}{{ tpos.name }}{% endblock %}
|
|
||||||
|
|
||||||
{% block footer %}{% endblock %}
|
|
||||||
|
|
||||||
{% block page_container %}
|
|
||||||
<q-page-container>
|
|
||||||
<q-page>
|
<q-page>
|
||||||
<q-page-sticky v-if="exchangeRate" expand position="top">
|
<q-page-sticky v-if="exchangeRate" expand position="top">
|
||||||
<div class="row justify-center full-width">
|
<div class="row justify-center full-width">
|
||||||
|
|
@ -22,57 +16,86 @@
|
||||||
<div class="row justify-center full-width">
|
<div class="row justify-center full-width">
|
||||||
<div class="col-12 col-sm-8 col-md-6 col-lg-4">
|
<div class="col-12 col-sm-8 col-md-6 col-lg-4">
|
||||||
<div class="keypad q-pa-sm">
|
<div class="keypad q-pa-sm">
|
||||||
<q-btn unelevated
|
<q-btn unelevated @click="stack.push(1)" size="xl" color="grey-8"
|
||||||
@click="stack.push(1)"
|
>1</q-btn
|
||||||
size="xl" color="grey-8">1</q-btn>
|
>
|
||||||
<q-btn unelevated
|
<q-btn unelevated @click="stack.push(2)" size="xl" color="grey-8"
|
||||||
@click="stack.push(2)"
|
>2</q-btn
|
||||||
size="xl" color="grey-8">2</q-btn>
|
>
|
||||||
<q-btn unelevated
|
<q-btn unelevated @click="stack.push(3)" size="xl" color="grey-8"
|
||||||
@click="stack.push(3)"
|
>3</q-btn
|
||||||
size="xl" color="grey-8">3</q-btn>
|
>
|
||||||
<q-btn unelevated
|
<q-btn
|
||||||
|
unelevated
|
||||||
@click="stack = []"
|
@click="stack = []"
|
||||||
size="xl" color="pink" class="btn-cancel">C</q-btn>
|
size="xl"
|
||||||
<q-btn unelevated
|
color="pink"
|
||||||
@click="stack.push(4)"
|
class="btn-cancel"
|
||||||
size="xl" color="grey-8">4</q-btn>
|
>C</q-btn
|
||||||
<q-btn unelevated
|
>
|
||||||
@click="stack.push(5)"
|
<q-btn unelevated @click="stack.push(4)" size="xl" color="grey-8"
|
||||||
size="xl" color="grey-8">5</q-btn>
|
>4</q-btn
|
||||||
<q-btn unelevated
|
>
|
||||||
@click="stack.push(6)"
|
<q-btn unelevated @click="stack.push(5)" size="xl" color="grey-8"
|
||||||
size="xl" color="grey-8">6</q-btn>
|
>5</q-btn
|
||||||
<q-btn unelevated
|
>
|
||||||
@click="stack.push(7)"
|
<q-btn unelevated @click="stack.push(6)" size="xl" color="grey-8"
|
||||||
size="xl" color="grey-8">7</q-btn>
|
>6</q-btn
|
||||||
<q-btn unelevated
|
>
|
||||||
@click="stack.push(8)"
|
<q-btn unelevated @click="stack.push(7)" size="xl" color="grey-8"
|
||||||
size="xl" color="grey-8">8</q-btn>
|
>7</q-btn
|
||||||
<q-btn unelevated
|
>
|
||||||
@click="stack.push(9)"
|
<q-btn unelevated @click="stack.push(8)" size="xl" color="grey-8"
|
||||||
size="xl" color="grey-8">9</q-btn>
|
>8</q-btn
|
||||||
<q-btn unelevated
|
>
|
||||||
|
<q-btn unelevated @click="stack.push(9)" size="xl" color="grey-8"
|
||||||
|
>9</q-btn
|
||||||
|
>
|
||||||
|
<q-btn
|
||||||
|
unelevated
|
||||||
:disabled="amount == 0"
|
:disabled="amount == 0"
|
||||||
@click="showInvoice()"
|
@click="showInvoice()"
|
||||||
size="xl" color="green" class="btn-confirm">OK</q-btn>
|
size="xl"
|
||||||
<q-btn unelevated
|
color="green"
|
||||||
|
class="btn-confirm"
|
||||||
|
>OK</q-btn
|
||||||
|
>
|
||||||
|
<q-btn
|
||||||
|
unelevated
|
||||||
@click="stack.splice(-1, 1)"
|
@click="stack.splice(-1, 1)"
|
||||||
size="xl" color="grey-7">DEL</q-btn>
|
size="xl"
|
||||||
<q-btn unelevated
|
color="grey-7"
|
||||||
@click="stack.push(0)"
|
>DEL</q-btn
|
||||||
size="xl" color="grey-8">0</q-btn>
|
>
|
||||||
<q-btn unelevated
|
<q-btn unelevated @click="stack.push(0)" size="xl" color="grey-8"
|
||||||
|
>0</q-btn
|
||||||
|
>
|
||||||
|
<q-btn
|
||||||
|
unelevated
|
||||||
@click="urlDialog.show = true"
|
@click="urlDialog.show = true"
|
||||||
size="xl" color="grey-7">#</q-btn>
|
size="xl"
|
||||||
|
color="grey-7"
|
||||||
|
>#</q-btn
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</q-page-sticky>
|
</q-page-sticky>
|
||||||
<q-dialog v-model="invoiceDialog.show" position="top" @hide="closeInvoiceDialog">
|
<q-dialog
|
||||||
<q-card v-if="invoiceDialog.data" class="q-pa-lg q-pt-xl lnbits__dialog-card">
|
v-model="invoiceDialog.show"
|
||||||
|
position="top"
|
||||||
|
@hide="closeInvoiceDialog"
|
||||||
|
>
|
||||||
|
<q-card
|
||||||
|
v-if="invoiceDialog.data"
|
||||||
|
class="q-pa-lg q-pt-xl lnbits__dialog-card"
|
||||||
|
>
|
||||||
<q-responsive :ratio="1" class="q-mx-xl q-mb-md">
|
<q-responsive :ratio="1" class="q-mx-xl q-mb-md">
|
||||||
<qrcode :value="invoiceDialog.data.payment_request" :options="{width: 800}" class="rounded-borders"></qrcode>
|
<qrcode
|
||||||
|
:value="invoiceDialog.data.payment_request"
|
||||||
|
:options="{width: 800}"
|
||||||
|
class="rounded-borders"
|
||||||
|
></qrcode>
|
||||||
</q-responsive>
|
</q-responsive>
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<h3 class="q-my-md">{% raw %}{{ famount }}{% endraw %}</h3>
|
<h3 class="q-my-md">{% raw %}{{ famount }}{% endraw %}</h3>
|
||||||
|
|
@ -88,23 +111,32 @@
|
||||||
<q-dialog v-model="urlDialog.show" position="top">
|
<q-dialog v-model="urlDialog.show" position="top">
|
||||||
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
|
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
|
||||||
<q-responsive :ratio="1" class="q-mx-xl q-mb-md">
|
<q-responsive :ratio="1" class="q-mx-xl q-mb-md">
|
||||||
<qrcode value="{{ request.url }}" :options="{width: 800}" class="rounded-borders"></qrcode>
|
<qrcode
|
||||||
|
value="{{ request.url }}"
|
||||||
|
:options="{width: 800}"
|
||||||
|
class="rounded-borders"
|
||||||
|
></qrcode>
|
||||||
</q-responsive>
|
</q-responsive>
|
||||||
<div class="text-center q-mb-xl">
|
<div class="text-center q-mb-xl">
|
||||||
<p style="word-break: break-all"><strong>{{ tpos.name }}</strong><br>{{ request.url }}</p>
|
<p style="word-break: break-all;">
|
||||||
|
<strong>{{ tpos.name }}</strong><br />{{ request.url }}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="row q-mt-lg">
|
<div class="row q-mt-lg">
|
||||||
<q-btn outline color="grey" @click="copyText('{{ request.url }}', 'TPoS URL copied to clipboard!')">Copy URL</q-btn>
|
<q-btn
|
||||||
|
outline
|
||||||
|
color="grey"
|
||||||
|
@click="copyText('{{ request.url }}', 'TPoS URL copied to clipboard!')"
|
||||||
|
>Copy URL</q-btn
|
||||||
|
>
|
||||||
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Close</q-btn>
|
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Close</q-btn>
|
||||||
</div>
|
</div>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
</q-page>
|
</q-page>
|
||||||
</q-page-container>
|
</q-page-container>
|
||||||
{% endblock %}
|
{% endblock %} {% block styles %}
|
||||||
|
<style>
|
||||||
{% block styles %}
|
|
||||||
<style>
|
|
||||||
.keypad {
|
.keypad {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-gap: 8px;
|
grid-gap: 8px;
|
||||||
|
|
@ -114,16 +146,15 @@
|
||||||
.keypad .btn {
|
.keypad .btn {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
.btn-cancel, .btn-confirm {
|
.btn-cancel,
|
||||||
|
.btn-confirm {
|
||||||
grid-row: auto/span 2;
|
grid-row: auto/span 2;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% endblock %}
|
{% endblock %} {% block scripts %}
|
||||||
|
<script src="{{ url_for('static', filename='vendor/vue-qrcode@1.0.2/vue-qrcode.min.js') }}"></script>
|
||||||
{% block scripts %}
|
<script>
|
||||||
<script src="{{ url_for('static', filename='vendor/vue-qrcode@1.0.2/vue-qrcode.min.js') }}"></script>
|
Vue.component(VueQrcode.name, VueQrcode)
|
||||||
<script>
|
|
||||||
Vue.component(VueQrcode.name, VueQrcode);
|
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
el: '#vue',
|
el: '#vue',
|
||||||
|
|
@ -143,83 +174,92 @@
|
||||||
urlDialog: {
|
urlDialog: {
|
||||||
show: false
|
show: false
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
amount: function () {
|
amount: function () {
|
||||||
if (!this.stack.length) return 0.00;
|
if (!this.stack.length) return 0.0
|
||||||
return (Number(this.stack.join('')) / 100).toFixed(2);
|
return (Number(this.stack.join('')) / 100).toFixed(2)
|
||||||
},
|
},
|
||||||
famount: function () {
|
famount: function () {
|
||||||
return LNbits.utils.formatCurrency(this.amount, this.currency);
|
return LNbits.utils.formatCurrency(this.amount, this.currency)
|
||||||
},
|
},
|
||||||
sat: function () {
|
sat: function () {
|
||||||
if (!this.exchangeRate) return 0;
|
if (!this.exchangeRate) return 0
|
||||||
return Math.ceil((this.amount / this.exchangeRate) * 100000000);
|
return Math.ceil((this.amount / this.exchangeRate) * 100000000)
|
||||||
},
|
},
|
||||||
fsat: function () {
|
fsat: function () {
|
||||||
return LNbits.utils.formatSat(this.sat);
|
return LNbits.utils.formatSat(this.sat)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
closeInvoiceDialog: function () {
|
closeInvoiceDialog: function () {
|
||||||
this.stack = [];
|
this.stack = []
|
||||||
var dialog = this.invoiceDialog;
|
var dialog = this.invoiceDialog
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
clearInterval(dialog.paymentChecker);
|
clearInterval(dialog.paymentChecker)
|
||||||
dialog.dismissMsg();
|
dialog.dismissMsg()
|
||||||
}, 3000);
|
}, 3000)
|
||||||
},
|
},
|
||||||
showInvoice: function () {
|
showInvoice: function () {
|
||||||
var self = this;
|
var self = this
|
||||||
var dialog = this.invoiceDialog;
|
var dialog = this.invoiceDialog
|
||||||
|
|
||||||
axios.post(
|
axios
|
||||||
'/tpos/api/v1/tposs/' + this.tposId + '/invoices/',
|
.post('/tpos/api/v1/tposs/' + this.tposId + '/invoices/', {
|
||||||
{amount: this.sat}
|
amount: this.sat
|
||||||
).then(function (response) {
|
})
|
||||||
dialog.data = response.data;
|
.then(function (response) {
|
||||||
dialog.show = true;
|
dialog.data = response.data
|
||||||
|
dialog.show = true
|
||||||
|
|
||||||
dialog.dismissMsg = self.$q.notify({
|
dialog.dismissMsg = self.$q.notify({
|
||||||
timeout: 0,
|
timeout: 0,
|
||||||
message: 'Waiting for payment...'
|
message: 'Waiting for payment...'
|
||||||
});
|
})
|
||||||
|
|
||||||
dialog.paymentChecker = setInterval(function () {
|
dialog.paymentChecker = setInterval(function () {
|
||||||
axios.get(
|
axios
|
||||||
'/tpos/api/v1/tposs/' + self.tposId + '/invoices/' + response.data.checking_id
|
.get(
|
||||||
).then(function (res) {
|
'/tpos/api/v1/tposs/' +
|
||||||
|
self.tposId +
|
||||||
|
'/invoices/' +
|
||||||
|
response.data.checking_id
|
||||||
|
)
|
||||||
|
.then(function (res) {
|
||||||
if (res.data.paid) {
|
if (res.data.paid) {
|
||||||
clearInterval(dialog.paymentChecker);
|
clearInterval(dialog.paymentChecker)
|
||||||
dialog.dismissMsg();
|
dialog.dismissMsg()
|
||||||
dialog.show = false;
|
dialog.show = false
|
||||||
|
|
||||||
self.$q.notify({
|
self.$q.notify({
|
||||||
type: 'positive',
|
type: 'positive',
|
||||||
message: self.fsat + ' sat received!',
|
message: self.fsat + ' sat received!',
|
||||||
icon: null
|
icon: null
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}, 2000);
|
}, 2000)
|
||||||
|
})
|
||||||
}).catch(function (error) {
|
.catch(function (error) {
|
||||||
LNbits.utils.notifyApiError(error);
|
LNbits.utils.notifyApiError(error)
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
getRates: function () {
|
getRates: function () {
|
||||||
var self = this;
|
var self = this
|
||||||
axios.get("https://api.opennode.co/v1/rates").then(function (response) {
|
axios.get('https://api.opennode.co/v1/rates').then(function (response) {
|
||||||
self.exchangeRate = response.data.data['BTC' + self.currency][self.currency];
|
self.exchangeRate =
|
||||||
});
|
response.data.data['BTC' + self.currency][self.currency]
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
var getRates = this.getRates;
|
var getRates = this.getRates
|
||||||
getRates();
|
getRates()
|
||||||
setInterval(function () { getRates(); }, 20000);
|
setInterval(function () {
|
||||||
|
getRates()
|
||||||
|
}, 20000)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,26 @@
|
||||||
|
<q-expansion-item
|
||||||
<q-expansion-item
|
|
||||||
group="extras"
|
group="extras"
|
||||||
icon="swap_vertical_circle"
|
icon="swap_vertical_circle"
|
||||||
label="Info"
|
label="Info"
|
||||||
:content-inset-level="0.5"
|
:content-inset-level="0.5"
|
||||||
>
|
>
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<h5 class="text-subtitle1 q-my-none">User Manager: Make and manager users/wallets</h5>
|
<h5 class="text-subtitle1 q-my-none">
|
||||||
<p>To help developers use LNbits to manage their users, the User Manager extension allows the creation and management of users and wallets. <br/>For example, a games developer may be developing a game that needs each user to have their own wallet, LNbits can be included in the develpoers stack as the user and wallet manager.<br/>
|
User Manager: Make and manager users/wallets
|
||||||
<small> Created by, <a href="https://github.com/benarc">Ben Arc</a></small></p>
|
</h5>
|
||||||
|
<p>
|
||||||
|
To help developers use LNbits to manage their users, the User Manager
|
||||||
|
extension allows the creation and management of users and wallets.
|
||||||
|
<br />For example, a games developer may be developing a game that needs
|
||||||
|
each user to have their own wallet, LNbits can be included in the
|
||||||
|
develpoers stack as the user and wallet manager.<br />
|
||||||
|
<small>
|
||||||
|
Created by, <a href="https://github.com/benarc">Ben Arc</a></small
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-card-section>
|
|
||||||
|
|
||||||
</q-card-section>
|
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
<q-expansion-item
|
<q-expansion-item
|
||||||
group="extras"
|
group="extras"
|
||||||
|
|
@ -21,59 +28,109 @@
|
||||||
label="API info"
|
label="API info"
|
||||||
:content-inset-level="0.5"
|
:content-inset-level="0.5"
|
||||||
>
|
>
|
||||||
|
|
||||||
<q-expansion-item group="api" dense expand-separator label="GET users">
|
<q-expansion-item group="api" dense expand-separator label="GET users">
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<code><span class="text-light-blue">GET</span> /usermanager/api/v1/users</code>
|
<code
|
||||||
|
><span class="text-light-blue">GET</span>
|
||||||
|
/usermanager/api/v1/users</code
|
||||||
|
>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Returns 201 CREATED (application/json)</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||||
|
Returns 201 CREATED (application/json)
|
||||||
|
</h5>
|
||||||
<code>JSON list of users</code>
|
<code>JSON list of users</code>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||||
<code>curl -X GET {{ request.url_root }}usermanager/api/v1/users -H "X-Api-Key: {{ g.user.wallets[0].inkey }}" </code>
|
<code
|
||||||
|
>curl -X GET {{ request.url_root }}usermanager/api/v1/users -H
|
||||||
|
"X-Api-Key: {{ g.user.wallets[0].inkey }}"
|
||||||
|
</code>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
<q-expansion-item group="api" dense expand-separator label="GET wallets">
|
<q-expansion-item group="api" dense expand-separator label="GET wallets">
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<code><span class="text-light-blue">GET</span> /usermanager/api/v1/wallets/<user_id></code>
|
<code
|
||||||
|
><span class="text-light-blue">GET</span>
|
||||||
|
/usermanager/api/v1/wallets/<user_id></code
|
||||||
|
>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
||||||
<code>{"X-Api-Key": <string>}</code>
|
<code>{"X-Api-Key": <string>}</code>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Returns 201 CREATED (application/json)</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||||
|
Returns 201 CREATED (application/json)
|
||||||
|
</h5>
|
||||||
<code>JSON wallet data</code>
|
<code>JSON wallet data</code>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||||
<code>curl -X GET {{ request.url_root }}usermanager/api/v1/wallets/<user_id> -H "X-Api-Key: {{ g.user.wallets[0].inkey }}" </code>
|
<code
|
||||||
|
>curl -X GET {{ request.url_root
|
||||||
|
}}usermanager/api/v1/wallets/<user_id> -H "X-Api-Key: {{
|
||||||
|
g.user.wallets[0].inkey }}"
|
||||||
|
</code>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
<q-expansion-item group="api" dense expand-separator label="GET transactions">
|
<q-expansion-item group="api" dense expand-separator label="GET transactions">
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<code><span class="text-light-blue">GET</span> /usermanager/api/v1/wallets<wallet_id></code>
|
<code
|
||||||
|
><span class="text-light-blue">GET</span>
|
||||||
|
/usermanager/api/v1/wallets<wallet_id></code
|
||||||
|
>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
||||||
<code>{"X-Api-Key": <string>}</code>
|
<code>{"X-Api-Key": <string>}</code>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Returns 201 CREATED (application/json)</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||||
|
Returns 201 CREATED (application/json)
|
||||||
|
</h5>
|
||||||
<code>JSON a wallets transactions</code>
|
<code>JSON a wallets transactions</code>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||||
<code>curl -X GET {{ request.url_root }}usermanager/api/v1/wallets<wallet_id> -H "X-Api-Key: {{ g.user.wallets[0].inkey }}" </code>
|
<code
|
||||||
|
>curl -X GET {{ request.url_root
|
||||||
|
}}usermanager/api/v1/wallets<wallet_id> -H "X-Api-Key: {{
|
||||||
|
g.user.wallets[0].inkey }}"
|
||||||
|
</code>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
<q-expansion-item group="api" dense expand-separator label="POST user + initial wallet">
|
<q-expansion-item
|
||||||
|
group="api"
|
||||||
|
dense
|
||||||
|
expand-separator
|
||||||
|
label="POST user + initial wallet"
|
||||||
|
>
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<code><span class="text-light-green">POST</span> /usermanager/api/v1/users</code>
|
<code
|
||||||
|
><span class="text-light-green">POST</span>
|
||||||
|
/usermanager/api/v1/users</code
|
||||||
|
>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
||||||
<code>{"X-Api-Key": <string>, "Content-type": "application/json"}</code>
|
<code
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json) - "admin_id" is a YOUR user ID</h5>
|
>{"X-Api-Key": <string>, "Content-type":
|
||||||
<code>{"admin_id": <string>, "user_name": <string>, "wallet_name": <string>}</code>
|
"application/json"}</code
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Returns 201 CREATED (application/json)</h5>
|
>
|
||||||
<code>{"checking_id": <string>,"payment_request": <string>}</code>
|
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||||
|
Body (application/json) - "admin_id" is a YOUR user ID
|
||||||
|
</h5>
|
||||||
|
<code
|
||||||
|
>{"admin_id": <string>, "user_name": <string>,
|
||||||
|
"wallet_name": <string>}</code
|
||||||
|
>
|
||||||
|
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||||
|
Returns 201 CREATED (application/json)
|
||||||
|
</h5>
|
||||||
|
<code
|
||||||
|
>{"checking_id": <string>,"payment_request":
|
||||||
|
<string>}</code
|
||||||
|
>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||||
<code>curl -X POST {{ request.url_root }}usermanager/api/v1/users -d '{"admin_id": "{{ g.user.id }}", "wallet_name": <string>, "user_name": <string>}' -H "X-Api-Key: {{ g.user.wallets[0].inkey }}" -H "Content-type: application/json"
|
<code
|
||||||
|
>curl -X POST {{ request.url_root }}usermanager/api/v1/users -d
|
||||||
|
'{"admin_id": "{{ g.user.id }}", "wallet_name": <string>,
|
||||||
|
"user_name": <string>}' -H "X-Api-Key: {{
|
||||||
|
g.user.wallets[0].inkey }}" -H "Content-type: application/json"
|
||||||
</code>
|
</code>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|
@ -81,41 +138,78 @@
|
||||||
<q-expansion-item group="api" dense expand-separator label="POST wallet">
|
<q-expansion-item group="api" dense expand-separator label="POST wallet">
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<code><span class="text-light-green">POST</span> /usermanager/api/v1/wallets</code>
|
<code
|
||||||
|
><span class="text-light-green">POST</span>
|
||||||
|
/usermanager/api/v1/wallets</code
|
||||||
|
>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
||||||
<code>{"X-Api-Key": <string>, "Content-type": "application/json"}</code>
|
<code
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json) - "admin_id" is a YOUR user ID</h5>
|
>{"X-Api-Key": <string>, "Content-type":
|
||||||
<code>{"user_id": <string>, "wallet_name": <string>, "admin_id": <string>}</code>
|
"application/json"}</code
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Returns 201 CREATED (application/json)</h5>
|
>
|
||||||
<code>{"checking_id": <string>,"payment_request": <string>}</code>
|
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||||
|
Body (application/json) - "admin_id" is a YOUR user ID
|
||||||
|
</h5>
|
||||||
|
<code
|
||||||
|
>{"user_id": <string>, "wallet_name": <string>,
|
||||||
|
"admin_id": <string>}</code
|
||||||
|
>
|
||||||
|
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||||
|
Returns 201 CREATED (application/json)
|
||||||
|
</h5>
|
||||||
|
<code
|
||||||
|
>{"checking_id": <string>,"payment_request":
|
||||||
|
<string>}</code
|
||||||
|
>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||||
<code>curl -X POST {{ request.url_root }}usermanager/api/v1/wallets -d '{"user_id": <string>, "wallet_name": <string>, "admin_id": "{{ g.user.id }}"}' -H "X-Api-Key: {{ g.user.wallets[0].inkey }}" -H "Content-type: application/json"
|
<code
|
||||||
|
>curl -X POST {{ request.url_root }}usermanager/api/v1/wallets -d
|
||||||
|
'{"user_id": <string>, "wallet_name": <string>,
|
||||||
|
"admin_id": "{{ g.user.id }}"}' -H "X-Api-Key: {{
|
||||||
|
g.user.wallets[0].inkey }}" -H "Content-type: application/json"
|
||||||
</code>
|
</code>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
<q-expansion-item group="api" dense expand-separator label="DELETE user and their wallets">
|
<q-expansion-item
|
||||||
|
group="api"
|
||||||
|
dense
|
||||||
|
expand-separator
|
||||||
|
label="DELETE user and their wallets"
|
||||||
|
>
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<code><span class="text-red">DELETE</span> /usermanager/api/v1/users/<user_id></code>
|
<code
|
||||||
|
><span class="text-red">DELETE</span>
|
||||||
|
/usermanager/api/v1/users/<user_id></code
|
||||||
|
>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
||||||
<code>{"X-Api-Key": <string>}</code>
|
<code>{"X-Api-Key": <string>}</code>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||||
<code>curl -X DELETE {{ request.url_root }}usermanager/api/v1/users/<user_id> -H "X-Api-Key: {{ g.user.wallets[0].inkey }}" </code>
|
<code
|
||||||
|
>curl -X DELETE {{ request.url_root
|
||||||
|
}}usermanager/api/v1/users/<user_id> -H "X-Api-Key: {{
|
||||||
|
g.user.wallets[0].inkey }}"
|
||||||
|
</code>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
<q-expansion-item group="api" dense expand-separator label="DELETE wallet">
|
<q-expansion-item group="api" dense expand-separator label="DELETE wallet">
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<code><span class="text-red">DELETE</span> /usermanager/api/v1/wallets/<wallet_id></code>
|
<code
|
||||||
|
><span class="text-red">DELETE</span>
|
||||||
|
/usermanager/api/v1/wallets/<wallet_id></code
|
||||||
|
>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
||||||
<code>{"X-Api-Key": <string>}</code>
|
<code>{"X-Api-Key": <string>}</code>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||||
<code>curl -X DELETE {{ request.url_root }}usermanager/api/v1/wallets/<wallet_id> -H "X-Api-Key: {{ g.user.wallets[0].inkey }}" </code>
|
<code
|
||||||
|
>curl -X DELETE {{ request.url_root
|
||||||
|
}}usermanager/api/v1/wallets/<wallet_id> -H "X-Api-Key: {{
|
||||||
|
g.user.wallets[0].inkey }}"
|
||||||
|
</code>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
|
|
||||||
|
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,14 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %} {% from "macros.jinja" import window_vars with context
|
||||||
|
%} {% block page %}
|
||||||
{% from "macros.jinja" import window_vars with context %}
|
<div class="row q-col-gutter-md">
|
||||||
|
|
||||||
|
|
||||||
{% block page %}
|
|
||||||
<div class="row q-col-gutter-md">
|
|
||||||
<div class="col-12 col-md-8 col-lg-7 q-gutter-y-md">
|
<div class="col-12 col-md-8 col-lg-7 q-gutter-y-md">
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<q-btn unelevated color="deep-purple" @click="userDialog.show = true">New User</q-btn>
|
<q-btn unelevated color="deep-purple" @click="userDialog.show = true"
|
||||||
<q-btn unelevated color="deep-purple" @click="walletDialog.show = true">New Wallet
|
>New User</q-btn
|
||||||
|
>
|
||||||
|
<q-btn unelevated color="deep-purple" @click="walletDialog.show = true"
|
||||||
|
>New Wallet
|
||||||
</q-btn>
|
</q-btn>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|
@ -21,22 +20,23 @@
|
||||||
<h5 class="text-subtitle1 q-my-none">Users</h5>
|
<h5 class="text-subtitle1 q-my-none">Users</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<q-btn flat color="grey" @click="exportUsersCSV">Export to CSV</q-btn>
|
<q-btn flat color="grey" @click="exportUsersCSV"
|
||||||
|
>Export to CSV</q-btn
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<q-table dense flat
|
<q-table
|
||||||
|
dense
|
||||||
|
flat
|
||||||
:data="users"
|
:data="users"
|
||||||
row-key="id"
|
row-key="id"
|
||||||
:columns="usersTable.columns"
|
:columns="usersTable.columns"
|
||||||
:pagination.sync="usersTable.pagination">
|
:pagination.sync="usersTable.pagination"
|
||||||
|
>
|
||||||
{% raw %}
|
{% raw %}
|
||||||
<template v-slot:header="props">
|
<template v-slot:header="props">
|
||||||
<q-tr :props="props">
|
<q-tr :props="props">
|
||||||
<q-th
|
<q-th v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
v-for="col in props.cols"
|
|
||||||
:key="col.name"
|
|
||||||
:props="props"
|
|
||||||
>
|
|
||||||
{{ col.label }}
|
{{ col.label }}
|
||||||
</q-th>
|
</q-th>
|
||||||
<q-th auto-width></q-th>
|
<q-th auto-width></q-th>
|
||||||
|
|
@ -44,16 +44,18 @@
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:body="props">
|
<template v-slot:body="props">
|
||||||
<q-tr :props="props">
|
<q-tr :props="props">
|
||||||
<q-td
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
v-for="col in props.cols"
|
|
||||||
:key="col.name"
|
|
||||||
:props="props"
|
|
||||||
>
|
|
||||||
{{ col.value }}
|
{{ col.value }}
|
||||||
</q-td>
|
</q-td>
|
||||||
<q-td auto-width>
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
<q-btn flat dense size="xs" @click="deleteUser(props.row.id)" icon="cancel" color="pink"></q-btn>
|
flat
|
||||||
|
dense
|
||||||
|
size="xs"
|
||||||
|
@click="deleteUser(props.row.id)"
|
||||||
|
icon="cancel"
|
||||||
|
color="pink"
|
||||||
|
></q-btn>
|
||||||
</q-td>
|
</q-td>
|
||||||
</q-tr>
|
</q-tr>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -69,23 +71,24 @@
|
||||||
<h5 class="text-subtitle1 q-my-none">Wallets</h5>
|
<h5 class="text-subtitle1 q-my-none">Wallets</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<q-btn flat color="grey" @click="exportWalletsCSV">Export to CSV</q-btn>
|
<q-btn flat color="grey" @click="exportWalletsCSV"
|
||||||
|
>Export to CSV</q-btn
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<q-table dense flat
|
<q-table
|
||||||
|
dense
|
||||||
|
flat
|
||||||
:data="wallets"
|
:data="wallets"
|
||||||
row-key="id"
|
row-key="id"
|
||||||
:columns="walletsTable.columns"
|
:columns="walletsTable.columns"
|
||||||
:pagination.sync="walletsTable.pagination">
|
:pagination.sync="walletsTable.pagination"
|
||||||
|
>
|
||||||
{% raw %}
|
{% raw %}
|
||||||
<template v-slot:header="props">
|
<template v-slot:header="props">
|
||||||
<q-tr :props="props">
|
<q-tr :props="props">
|
||||||
<q-th auto-width></q-th>
|
<q-th auto-width></q-th>
|
||||||
<q-th
|
<q-th v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
v-for="col in props.cols"
|
|
||||||
:key="col.name"
|
|
||||||
:props="props"
|
|
||||||
>
|
|
||||||
{{ col.label }}
|
{{ col.label }}
|
||||||
</q-th>
|
</q-th>
|
||||||
<q-th auto-width></q-th>
|
<q-th auto-width></q-th>
|
||||||
|
|
@ -94,23 +97,32 @@
|
||||||
<template v-slot:body="props">
|
<template v-slot:body="props">
|
||||||
<q-tr :props="props">
|
<q-tr :props="props">
|
||||||
<q-td auto-width>
|
<q-td auto-width>
|
||||||
<q-btn unelevated dense size="xs" icon="account_balance_wallet" :color="($q.dark.isActive) ? 'grey-7' : 'grey-5'" type="a" :href="props.row.walllink" target="_blank"></q-btn>
|
<q-btn
|
||||||
|
unelevated
|
||||||
|
dense
|
||||||
|
size="xs"
|
||||||
|
icon="account_balance_wallet"
|
||||||
|
:color="($q.dark.isActive) ? 'grey-7' : 'grey-5'"
|
||||||
|
type="a"
|
||||||
|
:href="props.row.walllink"
|
||||||
|
target="_blank"
|
||||||
|
></q-btn>
|
||||||
<q-tooltip>
|
<q-tooltip>
|
||||||
Link to wallet
|
Link to wallet
|
||||||
</q-tooltip>
|
</q-tooltip>
|
||||||
|
|
||||||
</q-td>
|
</q-td>
|
||||||
<q-td
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
v-for="col in props.cols"
|
|
||||||
:key="col.name"
|
|
||||||
:props="props"
|
|
||||||
>
|
|
||||||
|
|
||||||
{{ col.value }}
|
{{ col.value }}
|
||||||
</q-td>
|
</q-td>
|
||||||
<q-td auto-width>
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
<q-btn flat dense size="xs" @click="deleteWallet(props.row.id)" icon="cancel" color="pink"></q-btn>
|
flat
|
||||||
|
dense
|
||||||
|
size="xs"
|
||||||
|
@click="deleteWallet(props.row.id)"
|
||||||
|
icon="cancel"
|
||||||
|
color="pink"
|
||||||
|
></q-btn>
|
||||||
</q-td>
|
</q-td>
|
||||||
</q-tr>
|
</q-tr>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -118,8 +130,6 @@
|
||||||
</q-table>
|
</q-table>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-12 col-md-4 col-lg-5 q-gutter-y-md">
|
<div class="col-12 col-md-4 col-lg-5 q-gutter-y-md">
|
||||||
|
|
@ -136,62 +146,75 @@
|
||||||
</q-card>
|
</q-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<q-dialog v-model="userDialog.show" position="top">
|
<q-dialog v-model="userDialog.show" position="top">
|
||||||
<q-card class="q-pa-lg q-pt-xl" style="width: 500px">
|
<q-card class="q-pa-lg q-pt-xl" style="width: 500px;">
|
||||||
<q-form @submit="sendUserFormData" class="q-gutter-md">
|
<q-form @submit="sendUserFormData" class="q-gutter-md">
|
||||||
<q-input filled dense
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
v-model.trim="userDialog.data.usrname"
|
v-model.trim="userDialog.data.usrname"
|
||||||
label="Username"></q-input>
|
label="Username"
|
||||||
<q-input filled dense
|
></q-input>
|
||||||
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
v-model.trim="userDialog.data.walname"
|
v-model.trim="userDialog.data.walname"
|
||||||
label="Initial wallet name"></q-input>
|
label="Initial wallet name"
|
||||||
|
></q-input>
|
||||||
|
|
||||||
<q-btn unelevated
|
<q-btn
|
||||||
|
unelevated
|
||||||
color="deep-purple"
|
color="deep-purple"
|
||||||
:disable="userDialog.data.walname == null"
|
:disable="userDialog.data.walname == null"
|
||||||
type="submit">Create User</q-btn>
|
type="submit"
|
||||||
|
>Create User</q-btn
|
||||||
|
>
|
||||||
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Cancel</q-btn>
|
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Cancel</q-btn>
|
||||||
</div>
|
|
||||||
</q-form>
|
</q-form>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<q-dialog v-model="walletDialog.show" position="top">
|
<q-dialog v-model="walletDialog.show" position="top">
|
||||||
<q-card class="q-pa-lg q-pt-xl" style="width: 500px">
|
<q-card class="q-pa-lg q-pt-xl" style="width: 500px;">
|
||||||
<q-form @submit="sendWalletFormData" class="q-gutter-md">
|
<q-form @submit="sendWalletFormData" class="q-gutter-md">
|
||||||
<q-select filled dense emit-value v-model="walletDialog.data.user" :options="userOptions" label="User *">
|
<q-select
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
emit-value
|
||||||
|
v-model="walletDialog.data.user"
|
||||||
|
:options="userOptions"
|
||||||
|
label="User *"
|
||||||
|
>
|
||||||
</q-select>
|
</q-select>
|
||||||
<q-input filled dense
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
v-model.trim="walletDialog.data.walname"
|
v-model.trim="walletDialog.data.walname"
|
||||||
label="Wallet name"></q-input>
|
label="Wallet name"
|
||||||
<q-btn unelevated
|
></q-input>
|
||||||
|
<q-btn
|
||||||
|
unelevated
|
||||||
color="deep-purple"
|
color="deep-purple"
|
||||||
:disable="walletDialog.data.walname == null"
|
:disable="walletDialog.data.walname == null"
|
||||||
type="submit">Create Wallet</q-btn>
|
type="submit"
|
||||||
|
>Create Wallet</q-btn
|
||||||
|
>
|
||||||
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Cancel</q-btn>
|
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Cancel</q-btn>
|
||||||
</div>
|
|
||||||
</q-form>
|
</q-form>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
|
</div>
|
||||||
|
{% endblock %} {% block scripts %} {{ window_vars(user) }}
|
||||||
</div>
|
<script>
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block scripts %}
|
|
||||||
{{ window_vars(user) }}
|
|
||||||
<script>
|
|
||||||
|
|
||||||
var mapUserManager = function (obj) {
|
var mapUserManager = function (obj) {
|
||||||
|
obj.date = Quasar.utils.date.formatDate(
|
||||||
obj.date = Quasar.utils.date.formatDate(new Date(obj.time * 1000), 'YYYY-MM-DD HH:mm');
|
new Date(obj.time * 1000),
|
||||||
obj.fsat = new Intl.NumberFormat(LOCALE).format(obj.amount);
|
'YYYY-MM-DD HH:mm'
|
||||||
obj.walllink = ['../wallet?usr=', obj.user, '&wal=', obj.id].join('');
|
)
|
||||||
obj._data = _.clone(obj);
|
obj.fsat = new Intl.NumberFormat(LOCALE).format(obj.amount)
|
||||||
return obj;
|
obj.walllink = ['../wallet?usr=', obj.user, '&wal=', obj.id].join('')
|
||||||
|
obj._data = _.clone(obj)
|
||||||
|
return obj
|
||||||
}
|
}
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
|
|
@ -199,7 +222,6 @@
|
||||||
mixins: [windowMixin],
|
mixins: [windowMixin],
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
|
|
||||||
wallets: [],
|
wallets: [],
|
||||||
users: [],
|
users: [],
|
||||||
|
|
||||||
|
|
@ -217,7 +239,12 @@
|
||||||
{name: 'id', align: 'left', label: 'ID', field: 'id'},
|
{name: 'id', align: 'left', label: 'ID', field: 'id'},
|
||||||
{name: 'name', align: 'left', label: 'Name', field: 'name'},
|
{name: 'name', align: 'left', label: 'Name', field: 'name'},
|
||||||
{name: 'user', align: 'left', label: 'User', field: 'user'},
|
{name: 'user', align: 'left', label: 'User', field: 'user'},
|
||||||
{name: 'adminkey', align: 'left', label: 'Admin Key', field: 'adminkey'},
|
{
|
||||||
|
name: 'adminkey',
|
||||||
|
align: 'left',
|
||||||
|
label: 'Admin Key',
|
||||||
|
field: 'adminkey'
|
||||||
|
},
|
||||||
{name: 'inkey', align: 'left', label: 'Invoice Key', field: 'inkey'}
|
{name: 'inkey', align: 'left', label: 'Invoice Key', field: 'inkey'}
|
||||||
],
|
],
|
||||||
pagination: {
|
pagination: {
|
||||||
|
|
@ -231,8 +258,8 @@
|
||||||
userDialog: {
|
userDialog: {
|
||||||
show: false,
|
show: false,
|
||||||
data: {}
|
data: {}
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
userOptions: function () {
|
userOptions: function () {
|
||||||
|
|
@ -241,176 +268,186 @@
|
||||||
return {
|
return {
|
||||||
value: String(obj.id),
|
value: String(obj.id),
|
||||||
label: String(obj.id)
|
label: String(obj.id)
|
||||||
|
}
|
||||||
};
|
})
|
||||||
});
|
}
|
||||||
},
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
///////////////Users////////////////////////////
|
///////////////Users////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
getUsers: function () {
|
getUsers: function () {
|
||||||
|
var self = this
|
||||||
|
|
||||||
var self = this;
|
LNbits.api
|
||||||
|
.request(
|
||||||
LNbits.api.request(
|
|
||||||
'GET',
|
'GET',
|
||||||
'/usermanager/api/v1/users',
|
'/usermanager/api/v1/users',
|
||||||
this.g.user.wallets[0].inkey
|
this.g.user.wallets[0].inkey
|
||||||
).then(function (response) {
|
)
|
||||||
|
.then(function (response) {
|
||||||
|
|
||||||
self.users = response.data.map(function (obj) {
|
self.users = response.data.map(function (obj) {
|
||||||
|
return mapUserManager(obj)
|
||||||
return mapUserManager(obj);
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
openUserUpdateDialog: function (linkId) {
|
openUserUpdateDialog: function (linkId) {
|
||||||
var link = _.findWhere(this.users, {id: linkId});
|
var link = _.findWhere(this.users, {id: linkId})
|
||||||
|
|
||||||
this.userDialog.data = _.clone(link._data);
|
this.userDialog.data = _.clone(link._data)
|
||||||
this.userDialog.show = true;
|
this.userDialog.show = true
|
||||||
},
|
},
|
||||||
sendUserFormData: function () {
|
sendUserFormData: function () {
|
||||||
if (this.userDialog.data.id){}
|
if (this.userDialog.data.id) {
|
||||||
else{
|
} else {
|
||||||
|
|
||||||
var data = {
|
var data = {
|
||||||
|
|
||||||
admin_id: this.g.user.id,
|
admin_id: this.g.user.id,
|
||||||
user_name: this.userDialog.data.usrname,
|
user_name: this.userDialog.data.usrname,
|
||||||
wallet_name: this.userDialog.data.walname
|
wallet_name: this.userDialog.data.walname
|
||||||
};}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{ this.createUser(data); }
|
{
|
||||||
|
this.createUser(data)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
createUser: function (data) {
|
createUser: function (data) {
|
||||||
var self = this;
|
var self = this
|
||||||
LNbits.api.request(
|
LNbits.api
|
||||||
|
.request(
|
||||||
'POST',
|
'POST',
|
||||||
'/usermanager/api/v1/users',
|
'/usermanager/api/v1/users',
|
||||||
this.g.user.wallets[0].inkey,
|
this.g.user.wallets[0].inkey,
|
||||||
data
|
data
|
||||||
).then(function (response) {
|
)
|
||||||
|
.then(function (response) {
|
||||||
self.users.push(mapUserManager(response.data));
|
self.users.push(mapUserManager(response.data))
|
||||||
self.userDialog.show = false;
|
self.userDialog.show = false
|
||||||
self.userDialog.data = {};
|
self.userDialog.data = {}
|
||||||
data = {};
|
data = {}
|
||||||
}).catch(function (error) {
|
})
|
||||||
LNbits.utils.notifyApiError(error);
|
.catch(function (error) {
|
||||||
});
|
LNbits.utils.notifyApiError(error)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
deleteUser: function (userId) {
|
deleteUser: function (userId) {
|
||||||
var self = this;
|
var self = this
|
||||||
|
|
||||||
console.log(userId)
|
console.log(userId)
|
||||||
LNbits.utils.confirmDialog(
|
LNbits.utils
|
||||||
'Are you sure you want to delete this User link?'
|
.confirmDialog('Are you sure you want to delete this User link?')
|
||||||
).onOk(function () {
|
.onOk(function () {
|
||||||
|
LNbits.api
|
||||||
LNbits.api.request(
|
.request(
|
||||||
'DELETE',
|
'DELETE',
|
||||||
'/usermanager/api/v1/users/' + userId,
|
'/usermanager/api/v1/users/' + userId,
|
||||||
self.g.user.wallets[0].inkey
|
self.g.user.wallets[0].inkey
|
||||||
).then(function (response) {
|
)
|
||||||
self.users = _.reject(self.users, function (obj) { return obj.id == userId; });
|
.then(function (response) {
|
||||||
}).catch(function (error) {
|
self.users = _.reject(self.users, function (obj) {
|
||||||
LNbits.utils.notifyApiError(error);
|
return obj.id == userId
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
LNbits.utils.notifyApiError(error)
|
||||||
|
})
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
exportUsersCSV: function () {
|
exportUsersCSV: function () {
|
||||||
LNbits.utils.exportCSV(this.usersTable.columns, this.users);
|
LNbits.utils.exportCSV(this.usersTable.columns, this.users)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
///////////////Wallets////////////////////////////
|
///////////////Wallets////////////////////////////
|
||||||
|
|
||||||
getWallets: function () {
|
getWallets: function () {
|
||||||
var self = this;
|
var self = this
|
||||||
|
|
||||||
LNbits.api.request(
|
LNbits.api
|
||||||
|
.request(
|
||||||
'GET',
|
'GET',
|
||||||
'/usermanager/api/v1/wallets',
|
'/usermanager/api/v1/wallets',
|
||||||
this.g.user.wallets[0].inkey
|
this.g.user.wallets[0].inkey
|
||||||
).then(function (response) {
|
)
|
||||||
|
.then(function (response) {
|
||||||
self.wallets = response.data.map(function (obj) {
|
self.wallets = response.data.map(function (obj) {
|
||||||
return mapUserManager(obj);
|
return mapUserManager(obj)
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
openWalletUpdateDialog: function (linkId) {
|
openWalletUpdateDialog: function (linkId) {
|
||||||
var link = _.findWhere(this.users, {id: linkId});
|
var link = _.findWhere(this.users, {id: linkId})
|
||||||
|
|
||||||
this.walletDialog.data = _.clone(link._data);
|
this.walletDialog.data = _.clone(link._data)
|
||||||
this.walletDialog.show = true;
|
this.walletDialog.show = true
|
||||||
},
|
},
|
||||||
sendWalletFormData: function () {
|
sendWalletFormData: function () {
|
||||||
if (this.walletDialog.data.id){}
|
if (this.walletDialog.data.id) {
|
||||||
else{
|
} else {
|
||||||
var data = {
|
var data = {
|
||||||
user_id: this.walletDialog.data.user,
|
user_id: this.walletDialog.data.user,
|
||||||
admin_id: this.g.user.id,
|
admin_id: this.g.user.id,
|
||||||
wallet_name: this.walletDialog.data.walname
|
wallet_name: this.walletDialog.data.walname
|
||||||
};}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{ this.createWallet(data); }
|
{
|
||||||
|
this.createWallet(data)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
createWallet: function (data) {
|
createWallet: function (data) {
|
||||||
var self = this;
|
var self = this
|
||||||
LNbits.api.request(
|
LNbits.api
|
||||||
|
.request(
|
||||||
'POST',
|
'POST',
|
||||||
'/usermanager/api/v1/wallets',
|
'/usermanager/api/v1/wallets',
|
||||||
this.g.user.wallets[0].inkey,
|
this.g.user.wallets[0].inkey,
|
||||||
data
|
data
|
||||||
).then(function (response) {
|
)
|
||||||
self.wallets.push(mapUserManager(response.data));
|
.then(function (response) {
|
||||||
self.walletDialog.show = false;
|
self.wallets.push(mapUserManager(response.data))
|
||||||
self.walletDialog.data = {};
|
self.walletDialog.show = false
|
||||||
data = {};
|
self.walletDialog.data = {}
|
||||||
}).catch(function (error) {
|
data = {}
|
||||||
LNbits.utils.notifyApiError(error);
|
})
|
||||||
});
|
.catch(function (error) {
|
||||||
|
LNbits.utils.notifyApiError(error)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
deleteWallet: function (userId) {
|
deleteWallet: function (userId) {
|
||||||
var self = this;
|
var self = this
|
||||||
|
|
||||||
LNbits.utils.confirmDialog(
|
LNbits.utils
|
||||||
'Are you sure you want to delete this wallet link?'
|
.confirmDialog('Are you sure you want to delete this wallet link?')
|
||||||
).onOk(function () {
|
.onOk(function () {
|
||||||
LNbits.api.request(
|
LNbits.api
|
||||||
|
.request(
|
||||||
'DELETE',
|
'DELETE',
|
||||||
'/usermanager/api/v1/wallets/' + userId,
|
'/usermanager/api/v1/wallets/' + userId,
|
||||||
self.g.user.wallets[0].inkey
|
self.g.user.wallets[0].inkey
|
||||||
).then(function (response) {
|
)
|
||||||
self.wallets = _.reject(self.wallets, function (obj) { return obj.id == userId; });
|
.then(function (response) {
|
||||||
}).catch(function (error) {
|
self.wallets = _.reject(self.wallets, function (obj) {
|
||||||
LNbits.utils.notifyApiError(error);
|
return obj.id == userId
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
LNbits.utils.notifyApiError(error)
|
||||||
|
})
|
||||||
|
})
|
||||||
},
|
},
|
||||||
exportWalletsCSV: function () {
|
exportWalletsCSV: function () {
|
||||||
LNbits.utils.exportCSV(this.walletsTable.columns, this.wallets);
|
LNbits.utils.exportCSV(this.walletsTable.columns, this.wallets)
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
if (this.g.user.wallets.length) {
|
if (this.g.user.wallets.length) {
|
||||||
this.getUsers();
|
this.getUsers()
|
||||||
this.getWallets();
|
this.getWallets()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
</script>
|
||||||
</script>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -4,64 +4,126 @@
|
||||||
label="API info"
|
label="API info"
|
||||||
:content-inset-level="0.5"
|
:content-inset-level="0.5"
|
||||||
>
|
>
|
||||||
<q-expansion-item group="api" dense expand-separator label="List withdraw links">
|
<q-expansion-item
|
||||||
|
group="api"
|
||||||
|
dense
|
||||||
|
expand-separator
|
||||||
|
label="List withdraw links"
|
||||||
|
>
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<code><span class="text-light-blue">GET</span> /withdraw/api/v1/links</code>
|
<code
|
||||||
|
><span class="text-light-blue">GET</span> /withdraw/api/v1/links</code
|
||||||
|
>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
||||||
<code>{"X-Api-Key": <invoice_key>}</code><br />
|
<code>{"X-Api-Key": <invoice_key>}</code><br />
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Returns 201 CREATED (application/json)</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||||
|
Returns 201 CREATED (application/json)
|
||||||
|
</h5>
|
||||||
<code>{"lnurl": <string>}</code>
|
<code>{"lnurl": <string>}</code>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||||
<code>curl -X GET {{ request.url_root }}withdraw/api/v1/links -H "X-Api-Key: <invoice_key>" </code>
|
<code
|
||||||
</q-card-section>
|
>curl -X GET {{ request.url_root }}withdraw/api/v1/links -H
|
||||||
</q-card>
|
"X-Api-Key: <invoice_key>"
|
||||||
</q-expansion-item>
|
|
||||||
<q-expansion-item group="api" dense expand-separator label="Create a withdraw link">
|
|
||||||
<q-card>
|
|
||||||
<q-card-section>
|
|
||||||
<code><span class="text-light-green">POST</span> /withdraw/api/v1/links</code>
|
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
|
||||||
<code>{"X-Api-Key": <admin_key>}</code><br />
|
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
|
|
||||||
<code>{"title": <string>, "min_withdrawable": <integer>, "max_withdrawable": <integer>, "uses": <integer>, "wait_time": <integer>, "is_unique": <boolean>}</code>
|
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Returns 201 CREATED (application/json)</h5>
|
|
||||||
<code>{"lnurl": <string>}</code>
|
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
|
||||||
<code>curl -X POST {{ request.url_root }}withdraw/api/v1/links -d '{"title": <string>, "min_withdrawable": <integer>, "max_withdrawable": <integer>, "uses": <integer>, "wait_time": <integer>, "is_unique": <boolean>}' -H "Content-type: application/json" -H "X-Api-Key: <admin_key>"
|
|
||||||
</code>
|
</code>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
<q-expansion-item group="api" dense expand-separator label="Update a withdraw link">
|
<q-expansion-item
|
||||||
|
group="api"
|
||||||
|
dense
|
||||||
|
expand-separator
|
||||||
|
label="Create a withdraw link"
|
||||||
|
>
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<code><span class="text-light-blue">PUT</span> /withdraw/api/v1/links/<withdraw_id></code>
|
<code
|
||||||
|
><span class="text-light-green">POST</span>
|
||||||
|
/withdraw/api/v1/links</code
|
||||||
|
>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
||||||
<code>{"X-Api-Key": <admin_key>}</code><br />
|
<code>{"X-Api-Key": <admin_key>}</code><br />
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
|
||||||
<code>{"title": <string>, "min_withdrawable": <integer>, "max_withdrawable": <integer>, "uses": <integer>, "wait_time": <integer>, "is_unique": <boolean>}</code>
|
<code
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Returns 201 CREATED (application/json)</h5>
|
>{"title": <string>, "min_withdrawable": <integer>,
|
||||||
|
"max_withdrawable": <integer>, "uses": <integer>,
|
||||||
|
"wait_time": <integer>, "is_unique": <boolean>}</code
|
||||||
|
>
|
||||||
|
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||||
|
Returns 201 CREATED (application/json)
|
||||||
|
</h5>
|
||||||
<code>{"lnurl": <string>}</code>
|
<code>{"lnurl": <string>}</code>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||||
<code>curl -X PUT {{ request.url_root }}withdraw/api/v1/links/<withdraw_id> -d '{"title": <string>, "min_withdrawable": <integer>, "max_withdrawable": <integer>, "uses": <integer>, "wait_time": <integer>, "is_unique": <boolean>}' -H "Content-type: application/json" -H "X-Api-Key: <admin_key>"
|
<code
|
||||||
|
>curl -X POST {{ request.url_root }}withdraw/api/v1/links -d
|
||||||
|
'{"title": <string>, "min_withdrawable": <integer>,
|
||||||
|
"max_withdrawable": <integer>, "uses": <integer>,
|
||||||
|
"wait_time": <integer>, "is_unique": <boolean>}' -H
|
||||||
|
"Content-type: application/json" -H "X-Api-Key: <admin_key>"
|
||||||
</code>
|
</code>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
<q-expansion-item group="api" dense expand-separator label="Delete a withdraw link" class="q-pb-md">
|
<q-expansion-item
|
||||||
|
group="api"
|
||||||
|
dense
|
||||||
|
expand-separator
|
||||||
|
label="Update a withdraw link"
|
||||||
|
>
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<code><span class="text-light-green">DELETE</span> /withdraw/api/v1/links/<withdraw_id></code>
|
<code
|
||||||
|
><span class="text-light-blue">PUT</span>
|
||||||
|
/withdraw/api/v1/links/<withdraw_id></code
|
||||||
|
>
|
||||||
|
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
||||||
|
<code>{"X-Api-Key": <admin_key>}</code><br />
|
||||||
|
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
|
||||||
|
<code
|
||||||
|
>{"title": <string>, "min_withdrawable": <integer>,
|
||||||
|
"max_withdrawable": <integer>, "uses": <integer>,
|
||||||
|
"wait_time": <integer>, "is_unique": <boolean>}</code
|
||||||
|
>
|
||||||
|
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||||
|
Returns 201 CREATED (application/json)
|
||||||
|
</h5>
|
||||||
|
<code>{"lnurl": <string>}</code>
|
||||||
|
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||||
|
<code
|
||||||
|
>curl -X PUT {{ request.url_root
|
||||||
|
}}withdraw/api/v1/links/<withdraw_id> -d '{"title":
|
||||||
|
<string>, "min_withdrawable": <integer>,
|
||||||
|
"max_withdrawable": <integer>, "uses": <integer>,
|
||||||
|
"wait_time": <integer>, "is_unique": <boolean>}' -H
|
||||||
|
"Content-type: application/json" -H "X-Api-Key: <admin_key>"
|
||||||
|
</code>
|
||||||
|
</q-card-section>
|
||||||
|
</q-card>
|
||||||
|
</q-expansion-item>
|
||||||
|
<q-expansion-item
|
||||||
|
group="api"
|
||||||
|
dense
|
||||||
|
expand-separator
|
||||||
|
label="Delete a withdraw link"
|
||||||
|
class="q-pb-md"
|
||||||
|
>
|
||||||
|
<q-card>
|
||||||
|
<q-card-section>
|
||||||
|
<code
|
||||||
|
><span class="text-light-green">DELETE</span>
|
||||||
|
/withdraw/api/v1/links/<withdraw_id></code
|
||||||
|
>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
||||||
<code>{"X-Api-Key": <admin_key>}</code><br />
|
<code>{"X-Api-Key": <admin_key>}</code><br />
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Returns 201 NO_CONTENT</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Returns 201 NO_CONTENT</h5>
|
||||||
<code>{"lnurl": <string>}</code>
|
<code>{"lnurl": <string>}</code>
|
||||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||||
<code>curl -X DELETE {{ request.url_root }}withdraw/api/v1/links/<withdraw_id> -H "X-Api-Key: <admin_key>"
|
<code
|
||||||
|
>curl -X DELETE {{ request.url_root
|
||||||
|
}}withdraw/api/v1/links/<withdraw_id> -H "X-Api-Key:
|
||||||
|
<admin_key>"
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,29 @@
|
||||||
<q-expansion-item
|
<q-expansion-item group="extras" icon="info" label="Powered by LNURL">
|
||||||
group="extras"
|
|
||||||
icon="info"
|
|
||||||
label="Powered by LNURL">
|
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<p><b>WARNING: LNURL must be used over https or TOR</b><br/> LNURL is a range of lightning-network standards that allow us to use lightning-network differently. An LNURL withdraw is the permission for someone to pull a certain amount of funds from a lightning wallet. In this extension time is also added - an amount can be withdraw over a period of time. A typical use case for an LNURL withdraw is a faucet, although it is a very powerful technology, with much further reaching implications. For example, an LNURL withdraw could be minted to pay for a subscription service.</p>
|
<p>
|
||||||
<p>Exploring LNURL and finding use cases, is really helping inform lightning protocol development, rather than the protocol dictating how lightning-network should be engaged with.</p>
|
<b>WARNING: LNURL must be used over https or TOR</b><br />
|
||||||
<small>Check <a href="https://github.com/fiatjaf/awesome-lnurl" target="_blank">Awesome LNURL</a> for further information.</small>
|
LNURL is a range of lightning-network standards that allow us to use
|
||||||
|
lightning-network differently. An LNURL withdraw is the permission for
|
||||||
|
someone to pull a certain amount of funds from a lightning wallet. In
|
||||||
|
this extension time is also added - an amount can be withdraw over a
|
||||||
|
period of time. A typical use case for an LNURL withdraw is a faucet,
|
||||||
|
although it is a very powerful technology, with much further reaching
|
||||||
|
implications. For example, an LNURL withdraw could be minted to pay for
|
||||||
|
a subscription service.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Exploring LNURL and finding use cases, is really helping inform
|
||||||
|
lightning protocol development, rather than the protocol dictating how
|
||||||
|
lightning-network should be engaged with.
|
||||||
|
</p>
|
||||||
|
<small
|
||||||
|
>Check
|
||||||
|
<a href="https://github.com/fiatjaf/awesome-lnurl" target="_blank"
|
||||||
|
>Awesome LNURL</a
|
||||||
|
>
|
||||||
|
for further information.</small
|
||||||
|
>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,5 @@
|
||||||
{% extends "public.html" %}
|
{% extends "public.html" %} {% block page %}
|
||||||
|
<div class="row q-col-gutter-md justify-center">
|
||||||
|
|
||||||
{% block page %}
|
|
||||||
<div class="row q-col-gutter-md justify-center">
|
|
||||||
<div class="col-12 col-sm-6 col-md-5 col-lg-4">
|
<div class="col-12 col-sm-6 col-md-5 col-lg-4">
|
||||||
<q-card class="q-pa-lg">
|
<q-card class="q-pa-lg">
|
||||||
<q-card-section class="q-pa-none">
|
<q-card-section class="q-pa-none">
|
||||||
|
|
@ -12,12 +9,18 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a href="lightning:{{ link.lnurl }}">
|
<a href="lightning:{{ link.lnurl }}">
|
||||||
<q-responsive :ratio="1" class="q-mx-md">
|
<q-responsive :ratio="1" class="q-mx-md">
|
||||||
<qrcode value="{{ link.lnurl }}" :options="{width: 800}" class="rounded-borders"></qrcode>
|
<qrcode
|
||||||
|
value="{{ link.lnurl }}"
|
||||||
|
:options="{width: 800}"
|
||||||
|
class="rounded-borders"
|
||||||
|
></qrcode>
|
||||||
</q-responsive>
|
</q-responsive>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="row q-mt-lg">
|
<div class="row q-mt-lg">
|
||||||
<q-btn outline color="grey" @click="copyText('{{ link.lnurl }}')">Copy LNURL</q-btn>
|
<q-btn outline color="grey" @click="copyText('{{ link.lnurl }}')"
|
||||||
|
>Copy LNURL</q-btn
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|
@ -25,8 +28,12 @@
|
||||||
<div class="col-12 col-sm-6 col-md-5 col-lg-4 q-gutter-y-md">
|
<div class="col-12 col-sm-6 col-md-5 col-lg-4 q-gutter-y-md">
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<h6 class="text-subtitle1 q-mb-sm q-mt-none">LNbits LNURL-withdraw link</h6>
|
<h6 class="text-subtitle1 q-mb-sm q-mt-none">
|
||||||
<p class="q-my-none">Use a LNURL compatible bitcoin wallet to claim the sats.</p>
|
LNbits LNURL-withdraw link
|
||||||
|
</h6>
|
||||||
|
<p class="q-my-none">
|
||||||
|
Use a LNURL compatible bitcoin wallet to claim the sats.
|
||||||
|
</p>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-section class="q-pa-none">
|
<q-card-section class="q-pa-none">
|
||||||
<q-separator></q-separator>
|
<q-separator></q-separator>
|
||||||
|
|
@ -36,17 +43,15 @@
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %} {% block scripts %}
|
||||||
|
<script src="{{ url_for('static', filename='vendor/vue-qrcode@1.0.2/vue-qrcode.min.js') }}"></script>
|
||||||
{% block scripts %}
|
<script>
|
||||||
<script src="{{ url_for('static', filename='vendor/vue-qrcode@1.0.2/vue-qrcode.min.js') }}"></script>
|
Vue.component(VueQrcode.name, VueQrcode)
|
||||||
<script>
|
|
||||||
Vue.component(VueQrcode.name, VueQrcode);
|
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
el: '#vue',
|
el: '#vue',
|
||||||
mixins: [windowMixin]
|
mixins: [windowMixin]
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,17 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %} {% from "macros.jinja" import window_vars with context
|
||||||
|
%} {% block scripts %} {{ window_vars(user) }}
|
||||||
{% from "macros.jinja" import window_vars with context %}
|
<script src="{{ url_for('static', filename='vendor/vue-qrcode@1.0.2/vue-qrcode.min.js') }}"></script>
|
||||||
|
{% assets filters='rjsmin', output='__bundle__/withdraw/index.js',
|
||||||
|
'withdraw/js/index.js' %}
|
||||||
{% block scripts %}
|
<script type="text/javascript" src="{{ ASSET_URL }}"></script>
|
||||||
{{ window_vars(user) }}
|
{% endassets %} {% endblock %} {% block page %}
|
||||||
<script src="{{ url_for('static', filename='vendor/vue-qrcode@1.0.2/vue-qrcode.min.js') }}"></script>
|
<div class="row q-col-gutter-md">
|
||||||
{% assets filters='rjsmin', output='__bundle__/withdraw/index.js',
|
|
||||||
'withdraw/js/index.js' %}
|
|
||||||
<script type="text/javascript" src="{{ ASSET_URL }}"></script>
|
|
||||||
{% endassets %}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block page %}
|
|
||||||
<div class="row q-col-gutter-md">
|
|
||||||
<div class="col-12 col-md-7 q-gutter-y-md">
|
<div class="col-12 col-md-7 q-gutter-y-md">
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<q-btn unelevated color="deep-purple" @click="formDialog.show = true">New withdraw link</q-btn>
|
<q-btn unelevated color="deep-purple" @click="formDialog.show = true"
|
||||||
|
>New withdraw link</q-btn
|
||||||
|
>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|
||||||
|
|
@ -31,20 +25,19 @@
|
||||||
<q-btn flat color="grey" @click="exportCSV">Export to CSV</q-btn>
|
<q-btn flat color="grey" @click="exportCSV">Export to CSV</q-btn>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<q-table dense flat
|
<q-table
|
||||||
|
dense
|
||||||
|
flat
|
||||||
:data="sortedWithdrawLinks"
|
:data="sortedWithdrawLinks"
|
||||||
row-key="id"
|
row-key="id"
|
||||||
:columns="withdrawLinksTable.columns"
|
:columns="withdrawLinksTable.columns"
|
||||||
:pagination.sync="withdrawLinksTable.pagination">
|
:pagination.sync="withdrawLinksTable.pagination"
|
||||||
|
>
|
||||||
{% raw %}
|
{% raw %}
|
||||||
<template v-slot:header="props">
|
<template v-slot:header="props">
|
||||||
<q-tr :props="props">
|
<q-tr :props="props">
|
||||||
<q-th auto-width></q-th>
|
<q-th auto-width></q-th>
|
||||||
<q-th
|
<q-th v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
v-for="col in props.cols"
|
|
||||||
:key="col.name"
|
|
||||||
:props="props"
|
|
||||||
>
|
|
||||||
{{ col.label }}
|
{{ col.label }}
|
||||||
</q-th>
|
</q-th>
|
||||||
<q-th auto-width></q-th>
|
<q-th auto-width></q-th>
|
||||||
|
|
@ -53,19 +46,45 @@
|
||||||
<template v-slot:body="props">
|
<template v-slot:body="props">
|
||||||
<q-tr :props="props">
|
<q-tr :props="props">
|
||||||
<q-td auto-width>
|
<q-td auto-width>
|
||||||
<q-btn unelevated dense size="xs" icon="launch" :color="($q.dark.isActive) ? 'grey-7' : 'grey-5'" type="a" :href="props.row.withdraw_url" target="_blank"></q-btn>
|
<q-btn
|
||||||
<q-btn unelevated dense size="xs" icon="visibility" :color="($q.dark.isActive) ? 'grey-7' : 'grey-5'" @click="openQrCodeDialog(props.row.id)"></q-btn>
|
unelevated
|
||||||
|
dense
|
||||||
|
size="xs"
|
||||||
|
icon="launch"
|
||||||
|
:color="($q.dark.isActive) ? 'grey-7' : 'grey-5'"
|
||||||
|
type="a"
|
||||||
|
:href="props.row.withdraw_url"
|
||||||
|
target="_blank"
|
||||||
|
></q-btn>
|
||||||
|
<q-btn
|
||||||
|
unelevated
|
||||||
|
dense
|
||||||
|
size="xs"
|
||||||
|
icon="visibility"
|
||||||
|
:color="($q.dark.isActive) ? 'grey-7' : 'grey-5'"
|
||||||
|
@click="openQrCodeDialog(props.row.id)"
|
||||||
|
></q-btn>
|
||||||
</q-td>
|
</q-td>
|
||||||
<q-td
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
v-for="col in props.cols"
|
|
||||||
:key="col.name"
|
|
||||||
:props="props"
|
|
||||||
>
|
|
||||||
{{ col.value }}
|
{{ col.value }}
|
||||||
</q-td>
|
</q-td>
|
||||||
<q-td auto-width>
|
<q-td auto-width>
|
||||||
<q-btn flat dense size="xs" @click="openUpdateDialog(props.row.id)" icon="edit" color="light-blue"></q-btn>
|
<q-btn
|
||||||
<q-btn flat dense size="xs" @click="deleteWithdrawLink(props.row.id)" icon="cancel" color="pink"></q-btn>
|
flat
|
||||||
|
dense
|
||||||
|
size="xs"
|
||||||
|
@click="openUpdateDialog(props.row.id)"
|
||||||
|
icon="edit"
|
||||||
|
color="light-blue"
|
||||||
|
></q-btn>
|
||||||
|
<q-btn
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
size="xs"
|
||||||
|
@click="deleteWithdrawLink(props.row.id)"
|
||||||
|
icon="cancel"
|
||||||
|
color="pink"
|
||||||
|
></q-btn>
|
||||||
</q-td>
|
</q-td>
|
||||||
</q-tr>
|
</q-tr>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -78,7 +97,9 @@
|
||||||
<div class="col-12 col-md-5 q-gutter-y-md">
|
<div class="col-12 col-md-5 q-gutter-y-md">
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<h6 class="text-subtitle1 q-my-none">LNbits LNURL-withdraw extension</h6>
|
<h6 class="text-subtitle1 q-my-none">
|
||||||
|
LNbits LNURL-withdraw extension
|
||||||
|
</h6>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-section class="q-pa-none">
|
<q-card-section class="q-pa-none">
|
||||||
<q-separator></q-separator>
|
<q-separator></q-separator>
|
||||||
|
|
@ -94,53 +115,97 @@
|
||||||
<q-dialog v-model="formDialog.show" position="top" @hide="closeFormDialog">
|
<q-dialog v-model="formDialog.show" position="top" @hide="closeFormDialog">
|
||||||
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
|
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
|
||||||
<q-form @submit="sendFormData" class="q-gutter-md">
|
<q-form @submit="sendFormData" class="q-gutter-md">
|
||||||
<q-select filled dense emit-value v-model="formDialog.data.wallet" :options="g.user.walletOptions" label="Wallet *">
|
<q-select
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
emit-value
|
||||||
|
v-model="formDialog.data.wallet"
|
||||||
|
:options="g.user.walletOptions"
|
||||||
|
label="Wallet *"
|
||||||
|
>
|
||||||
</q-select>
|
</q-select>
|
||||||
<q-input filled dense
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
v-model.trim="formDialog.data.title"
|
v-model.trim="formDialog.data.title"
|
||||||
type="text"
|
type="text"
|
||||||
label="Link title *"></q-input>
|
label="Link title *"
|
||||||
<q-input filled dense
|
></q-input>
|
||||||
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
v-model.number="formDialog.data.min_withdrawable"
|
v-model.number="formDialog.data.min_withdrawable"
|
||||||
type="number"
|
type="number"
|
||||||
label="Min withdrawable (sat) *"></q-input>
|
label="Min withdrawable (sat) *"
|
||||||
<q-input filled dense
|
></q-input>
|
||||||
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
v-model.number="formDialog.data.max_withdrawable"
|
v-model.number="formDialog.data.max_withdrawable"
|
||||||
type="number"
|
type="number"
|
||||||
label="Max withdrawable (sat) *"></q-input>
|
label="Max withdrawable (sat) *"
|
||||||
<q-input filled dense
|
></q-input>
|
||||||
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
v-model.number="formDialog.data.uses"
|
v-model.number="formDialog.data.uses"
|
||||||
type="number"
|
type="number"
|
||||||
:default="1"
|
:default="1"
|
||||||
label="Amount of uses *"></q-input>
|
label="Amount of uses *"
|
||||||
|
></q-input>
|
||||||
<div class="row q-col-gutter-none">
|
<div class="row q-col-gutter-none">
|
||||||
<div class="col-8">
|
<div class="col-8">
|
||||||
<q-input filled dense
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
v-model.number="formDialog.data.wait_time"
|
v-model.number="formDialog.data.wait_time"
|
||||||
type="number"
|
type="number"
|
||||||
:default="1"
|
:default="1"
|
||||||
label="Time between withdrawals *">
|
label="Time between withdrawals *"
|
||||||
|
>
|
||||||
</q-input>
|
</q-input>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4 q-pl-xs">
|
<div class="col-4 q-pl-xs">
|
||||||
<q-select filled dense v-model="formDialog.secondMultiplier" :options="formDialog.secondMultiplierOptions">
|
<q-select
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
v-model="formDialog.secondMultiplier"
|
||||||
|
:options="formDialog.secondMultiplierOptions"
|
||||||
|
>
|
||||||
</q-select>
|
</q-select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<q-list>
|
<q-list>
|
||||||
<q-item tag="label" class="rounded-borders">
|
<q-item tag="label" class="rounded-borders">
|
||||||
<q-item-section avatar>
|
<q-item-section avatar>
|
||||||
<q-checkbox v-model="formDialog.data.is_unique" color="deep-purple"></q-checkbox>
|
<q-checkbox
|
||||||
|
v-model="formDialog.data.is_unique"
|
||||||
|
color="deep-purple"
|
||||||
|
></q-checkbox>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
<q-item-section>
|
<q-item-section>
|
||||||
<q-item-label>Use unique withdraw QR codes to reduce `assmilking`</q-item-label>
|
<q-item-label
|
||||||
<q-item-label caption>This is recommended if you are sharing the links on social media. NOT if you plan to print QR codes.</q-item-label>
|
>Use unique withdraw QR codes to reduce
|
||||||
|
`assmilking`</q-item-label
|
||||||
|
>
|
||||||
|
<q-item-label caption
|
||||||
|
>This is recommended if you are sharing the links on social
|
||||||
|
media. NOT if you plan to print QR codes.</q-item-label
|
||||||
|
>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
</q-list>
|
</q-list>
|
||||||
<div class="row q-mt-lg">
|
<div class="row q-mt-lg">
|
||||||
<q-btn v-if="formDialog.data.id" unelevated color="deep-purple" type="submit">Update withdraw link</q-btn>
|
<q-btn
|
||||||
<q-btn v-else unelevated
|
v-if="formDialog.data.id"
|
||||||
|
unelevated
|
||||||
|
color="deep-purple"
|
||||||
|
type="submit"
|
||||||
|
>Update withdraw link</q-btn
|
||||||
|
>
|
||||||
|
<q-btn
|
||||||
|
v-else
|
||||||
|
unelevated
|
||||||
color="deep-purple"
|
color="deep-purple"
|
||||||
:disable="
|
:disable="
|
||||||
formDialog.data.wallet == null ||
|
formDialog.data.wallet == null ||
|
||||||
|
|
@ -153,8 +218,12 @@
|
||||||
) ||
|
) ||
|
||||||
formDialog.data.uses == null ||
|
formDialog.data.uses == null ||
|
||||||
formDialog.data.wait_time == null"
|
formDialog.data.wait_time == null"
|
||||||
type="submit">Create withdraw link</q-btn>
|
type="submit"
|
||||||
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Cancel</q-btn>
|
>Create withdraw link</q-btn
|
||||||
|
>
|
||||||
|
<q-btn v-close-popup flat color="grey" class="q-ml-auto"
|
||||||
|
>Cancel</q-btn
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</q-form>
|
</q-form>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|
@ -164,23 +233,58 @@
|
||||||
<q-card v-if="qrCodeDialog.data" class="q-pa-lg lnbits__dialog-card">
|
<q-card v-if="qrCodeDialog.data" class="q-pa-lg lnbits__dialog-card">
|
||||||
{% raw %}
|
{% raw %}
|
||||||
<q-responsive :ratio="1" class="q-mx-xl q-mb-md">
|
<q-responsive :ratio="1" class="q-mx-xl q-mb-md">
|
||||||
<qrcode :value="qrCodeDialog.data.lnurl" :options="{width: 800}" class="rounded-borders"></qrcode>
|
<qrcode
|
||||||
|
:value="qrCodeDialog.data.lnurl"
|
||||||
|
:options="{width: 800}"
|
||||||
|
class="rounded-borders"
|
||||||
|
></qrcode>
|
||||||
</q-responsive>
|
</q-responsive>
|
||||||
<p style="word-break: break-all">
|
<p style="word-break: break-all;">
|
||||||
<strong>ID:</strong> {{ qrCodeDialog.data.id }}<br>
|
<strong>ID:</strong> {{ qrCodeDialog.data.id }}<br />
|
||||||
<strong>Unique:</strong> {{ qrCodeDialog.data.is_unique }}<span v-if="qrCodeDialog.data.is_unique" class="text-deep-purple"> (QR code will change after each withdrawal)</span><br>
|
<strong>Unique:</strong> {{ qrCodeDialog.data.is_unique }}<span
|
||||||
<strong>Max. withdrawable:</strong> {{ qrCodeDialog.data.max_withdrawable }} sat<br>
|
v-if="qrCodeDialog.data.is_unique"
|
||||||
<strong>Wait time:</strong> {{ qrCodeDialog.data.wait_time }} seconds<br>
|
class="text-deep-purple"
|
||||||
<strong>Withdraws:</strong> {{ qrCodeDialog.data.used }} / {{ qrCodeDialog.data.uses }} <q-linear-progress :value="qrCodeDialog.data.used / qrCodeDialog.data.uses" color="deep-purple" class="q-mt-sm"></q-linear-progress>
|
>
|
||||||
|
(QR code will change after each withdrawal)</span
|
||||||
|
><br />
|
||||||
|
<strong>Max. withdrawable:</strong> {{
|
||||||
|
qrCodeDialog.data.max_withdrawable }} sat<br />
|
||||||
|
<strong>Wait time:</strong> {{ qrCodeDialog.data.wait_time }} seconds<br />
|
||||||
|
<strong>Withdraws:</strong> {{ qrCodeDialog.data.used }} / {{
|
||||||
|
qrCodeDialog.data.uses }}
|
||||||
|
<q-linear-progress
|
||||||
|
:value="qrCodeDialog.data.used / qrCodeDialog.data.uses"
|
||||||
|
color="deep-purple"
|
||||||
|
class="q-mt-sm"
|
||||||
|
></q-linear-progress>
|
||||||
</p>
|
</p>
|
||||||
{% endraw %}
|
{% endraw %}
|
||||||
<div class="row q-mt-lg q-gutter-sm">
|
<div class="row q-mt-lg q-gutter-sm">
|
||||||
<q-btn outline color="grey" @click="copyText(qrCodeDialog.data.lnurl, 'LNURL copied to clipboard!')" class="q-ml-sm">Copy LNURL</q-btn>
|
<q-btn
|
||||||
<q-btn outline color="grey" @click="copyText(qrCodeDialog.data.withdraw_url, 'Link copied to clipboard!')">Shareable link</q-btn>
|
outline
|
||||||
<q-btn v-if="!qrCodeDialog.data.is_unique" outline color="grey" icon="print" type="a" :href="qrCodeDialog.data.print_url" target="_blank"></q-btn>
|
color="grey"
|
||||||
|
@click="copyText(qrCodeDialog.data.lnurl, 'LNURL copied to clipboard!')"
|
||||||
|
class="q-ml-sm"
|
||||||
|
>Copy LNURL</q-btn
|
||||||
|
>
|
||||||
|
<q-btn
|
||||||
|
outline
|
||||||
|
color="grey"
|
||||||
|
@click="copyText(qrCodeDialog.data.withdraw_url, 'Link copied to clipboard!')"
|
||||||
|
>Shareable link</q-btn
|
||||||
|
>
|
||||||
|
<q-btn
|
||||||
|
v-if="!qrCodeDialog.data.is_unique"
|
||||||
|
outline
|
||||||
|
color="grey"
|
||||||
|
icon="print"
|
||||||
|
type="a"
|
||||||
|
:href="qrCodeDialog.data.print_url"
|
||||||
|
target="_blank"
|
||||||
|
></q-btn>
|
||||||
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Close</q-btn>
|
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Close</q-btn>
|
||||||
</div>
|
</div>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,22 @@
|
||||||
{% extends "print.html" %}
|
{% extends "print.html" %} {% block page %}
|
||||||
|
<div class="row justify-center">
|
||||||
|
|
||||||
{% block page %}
|
|
||||||
<div class="row justify-center">
|
|
||||||
<div class="col-12 col-sm-8 col-lg-6 text-center">
|
<div class="col-12 col-sm-8 col-lg-6 text-center">
|
||||||
{% for i in range(link.uses) %}
|
{% for i in range(link.uses) %}
|
||||||
<div class="zimbabwe">
|
<div class="zimbabwe">
|
||||||
<div class="qr">
|
<div class="qr">
|
||||||
<qrcode value="{{ link.lnurl }}" :options="{width: 150}"></qrcode>
|
<qrcode value="{{ link.lnurl }}" :options="{width: 150}"></qrcode>
|
||||||
<br><br>
|
<br /><br />
|
||||||
<strong>{{ SITE_TITLE }}</strong><br>
|
<strong>{{ SITE_TITLE }}</strong><br />
|
||||||
<strong>{{ link.max_withdrawable }} FREE SATS</strong><br>
|
<strong>{{ link.max_withdrawable }} FREE SATS</strong><br />
|
||||||
<small>Scan and follow link<br>or use Lightning wallet</small>
|
<small>Scan and follow link<br />or use Lightning wallet</small>
|
||||||
</div>
|
</div>
|
||||||
<img src="{{ url_for('static', filename='images/note.jpg') }}">
|
<img src="{{ url_for('static', filename='images/note.jpg') }}" />
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %} {% block styles %}
|
||||||
|
<style>
|
||||||
{% block styles %}
|
|
||||||
<style>
|
|
||||||
.zimbabwe {
|
.zimbabwe {
|
||||||
page-break-inside: avoid;
|
page-break-inside: avoid;
|
||||||
height: 7cm;
|
height: 7cm;
|
||||||
|
|
@ -48,19 +43,17 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
line-height: 1.1;
|
line-height: 1.1;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% endblock %}
|
{% endblock %} {% block scripts %}
|
||||||
|
<script src="{{ url_for('static', filename='vendor/vue-qrcode@1.0.2/vue-qrcode.min.js') }}"></script>
|
||||||
{% block scripts %}
|
<script>
|
||||||
<script src="{{ url_for('static', filename='vendor/vue-qrcode@1.0.2/vue-qrcode.min.js') }}"></script>
|
Vue.component(VueQrcode.name, VueQrcode)
|
||||||
<script>
|
|
||||||
Vue.component(VueQrcode.name, VueQrcode);
|
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
el: '#vue',
|
el: '#vue',
|
||||||
created: function () {
|
created: function () {
|
||||||
window.print();
|
window.print()
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
var LOCALE = 'en';
|
var LOCALE = 'en'
|
||||||
|
|
||||||
var EventHub = new Vue();
|
var EventHub = new Vue()
|
||||||
|
|
||||||
var LNbits = {
|
var LNbits = {
|
||||||
api: {
|
api: {
|
||||||
|
|
@ -12,78 +12,97 @@ var LNbits = {
|
||||||
'X-Api-Key': apiKey
|
'X-Api-Key': apiKey
|
||||||
},
|
},
|
||||||
data: data
|
data: data
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
createInvoice: function (wallet, amount, memo) {
|
createInvoice: function (wallet, amount, memo) {
|
||||||
return this.request('post', '/api/v1/payments', wallet.inkey, {
|
return this.request('post', '/api/v1/payments', wallet.inkey, {
|
||||||
out: false,
|
out: false,
|
||||||
amount: amount,
|
amount: amount,
|
||||||
memo: memo
|
memo: memo
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
payInvoice: function (wallet, bolt11) {
|
payInvoice: function (wallet, bolt11) {
|
||||||
return this.request('post', '/api/v1/payments', wallet.adminkey, {
|
return this.request('post', '/api/v1/payments', wallet.adminkey, {
|
||||||
out: true,
|
out: true,
|
||||||
bolt11: bolt11
|
bolt11: bolt11
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
getPayments: function (wallet, checkPending) {
|
getPayments: function (wallet, checkPending) {
|
||||||
var query_param = (checkPending) ? '?check_pending' : '';
|
var query_param = checkPending ? '?check_pending' : ''
|
||||||
return this.request('get', ['/api/v1/payments', query_param].join(''), wallet.inkey);
|
return this.request(
|
||||||
|
'get',
|
||||||
|
['/api/v1/payments', query_param].join(''),
|
||||||
|
wallet.inkey
|
||||||
|
)
|
||||||
},
|
},
|
||||||
getPayment: function (wallet, payhash) {
|
getPayment: function (wallet, payhash) {
|
||||||
return this.request('get', '/api/v1/payments/' + payhash, wallet.inkey);
|
return this.request('get', '/api/v1/payments/' + payhash, wallet.inkey)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
href: {
|
href: {
|
||||||
createWallet: function (walletName, userId) {
|
createWallet: function (walletName, userId) {
|
||||||
window.location.href = '/wallet?' + (userId ? 'usr=' + userId + '&' : '') + 'nme=' + walletName;
|
window.location.href =
|
||||||
|
'/wallet?' + (userId ? 'usr=' + userId + '&' : '') + 'nme=' + walletName
|
||||||
},
|
},
|
||||||
deleteWallet: function (walletId, userId) {
|
deleteWallet: function (walletId, userId) {
|
||||||
window.location.href = '/deletewallet?usr=' + userId + '&wal=' + walletId;
|
window.location.href = '/deletewallet?usr=' + userId + '&wal=' + walletId
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
map: {
|
map: {
|
||||||
extension: function (data) {
|
extension: function (data) {
|
||||||
var obj = _.object(['code', 'isValid', 'name', 'shortDescription', 'icon'], data);
|
var obj = _.object(
|
||||||
obj.url = ['/', obj.code, '/'].join('');
|
['code', 'isValid', 'name', 'shortDescription', 'icon'],
|
||||||
return obj;
|
data
|
||||||
|
)
|
||||||
|
obj.url = ['/', obj.code, '/'].join('')
|
||||||
|
return obj
|
||||||
},
|
},
|
||||||
user: function (data) {
|
user: function (data) {
|
||||||
var obj = _.object(['id', 'email', 'extensions', 'wallets'], data);
|
var obj = _.object(['id', 'email', 'extensions', 'wallets'], data)
|
||||||
var mapWallet = this.wallet;
|
var mapWallet = this.wallet
|
||||||
obj.wallets = obj.wallets.map(function (obj) {
|
obj.wallets = obj.wallets
|
||||||
return mapWallet(obj);
|
.map(function (obj) {
|
||||||
}).sort(function (a, b) {
|
return mapWallet(obj)
|
||||||
return a.name.localeCompare(b.name);
|
})
|
||||||
});
|
.sort(function (a, b) {
|
||||||
|
return a.name.localeCompare(b.name)
|
||||||
|
})
|
||||||
obj.walletOptions = obj.wallets.map(function (obj) {
|
obj.walletOptions = obj.wallets.map(function (obj) {
|
||||||
return {
|
return {
|
||||||
label: [obj.name, ' - ', obj.id].join(''),
|
label: [obj.name, ' - ', obj.id].join(''),
|
||||||
value: obj.id
|
value: obj.id
|
||||||
};
|
}
|
||||||
});
|
})
|
||||||
return obj;
|
return obj
|
||||||
},
|
},
|
||||||
wallet: function (data) {
|
wallet: function (data) {
|
||||||
var obj = _.object(['id', 'name', 'user', 'adminkey', 'inkey', 'balance'], data);
|
var obj = _.object(
|
||||||
obj.msat = obj.balance;
|
['id', 'name', 'user', 'adminkey', 'inkey', 'balance'],
|
||||||
obj.sat = Math.round(obj.balance / 1000);
|
data
|
||||||
obj.fsat = new Intl.NumberFormat(LOCALE).format(obj.sat);
|
)
|
||||||
obj.url = ['/wallet?usr=', obj.user, '&wal=', obj.id].join('');
|
obj.msat = obj.balance
|
||||||
return obj;
|
obj.sat = Math.round(obj.balance / 1000)
|
||||||
|
obj.fsat = new Intl.NumberFormat(LOCALE).format(obj.sat)
|
||||||
|
obj.url = ['/wallet?usr=', obj.user, '&wal=', obj.id].join('')
|
||||||
|
return obj
|
||||||
},
|
},
|
||||||
payment: function (data) {
|
payment: function (data) {
|
||||||
var obj = _.object(['payhash', 'pending', 'amount', 'fee', 'memo', 'time'], data);
|
var obj = _.object(
|
||||||
obj.date = Quasar.utils.date.formatDate(new Date(obj.time * 1000), 'YYYY-MM-DD HH:mm');
|
['payhash', 'pending', 'amount', 'fee', 'memo', 'time'],
|
||||||
obj.msat = obj.amount;
|
data
|
||||||
obj.sat = obj.msat / 1000;
|
)
|
||||||
obj.fsat = new Intl.NumberFormat(LOCALE).format(obj.sat);
|
obj.date = Quasar.utils.date.formatDate(
|
||||||
obj.isIn = obj.amount > 0;
|
new Date(obj.time * 1000),
|
||||||
obj.isOut = obj.amount < 0;
|
'YYYY-MM-DD HH:mm'
|
||||||
obj.isPaid = obj.pending == 0;
|
)
|
||||||
obj._q = [obj.memo, obj.sat].join(' ').toLowerCase();
|
obj.msat = obj.amount
|
||||||
return obj;
|
obj.sat = obj.msat / 1000
|
||||||
|
obj.fsat = new Intl.NumberFormat(LOCALE).format(obj.sat)
|
||||||
|
obj.isIn = obj.amount > 0
|
||||||
|
obj.isOut = obj.amount < 0
|
||||||
|
obj.isPaid = obj.pending == 0
|
||||||
|
obj._q = [obj.memo, obj.sat].join(' ').toLowerCase()
|
||||||
|
return obj
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
utils: {
|
utils: {
|
||||||
|
|
@ -98,84 +117,99 @@ var LNbits = {
|
||||||
flat: true,
|
flat: true,
|
||||||
color: 'grey'
|
color: 'grey'
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
formatCurrency: function (value, currency) {
|
formatCurrency: function (value, currency) {
|
||||||
return new Intl.NumberFormat(LOCALE, {style: 'currency', currency: currency}).format(value);
|
return new Intl.NumberFormat(LOCALE, {
|
||||||
|
style: 'currency',
|
||||||
|
currency: currency
|
||||||
|
}).format(value)
|
||||||
},
|
},
|
||||||
formatSat: function (value) {
|
formatSat: function (value) {
|
||||||
return new Intl.NumberFormat(LOCALE).format(value);
|
return new Intl.NumberFormat(LOCALE).format(value)
|
||||||
},
|
},
|
||||||
notifyApiError: function (error) {
|
notifyApiError: function (error) {
|
||||||
var types = {
|
var types = {
|
||||||
400: 'warning',
|
400: 'warning',
|
||||||
401: 'warning',
|
401: 'warning',
|
||||||
500: 'negative'
|
500: 'negative'
|
||||||
};
|
}
|
||||||
Quasar.plugins.Notify.create({
|
Quasar.plugins.Notify.create({
|
||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
type: types[error.response.status] || 'warning',
|
type: types[error.response.status] || 'warning',
|
||||||
message: error.response.data.message || null,
|
message: error.response.data.message || null,
|
||||||
caption: [error.response.status, ' ', error.response.statusText].join('').toUpperCase() || null,
|
caption:
|
||||||
|
[error.response.status, ' ', error.response.statusText]
|
||||||
|
.join('')
|
||||||
|
.toUpperCase() || null,
|
||||||
icon: null
|
icon: null
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
search: function (data, q, field, separator) {
|
search: function (data, q, field, separator) {
|
||||||
var field = field || '_q';
|
var field = field || '_q'
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var queries = q.toLowerCase().split(separator || ' ');
|
var queries = q.toLowerCase().split(separator || ' ')
|
||||||
return data.filter(function (obj) {
|
return data.filter(function (obj) {
|
||||||
var matches = 0;
|
var matches = 0
|
||||||
_.each(queries, function (q) {
|
_.each(queries, function (q) {
|
||||||
if (obj[field].indexOf(q) !== -1) matches++;
|
if (obj[field].indexOf(q) !== -1) matches++
|
||||||
});
|
})
|
||||||
return matches == queries.length;
|
return matches == queries.length
|
||||||
});
|
})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return data;
|
return data
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
exportCSV: function (columns, data) {
|
exportCSV: function (columns, data) {
|
||||||
var wrapCsvValue = function(val, formatFn) {
|
var wrapCsvValue = function (val, formatFn) {
|
||||||
var formatted = formatFn !== void 0
|
var formatted = formatFn !== void 0 ? formatFn(val) : val
|
||||||
? formatFn(val)
|
|
||||||
: val;
|
|
||||||
|
|
||||||
formatted = (formatted === void 0 || formatted === null)
|
formatted =
|
||||||
? ''
|
formatted === void 0 || formatted === null ? '' : String(formatted)
|
||||||
: String(formatted);
|
|
||||||
|
|
||||||
formatted = formatted.split('"').join('""');
|
formatted = formatted.split('"').join('""')
|
||||||
|
|
||||||
return `"${formatted}"`;
|
return `"${formatted}"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var content = [columns.map(function (col) {
|
var content = [
|
||||||
return wrapCsvValue(col.label);
|
columns.map(function (col) {
|
||||||
})].concat(data.map(function (row) {
|
return wrapCsvValue(col.label)
|
||||||
return columns.map(function (col) {
|
})
|
||||||
|
]
|
||||||
|
.concat(
|
||||||
|
data.map(function (row) {
|
||||||
|
return columns
|
||||||
|
.map(function (col) {
|
||||||
return wrapCsvValue(
|
return wrapCsvValue(
|
||||||
(typeof col.field === 'function')
|
typeof col.field === 'function'
|
||||||
? col.field(row)
|
? col.field(row)
|
||||||
: row[(col.field === void 0) ? col.name : col.field],
|
: row[col.field === void 0 ? col.name : col.field],
|
||||||
col.format
|
col.format
|
||||||
);
|
)
|
||||||
}).join(',');
|
})
|
||||||
})).join('\r\n');
|
.join(',')
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.join('\r\n')
|
||||||
|
|
||||||
var status = Quasar.utils.exportFile('table-export.csv', content, 'text/csv');
|
var status = Quasar.utils.exportFile(
|
||||||
|
'table-export.csv',
|
||||||
|
content,
|
||||||
|
'text/csv'
|
||||||
|
)
|
||||||
|
|
||||||
if (status !== true) {
|
if (status !== true) {
|
||||||
Quasar.plugins.Notify.create({
|
Quasar.plugins.Notify.create({
|
||||||
message: 'Browser denied file download...',
|
message: 'Browser denied file download...',
|
||||||
color: 'negative',
|
color: 'negative',
|
||||||
icon: null
|
icon: null
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
var windowMixin = {
|
var windowMixin = {
|
||||||
data: function () {
|
data: function () {
|
||||||
|
|
@ -185,44 +219,52 @@ var windowMixin = {
|
||||||
extensions: [],
|
extensions: [],
|
||||||
user: null,
|
user: null,
|
||||||
wallet: null,
|
wallet: null,
|
||||||
payments: [],
|
payments: []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
toggleDarkMode: function () {
|
toggleDarkMode: function () {
|
||||||
this.$q.dark.toggle();
|
this.$q.dark.toggle()
|
||||||
this.$q.localStorage.set('lnbits.darkMode', this.$q.dark.isActive);
|
this.$q.localStorage.set('lnbits.darkMode', this.$q.dark.isActive)
|
||||||
},
|
},
|
||||||
copyText: function (text, message, position) {
|
copyText: function (text, message, position) {
|
||||||
var notify = this.$q.notify;
|
var notify = this.$q.notify
|
||||||
Quasar.utils.copyToClipboard(text).then(function () {
|
Quasar.utils.copyToClipboard(text).then(function () {
|
||||||
notify({message: message || 'Copied to clipboard!', position: position || 'bottom'});
|
notify({
|
||||||
});
|
message: message || 'Copied to clipboard!',
|
||||||
|
position: position || 'bottom'
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
this.$q.dark.set(this.$q.localStorage.getItem('lnbits.darkMode'));
|
this.$q.dark.set(this.$q.localStorage.getItem('lnbits.darkMode'))
|
||||||
if (window.user) {
|
if (window.user) {
|
||||||
this.g.user = Object.freeze(LNbits.map.user(window.user));
|
this.g.user = Object.freeze(LNbits.map.user(window.user))
|
||||||
}
|
}
|
||||||
if (window.wallet) {
|
if (window.wallet) {
|
||||||
this.g.wallet = Object.freeze(LNbits.map.wallet(window.wallet));
|
this.g.wallet = Object.freeze(LNbits.map.wallet(window.wallet))
|
||||||
}
|
}
|
||||||
if (window.extensions) {
|
if (window.extensions) {
|
||||||
var user = this.g.user;
|
var user = this.g.user
|
||||||
this.g.extensions = Object.freeze(window.extensions.map(function (data) {
|
this.g.extensions = Object.freeze(
|
||||||
return LNbits.map.extension(data);
|
window.extensions
|
||||||
}).map(function (obj) {
|
.map(function (data) {
|
||||||
|
return LNbits.map.extension(data)
|
||||||
|
})
|
||||||
|
.map(function (obj) {
|
||||||
if (user) {
|
if (user) {
|
||||||
obj.isEnabled = user.extensions.indexOf(obj.code) != -1;
|
obj.isEnabled = user.extensions.indexOf(obj.code) != -1
|
||||||
} else {
|
} else {
|
||||||
obj.isEnabled = false;
|
obj.isEnabled = false
|
||||||
}
|
}
|
||||||
return obj;
|
return obj
|
||||||
}).sort(function (a, b) {
|
})
|
||||||
return a.name > b.name;
|
.sort(function (a, b) {
|
||||||
}));
|
return a.name > b.name
|
||||||
|
})
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,10 @@ Vue.component('lnbits-fsat', {
|
||||||
template: '<span>{{ fsat }}</span>',
|
template: '<span>{{ fsat }}</span>',
|
||||||
computed: {
|
computed: {
|
||||||
fsat: function () {
|
fsat: function () {
|
||||||
return LNbits.utils.formatSat(this.amount);
|
return LNbits.utils.formatSat(this.amount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
Vue.component('lnbits-wallet-list', {
|
Vue.component('lnbits-wallet-list', {
|
||||||
data: function () {
|
data: function () {
|
||||||
|
|
@ -70,33 +70,34 @@ Vue.component('lnbits-wallet-list', {
|
||||||
`,
|
`,
|
||||||
computed: {
|
computed: {
|
||||||
wallets: function () {
|
wallets: function () {
|
||||||
var bal = this.activeBalance;
|
var bal = this.activeBalance
|
||||||
return this.user.wallets.map(function (obj) {
|
return this.user.wallets.map(function (obj) {
|
||||||
obj.live_fsat = (bal.length && bal[0] == obj.id)
|
obj.live_fsat =
|
||||||
|
bal.length && bal[0] == obj.id
|
||||||
? LNbits.utils.formatSat(bal[1])
|
? LNbits.utils.formatSat(bal[1])
|
||||||
: obj.fsat;
|
: obj.fsat
|
||||||
return obj;
|
return obj
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
createWallet: function () {
|
createWallet: function () {
|
||||||
LNbits.href.createWallet(this.walletName, this.user.id);
|
LNbits.href.createWallet(this.walletName, this.user.id)
|
||||||
},
|
},
|
||||||
updateWalletBalance: function (payload) {
|
updateWalletBalance: function (payload) {
|
||||||
this.activeBalance = payload;
|
this.activeBalance = payload
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
if (window.user) {
|
if (window.user) {
|
||||||
this.user = LNbits.map.user(window.user);
|
this.user = LNbits.map.user(window.user)
|
||||||
}
|
}
|
||||||
if (window.wallet) {
|
if (window.wallet) {
|
||||||
this.activeWallet = LNbits.map.wallet(window.wallet);
|
this.activeWallet = LNbits.map.wallet(window.wallet)
|
||||||
}
|
}
|
||||||
EventHub.$on('update-wallet-balance', this.updateWalletBalance);
|
EventHub.$on('update-wallet-balance', this.updateWalletBalance)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
Vue.component('lnbits-extension-list', {
|
Vue.component('lnbits-extension-list', {
|
||||||
data: function () {
|
data: function () {
|
||||||
|
|
@ -140,30 +141,34 @@ Vue.component('lnbits-extension-list', {
|
||||||
`,
|
`,
|
||||||
computed: {
|
computed: {
|
||||||
userExtensions: function () {
|
userExtensions: function () {
|
||||||
if (!this.user) return [];
|
if (!this.user) return []
|
||||||
|
|
||||||
var path = window.location.pathname;
|
var path = window.location.pathname
|
||||||
var userExtensions = this.user.extensions;
|
var userExtensions = this.user.extensions
|
||||||
|
|
||||||
return this.extensions.filter(function (obj) {
|
return this.extensions
|
||||||
return userExtensions.indexOf(obj.code) !== -1;
|
.filter(function (obj) {
|
||||||
}).map(function (obj) {
|
return userExtensions.indexOf(obj.code) !== -1
|
||||||
obj.isActive = path.startsWith(obj.url);
|
})
|
||||||
return obj;
|
.map(function (obj) {
|
||||||
});
|
obj.isActive = path.startsWith(obj.url)
|
||||||
|
return obj
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
if (window.extensions) {
|
if (window.extensions) {
|
||||||
this.extensions = window.extensions.map(function (data) {
|
this.extensions = window.extensions
|
||||||
return LNbits.map.extension(data);
|
.map(function (data) {
|
||||||
}).sort(function (a, b) {
|
return LNbits.map.extension(data)
|
||||||
return a.name.localeCompare(b.name);
|
})
|
||||||
});
|
.sort(function (a, b) {
|
||||||
|
return a.name.localeCompare(b.name)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.user) {
|
if (window.user) {
|
||||||
this.user = LNbits.map.user(window.user);
|
this.user = LNbits.map.user(window.user)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
|
||||||
5
package.json
Normal file
5
package.json
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"devDependencies": {
|
||||||
|
"prettier": "^2.0.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue