mirror of https://github.com/lukechilds/lnbits.git
4 changed files with 191 additions and 4 deletions
@ -0,0 +1,168 @@ |
|||||
|
{% extends "public.html" %} {% block page %} |
||||
|
<div class="row q-col-gutter-md justify-center"> |
||||
|
<div class="col-12 col-md-7 col-lg-6 q-gutter-y-md"> |
||||
|
<q-card class="q-pa-lg"> |
||||
|
<q-card-section class="q-pa-none"> |
||||
|
<h3 class="q-my-none">{{ form_domain }}</h3> |
||||
|
<br /> |
||||
|
<h5 class="q-my-none">{{ form_desc }}</h5> |
||||
|
<br /> |
||||
|
<q-form @submit="Invoice()" class="q-gutter-md"> |
||||
|
<q-input filled dense v-model.trim="formDialog.data.email" type="email" |
||||
|
label="Your email (optional, if you want a reply)"></q-input> |
||||
|
<q-input filled dense v-model.trim="formDialog.data.subdomain" type="text" label="subdomain you want"> |
||||
|
</q-input> |
||||
|
<q-input filled dense v-model.trim="formDialog.data.ip" type="text" label="ip of your server"> |
||||
|
</q-input> |
||||
|
<q-input filled dense v-model.trim="formDialog.data.duration" type="number" label="{{ form_cost }} sats per day"> |
||||
|
</q-input> |
||||
|
<p>{% raw %}{{amountSats}}{% endraw %}</p> |
||||
|
<div class="row q-mt-lg"> |
||||
|
<q-btn unelevated color="deep-purple" :disable="formDialog.data.subdomain == '' || formDialog.data.ip == '' || formDialog.data.duration == ''" |
||||
|
type="submit">Submit</q-btn> |
||||
|
<q-btn @click="resetForm" flat color="grey" class="q-ml-auto">Cancel</q-btn> |
||||
|
</div> |
||||
|
</q-form> |
||||
|
</q-card-section> |
||||
|
</q-card> |
||||
|
</div> |
||||
|
|
||||
|
<q-dialog v-model="receive.show" position="top" @hide="closeReceiveDialog"> |
||||
|
<q-card v-if="!receive.paymentReq" class="q-pa-lg q-pt-xl lnbits__dialog-card"> |
||||
|
</q-card> |
||||
|
<q-card v-else class="q-pa-lg q-pt-xl lnbits__dialog-card"> |
||||
|
<div class="text-center q-mb-lg"> |
||||
|
<a :href="'lightning:' + receive.paymentReq"> |
||||
|
<q-responsive :ratio="1" class="q-mx-xl"> |
||||
|
<qrcode :value="paymentReq" :options="{width: 340}" class="rounded-borders"></qrcode> |
||||
|
</q-responsive> |
||||
|
</a> |
||||
|
</div> |
||||
|
<div class="row q-mt-lg"> |
||||
|
<q-btn outline color="grey" @click="copyText(receive.paymentReq)">Copy invoice</q-btn> |
||||
|
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Close</q-btn> |
||||
|
</div> |
||||
|
</q-card> |
||||
|
</q-dialog> |
||||
|
</div> |
||||
|
|
||||
|
{% endblock %} {% block scripts %} |
||||
|
<script> |
||||
|
console.log('{{ form_cost }}') |
||||
|
Vue.component(VueQrcode.name, VueQrcode) |
||||
|
|
||||
|
new Vue({ |
||||
|
el: '#vue', |
||||
|
mixins: [windowMixin], |
||||
|
data: function () { |
||||
|
return { |
||||
|
paymentReq: null, |
||||
|
redirectUrl: null, |
||||
|
formDialog: { |
||||
|
show: false, |
||||
|
data: { |
||||
|
ip: '', |
||||
|
subdomain: '', |
||||
|
duration: '', |
||||
|
email: '', |
||||
|
} |
||||
|
}, |
||||
|
receive: { |
||||
|
show: false, |
||||
|
status: 'pending', |
||||
|
paymentReq: null |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
amountSats() { |
||||
|
var sats = this.formDialog.data.duration * parseInt('{{ form_cost }}') |
||||
|
if (sats === parseInt('{{ form_cost }}')) { |
||||
|
return '0 Sats to pay' |
||||
|
} else { |
||||
|
this.formDialog.data.sats = sats |
||||
|
return sats + ' Sats to pay' |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
methods: { |
||||
|
resetForm: function (e) { |
||||
|
e.preventDefault() |
||||
|
this.formDialog.data.subdomain = '' |
||||
|
this.formDialog.data.email = '' |
||||
|
this.formDialog.data.ip = '' |
||||
|
this.formDialog.data.duration = '' |
||||
|
}, |
||||
|
|
||||
|
closeReceiveDialog: function () { |
||||
|
var checker = this.receive.paymentChecker |
||||
|
dismissMsg() |
||||
|
|
||||
|
clearInterval(paymentChecker) |
||||
|
setTimeout(function () { }, 10000) |
||||
|
}, |
||||
|
Invoice: function () { |
||||
|
var self = this |
||||
|
axios |
||||
|
.post('/subdomains/api/v1/subdomains/{{ domain_id }}', { |
||||
|
domain: '{{ domain_id }}', |
||||
|
subdomain: self.formDialog.data.subdomain, |
||||
|
ip: self.formDialog.data.ip, |
||||
|
email: self.formDialog.data.email, |
||||
|
sats: self.formDialog.data.sats, |
||||
|
}) |
||||
|
.then(function (response) { |
||||
|
self.paymentReq = response.data.payment_request |
||||
|
self.paymentCheck = response.data.payment_hash |
||||
|
|
||||
|
dismissMsg = self.$q.notify({ |
||||
|
timeout: 0, |
||||
|
message: 'Waiting for payment...' |
||||
|
}) |
||||
|
|
||||
|
self.receive = { |
||||
|
show: true, |
||||
|
status: 'pending', |
||||
|
paymentReq: self.paymentReq |
||||
|
} |
||||
|
|
||||
|
paymentChecker = setInterval(function () { |
||||
|
axios |
||||
|
.get('/subdomains/api/v1/subdomains/' + self.paymentCheck) |
||||
|
.then(function (res) { |
||||
|
if (res.data.paid) { |
||||
|
clearInterval(paymentChecker) |
||||
|
self.receive = { |
||||
|
show: false, |
||||
|
status: 'complete', |
||||
|
paymentReq: null |
||||
|
} |
||||
|
dismissMsg() |
||||
|
|
||||
|
|
||||
|
this.formDialog.data.subdomain = '' |
||||
|
this.formDialog.data.email = '' |
||||
|
this.formDialog.data.ip = '' |
||||
|
this.formDialog.data.duration = '' |
||||
|
self.$q.notify({ |
||||
|
type: 'positive', |
||||
|
message: 'Sent, thank you!', |
||||
|
icon: 'thumb_up', |
||||
|
}) |
||||
|
|
||||
|
} |
||||
|
}) |
||||
|
.catch(function (error) { |
||||
|
LNbits.utils.notifyApiError(error) |
||||
|
}) |
||||
|
}, 2000) |
||||
|
}) |
||||
|
.catch(function (error) { |
||||
|
LNbits.utils.notifyApiError(error) |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
</script> |
||||
|
{% endblock %} |
@ -1,12 +1,27 @@ |
|||||
from quart import g, render_template |
from quart import g, abort, render_template |
||||
|
|
||||
from lnbits.decorators import check_user_exists, validate_uuids |
from lnbits.decorators import check_user_exists, validate_uuids |
||||
|
from http import HTTPStatus |
||||
|
|
||||
from . import subdomains_ext |
from . import subdomains_ext |
||||
|
from .crud import get_domain |
||||
|
|
||||
@subdomains_ext.route("/") |
@subdomains_ext.route("/") |
||||
@validate_uuids(["usr"], required=True) |
@validate_uuids(["usr"], required=True) |
||||
@check_user_exists() |
@check_user_exists() |
||||
async def index(): |
async def index(): |
||||
return await render_template("subdomains/index.html", user=g.user) |
return await render_template("subdomains/index.html", user=g.user) |
||||
|
|
||||
|
@subdomains_ext.route("/<domain_id>") |
||||
|
async def display(domain_id): |
||||
|
domain = await get_domain(domain_id) |
||||
|
if not domain: |
||||
|
abort(HTTPStatus.NOT_FOUND, "Domain does not exist.") |
||||
|
|
||||
|
return await render_template( |
||||
|
"subdomains/display.html", |
||||
|
domain_id=domain.id, |
||||
|
domain_domain=domain.domain, |
||||
|
form_desc=domain.description, |
||||
|
form_cost=domain.cost, |
||||
|
) |
||||
|
Loading…
Reference in new issue