This commit is contained in:
commit
fcb973b540
21 changed files with 2267 additions and 0 deletions
204
templates/withdraw/_api_docs.html
Normal file
204
templates/withdraw/_api_docs.html
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
<q-expansion-item
|
||||
group="extras"
|
||||
icon="swap_vertical_circle"
|
||||
label="API info"
|
||||
:content-inset-level="0.5"
|
||||
>
|
||||
<q-btn flat label="Swagger API" type="a" href="../docs#/withdraw"></q-btn>
|
||||
<q-expansion-item
|
||||
group="api"
|
||||
dense
|
||||
expand-separator
|
||||
label="List withdraw links"
|
||||
>
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<code><span class="text-blue">GET</span> /withdraw/api/v1/links</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
||||
<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">
|
||||
Returns 200 OK (application/json)
|
||||
</h5>
|
||||
<code>[<withdraw_link_object>, ...]</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url }}withdraw/api/v1/links -H
|
||||
"X-Api-Key: {{ user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-expansion-item>
|
||||
<q-expansion-item
|
||||
group="api"
|
||||
dense
|
||||
expand-separator
|
||||
label="Get a withdraw link"
|
||||
>
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<code
|
||||
><span class="text-blue">GET</span>
|
||||
/withdraw/api/v1/links/<withdraw_id></code
|
||||
>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
||||
<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">
|
||||
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 GET {{ request.base_url
|
||||
}}withdraw/api/v1/links/<withdraw_id> -H "X-Api-Key: {{
|
||||
user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</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-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>,
|
||||
"webhook_url": <string>}</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.base_url }}withdraw/api/v1/links -d
|
||||
'{"title": <string>, "min_withdrawable": <integer>,
|
||||
"max_withdrawable": <integer>, "uses": <integer>,
|
||||
"wait_time": <integer>, "is_unique": <boolean>,
|
||||
"webhook_url": <string>}' -H "Content-type: application/json" -H
|
||||
"X-Api-Key: {{ user.wallets[0].adminkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-expansion-item>
|
||||
<q-expansion-item
|
||||
group="api"
|
||||
dense
|
||||
expand-separator
|
||||
label="Update a withdraw link"
|
||||
>
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<code
|
||||
><span class="text-green">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 200 OK (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.base_url
|
||||
}}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: {{
|
||||
user.wallets[0].adminkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-expansion-item>
|
||||
<q-expansion-item
|
||||
group="api"
|
||||
dense
|
||||
expand-separator
|
||||
label="Delete a withdraw link"
|
||||
>
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<code
|
||||
><span class="text-pink">DELETE</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">Returns 204 NO CONTENT</h5>
|
||||
<code></code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X DELETE {{ request.base_url
|
||||
}}withdraw/api/v1/links/<withdraw_id> -H "X-Api-Key: {{
|
||||
user.wallets[0].adminkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-expansion-item>
|
||||
<q-expansion-item
|
||||
group="api"
|
||||
dense
|
||||
expand-separator
|
||||
label="Get hash check (for captchas to prevent milking)"
|
||||
>
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<code
|
||||
><span class="text-blue">GET</span>
|
||||
/withdraw/api/v1/links/<the_hash>/<lnurl_id></code
|
||||
>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
||||
<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">
|
||||
Returns 201 CREATED (application/json)
|
||||
</h5>
|
||||
<code>{"status": <bool>}</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url
|
||||
}}withdraw/api/v1/links/<the_hash>/<lnurl_id> -H
|
||||
"X-Api-Key: {{ user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-expansion-item>
|
||||
<q-expansion-item
|
||||
group="api"
|
||||
dense
|
||||
expand-separator
|
||||
label="Get image to embed"
|
||||
class="q-pb-md"
|
||||
>
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<code
|
||||
><span class="text-blue">GET</span>
|
||||
/withdraw/img/<lnurl_id></code
|
||||
>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.base_url }}withdraw/img/<lnurl_id>"
|
||||
</code>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-expansion-item>
|
||||
</q-expansion-item>
|
||||
32
templates/withdraw/_lnurl.html
Normal file
32
templates/withdraw/_lnurl.html
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<q-expansion-item group="extras" icon="info" label="Powered by LNURL">
|
||||
<q-card>
|
||||
<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>
|
||||
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
|
||||
class="text-secondary"
|
||||
href="https://github.com/fiatjaf/awesome-lnurl"
|
||||
target="_blank"
|
||||
>Awesome LNURL</a
|
||||
>
|
||||
for further information.</small
|
||||
>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-expansion-item>
|
||||
12
templates/withdraw/csv.html
Normal file
12
templates/withdraw/csv.html
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{% extends "print.html" %} {% block page %} {% for page in link %} {% for threes
|
||||
in page %} {% for one in threes %} {{one}}, {% endfor %} {% endfor %} {% endfor
|
||||
%} {% endblock %} {% block scripts %}
|
||||
<script>
|
||||
new Vue({
|
||||
el: '#vue',
|
||||
data: function () {
|
||||
return {}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
68
templates/withdraw/display.html
Normal file
68
templates/withdraw/display.html
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
{% extends "public.html" %} {% block page %}
|
||||
<div class="row q-col-gutter-md justify-center">
|
||||
<div class="col-12 col-sm-6 col-md-5 col-lg-4">
|
||||
<q-card class="q-pa-lg">
|
||||
<q-card-section class="q-pa-none">
|
||||
<div class="text-center">
|
||||
{% if link.is_spent %}
|
||||
<q-badge color="red" class="q-mb-md">Withdraw is spent.</q-badge>
|
||||
{% endif %}
|
||||
<a class="text-secondary" href="lightning:{{ lnurl }}">
|
||||
<q-responsive :ratio="1" class="q-mx-md">
|
||||
<qrcode
|
||||
:value="this.here + '/?lightning={{lnurl }}'"
|
||||
:options="{width: 800}"
|
||||
class="rounded-borders"
|
||||
>
|
||||
</qrcode>
|
||||
</q-responsive>
|
||||
</a>
|
||||
</div>
|
||||
<div class="row q-mt-lg q-gutter-sm">
|
||||
<q-btn outline color="grey" @click="copyText('{{ lnurl }}')"
|
||||
>Copy LNURL</q-btn
|
||||
>
|
||||
<q-btn
|
||||
outline
|
||||
color="grey"
|
||||
icon="nfc"
|
||||
@click="writeNfcTag(' {{ lnurl }} ')"
|
||||
:disable="nfcTagWriting"
|
||||
></q-btn>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-5 col-lg-4 q-gutter-y-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-mb-sm q-mt-none">
|
||||
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 class="q-pa-none">
|
||||
<q-separator></q-separator>
|
||||
<q-list> {% include "withdraw/_lnurl.html" %} </q-list>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %} {% block scripts %}
|
||||
<script>
|
||||
Vue.component(VueQrcode.name, VueQrcode)
|
||||
|
||||
new Vue({
|
||||
el: '#vue',
|
||||
mixins: [windowMixin],
|
||||
data: function () {
|
||||
return {
|
||||
here: location.protocol + '//' + location.host,
|
||||
nfcTagWriting: false
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
471
templates/withdraw/index.html
Normal file
471
templates/withdraw/index.html
Normal file
|
|
@ -0,0 +1,471 @@
|
|||
{% extends "base.html" %} {% from "macros.jinja" import window_vars with context
|
||||
%} {% block scripts %} {{ window_vars(user) }}
|
||||
<script src="/withdraw/static/js/index.js"></script>
|
||||
{% endblock %} {% block page %}
|
||||
<div class="row q-col-gutter-md">
|
||||
<div class="col-12 col-md-7 q-gutter-y-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<q-btn unelevated color="primary" @click="simpleformDialog.show = true"
|
||||
>Quick vouchers</q-btn
|
||||
>
|
||||
<q-btn unelevated color="primary" @click="formDialog.show = true"
|
||||
>Advanced withdraw link(s)</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">Withdraw links</h5>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<q-btn flat color="grey" @click="exportCSV">Export to CSV</q-btn>
|
||||
</div>
|
||||
</div>
|
||||
<q-table
|
||||
dense
|
||||
flat
|
||||
:data="sortedWithdrawLinks"
|
||||
row-key="id"
|
||||
:columns="withdrawLinksTable.columns"
|
||||
:pagination.sync="withdrawLinksTable.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-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="launch"
|
||||
:color="($q.dark.isActive) ? 'grey-7' : 'grey-5'"
|
||||
type="a"
|
||||
:href="props.row.withdraw_url"
|
||||
target="_blank"
|
||||
>
|
||||
<q-tooltip> shareable link </q-tooltip></q-btn
|
||||
>
|
||||
<q-btn
|
||||
unelevated
|
||||
dense
|
||||
size="xs"
|
||||
icon="web_asset"
|
||||
:color="($q.dark.isActive) ? 'grey-7' : 'grey-5'"
|
||||
type="a"
|
||||
:href="'/withdraw/img/' + props.row.id"
|
||||
target="_blank"
|
||||
><q-tooltip> embeddable image </q-tooltip></q-btn
|
||||
>
|
||||
<q-btn
|
||||
unelevated
|
||||
dense
|
||||
size="xs"
|
||||
icon="reorder"
|
||||
:color="($q.dark.isActive) ? 'grey-7' : 'grey-5'"
|
||||
type="a"
|
||||
:href="'/withdraw/csv/' + props.row.id"
|
||||
target="_blank"
|
||||
><q-tooltip> csv list </q-tooltip></q-btn
|
||||
>
|
||||
<q-btn
|
||||
unelevated
|
||||
dense
|
||||
size="xs"
|
||||
icon="visibility"
|
||||
:color="($q.dark.isActive) ? 'grey-7' : 'grey-5'"
|
||||
@click="openQrCodeDialog(props.row.id)"
|
||||
><q-tooltip> view LNURL </q-tooltip></q-btn
|
||||
>
|
||||
</q-td>
|
||||
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||
{{ col.value }}
|
||||
</q-td>
|
||||
<q-td>
|
||||
<q-icon v-if="props.row.webhook_url" size="14px" name="http">
|
||||
<q-tooltip>Webhook to {{ props.row.webhook_url}}</q-tooltip>
|
||||
</q-icon>
|
||||
</q-td>
|
||||
<q-td auto-width>
|
||||
<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-tr>
|
||||
</template>
|
||||
{% endraw %}
|
||||
</q-table>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-md-5 q-gutter-y-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-my-none">
|
||||
{{SITE_TITLE}} LNURL-withdraw extension
|
||||
</h6>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-none">
|
||||
<q-separator></q-separator>
|
||||
<q-list>
|
||||
{% include "withdraw/_api_docs.html" %}
|
||||
<q-separator></q-separator>
|
||||
{% include "withdraw/_lnurl.html" %}
|
||||
</q-list>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</div>
|
||||
|
||||
<q-dialog v-model="formDialog.show" position="top" @hide="closeFormDialog">
|
||||
<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="formDialog.data.wallet"
|
||||
:options="g.user.walletOptions"
|
||||
label="Wallet *"
|
||||
>
|
||||
</q-select>
|
||||
<q-input
|
||||
filled
|
||||
dense
|
||||
v-model.trim="formDialog.data.title"
|
||||
type="text"
|
||||
label="Link title *"
|
||||
></q-input>
|
||||
<q-input
|
||||
filled
|
||||
dense
|
||||
v-model.number="formDialog.data.min_withdrawable"
|
||||
type="number"
|
||||
min="10"
|
||||
label="Min withdrawable (sat, at least 10) *"
|
||||
></q-input>
|
||||
<q-input
|
||||
filled
|
||||
dense
|
||||
v-model.number="formDialog.data.max_withdrawable"
|
||||
type="number"
|
||||
min="10"
|
||||
label="Max withdrawable (sat, at least 10) *"
|
||||
></q-input>
|
||||
<q-input
|
||||
filled
|
||||
dense
|
||||
v-model.number="formDialog.data.uses"
|
||||
type="number"
|
||||
max="250"
|
||||
:default="1"
|
||||
label="Amount of uses *"
|
||||
></q-input>
|
||||
<div class="row q-col-gutter-none">
|
||||
<div class="col-8">
|
||||
<q-input
|
||||
filled
|
||||
dense
|
||||
v-model.number="formDialog.data.wait_time"
|
||||
type="number"
|
||||
:default="1"
|
||||
label="Time between withdrawals *"
|
||||
>
|
||||
</q-input>
|
||||
</div>
|
||||
<div class="col-4 q-pl-xs">
|
||||
<q-select
|
||||
filled
|
||||
dense
|
||||
v-model="formDialog.secondMultiplier"
|
||||
:options="formDialog.secondMultiplierOptions"
|
||||
>
|
||||
</q-select>
|
||||
</div>
|
||||
</div>
|
||||
<q-toggle
|
||||
label="Webhook"
|
||||
color="secodary"
|
||||
v-model="formDialog.data.has_webhook"
|
||||
></q-toggle>
|
||||
<q-input
|
||||
v-if="formDialog.data.has_webhook"
|
||||
filled
|
||||
dense
|
||||
v-model="formDialog.data.webhook_url"
|
||||
type="text"
|
||||
label="Webhook URL (optional)"
|
||||
hint="A URL to be called whenever this link gets used."
|
||||
></q-input>
|
||||
<q-input
|
||||
v-if="formDialog.data.has_webhook"
|
||||
filled
|
||||
dense
|
||||
v-model="formDialog.data.webhook_headers"
|
||||
type="text"
|
||||
label="Webhook Headers (optional)"
|
||||
hint="Custom data as JSON string, send headers along with the webhook."
|
||||
></q-input>
|
||||
<q-input
|
||||
v-if="formDialog.data.has_webhook"
|
||||
filled
|
||||
dense
|
||||
v-model="formDialog.data.webhook_body"
|
||||
type="text"
|
||||
label="Webhook custom data (optional)"
|
||||
hint="Custom data as JSON string, will get posted along with webhook 'body' field."
|
||||
></q-input>
|
||||
<q-list>
|
||||
<q-item tag="label" class="rounded-borders">
|
||||
<q-item-section avatar>
|
||||
<q-checkbox
|
||||
v-model="formDialog.data.use_custom"
|
||||
color="primary"
|
||||
></q-checkbox>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label>Use a custom voucher design </q-item-label>
|
||||
<q-item-label caption
|
||||
>You can use an LNbits voucher design or a custom
|
||||
one</q-item-label
|
||||
>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
<q-input
|
||||
v-if="formDialog.data.use_custom"
|
||||
filled
|
||||
dense
|
||||
v-model="formDialog.data.custom_url"
|
||||
type="text"
|
||||
label="Custom design .png (optional)"
|
||||
hint="Enter a URL if you want to use a custom design or leave blank for LNbits designed vouchers!"
|
||||
></q-input>
|
||||
<q-list>
|
||||
<q-item tag="label" class="rounded-borders">
|
||||
<q-item-section avatar>
|
||||
<q-checkbox
|
||||
v-model="formDialog.data.is_unique"
|
||||
color="primary"
|
||||
></q-checkbox>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<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 or print QR codes.</q-item-label
|
||||
>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
<div class="row q-mt-lg">
|
||||
<q-btn
|
||||
v-if="formDialog.data.id"
|
||||
unelevated
|
||||
color="primary"
|
||||
type="submit"
|
||||
>Update withdraw link</q-btn
|
||||
>
|
||||
<q-btn
|
||||
v-else
|
||||
unelevated
|
||||
color="primary"
|
||||
:disable="
|
||||
formDialog.data.wallet == null ||
|
||||
formDialog.data.title == null ||
|
||||
(formDialog.data.min_withdrawable == null || formDialog.data.min_withdrawable < 1) ||
|
||||
(
|
||||
formDialog.data.max_withdrawable == null ||
|
||||
formDialog.data.max_withdrawable < 1 ||
|
||||
formDialog.data.max_withdrawable < formDialog.data.min_withdrawable
|
||||
) ||
|
||||
formDialog.data.uses == null ||
|
||||
formDialog.data.wait_time == null"
|
||||
type="submit"
|
||||
>Create withdraw link</q-btn
|
||||
>
|
||||
<q-btn v-close-popup flat color="grey" class="q-ml-auto"
|
||||
>Cancel</q-btn
|
||||
>
|
||||
</div>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<q-dialog
|
||||
v-model="simpleformDialog.show"
|
||||
position="top"
|
||||
@hide="simplecloseFormDialog"
|
||||
>
|
||||
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
|
||||
<q-form @submit="simplesendFormData" class="q-gutter-md">
|
||||
<q-select
|
||||
filled
|
||||
dense
|
||||
emit-value
|
||||
v-model="simpleformDialog.data.wallet"
|
||||
:options="g.user.walletOptions"
|
||||
label="Wallet *"
|
||||
>
|
||||
</q-select>
|
||||
<q-input
|
||||
filled
|
||||
dense
|
||||
v-model.number="simpleformDialog.data.max_withdrawable"
|
||||
type="number"
|
||||
min="10"
|
||||
label="Withdraw amount per voucher (sat, at least 10)"
|
||||
></q-input>
|
||||
<q-input
|
||||
filled
|
||||
dense
|
||||
v-model.number="simpleformDialog.data.uses"
|
||||
type="number"
|
||||
max="250"
|
||||
:default="1"
|
||||
label="Number of vouchers"
|
||||
></q-input>
|
||||
<q-list>
|
||||
<q-item tag="label" class="rounded-borders">
|
||||
<q-item-section avatar>
|
||||
<q-checkbox
|
||||
v-model="simpleformDialog.data.use_custom"
|
||||
color="primary"
|
||||
></q-checkbox>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label>Use a custom voucher design </q-item-label>
|
||||
<q-item-label caption
|
||||
>You can use an LNbits voucher design or a custom
|
||||
one</q-item-label
|
||||
>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
<q-input
|
||||
v-if="simpleformDialog.data.use_custom"
|
||||
filled
|
||||
dense
|
||||
v-model="simpleformDialog.data.custom_url"
|
||||
type="text"
|
||||
label="Custom design .png (optional)"
|
||||
hint="Enter a URL if you want to use a custom design or leave blank for LNbits designed vouchers!"
|
||||
></q-input>
|
||||
|
||||
<div class="row q-mt-lg">
|
||||
<q-btn
|
||||
unelevated
|
||||
color="primary"
|
||||
:disable="
|
||||
simpleformDialog.data.wallet == null ||
|
||||
|
||||
simpleformDialog.data.max_withdrawable == null ||
|
||||
simpleformDialog.data.max_withdrawable < 1 ||
|
||||
simpleformDialog.data.uses == null"
|
||||
type="submit"
|
||||
>Create vouchers</q-btn
|
||||
>
|
||||
<q-btn v-close-popup flat color="grey" class="q-ml-auto"
|
||||
>Cancel</q-btn
|
||||
>
|
||||
</div>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<q-dialog v-model="qrCodeDialog.show" position="top">
|
||||
<q-card v-if="qrCodeDialog.data" class="q-pa-lg lnbits__dialog-card">
|
||||
<q-responsive :ratio="1" class="q-mx-xl q-mb-md">
|
||||
<qrcode
|
||||
:value="qrCodeDialog.data.url + '/?lightning=' + qrCodeDialog.data.lnurl"
|
||||
:options="{width: 800}"
|
||||
class="rounded-borders"
|
||||
></qrcode>
|
||||
{% raw %}
|
||||
</q-responsive>
|
||||
<p style="word-break: break-all">
|
||||
<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>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="primary"
|
||||
class="q-mt-sm"
|
||||
></q-linear-progress>
|
||||
</p>
|
||||
{% endraw %}
|
||||
<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
|
||||
outline
|
||||
color="grey"
|
||||
icon="link"
|
||||
@click="copyText(qrCodeDialog.data.withdraw_url, 'Link copied to clipboard!')"
|
||||
><q-tooltip>Copy sharable link</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
outline
|
||||
color="grey"
|
||||
icon="nfc"
|
||||
@click="writeNfcTag(qrCodeDialog.data.lnurl)"
|
||||
:disable="nfcTagWriting"
|
||||
><q-tooltip>Write to NFC</q-tooltip></q-btn
|
||||
>
|
||||
<q-btn
|
||||
outline
|
||||
color="grey"
|
||||
icon="print"
|
||||
type="a"
|
||||
:href="qrCodeDialog.data.print_url"
|
||||
target="_blank"
|
||||
><q-tooltip>Print</q-tooltip></q-btn
|
||||
>
|
||||
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Close</q-btn>
|
||||
</div>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</div>
|
||||
{% endblock %}
|
||||
71
templates/withdraw/print_qr.html
Normal file
71
templates/withdraw/print_qr.html
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
{% extends "print.html" %} {% block page %}
|
||||
|
||||
<div class="row">
|
||||
<div class="" id="vue">
|
||||
{% for page in link %}
|
||||
<page size="A4" id="pdfprint">
|
||||
<table style="width: 100%">
|
||||
{% for threes in page %}
|
||||
<tr style="height: 59.4mm">
|
||||
{% for one in threes %}
|
||||
<td style="width: 105mm">
|
||||
<center>
|
||||
<qrcode
|
||||
:value="theurl + '/?lightning={{one}}'"
|
||||
:options="{width: 150}"
|
||||
></qrcode>
|
||||
</center>
|
||||
</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</page>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %} {% block styles %}
|
||||
<style>
|
||||
body {
|
||||
background: rgb(204, 204, 204);
|
||||
}
|
||||
page {
|
||||
background: white;
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
margin-bottom: 0.5cm;
|
||||
box-shadow: 0 0 0.5cm rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
page[size='A4'] {
|
||||
width: 21cm;
|
||||
height: 29.7cm;
|
||||
}
|
||||
@media print {
|
||||
body,
|
||||
page {
|
||||
margin: 0px !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
.q-page {
|
||||
padding: 0px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
{% endblock %} {% block scripts %}
|
||||
<script>
|
||||
Vue.component(VueQrcode.name, VueQrcode)
|
||||
|
||||
new Vue({
|
||||
el: '#vue',
|
||||
data: function () {
|
||||
return {
|
||||
theurl: location.protocol + '//' + location.host,
|
||||
printDialog: {
|
||||
show: true,
|
||||
data: null
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
113
templates/withdraw/print_qr_custom.html
Normal file
113
templates/withdraw/print_qr_custom.html
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
{% extends "print.html" %} {% block page %}
|
||||
|
||||
<div class="row">
|
||||
<div class="" id="vue">
|
||||
{% for page in link %}
|
||||
<page size="A4" id="pdfprint">
|
||||
{% for one in page %}
|
||||
<div class="wrapper">
|
||||
<img src="{{custom_url}}" alt="..." />
|
||||
<span>{{ amt }} sats</span>
|
||||
<div class="lnurlw">
|
||||
<qrcode
|
||||
:value="theurl + '/?lightning={{one}}'"
|
||||
:options="{width: 95, margin: 1}"
|
||||
></qrcode>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</page>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %} {% block styles %}
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400');
|
||||
body {
|
||||
background: rgb(204, 204, 204);
|
||||
}
|
||||
page {
|
||||
background: white;
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
margin-bottom: 0.5cm;
|
||||
box-shadow: 0 0 0.5cm rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
page[size='A4'] {
|
||||
width: 21cm;
|
||||
height: 29.7cm;
|
||||
}
|
||||
.wrapper {
|
||||
position: relative;
|
||||
margin-bottom: 1rem;
|
||||
padding: 1rem;
|
||||
width: fit-content;
|
||||
}
|
||||
.wrapper span {
|
||||
display: block;
|
||||
position: absolute;
|
||||
font-family: 'Inter';
|
||||
font-size: 0.75rem;
|
||||
color: #fff;
|
||||
top: calc(3.2mm + 1rem);
|
||||
right: calc(4mm + 1rem);
|
||||
}
|
||||
.wrapper img {
|
||||
display: block;
|
||||
width: 187mm;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.wrapper .lnurlw {
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: calc(7.3mm + 1rem);
|
||||
left: calc(7.5mm + 1rem);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
@media print {
|
||||
body,
|
||||
page {
|
||||
margin: 0px !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
.q-page,
|
||||
.wrapper {
|
||||
padding: 0px !important;
|
||||
}
|
||||
.wrapper span {
|
||||
top: 3mm;
|
||||
right: 4mm;
|
||||
}
|
||||
.wrapper .lnurlw {
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 7.3mm;
|
||||
left: 7.5mm;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
{% endblock %} {% block scripts %}
|
||||
<script>
|
||||
Vue.component(VueQrcode.name, VueQrcode)
|
||||
|
||||
new Vue({
|
||||
el: '#vue',
|
||||
data: function () {
|
||||
return {
|
||||
theurl: location.protocol + '//' + location.host,
|
||||
printDialog: {
|
||||
show: true,
|
||||
data: null
|
||||
},
|
||||
links: []
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.links = '{{ link | tojson }}'
|
||||
}
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
Loading…
Add table
Add a link
Reference in a new issue