lnbits-legend/lnbits/extensions/diagonalley/templates/diagonalley/index.html
2022-07-18 09:11:19 +01:00

1590 lines
45 KiB
HTML

{% extends "base.html" %} {% from "macros.jinja" import window_vars with context
%} {% block page %}
<div class="row q-col-gutter-md">
<!-- PRODUCT DIALOG -->
<q-dialog v-model="productDialog.show" position="top">
<q-card class="q-pa-lg q-pt-xl" style="width: 500px">
<q-form @submit="sendProductFormData" class="q-gutter-md">
<q-select
filled
dense
emit-value
v-model="productDialog.data.stall"
:options="stalls.map(s => ({label: s.name, value: s.id}))"
label="Stall"
>
</q-select>
<q-input
filled
dense
v-model.trim="productDialog.data.product"
label="Product"
></q-input>
<q-input
filled
dense
v-model.trim="productDialog.data.description"
label="Description"
></q-input>
<!-- <div class="row"> -->
<!-- <div class="col-5">
<q-select
filled
dense
multiple
v-model.trim="productDialog.data.categories"
:options="categories"
label="Categories"
class="q-pr-sm"
></q-select>
</div> -->
<!-- <div class="col-7"> -->
<q-select
filled
multiple
dense
emit-value
v-model.trim="productDialog.data.categories"
use-input
use-chips
multiple
hide-dropdown-icon
input-debounce="0"
new-value-mode="add-unique"
label="Categories"
placeholder="crafts,robots,etc"
hint="Hit Enter to add"
></q-select>
<!-- </div> -->
<!-- </div> -->
<q-file
class="q-pr-md"
filled
dense
capture="environment"
accept="image/jpeg, image/png"
:max-file-size="3*1024**2"
label="Small image (optional)"
clearable
@input="imageAdded"
@clear="imageCleared"
>
<template v-if="productDialog.data.image" v-slot:before>
<img style="height: 1em" :src="productDialog.data.image" />
</template>
<template v-if="productDialog.data.image" v-slot:append>
<q-icon
name="cancel"
@click.stop.prevent="imageCleared"
class="cursor-pointer"
/>
</template>
</q-file>
<q-input
filled
dense
v-model.number="productDialog.data.price"
type="number"
label="Price"
></q-input>
<q-input
filled
dense
v-model.number="productDialog.data.quantity"
type="number"
label="Quantity"
></q-input>
<div class="row q-mt-lg">
<q-btn
v-if="productDialog.data.id"
unelevated
color="primary"
type="submit"
>Update Product</q-btn
>
<q-btn
v-else
unelevated
color="primary"
:disable="productDialog.data.price == null
|| productDialog.data.product == null
|| productDialog.data.description == null
|| productDialog.data.quantity == null"
type="submit"
>Create Product</q-btn
>
<q-btn v-close-popup flat @click="resetDialog('productDialog')" color="grey" class="q-ml-auto"
>Cancel</q-btn
>
</div>
</q-form>
</q-card>
</q-dialog>
<!-- ZONE DIALOG -->
<q-dialog v-model="zoneDialog.show" position="top">
<q-card class="q-pa-lg q-pt-xl" style="width: 500px">
<q-form @submit="sendZoneFormData" class="q-gutter-md">
<q-select
filled
dense
multiple
:options="shippingZoneOptions"
label="Countries"
v-model.trim="zoneDialog.data.countries"
></q-select>
<q-input
filled
dense
type="number"
v-model.trim="zoneDialog.data.cost"
label="Cost (sats)"
></q-input>
<div class="row q-mt-lg">
<q-btn
v-if="zoneDialog.data.id"
unelevated
color="primary"
type="submit"
>Update Shipping Zone</q-btn
>
<q-btn
v-else
unelevated
color="primary"
:disable="zoneDialog.data.countries == null
|| zoneDialog.data.cost == null"
type="submit"
>Create Shipping Zone</q-btn
>
<q-btn v-close-popup flat @click="resetDialog('zoneDialog')" color="grey" class="q-ml-auto"
>Cancel</q-btn
>
</div>
</q-form>
</q-card>
</q-dialog>
<!-- SHOP DIALOG -->
<q-dialog v-model="shopDialog.show" position="top">
<q-card class="q-pa-lg q-pt-xl" style="width: 500px">
<q-form @submit="sendShopFormData" class="q-gutter-md">
<q-toggle
label="Activate shop"
color="primary"
v-model="shopDialog.data.activate"
></q-toggle>
<q-select
filled
dense
multiple
emit-value
:options="stalls.map(s => ({label: s.name, value: s.id}))"
label="Stalls"
v-model.trim="shopDialog.data.stalls"
></q-select>
<div class="row q-mt-lg">
<q-btn
v-if="shopDialog.data.id"
unelevated
color="primary"
type="submit"
>Update Relay</q-btn
>
<q-btn
v-else
unelevated
color="primary"
:disable="shopDialog.data.activate == null
|| shopDialog.data.stalls == null"
type="submit"
>Launch</q-btn
>
<q-btn v-close-popup flat @click="resetDialog('shopDialog')" color="grey" class="q-ml-auto"
>Cancel</q-btn
>
</div>
</q-form>
</q-card>
</q-dialog>
<!-- STALL/STORE DIALOG -->
<q-dialog v-model="stallDialog.show" position="top">
<q-card class="q-pa-lg q-pt-xl" style="width: 500px">
<q-form @submit="sendStallFormData" class="q-gutter-md">
<q-input
filled
dense
v-model.trim="stallDialog.data.name"
label="Name"
></q-input>
<q-select
filled
dense
emit-value
v-model="stallDialog.data.wallet"
:options="g.user.walletOptions"
label="Wallet *"
>
</q-select>
<!-- NOSTR -->
<!-- <div class="row">
<div class="col-5">
<q-btn unelevated @onclick="generateKeys" color="primary">Generate keys</q-btn>
</div>
<div class="col-5">
<q-btn unelevated @onclick="restoreKeys" color="primary">Restore keys</q-btn>
</div>
</div>
<q-input
v-if="stallDialog.restorekeys"
filled
dense
v-model.trim="stallDialog.data.publickey"
label="Public Key"
></q-input>
<q-input
v-if="stallDialog.restorekeys"
filled
dense
v-model.trim="stallDialog.data.privatekey"
label="Private Key"
></q-input> -->
<q-select
:options="zoneOptions"
filled
dense
multiple
v-model.trim="stallDialog.data.shippingzones"
label="Shipping Zones"
></q-select>
<!-- NOSTR -->
<!-- <q-select
:options="relayOptions"
filled
dense
multiple
v-model.trim="stallDialog.data.relays"
label="Relays"
></q-select>
<q-input
filled
dense
v-model.trim="stallDialog.data.crelays"
label="Custom relays (seperate by comma)"
></q-input>
<q-input
filled
dense
v-model.trim="stallDialog.data.nostrShops"
label="Nostr shop public keys (seperate by comma)"
></q-input> -->
<p><strong><small>Nostr support coming soon!</small></strong></p>
<div class="row q-mt-lg">
<q-btn
v-if="stallDialog.data.id"
unelevated
color="primary"
type="submit"
>Update Store</q-btn
>
<q-btn
v-else
unelevated
color="primary"
:disable="stallDialog.data.wallet == null
|| stallDialog.data.shippingzones == null"
type="submit"
>Create Store</q-btn
>
<q-btn v-close-popup flat @click="resetDialog('stallDialog')" color="grey" class="q-ml-auto"
>Cancel</q-btn
>
</div>
</q-form>
</q-card>
</q-dialog>
<div class="col-12 col-md-8 col-lg-7 q-gutter-y-md">
<q-card>
<q-card-section>
<q-btn unelevated v-if="stalls.length > 0" color="primary" @click="productDialog.show = true"
>+ Product <q-tooltip> List a product </q-tooltip></q-btn
>
<q-btn unelevated v-else color="primary" @click="errorMessage('First set shipping zone(s), then create a stall.')"
>+ Product <q-tooltip> List a product </q-tooltip></q-btn
>
<q-btn unelevated color="primary" @click="zoneDialog.show = true"
>+ Shipping Zone<q-tooltip> Create a shipping zone </q-tooltip></q-btn
>
<q-btn unelevated v-if="zones.length > 0" color="primary" @click="openStallDialog()"
>+ Store
<q-tooltip> Create a stall to list products on </q-tooltip></q-btn
>
<q-btn unelevated v-else color="primary" @click="errorMessage('First set shipping zone(s).')"
>+ Store
<q-tooltip> Create a store to list products on </q-tooltip></q-btn
>
<q-btn unelevated color="primary" @click="shopDialog.show = true"
>Launch frontend shop (not Nostr)
<q-tooltip> Makes a simple frontend shop for your stalls</q-tooltip></q-btn
>
</q-card-section>
</q-card>
<q-card> <!-- ORDERS TABLE -->
<q-card-section>
<div class="row items-center no-wrap q-mb-md">
<div class="col">
<h5 class="text-subtitle1 q-my-none">Orders</h5>
</div>
<div class="col-auto">
<q-btn flat color="grey" @click="exportOrdersCSV"
>Export to CSV</q-btn
>
</div>
</div>
<q-table
dense
flat
:data="orders"
row-key="id"
:columns="ordersTable.columns"
:pagination.sync="ordersTable.pagination"
>
{% raw %}
<template v-slot:header="props">
<q-tr :props="props">
<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 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="shipOrder(props.row.id)"
icon="add_shopping_cart"
color="green"
>
<q-tooltip> Product shipped? </q-tooltip>
</q-btn>
</q-td>
<q-td auto-width>
<q-btn
flat
dense
size="xs"
@click="deleteOrder(props.row.id)"
icon="cancel"
color="pink"
></q-btn>
</q-td>
</q-tr>
</template>
{% endraw %}
</q-table>
</q-card-section>
</q-card>
<q-card> <!-- PRODUCTS TABLE -->
<q-card-section>
<div class="row items-center no-wrap q-mb-md">
<div class="col">
<h5 class="text-subtitle1 q-my-none">Products</h5>
</div>
<div class="col-auto">
<q-btn flat color="grey" @click="exportProductsCSV"
>Export to CSV</q-btn
>
</div>
</div>
<q-table
dense
flat
:data="products"
row-key="id"
:columns="productsTable.columns"
:pagination.sync="productsTable.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="add_shopping_cart"
:color="($q.dark.isActive) ? 'grey-7' : 'grey-5'"
type="a"
:href="props.row.wallet"
target="_blank"
></q-btn>
<q-tooltip> Link to pass to stall relay </q-tooltip>
</q-td>
<q-td v-for="col in props.cols" :key="col.name" :props="props">
{{ col.value }}
</q-td>
<q-td class="text-center" auto-width>
<img
v-if="props.row.image"
:src="props.row.image"
style="height: 1.5em"
/>
</q-td>
<q-td auto-width>
<q-btn
flat
dense
size="xs"
@click="openProductUpdateDialog(props.row.id)"
icon="edit"
color="light-blue"
></q-btn>
<q-btn
flat
dense
size="xs"
@click="deleteProduct(props.row.id)"
icon="cancel"
color="pink"
></q-btn>
</q-td>
</q-tr>
</template>
{% endraw %}
</q-table>
</q-card-section>
</q-card>
<q-card> <!-- STORES TABLE -->
<q-card-section>
<div class="row items-center no-wrap q-mb-md">
<div class="col">
<h5 class="text-subtitle1 q-my-none">Stores</h5>
</div>
<div class="col-auto">
<q-btn flat color="grey" @click="exportStallsCSV"
>Export to CSV</q-btn
>
</div>
</div>
<q-table
dense
flat
:data="stalls"
row-key="id"
:columns="stallTable.columns"
:pagination.sync="stallTable.pagination"
>
{% raw %}
<template v-slot:header="props">
<q-tr :props="props">
<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 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="openStallUpdateDialog(props.row.id)"
icon="edit"
color="light-blue"
></q-btn>
<q-btn
flat
dense
size="xs"
@click="deleteStall(props.row.id)"
icon="cancel"
color="pink"
></q-btn>
</q-td>
</q-tr>
</template>
{% endraw %}
</q-table>
</q-card-section>
</q-card>
<q-card> <!-- ZONES TABLE -->
<q-card-section>
<div class="row items-center no-wrap q-mb-md">
<div class="col">
<h5 class="text-subtitle1 q-my-none">Shipping Zones</h5>
</div>
<div class="col-auto">
<q-btn flat color="grey" @click="exportZonesCSV"
>Export to CSV</q-btn
>
</div>
</div>
<q-table
dense
flat
:data="zones"
row-key="id"
:columns="zonesTable.columns"
:pagination.sync="zonesTable.pagination"
>
{% raw %}
<template v-slot:header="props">
<q-tr :props="props">
<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 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="openZoneUpdateDialog(props.row.id)"
icon="edit"
color="light-blue"
></q-btn>
<q-btn
flat
dense
size="xs"
@click="deleteZone(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">
LNbits Diagon Alley Extension, powered by Nostr
</h6>
</q-card-section>
<q-card-section class="q-pa-none">
<q-separator></q-separator>
<q-list> {% include "diagonalley/_api_docs.html" %} </q-list>
</q-card-section>
</q-card>
<q-card>
<q-card-section>
<h6 class="text-subtitle1 q-my-none">Messages</h6>
</q-card-section>
<q-card-section class="q-pa-none" >
<q-separator></q-separator>
<div class="column q-ma-md q-pb-lg"
style="height: 350px">
<div class="col q-pb-md">
<q-select v-model="customerKey" style="width: 80%;"
:options="customerKeys" label="Customers" @input="getMessages(customerKey)"></q-select>
</div>
<div class="col-8 q-px-md">
<div v-for="message in customerMessages">
<q-chat-message
v-if="message[0] == 'out'"
:text="[message[1]]"
sent
></q-chat-message>
<q-chat-message
v-else
:text="[message[1]]"
></q-chat-message>
</div>
</div>
<div class="col on-right" style="width: 90%">
<q-input >
<template v-slot:after>
<q-btn round dense flat icon="send" />
</template>
</q-input>
</div>
</div>
</q-card-section>
</q-card>
</div>
</div>
</div>
</div>
{% endblock %} {% block scripts %} {{ window_vars(user) }}
<script src="https://cdn.jsdelivr.net/npm/pica@6.1.1/dist/pica.min.js"></script>
<script>
Vue.component(VueQrcode.name, VueQrcode)
const pica = window.pica()
const mapStalls = obj => {
obj._data = _.clone(obj)
return obj
}
const mapProducts = obj => {
obj._data = _.clone(obj)
console.log(obj)
return obj
}
const mapZone = obj => {
obj._data = _.clone(obj)
return obj
}
const mapOrders = obj => {
obj._data = _.clone(obj)
return obj
}
const mapKeys = obj => {
obj._data = _.clone(obj)
return obj
}
const humanReadableZones = (zones) => {
return zones.map(z => `${z.id} - ${z.countries}`)
}
new Vue({
el: '#vue',
mixins: [windowMixin],
data: function () {
return {
products: [],
orders: [],
stalls: [],
zones: [],
zoneOptions: [],
customerKeys: [],
customerKey: '',
customerMessages: {},
shippedModel: false,
shippingZoneOptions: [
'Worldwide',
'Europe',
'Australia',
'Austria',
'Belgium',
'Brazil',
'Canada',
'Denmark',
'Finland',
'France',
'Germany',
'Greece',
'Hong Kong',
'Hungary',
'Ireland',
'Indonesia',
'Israel',
'Italy',
'Japan',
'Kazakhstan',
'Korea',
'Luxembourg',
'Malaysia',
'Mexico',
'Netherlands',
'New Zealand',
'Norway',
'Poland',
'Portugal',
'Russia',
'Saudi Arabia',
'Singapore',
'Spain',
'Sweden',
'Switzerland',
'Thailand',
'Turkey',
'Ukraine',
'United Kingdom**',
'United States***',
'Vietnam',
'China'
],
categories: [
'Fashion (clothing and accessories)',
'Health (and beauty)',
'Toys (and baby equipment)',
'Media (Books and CDs)',
'Groceries (Food and Drink)',
'Technology (Phones and Computers)',
'Home (furniture and accessories)',
'Gifts (flowers, cards, etc)',
'Adult',
'Other'
],
relayOptions: [
'wss://nostr-relay.herokuapp.com/ws',
'wss://nostr-relay.bigsun.xyz/ws',
'wss://freedom-relay.herokuapp.com/ws'
],
label: '',
ordersTable: {
columns: [
{
name: 'product',
align: 'left',
label: 'Product',
field: 'product'
},
{
name: 'quantity',
align: 'left',
label: 'Quantity',
field: 'quantity'
},
{
name: 'address',
align: 'left',
label: 'Address',
field: 'address'
},
{
name: 'invoiceid',
align: 'left',
label: 'InvoiceID',
field: 'invoiceid'
},
{name: 'paid', align: 'left', label: 'Paid', field: 'paid'},
{name: 'shipped', align: 'left', label: 'Shipped', field: 'shipped'}
],
pagination: {
rowsPerPage: 10
}
},
productsTable: {
columns: [
{
name: 'stall',
align: 'left',
label: 'Stall',
field: 'stall'
},
{
name: 'product',
align: 'left',
label: 'Product',
field: 'product'
},
{
name: 'description',
align: 'left',
label: 'Description',
field: 'description'
},
{
name: 'categories',
align: 'left',
label: 'Categories',
field: 'categories'
},
{name: 'price', align: 'left', label: 'Price', field: 'price'},
{
name: 'quantity',
align: 'left',
label: 'Quantity',
field: 'quantity'
},
{name: 'id', align: 'left', label: 'ID', field: 'id'}
],
pagination: {
rowsPerPage: 10
}
},
stallTable: {
columns: [
{
name: 'id',
align: 'left',
label: 'ID',
field: 'id'
},
{
name: 'name',
align: 'left',
label: 'Name',
field: 'name'
},
{
name: 'wallet',
align: 'left',
label: 'Wallet',
field: 'wallet'
},
{
name: 'publickey',
align: 'left',
label: 'Public key',
field: 'publickey'
},
{
name: 'privatekey',
align: 'left',
label: 'Private key',
field: 'privatekey'
}
],
pagination: {
rowsPerPage: 10
}
},
zonesTable: {
columns: [
{
name: 'id',
align: 'left',
label: 'ID',
field: 'id'
},
{
name: 'countries',
align: 'left',
label: 'Countries',
field: 'countries'
},
{
name: 'cost',
align: 'left',
label: 'Cost',
field: 'cost'
}
],
pagination: {
rowsPerPage: 10
}
},
productDialog: {
show: false,
data: {}
},
stallDialog: {
show: false,
data: {}
},
zoneDialog: {
show: false,
data: {countries:[]}
},
shopDialog: {
show: false,
data: {activate: false}
},
orderDialog: {
show: false,
data: {}
},
relayDialog: {
show: false,
data: {}
}
}
},
computed: {
categoryOther: function () {
cats = trim(this.productDialog.data.categories.split(','))
for (let i = 0; i < cats.length; i++) {
if (cats[i] == 'Others') {
return true
}
}
return false
}
},
methods: {
resetDialog(dialog){
this[dialog].show = false
this[dialog].data = {}
},
generateKeys: function(){
var self = this
LNbits.api
.request(
'GET',
'/diagonalley/api/v1/keys',
self.g.user.wallets[0].adminkey
)
.then(function (response) {
if (response.data) {
self.keys = response.data.map(mapKeys)
}
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
restoreKeys: function(){
},
capitalizeFirstLetter: function (string) {
return string.charAt(0).toUpperCase() + string.slice(1);
},
errorMessage: function (error) {
this.$q.notify({
color: 'primary',
message: error
})
},
////////////////////////////////////////
///////////SUPPORT MESSAGES/////////////
////////////////////////////////////////
getMessages: function (customerKey) {
var self = this
messages = []
messages.push(['in', 'blah blah'])
messages.push(['out', 'blah blah'])
self.customerMessages = messages
},
////////////////////////////////////////
////////////////STALLS//////////////////
////////////////////////////////////////
getStalls: function () {
console.log(this.g.user)
var self = this
LNbits.api
.request(
'GET',
'/diagonalley/api/v1/stalls?all_wallets=true',
self.g.user.wallets[0].adminkey
)
.then(function (response) {
if (response.data) {
self.stalls = response.data.map(mapStalls)
console.log(self.stalls)
}
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
openStallDialog: function () {
this.zoneOptions = humanReadableZones(this.zones)
this.stallDialog.show = true
},
openStallUpdateDialog: function (linkId) {
var self = this
var link = _.findWhere(self.stalls, {id: linkId})
this.zoneOptions = humanReadableZones(this.zones)
this.stallDialog.data = _.clone(link._data)
let shippingzones = this.zoneOptions.filter(z => this.stallDialog.data.shippingzones.split(",").includes(z.split("-")[0].trim()))
this.stallDialog.data.shippingzones = shippingzones//this.stallDialog.data.shippingzones.split(",")
console.log(this.stallDialog.data)
//let zones = this.zoneOptions
// .filter(z => z.id == )
this.stallDialog.show = true
},
sendStallFormData: function () {
let data = {
name: this.stallDialog.data.name,
wallet: this.stallDialog.data.wallet,
publickey: this.stallDialog.data.publickey,
privatekey: this.stallDialog.data.privatekey,
relays: this.stallDialog.data.relays,
shippingzones: this.stallDialog.data.shippingzones
.map(z => z.split("-")[0].trim())
.toString()
}
if (this.stallDialog.data.id) {
this.stallDialog.data = {...this.stallDialog.data, ...data}
this.updateStall(this.stallDialog.data)
} else {
this.createStall(data)
}
},
updateStall: function (data) {
console.log(data)
var self = this
LNbits.api
.request(
'PUT',
'/diagonalley/api/v1/stalls/' + data.id,
_.findWhere(self.g.user.wallets, {
id: self.stallDialog.data.wallet
}).inkey,
data
)
.then(function (response) {
self.stalls = _.reject(self.stalls, function (obj) {
return obj.id == data.id
})
self.stalls.push(mapStalls(response.data))
self.resetDialog('stallDialog')
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
createStall: function (data) {
var self = this
LNbits.api
.request(
'POST',
'/diagonalley/api/v1/stalls',
_.findWhere(self.g.user.wallets, {
id: self.stallDialog.data.wallet
}).inkey,
data
)
.then(function (response) {
self.stalls.push(mapStalls(response.data))
self.resetDialog('stallDialog')
//self.stallDialog.show = false
//self.stallDialog.data = {}
//data = {}
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
deleteStall: function (stallId) {
var self = this
var stall = _.findWhere(self.stalls, {id: stallId})
LNbits.utils
.confirmDialog('Are you sure you want to delete this Stall link?')
.onOk(function () {
LNbits.api
.request(
'DELETE',
'/diagonalley/api/v1/stalls/' + stallId,
_.findWhere(self.g.user.wallets, {id: stall.wallet}).adminkey
)
.then(function (response) {
self.stalls = _.reject(self.stalls, function (obj) {
return obj.id == stallId
})
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
})
},
exportStallsCSV: function () {
LNbits.utils.exportCSV(this.stallsTable.columns, this.stalls)
},
////////////////////////////////////////
///////////////PRODUCTS/////////////////
////////////////////////////////////////
getProducts: function () {
var self = this
LNbits.api
.request(
'GET',
'/diagonalley/api/v1/products?all_stalls=true',
self.g.user.wallets[0].inkey
)
.then(function (response) {
console.log("RESP DATA", response.data)
if (response.data) {
self.products = response.data.map(mapProducts)
}
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
openProductUpdateDialog: function (linkId) {
var self = this
var link = _.findWhere(self.products, {id: linkId})
self.productDialog.data = _.clone(link._data)
self.productDialog.data.categories = self.productDialog.data.categories.split(",")
self.productDialog.show = true
},
sendProductFormData: function () {
let _data = {...this.productDialog.data}
var data = {
stall: _data.stall,
product: _data.product,
categories: _data.categories && _data.categories.toString(),
description: _data.description,
image: _data.image,
price: _data.price,
quantity: _data.quantity
}
if (_data.id) {
data.id = _data.id
this.updateProduct(data)
} else {
this.createProduct(data)
}
},
imageAdded(file) {
let blobURL = URL.createObjectURL(file)
let image = new Image()
image.src = blobURL
image.onload = async () => {
let canvas = document.createElement('canvas')
canvas.setAttribute('width', 100)
canvas.setAttribute('height', 100)
await pica.resize(image, canvas, {
quality: 0,
alpha: true,
unsharpAmount: 95,
unsharpRadius: 0.9,
unsharpThreshold: 70
})
this.productDialog.data.image = canvas.toDataURL()
this.productDialog = {...this.productDialog}
}
},
imageCleared() {
this.productDialog.data.image = null
this.productDialog = {...this.productDialog}
},
updateProduct: function (data) {
var self = this
let wallet = _.findWhere(this.stalls, {
id: self.productDialog.data.stall
}).wallet
LNbits.api
.request(
'PUT',
'/diagonalley/api/v1/products/' + data.id,
_.findWhere(self.g.user.wallets, {
id: wallet
}).inkey,
data
)
.then(function (response) {
self.products = _.reject(self.products, function (obj) {
return obj.id == data.id
})
self.products.push(mapProducts(response.data))
self.resetDialog('productDialog')
//self.productDialog.show = false
//self.productDialog.data = {}
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
createProduct: function (data) {
let self = this
const walletId = _.findWhere(this.stalls, {id: data.stall}).wallet
console.log("DATA", walletId, data)
LNbits.api
.request(
'POST',
'/diagonalley/api/v1/products',
_.findWhere(self.g.user.wallets, {id: walletId}).inkey,
data
)
.then((response) => {
console.log(response)
self.products.push(mapProducts(response.data))
self.resetDialog('productDialog')
})
.catch((error) => {
LNbits.utils.notifyApiError(error)
})
},
deleteProduct: function (productId) {
const product = _.findWhere(this.products, {id: productId})
const walletId = _.findWhere(this.stalls, {id: product.stall}).wallet
LNbits.utils
.confirmDialog('Are you sure you want to delete this products link?')
.onOk(() => {
LNbits.api
.request(
'DELETE',
'/diagonalley/api/v1/products/' + productId,
_.findWhere(this.g.user.wallets, {id: walletId}).adminkey
)
.then(() => {
this.products = _.reject(this.products, (obj) => {
return obj.id == productId
})
})
.catch((error) => {
LNbits.utils.notifyApiError(error)
})
})
},
exportProductsCSV: function () {
LNbits.utils.exportCSV(this.productsTable.columns, this.products)
},
////////////////////////////////////////
//////////////////ZONE//////////////////
////////////////////////////////////////
getZones: function () {
var self = this
LNbits.api
.request(
'GET',
'/diagonalley/api/v1/zones',
this.g.user.wallets[0].inkey
)
.then(function (response) {
if (response.data) {
console.log(response)
self.zones = response.data.map(mapZone)
}
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
openZoneUpdateDialog: function (linkId) {
var self = this
var link = _.findWhere(self.zones, {id: linkId})
countriesArray = link._data.countries.split(",")
for (let i = 0; i < countriesArray.length; i++) {
countriesArray[i] = self.capitalizeFirstLetter(countriesArray[i])
}
link._data.countries = countriesArray
this.zoneDialog.data = _.clone(link._data)
this.zoneDialog.show = true
},
sendZoneFormData: function () {
var data = {
countries: String(this.zoneDialog.data.countries),
cost: parseInt(this.zoneDialog.data.cost)
}
if (this.zoneDialog.data.id) {
data.id = this.zoneDialog.data.id
this.updateZone(data)
} else {
this.createZone(data)
}
},
updateZone: function (data) {
console.log(data)
var self = this
LNbits.api
.request(
'POST',
'/diagonalley/api/v1/zones/' + data.id,
self.g.user.wallets[0].adminkey,
data
)
.then(function (response) {
console.log(response)
self.zones = _.reject(self.zones, function (obj) {
return obj.id == data.id
})
self.zones.push(mapZone(response.data))
self.zoneDialog.show = false
self.zoneDialog.data = {}
data = {}
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
createZone: function (data) {
var self = this
LNbits.api
.request(
'POST',
'/diagonalley/api/v1/zones',
self.g.user.wallets[0].inkey,
data
)
.then(function (response) {
self.zones.push(mapZone(response.data))
self.zoneDialog.show = false
self.zoneDialog.data = {}
data = {}
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
deleteZone: function (zoneId) {
var self = this
var zone = _.findWhere(self.zones, {id: zoneId})
LNbits.utils
.confirmDialog('Are you sure you want to delete this Zone link?')
.onOk(function () {
LNbits.api
.request(
'DELETE',
'/diagonalley/api/v1/zones/' + zoneId,
self.g.user.wallets[0].adminkey
)
.then(function (response) {
self.zones = _.reject(self.zones, function (obj) {
return obj.id == zoneId
})
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
})
},
exportZonesCSV: function () {
LNbits.utils.exportCSV(this.zonesTable.columns, this.zones)
},
////////////////////////////////////////
//////////////////SHOP//////////////////
////////////////////////////////////////
getShops: function () {
var self = this
LNbits.api
.request(
'GET',
'/diagonalley/api/v1/shops?all_wallets=true',
this.g.user.wallets[0].inkey
)
.then(function (response) {
if (response.data) {
self.shops = response.data.map(mapShops)
}
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
openShopUpdateDialog: function (linkId) {
var self = this
var link = _.findWhere(self.shops, {id: linkId})
this.shopDialog.data = _.clone(link._data)
this.shopDialog.show = true
},
sendShopFormData: function () {
if (this.shopDialog.data.id) {
} else {
var data = {
countries: this.shopDialog.data.countries,
cost: this.shopDialog.data.cost
}
}
if (this.shopDialog.data.id) {
this.updateZone(this.shopDialog.data)
} else {
this.createZone(data)
}
},
updateShop: function (data) {
var self = this
LNbits.api
.request(
'PUT',
'/diagonalley/api/v1/shops' + data.id,
_.findWhere(self.g.user.wallets, {
id: self.shopDialog.data.wallet
}).inkey,
_.pick(data, 'countries', 'cost')
)
.then(function (response) {
self.shops = _.reject(self.shops, function (obj) {
return obj.id == data.id
})
self.shops.push(mapShops(response.data))
self.shopDialog.show = false
self.shopDialog.data = {}
data = {}
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
createShop: function (data) {
var self = this
console.log('cuntywoo')
LNbits.api
.request(
'POST',
'/diagonalley/api/v1/shops',
_.findWhere(self.g.user.wallets, {
id: self.shopDialog.data.wallet
}).inkey,
data
)
.then(function (response) {
self.shops.push(mapShops(response.data))
self.shopDialog.show = false
self.shopDialog.data = {}
data = {}
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
deleteShop: function (shopId) {
var self = this
var shop = _.findWhere(self.shops, {id: shopId})
LNbits.utils
.confirmDialog('Are you sure you want to delete this Shop link?')
.onOk(function () {
LNbits.api
.request(
'DELETE',
'/diagonalley/api/v1/shops/' + shopId,
_.findWhere(self.g.user.wallets, {id: shop.wallet}).inkey
)
.then(function (response) {
self.shops = _.reject(self.shops, function (obj) {
return obj.id == shopId
})
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
})
},
exportShopsCSV: function () {
LNbits.utils.exportCSV(this.shopsTable.columns, this.shops)
},
////////////////////////////////////////
////////////////ORDERS//////////////////
////////////////////////////////////////
getOrders: function () {
var self = this
LNbits.api
.request(
'GET',
'/diagonalley/api/v1/orders?all_wallets',
this.g.user.wallets[0].inkey
)
.then(function (response) {
if (response.data) {
self.orders = response.data.map(mapOrders)
}
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
createOrder: function () {
var data = {
address: this.orderDialog.data.address,
email: this.orderDialog.data.email,
quantity: this.orderDialog.data.quantity,
shippingzone: this.orderDialog.data.shippingzone
}
var self = this
LNbits.api
.request(
'POST',
'/diagonalley/api/v1/orders',
_.findWhere(self.g.user.wallets, {id: self.orderDialog.data.wallet})
.inkey,
data
)
.then(function (response) {
self.orders.push(mapOrders(response.data))
self.orderDialog.show = false
self.orderDialog.data = {}
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
deleteOrder: function (orderId) {
var self = this
var order = _.findWhere(self.orders, {id: orderId})
LNbits.utils
.confirmDialog('Are you sure you want to delete this order link?')
.onOk(function () {
LNbits.api
.request(
'DELETE',
'/diagonalley/api/v1/orders/' + orderId,
_.findWhere(self.g.user.wallets, {id: order.wallet}).inkey
)
.then(function (response) {
self.orders = _.reject(self.orders, function (obj) {
return obj.id == orderId
})
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
})
},
shipOrder: function (order_id) {
var self = this
LNbits.api
.request(
'GET',
'/diagonalley/api/v1/orders/shipped/' + order_id,
this.g.user.wallets[0].inkey
)
.then(function (response) {
self.orders.push(mapOrders(response.data))
})
},
exportOrdersCSV: function () {
LNbits.utils.exportCSV(this.ordersTable.columns, this.orders)
}
},
created: function () {
if (this.g.user.wallets.length) {
this.getStalls()
this.getProducts()
this.getZones()
this.getOrders()
this.customerKeys = [
'cb4c0164fe03fcdadcbfb4f76611c71620790944c24f21a1cd119395cdedfe1b',
'a9c17358a6dc4ceb3bb4d883eb87967a66b3453a0f3199f0b1c8eef8070c6a07'
]
console.log(_.pick(this.g.user, "id"))
}
}
})
</script>
{% endblock %}