mirror of
https://github.com/lnbits/lnbits.git
synced 2025-07-01 02:51:29 +02:00
Merge pull request #595 from lnbits/lnurlwlist
Adds csv list to lnurlw extension
This commit is contained in:
10
lnbits/extensions/withdraw/templates/withdraw/csv.html
Normal file
10
lnbits/extensions/withdraw/templates/withdraw/csv.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{% 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 %}
|
@ -1,17 +1,12 @@
|
|||||||
{% extends "base.html" %} {% from "macros.jinja" import window_vars with context
|
{% extends "base.html" %} {% from "macros.jinja" import window_vars with context %} {% block scripts %} {{ window_vars(user) }}
|
||||||
%} {% block scripts %} {{ window_vars(user) }}
|
|
||||||
<script src="/withdraw/static/js/index.js"></script>
|
<script src="/withdraw/static/js/index.js"></script>
|
||||||
{% endblock %} {% block page %}
|
{% endblock %} {% block page %}
|
||||||
<div class="row q-col-gutter-md">
|
<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="primary" @click="simpleformDialog.show = true"
|
<q-btn unelevated color="primary" @click="simpleformDialog.show = true">Quick vouchers</q-btn>
|
||||||
>Quick vouchers</q-btn
|
<q-btn unelevated color="primary" @click="formDialog.show = true">Advanced withdraw link(s)</q-btn>
|
||||||
>
|
|
||||||
<q-btn unelevated color="primary" @click="formDialog.show = true"
|
|
||||||
>Advanced withdraw link(s)</q-btn
|
|
||||||
>
|
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|
||||||
@ -25,14 +20,7 @@
|
|||||||
<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
|
<q-table dense flat :data="sortedWithdrawLinks" row-key="id" :columns="withdrawLinksTable.columns" :pagination.sync="withdrawLinksTable.pagination">
|
||||||
dense
|
|
||||||
flat
|
|
||||||
:data="sortedWithdrawLinks"
|
|
||||||
row-key="id"
|
|
||||||
:columns="withdrawLinksTable.columns"
|
|
||||||
:pagination.sync="withdrawLinksTable.pagination"
|
|
||||||
>
|
|
||||||
{% raw %}
|
{% raw %}
|
||||||
<template v-slot:header="props">
|
<template v-slot:header="props">
|
||||||
<q-tr :props="props">
|
<q-tr :props="props">
|
||||||
@ -69,6 +57,17 @@
|
|||||||
target="_blank"
|
target="_blank"
|
||||||
><q-tooltip> embeddable image </q-tooltip></q-btn
|
><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
|
<q-btn
|
||||||
unelevated
|
unelevated
|
||||||
dense
|
dense
|
||||||
@ -101,8 +100,7 @@
|
|||||||
></q-btn>
|
></q-btn>
|
||||||
</q-td>
|
</q-td>
|
||||||
</q-tr>
|
</q-tr>
|
||||||
</template>
|
</template> {% endraw %}
|
||||||
{% endraw %}
|
|
||||||
</q-table>
|
</q-table>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
@ -129,101 +127,37 @@
|
|||||||
<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
|
<q-select filled dense emit-value v-model="formDialog.data.wallet" :options="g.user.walletOptions" label="Wallet *">
|
||||||
filled
|
|
||||||
dense
|
|
||||||
emit-value
|
|
||||||
v-model="formDialog.data.wallet"
|
|
||||||
:options="g.user.walletOptions"
|
|
||||||
label="Wallet *"
|
|
||||||
>
|
|
||||||
</q-select>
|
</q-select>
|
||||||
<q-input
|
<q-input filled dense v-model.trim="formDialog.data.title" type="text" label="Link title *"></q-input>
|
||||||
filled
|
<q-input filled dense v-model.number="formDialog.data.min_withdrawable" type="number" min="10" label="Min withdrawable (sat, at least 10) *"></q-input>
|
||||||
dense
|
<q-input filled dense v-model.number="formDialog.data.max_withdrawable" type="number" min="10" label="Max withdrawable (sat, at least 10) *"></q-input>
|
||||||
v-model.trim="formDialog.data.title"
|
<q-input filled dense v-model.number="formDialog.data.uses" type="number" :default="1" label="Amount of uses *"></q-input>
|
||||||
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"
|
|
||||||
:default="1"
|
|
||||||
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
|
<q-input filled dense v-model.number="formDialog.data.wait_time" type="number" :default="1" label="Time between withdrawals *">
|
||||||
filled
|
|
||||||
dense
|
|
||||||
v-model.number="formDialog.data.wait_time"
|
|
||||||
type="number"
|
|
||||||
:default="1"
|
|
||||||
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
|
<q-select filled dense v-model="formDialog.secondMultiplier" :options="formDialog.secondMultiplierOptions">
|
||||||
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
|
<q-checkbox v-model="formDialog.data.is_unique" color="primary"></q-checkbox>
|
||||||
v-model="formDialog.data.is_unique"
|
|
||||||
color="primary"
|
|
||||||
></q-checkbox>
|
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
<q-item-section>
|
<q-item-section>
|
||||||
<q-item-label
|
<q-item-label>Use unique withdraw QR codes to reduce `assmilking`
|
||||||
>Use unique withdraw QR codes to reduce
|
</q-item-label>
|
||||||
`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-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-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
</q-list>
|
</q-list>
|
||||||
<div class="row q-mt-lg">
|
<div class="row q-mt-lg">
|
||||||
<q-btn
|
<q-btn v-if="formDialog.data.id" unelevated color="primary" type="submit">Update withdraw link</q-btn>
|
||||||
v-if="formDialog.data.id"
|
<q-btn v-else unelevated color="primary" :disable="
|
||||||
unelevated
|
|
||||||
color="primary"
|
|
||||||
type="submit"
|
|
||||||
>Update withdraw link</q-btn
|
|
||||||
>
|
|
||||||
<q-btn
|
|
||||||
v-else
|
|
||||||
unelevated
|
|
||||||
color="primary"
|
|
||||||
:disable="
|
|
||||||
formDialog.data.wallet == null ||
|
formDialog.data.wallet == null ||
|
||||||
formDialog.data.title == null ||
|
formDialog.data.title == null ||
|
||||||
(formDialog.data.min_withdrawable == null || formDialog.data.min_withdrawable < 1) ||
|
(formDialog.data.min_withdrawable == null || formDialog.data.min_withdrawable < 1) ||
|
||||||
@ -233,67 +167,29 @@
|
|||||||
formDialog.data.max_withdrawable < formDialog.data.min_withdrawable
|
formDialog.data.max_withdrawable < formDialog.data.min_withdrawable
|
||||||
) ||
|
) ||
|
||||||
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>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
|
|
||||||
<q-dialog
|
<q-dialog v-model="simpleformDialog.show" position="top" @hide="simplecloseFormDialog">
|
||||||
v-model="simpleformDialog.show"
|
|
||||||
position="top"
|
|
||||||
@hide="simplecloseFormDialog"
|
|
||||||
>
|
|
||||||
<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="simplesendFormData" class="q-gutter-md">
|
<q-form @submit="simplesendFormData" class="q-gutter-md">
|
||||||
<q-select
|
<q-select filled dense emit-value v-model="simpleformDialog.data.wallet" :options="g.user.walletOptions" label="Wallet *">
|
||||||
filled
|
|
||||||
dense
|
|
||||||
emit-value
|
|
||||||
v-model="simpleformDialog.data.wallet"
|
|
||||||
:options="g.user.walletOptions"
|
|
||||||
label="Wallet *"
|
|
||||||
>
|
|
||||||
</q-select>
|
</q-select>
|
||||||
<q-input
|
<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>
|
||||||
filled
|
<q-input filled dense v-model.number="simpleformDialog.data.uses" type="number" :default="1" label="Number of vouchers"></q-input>
|
||||||
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"
|
|
||||||
:default="1"
|
|
||||||
label="Number of vouchers"
|
|
||||||
></q-input>
|
|
||||||
|
|
||||||
<div class="row q-mt-lg">
|
<div class="row q-mt-lg">
|
||||||
<q-btn
|
<q-btn unelevated color="primary" :disable="
|
||||||
unelevated
|
|
||||||
color="primary"
|
|
||||||
:disable="
|
|
||||||
simpleformDialog.data.wallet == null ||
|
simpleformDialog.data.wallet == null ||
|
||||||
|
|
||||||
simpleformDialog.data.max_withdrawable == null ||
|
simpleformDialog.data.max_withdrawable == null ||
|
||||||
simpleformDialog.data.max_withdrawable < 1 ||
|
simpleformDialog.data.max_withdrawable < 1 ||
|
||||||
simpleformDialog.data.uses == null"
|
simpleformDialog.data.uses == null" type="submit">Create vouchers</q-btn>
|
||||||
type="submit"
|
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Cancel</q-btn>
|
||||||
>Create vouchers</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>
|
||||||
@ -302,19 +198,12 @@
|
|||||||
<q-dialog v-model="qrCodeDialog.show" position="top">
|
<q-dialog v-model="qrCodeDialog.show" position="top">
|
||||||
<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">
|
||||||
<q-responsive :ratio="1" class="q-mx-xl q-mb-md">
|
<q-responsive :ratio="1" class="q-mx-xl q-mb-md">
|
||||||
<qrcode
|
<qrcode :value="qrCodeDialog.data.url + '/?lightning=' + qrCodeDialog.data.lnurl" :options="{width: 800}" class="rounded-borders"></qrcode>
|
||||||
:value="qrCodeDialog.data.url + '/?lightning=' + qrCodeDialog.data.lnurl"
|
|
||||||
:options="{width: 800}"
|
|
||||||
class="rounded-borders"
|
|
||||||
></qrcode>
|
|
||||||
{% raw %}
|
{% raw %}
|
||||||
</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
|
<strong>Unique:</strong> {{ qrCodeDialog.data.is_unique }}<span v-if="qrCodeDialog.data.is_unique" class="text-deep-purple">
|
||||||
v-if="qrCodeDialog.data.is_unique"
|
|
||||||
class="text-deep-purple"
|
|
||||||
>
|
|
||||||
(QR code will change after each withdrawal)</span
|
(QR code will change after each withdrawal)</span
|
||||||
><br />
|
><br />
|
||||||
<strong>Max. withdrawable:</strong> {{
|
<strong>Max. withdrawable:</strong> {{
|
||||||
|
@ -102,3 +102,37 @@ async def print_qr(request: Request, link_id):
|
|||||||
return withdraw_renderer().TemplateResponse(
|
return withdraw_renderer().TemplateResponse(
|
||||||
"withdraw/print_qr.html", {"request": request, "link": linked, "unique": True}
|
"withdraw/print_qr.html", {"request": request, "link": linked, "unique": True}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@withdraw_ext.get("/csv/{link_id}", response_class=HTMLResponse)
|
||||||
|
async def print_qr(request: Request, link_id):
|
||||||
|
link = await get_withdraw_link(link_id)
|
||||||
|
if not link:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=HTTPStatus.NOT_FOUND, detail="Withdraw link does not exist."
|
||||||
|
)
|
||||||
|
# response.status_code = HTTPStatus.NOT_FOUND
|
||||||
|
# return "Withdraw link does not exist."
|
||||||
|
|
||||||
|
if link.uses == 0:
|
||||||
|
|
||||||
|
return withdraw_renderer().TemplateResponse(
|
||||||
|
"withdraw/csv.html",
|
||||||
|
{"request": request, "link": link.dict(), "unique": False},
|
||||||
|
)
|
||||||
|
links = []
|
||||||
|
count = 0
|
||||||
|
|
||||||
|
for x in link.usescsv.split(","):
|
||||||
|
linkk = await get_withdraw_link(link_id, count)
|
||||||
|
if not linkk:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=HTTPStatus.NOT_FOUND, detail="Withdraw link does not exist."
|
||||||
|
)
|
||||||
|
links.append(str(linkk.lnurl(request)))
|
||||||
|
count = count + 1
|
||||||
|
page_link = list(chunks(links, 2))
|
||||||
|
linked = list(chunks(page_link, 5))
|
||||||
|
|
||||||
|
return withdraw_renderer().TemplateResponse(
|
||||||
|
"withdraw/csv.html", {"request": request, "link": linked, "unique": True}
|
||||||
|
)
|
Reference in New Issue
Block a user