lnbits-legend/lnbits/extensions/lnaddress/templates/lnaddress/index.html
Tiago Vasconcelos 847fd18796
update readme link (#687)
Co-authored-by: calle <93376500+callebtc@users.noreply.github.com>
2022-07-07 00:14:27 +02:00

503 lines
15 KiB
HTML

{% extends "base.html" %} {% from "macros.jinja" import window_vars with context
%} {% block page %}
<div class="row q-col-gutter-md">
<div class="col-12 col-md-8 col-lg-7 q-gutter-y-md">
<q-card>
<q-card-section>
<q-btn unelevated color="primary" @click="domainDialog.show = true"
>Add Domain</q-btn
>
</q-card-section>
</q-card>
<q-card>
<q-card-section>
<div class="row items-center no-wrap q-mb-md">
<div class="col">
<h5 class="text-subtitle1 q-my-none">Domains</h5>
</div>
<div class="col-auto">
<q-btn flat color="grey" @click="exportDomainsCSV"
>Export to CSV</q-btn
>
</div>
</div>
<q-table
dense
flat
:data="domains"
row-key="id"
:columns="domainsTable.columns"
:pagination.sync="domainsTable.pagination"
>
{% raw %}
<template v-slot:header="props">
<q-tr :props="props">
<q-th auto-width></q-th>
<q-th v-for="col in props.cols" :key="col.name" :props="props">
{{ col.label }}
</q-th>
<q-th auto-width></q-th>
</q-tr>
</template>
<template v-slot:body="props">
<q-tr :props="props">
<q-td auto-width>
<q-btn
unelevated
dense
size="xs"
icon="link"
:color="($q.dark.isActive) ? 'grey-7' : 'grey-5'"
type="a"
:href="props.row.displayUrl"
target="_blank"
></q-btn>
</q-td>
<q-td v-for="col in props.cols" :key="col.name" :props="props">
{{ col.value }}
</q-td>
<q-td auto-width>
<q-btn
flat
dense
size="xs"
@click="updateDomainDialog(props.row.id)"
icon="edit"
color="light-blue"
>
</q-btn>
</q-td>
<q-td auto-width>
<q-btn
flat
dense
size="xs"
@click="deleteDomain(props.row.id)"
icon="cancel"
color="pink"
></q-btn>
</q-td>
</q-tr>
</template>
{% endraw %}
</q-table>
</q-card-section>
</q-card>
<q-card>
<q-card-section>
<div class="row items-center no-wrap q-mb-md">
<div class="col">
<h5 class="text-subtitle1 q-my-none">Addresses</h5>
</div>
<div class="col-auto">
<q-btn flat color="grey" @click="exportAddressesCSV"
>Export to CSV</q-btn
>
</div>
</div>
<q-table
dense
flat
:data="addresses"
row-key="id"
:columns="addressesTable.columns"
:pagination.sync="addressesTable.pagination"
>
{% raw %}
<template v-slot:header="props">
<q-tr :props="props">
<q-th auto-width></q-th>
<q-th v-for="col in props.cols" :key="col.name" :props="props">
{{ col.label }}
</q-th>
</q-tr>
</template>
<template v-slot:body="props">
<q-tr :props="props" v-if="props.row.paid">
<q-td auto-width>
<q-btn
unelevated
dense
size="xs"
icon="email"
:color="($q.dark.isActive) ? 'grey-7' : 'grey-5'"
type="a"
:href="'mailto:' + props.row.email"
></q-btn>
</q-td>
<q-td v-for="col in props.cols" :key="col.name" :props="props">
{{ col.value }}
</q-td>
<q-td auto-width>
<q-btn
flat
dense
size="xs"
@click="deleteAddress(props.row.id)"
icon="cancel"
color="pink"
></q-btn>
</q-td>
</q-tr>
</template>
{% endraw %}
</q-table>
</q-card-section>
</q-card>
</div>
<div class="col-12 col-md-4 col-lg-5 q-gutter-y-md">
<q-card>
<q-card-section>
<h6 class="text-subtitle1 q-my-none">
{{SITE_TITLE}} LN Address extension
</h6>
</q-card-section>
<q-card-section class="q-pa-none">
<q-separator></q-separator>
<q-list> {% include "lnaddress/_api_docs.html" %} </q-list>
</q-card-section>
</q-card>
</div>
<q-dialog v-model="domainDialog.show" position="top">
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
<q-form @submit="sendFormData" class="q-gutter-md">
<q-select
filled
dense
emit-value
v-model="domainDialog.data.wallet"
:options="g.user.walletOptions"
label="Wallet *"
>
</q-select>
<q-input
filled
dense
emit-value
v-model.trim="domainDialog.data.domain"
type="text"
label="Domain name "
><q-tooltip class="bg-grey-8" anchor="bottom left" self="top left"
>The domain to use ex: "example.com"</q-tooltip
></q-input
>
<q-input
filled
dense
bottom-slots
v-model.trim="domainDialog.data.cf_token"
type="text"
label="Cloudflare API token"
>
<template v-slot:hint>
Check extension
<a
href="https://github.com/lnbits/lnbits-legend/blob/main/lnbits/extensions/lnaddress/README.md"
>documentation!</a
>
</template>
<q-tooltip class="bg-grey-8" anchor="bottom left" self="top left"
>Your API key in cloudflare</q-tooltip
>
</q-input>
<q-input
filled
dense
v-model.trim="domainDialog.data.cf_zone_id"
type="text"
label="Cloudflare Zone Id"
>
<q-tooltip class="bg-grey-8" anchor="bottom left" self="top left"
>Create a "Edit zone DNS" API token in cloudflare</q-tooltip
>
</q-input>
<q-input
filled
dense
v-model.trim="domainDialog.data.webhook"
type="text"
label="Webhook (optional)"
hint="A URL to be called whenever this link receives a payment."
></q-input>
<q-input
filled
dense
v-model.number="domainDialog.data.cost"
type="number"
label="Amount per day in satoshis"
><q-tooltip class="bg-grey-8" anchor="bottom left" self="top left"
>How much to charge per day</q-tooltip
></q-input
>
<div class="row q-mt-lg">
<q-btn
v-if="domainDialog.data.id"
unelevated
color="primary"
type="submit"
>Update Form</q-btn
>
<q-btn
v-else
unelevated
color="primary"
:disable="domainDialog.data.cost == null || domainDialog.data.cost < 0 || domainDialog.data.domain == null"
type="submit"
>Create Domain</q-btn
>
<q-btn v-close-popup flat color="grey" class="q-ml-auto"
>Cancel</q-btn
>
</div>
</q-form>
</q-card>
</q-dialog>
</div>
{% endblock %} {% block scripts %} {{ window_vars(user) }}
<script>
const mapLNDomain = obj => {
obj.date = Quasar.utils.date.formatDate(
new Date(obj.time * 1000),
'YYYY-MM-DD HH:mm'
)
obj.displayUrl = ['/lnaddress/', obj.id].join('')
return obj
}
new Vue({
el: '#vue',
mixins: [windowMixin],
data: function () {
return {
domains: [],
addresses: [],
domainDialog: {
show: false,
data: {}
},
domainsTable: {
columns: [
{name: 'id', align: 'left', label: 'ID', field: 'id'},
{
name: 'domain',
align: 'left',
label: 'Domain name',
field: 'domain'
},
{name: 'wallet', align: 'left', label: 'Wallet', field: 'wallet'},
{
name: 'webhook',
align: 'left',
label: 'Webhook',
field: 'webhook'
},
{
name: 'cost',
align: 'left',
label: 'Cost Per Day',
field: 'cost'
}
],
pagination: {
rowsPerPage: 10
}
},
addressesTable: {
columns: [
{
name: 'username',
align: 'left',
label: 'Alias/username',
field: 'username'
},
{
name: 'domain',
align: 'left',
label: 'Domain name',
field: 'domain'
},
{
name: 'email',
align: 'left',
label: 'Email',
field: 'email'
},
{
name: 'sats',
align: 'left',
label: 'Sats paid',
field: 'sats'
},
{
name: 'duration',
align: 'left',
label: 'Duration in days',
field: 'duration'
},
{name: 'id', align: 'left', label: 'ID', field: 'id'}
],
pagination: {
rowsPerPage: 10
}
}
}
},
methods: {
//DOMAINS
getDomains: function () {
LNbits.api
.request(
'GET',
'/lnaddress/api/v1/domains?all_wallets=true',
this.g.user.wallets[0].inkey
)
.then(response => {
this.domains = response.data.map(function (obj) {
return mapLNDomain(obj)
})
})
},
sendFormData: function () {
let wallet = _.findWhere(this.g.user.wallets, {
id: this.domainDialog.data.wallet
})
let data = this.domainDialog.data
if (data.id) {
this.updateDomain(wallet, data)
} else {
this.createDomain(wallet, data)
}
},
createDomain: function (wallet, data) {
var self = this
console.log(data)
LNbits.api
.request('POST', '/lnaddress/api/v1/domains', wallet.inkey, data)
.then(response => {
this.domains.push(mapLNDomain(response.data))
this.domainDialog.show = false
this.domainDialog.data = {}
})
.catch(error => {
LNbits.utils.notifyApiError(error)
})
},
updateDomainDialog: function (formId) {
var link = _.findWhere(this.domains, {id: formId})
console.log(link.id)
this.domainDialog.data = _.clone(link)
this.domainDialog.show = true
},
updateDomain: function (wallet, data) {
console.log(data)
if (!data.webhook) {
delete data.webhook
}
LNbits.api
.request(
'PUT',
'/lnaddress/api/v1/domains/' + data.id,
wallet.inkey,
data
)
.then(response => {
this.domains = _.reject(this.domains, function (obj) {
return obj.id == data.id
})
this.domains.push(mapLNDomain(response.data))
this.domainDialog.show = false
this.domainDialog.data = {}
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
deleteDomain: function (domainId) {
var self = this
var domains = _.findWhere(this.domains, {id: domainId})
LNbits.utils
.confirmDialog('Are you sure you want to delete this domain link?')
.onOk(function () {
LNbits.api
.request(
'DELETE',
'/lnaddress/api/v1/domains/' + domainId,
_.findWhere(self.g.user.wallets, {id: domains.wallet}).inkey
)
.then(function (response) {
self.domains = _.reject(self.domains, function (obj) {
return obj.id == domainId
})
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
})
},
exportDomainsCSV: function () {
LNbits.utils.exportCSV(this.domainsTable.columns, this.domains)
},
//ADDRESSES
getAddresses: function () {
var self = this
LNbits.api
.request(
'GET',
'/lnaddress/api/v1/addresses?all_wallets=true',
this.g.user.wallets[0].inkey
)
.then(function (response) {
self.addresses = response.data
.filter(d => d.paid)
.map(function (obj) {
// obj.domain_name = this.domains.find(d => d.id == obj.domain)
return mapLNDomain(obj)
})
console.log(self.addresses)
})
},
deleteAddress: function (addressId) {
let self = this
let addresses = _.findWhere(this.addresses, {id: addressId})
LNbits.utils
.confirmDialog('Are you sure you want to delete this LN address')
.onOk(function () {
LNbits.api
.request(
'DELETE',
'/lnaddress/api/v1/addresses/' + addressId,
_.findWhere(self.g.user.wallets, {id: addresses.wallet}).inkey
)
.then(function (response) {
self.addresses = _.reject(self.addresses, function (obj) {
return obj.id == addressId
})
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
})
},
exportAddressesCSV: function () {
LNbits.utils.exportCSV(this.addressesTable.columns, this.addresses)
}
},
created: function () {
if (this.g.user.wallets.length) {
this.getDomains()
this.getAddresses()
}
}
})
</script>
{% endblock %}