routing done
This commit is contained in:
parent
8af6abedbe
commit
64ed5795b8
9 changed files with 78 additions and 267 deletions
|
|
@ -10,7 +10,7 @@
|
|||
v-for="(item, idx) in products"
|
||||
:key="idx"
|
||||
>
|
||||
<product-card :product="item" @change-page="change-page"></product-card>
|
||||
<product-card :product="item" @change-page="changePageM"></product-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,11 @@ async function customerMarket(path) {
|
|||
data: function () {
|
||||
return {}
|
||||
},
|
||||
methods: {},
|
||||
methods: {
|
||||
changePageM(page, opts) {
|
||||
this.$emit('change-page', page, opts)
|
||||
}
|
||||
},
|
||||
created() {}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,94 +10,25 @@
|
|||
<q-breadcrumbs-el :label="stall.name" icon="widgets"></q-breadcrumbs-el>
|
||||
</q-breadcrumbs>
|
||||
<q-toolbar-title></q-toolbar-title>
|
||||
<q-btn dense round flat icon="shopping_cart" class="q-ml-md"></q-btn>
|
||||
<shopping-cart></shopping-cart>
|
||||
</q-toolbar>
|
||||
<product-detail v-if="productDetail" :product="mock"></product-detail>
|
||||
<div class="row">
|
||||
<product-detail
|
||||
class="col-12"
|
||||
v-if="productDetail && product"
|
||||
:product="product"
|
||||
></product-detail>
|
||||
<div class="col-12 q-my-lg">
|
||||
<q-separator></q-separator>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row q-col-gutter-md">
|
||||
<div
|
||||
class="col-xs-12 col-sm-6 col-md-4 col-lg-3"
|
||||
v-for="(item, idx) in products"
|
||||
:key="idx"
|
||||
>
|
||||
<q-card class="card--product">
|
||||
<q-img
|
||||
:src="item.image ? item.image : '/nostrmarket/static/images/placeholder.png'"
|
||||
alt="Product Image"
|
||||
loading="lazy"
|
||||
spinner-color="white"
|
||||
fit="contain"
|
||||
height="300px"
|
||||
></q-img>
|
||||
|
||||
<q-card-section class="q-pb-xs q-pt-md">
|
||||
<q-btn
|
||||
round
|
||||
:disabled="item.amount < 1"
|
||||
color="primary"
|
||||
icon="shopping_cart"
|
||||
size="lg"
|
||||
style="
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
transform: translate(-50%, -50%);
|
||||
"
|
||||
@click=""
|
||||
><q-tooltip> Add to cart </q-tooltip></q-btn
|
||||
>
|
||||
<div class="row no-wrap items-center">
|
||||
<div class="col text-subtitle2 ellipsis-2-lines">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <q-rating v-model="stars" color="orange" :max="5" readonly size="17px"></q-rating> -->
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section class="q-py-sm">
|
||||
<div>
|
||||
<div class="text-caption text-weight-bolder">
|
||||
{{ item.stallName }}
|
||||
</div>
|
||||
<span v-if="item.currency == 'sat'">
|
||||
<span class="text-h6">{{ item.price }} sats</span
|
||||
><span class="q-ml-sm text-grey-6"
|
||||
>BTC {{ (item.price / 1e8).toFixed(8) }}</span
|
||||
>
|
||||
</span>
|
||||
<span v-else>
|
||||
<span class="text-h6">{{ item.formatedPrice }}</span>
|
||||
<span v-if="exchangeRates" class="q-ml-sm text-grey-6"
|
||||
>({{ item.priceInSats }} sats)</span
|
||||
>
|
||||
</span>
|
||||
<span
|
||||
class="q-ml-md text-caption text-green-8 text-weight-bolder q-mt-md"
|
||||
>{{ item.amount }} left</span
|
||||
>
|
||||
</div>
|
||||
<div v-if="item.categories" class="text-subtitle1">
|
||||
<q-chip v-for="(cat, i) in item.categories" :key="i" dense
|
||||
>{{cat}}</q-chip
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="text-caption text-grey ellipsis-2-lines"
|
||||
style="min-height: 40px"
|
||||
>
|
||||
<p v-if="item.description">{{ item.description }}</p>
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-separator></q-separator>
|
||||
|
||||
<q-card-actions>
|
||||
<span>Stall: {{ item.stallName }}</span>
|
||||
<div class="q-ml-auto">
|
||||
<q-btn flat dense>See product</q-btn>
|
||||
</div>
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
<product-card :product="item" @change-page="changePageS"></product-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,34 +1,32 @@
|
|||
async function customerStall(path) {
|
||||
const template = await loadTemplateAsync(path)
|
||||
const mock = {
|
||||
stall: '4M8j9KKGzUckHgb4C3pKCv',
|
||||
name: 'product 1',
|
||||
description:
|
||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Leo integer malesuada nunc vel risus commodo. Sapien faucibus et molestie ac feugiat sed lectus vestibulum mattis. Cras ornare arcu dui vivamus. Risus pretium quam vulputate dignissim suspendisse in est ante in. Faucibus in ornare quam viverra orci sagittis eu volutpat odio.',
|
||||
amount: 100,
|
||||
price: '10',
|
||||
images: ['https://i.imgur.com/cEfpEjq.jpeg'],
|
||||
id: ['RyMbE9Hdwk9X333JKtkkNS'],
|
||||
categories: ['crafts', 'robots'],
|
||||
currency: 'EUR',
|
||||
stallName: 'stall 1',
|
||||
formatedPrice: '€10.00',
|
||||
priceInSats: 0
|
||||
}
|
||||
|
||||
Vue.component('customer-stall', {
|
||||
name: 'customer-stall',
|
||||
template,
|
||||
|
||||
props: ['stall', 'products', 'exchange-rates', 'product-detail'],
|
||||
props: [
|
||||
'stall',
|
||||
'products',
|
||||
'exchange-rates',
|
||||
'product-detail',
|
||||
'change-page'
|
||||
],
|
||||
data: function () {
|
||||
return {
|
||||
mock: mock
|
||||
return {}
|
||||
},
|
||||
computed: {
|
||||
product() {
|
||||
if (this.productDetail) {
|
||||
return this.products.find(p => p.id == this.productDetail)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {},
|
||||
created() {
|
||||
console.log(this.stall)
|
||||
console.log(this.products)
|
||||
}
|
||||
methods: {
|
||||
changePageS(page, opts) {
|
||||
this.$emit('change-page', page, opts)
|
||||
}
|
||||
},
|
||||
created() {}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@
|
|||
|
||||
<q-card-actions>
|
||||
<span>Stall: {{ product.stallName }}</span>
|
||||
<span>{{ $parent.activeStall }}</span>
|
||||
<div class="q-ml-auto">
|
||||
<q-btn
|
||||
flat
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ async function productCard(path) {
|
|||
name: 'product-card',
|
||||
template,
|
||||
|
||||
props: ['product'],
|
||||
props: ['product', 'change-page'],
|
||||
data: function () {
|
||||
return {}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
<div class="col-lg-5 col-md-5 col-sm-12 col-xs-12">
|
||||
<div class="q-pa-md">
|
||||
<q-carousel
|
||||
v-if="product.images"
|
||||
swipeable
|
||||
animated
|
||||
v-model="slide"
|
||||
|
|
@ -48,19 +49,6 @@
|
|||
class="q-ml-md text-caption text-green-8 text-weight-bolder q-mt-md"
|
||||
>{{ product.amount > 0 ? 'In stock.' : 'Out of stock.' }}</span
|
||||
>
|
||||
<!-- <div class="text-caption text-weight-bolder q-mt-sm">
|
||||
Special Price
|
||||
</div>
|
||||
<span class="text-h6">₹3,149</span
|
||||
><span
|
||||
class="q-ml-sm text-grey-6"
|
||||
style="text-decoration: line-through"
|
||||
>₹3,699</span
|
||||
>
|
||||
<span
|
||||
class="q-ml-md text-caption text-green-8 text-weight-bolder q-mt-md"
|
||||
>20% off</span
|
||||
> -->
|
||||
</div>
|
||||
<div class="q-mt-md">
|
||||
<q-btn
|
||||
|
|
@ -78,110 +66,6 @@
|
|||
</div>
|
||||
</div>
|
||||
<!-- RATING TO BE DONE -->
|
||||
<div
|
||||
class="col-lg-5 col-md-5 col-sm-12 col-xs-12 q-mt-md q-pt-xs q-pl-lg"
|
||||
>
|
||||
<div class="text-subtitle2">Customer rating</div>
|
||||
<div class="text-h3">4.2</div>
|
||||
<div>
|
||||
<q-rating
|
||||
v-model="rating_point"
|
||||
max="5"
|
||||
size="2em"
|
||||
color="orange"
|
||||
icon="star_border"
|
||||
icon-selected="star"
|
||||
icon-half="star_half"
|
||||
no-dimming
|
||||
readonly
|
||||
/>
|
||||
</div>
|
||||
<div class="text-subtitle2 text-grey-8">(357 reviews)</div>
|
||||
<div class="text-subtitle2 text-grey-10 q-mt-sm">
|
||||
93% would recommend to a friend
|
||||
</div>
|
||||
|
||||
<q-list dense bordered padding class="no-border q-mt-lg q-pr-xl">
|
||||
<q-item style="padding-left: 0 !important" v-ripple>
|
||||
<span class="text-subtitle2 q-mr-xs">5</span>
|
||||
<q-icon name="star" size="1.5em" color="orange"></q-icon>
|
||||
<q-linear-progress
|
||||
class="q-ml-sm q-mr-sm"
|
||||
style="margin-top: 5px"
|
||||
size="13px"
|
||||
:value="0.9"
|
||||
/>
|
||||
<span
|
||||
style="margin-top: 2px"
|
||||
class="text-caption text-weight-bold text-grey-8"
|
||||
>273</span
|
||||
>
|
||||
</q-item>
|
||||
<q-item style="padding-left: 0 !important" v-ripple>
|
||||
<span class="text-subtitle2 q-mr-xs">4</span>
|
||||
<q-icon name="star" size="1.5em" color="orange"></q-icon>
|
||||
<q-linear-progress
|
||||
class="q-ml-sm q-mr-sm"
|
||||
style="margin-top: 5px"
|
||||
size="13px"
|
||||
:value="0.6"
|
||||
/>
|
||||
<span
|
||||
style="margin-top: 2px"
|
||||
class="text-caption text-weight-bold text-grey-8"
|
||||
> 69</span
|
||||
>
|
||||
</q-item>
|
||||
<q-item style="padding-left: 0 !important" v-ripple>
|
||||
<span class="text-subtitle2 q-mr-xs">3</span>
|
||||
<q-icon name="star" size="1.5em" color="orange"></q-icon>
|
||||
<q-linear-progress
|
||||
class="q-ml-sm q-mr-sm"
|
||||
style="margin-top: 5px"
|
||||
size="13px"
|
||||
:value="0.1"
|
||||
/>
|
||||
<span
|
||||
style="margin-top: 2px"
|
||||
class="text-caption text-weight-bold text-grey-8"
|
||||
> 6</span
|
||||
>
|
||||
</q-item>
|
||||
<q-item style="padding-left: 0 !important" v-ripple>
|
||||
<span class="text-subtitle2 q-mr-xs">2</span>
|
||||
<q-icon name="star" size="1.5em" color="orange"></q-icon>
|
||||
<q-linear-progress
|
||||
class="q-ml-sm q-mr-sm"
|
||||
style="margin-top: 5px"
|
||||
size="13px"
|
||||
:value="0.1"
|
||||
/>
|
||||
<span
|
||||
style="margin-top: 2px"
|
||||
class="text-caption text-weight-bold text-grey-8"
|
||||
> 3</span
|
||||
>
|
||||
</q-item>
|
||||
<q-item style="padding-left: 0 !important" v-ripple>
|
||||
<span class="text-subtitle2 q-mr-xs">1</span>
|
||||
<q-icon name="star" size="1.5em" color="orange"></q-icon>
|
||||
<q-linear-progress
|
||||
class="q-ml-sm q-mr-sm"
|
||||
style="margin-top: 5px"
|
||||
size="13px"
|
||||
:value="0.1"
|
||||
/>
|
||||
<span
|
||||
style="margin-top: 2px"
|
||||
class="text-caption text-weight-bold text-grey-8"
|
||||
> 6</span
|
||||
>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 q-mb-lg">
|
||||
<q-separator></q-separator>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ const market = async () => {
|
|||
productCard('static/components/product-card/product-card.html'),
|
||||
customerMarket('static/components/customer-market/customer-market.html'),
|
||||
customerStall('static/components/customer-stall/customer-stall.html'),
|
||||
productDetail('static/components/product-detail/product-detail.html')
|
||||
productDetail('static/components/product-detail/product-detail.html'),
|
||||
shoppingCart('static/components/shopping-cart/shopping-cart.html')
|
||||
])
|
||||
|
||||
new Vue({
|
||||
|
|
@ -58,7 +59,7 @@ const market = async () => {
|
|||
filterProducts() {
|
||||
let products = this.products
|
||||
if (this.activeStall) {
|
||||
products = products.filter(p => p.stall == this.activeStall)
|
||||
products = products.filter(p => p.stall_id == this.activeStall)
|
||||
}
|
||||
if (!this.searchText || this.searchText.length < 2) return products
|
||||
return products.filter(p => {
|
||||
|
|
@ -76,6 +77,9 @@ const market = async () => {
|
|||
return (
|
||||
this.products.find(p => p.id == this.activeProduct)?.name || 'Product'
|
||||
)
|
||||
},
|
||||
isLoading() {
|
||||
return this.$q.loading.isActive
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
|
|
@ -88,51 +92,17 @@ const market = async () => {
|
|||
}
|
||||
if (relays && relays.length) {
|
||||
this.relays = new Set([...defaultRelays, ...relays])
|
||||
} else {
|
||||
this.relays = new Set(defaultRelays)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
// Hardcode pubkeys for testing
|
||||
/*
|
||||
this.pubkeys.add(
|
||||
'c1415f950a1e3431de2bc5ee35144639e2f514cf158279abff9ed77d50118796'
|
||||
)
|
||||
this.pubkeys.add(
|
||||
'8f69ac99b96f7c4ad58b98cc38fe5d35ce02daefae7d1609c797ce3b4f92f5fd'
|
||||
)
|
||||
*/
|
||||
// stall ids S4hQgtTwiF5kGJZPbqMH9M jkCbdtkXeMjGBY3LBf8yn4
|
||||
/*let naddr = nostr.nip19.naddrEncode({
|
||||
identifier: '1234',
|
||||
pubkey:
|
||||
'c1415f950a1e3431de2bc5ee35144639e2f514cf158279abff9ed77d50118796',
|
||||
kind: 30018,
|
||||
relays: defaultRelays
|
||||
})
|
||||
console.log(naddr)
|
||||
console.log(nostr.nip19.decode(naddr))
|
||||
*/
|
||||
|
||||
let params = new URLSearchParams(window.location.search)
|
||||
let merchant_pubkey = params.get('merchant_pubkey')
|
||||
let stall_id = params.get('stall_id')
|
||||
let product_id = params.get('product_id')
|
||||
console.log(merchant_pubkey, stall_id, product_id)
|
||||
if (merchant_pubkey) {
|
||||
await addPubkey(merchant_pubkey)
|
||||
/*LNbits.utils
|
||||
.confirmDialog(
|
||||
`We found a merchant pubkey in your request. Do you want to add it to the merchants list?`
|
||||
)
|
||||
.onCancel(() => {})
|
||||
.onDismiss(() => {})
|
||||
.onOk(() => {
|
||||
this.pubkeys.add(merchant_pubkey)
|
||||
})*/
|
||||
}
|
||||
this.$q.loading.show()
|
||||
this.relays = new Set(defaultRelays)
|
||||
// Get notes from Nostr
|
||||
await this.initNostr()
|
||||
|
||||
// What component to render on start
|
||||
if (stall_id) {
|
||||
|
|
@ -142,11 +112,33 @@ const market = async () => {
|
|||
this.activePage = 'stall'
|
||||
this.activeStall = stall_id
|
||||
}
|
||||
if (merchant_pubkey && !this.pubkeys.has(merchant_pubkey)) {
|
||||
await LNbits.utils
|
||||
.confirmDialog(
|
||||
`We found a merchant pubkey in your request. Do you want to add it to the merchants list?`
|
||||
)
|
||||
.onOk(async () => {
|
||||
await this.addPubkey(merchant_pubkey)
|
||||
})
|
||||
}
|
||||
|
||||
// Get notes from Nostr
|
||||
await this.initNostr()
|
||||
this.$q.loading.hide()
|
||||
},
|
||||
methods: {
|
||||
naddr() {
|
||||
let naddr = nostr.nip19.naddrEncode({
|
||||
identifier: '1234',
|
||||
pubkey:
|
||||
'c1415f950a1e3431de2bc5ee35144639e2f514cf158279abff9ed77d50118796',
|
||||
kind: 30018,
|
||||
relays: defaultRelays
|
||||
})
|
||||
console.log(naddr)
|
||||
},
|
||||
async initNostr() {
|
||||
this.$q.loading.show()
|
||||
const pool = new nostr.SimplePool()
|
||||
let relays = Array.from(this.relays)
|
||||
let products = new Map()
|
||||
|
|
@ -168,10 +160,10 @@ const market = async () => {
|
|||
return
|
||||
} else if (e.kind == 30018) {
|
||||
//it's a product `d` is the prod. id
|
||||
products.set(e.d, {...e.content, id: e.d, categories: e.t})
|
||||
products.set(e.d, {...e.content, id: e.d[0], categories: e.t})
|
||||
} else if (e.kind == 30017) {
|
||||
// it's a stall `d` is the stall id
|
||||
stalls.set(e.d, {...e.content, id: e.d, pubkey: e.pubkey})
|
||||
stalls.set(e.d, {...e.content, id: e.d[0], pubkey: e.pubkey})
|
||||
return
|
||||
}
|
||||
})
|
||||
|
|
@ -182,13 +174,13 @@ const market = async () => {
|
|||
this.products = Array.from(products.values()).map(obj => {
|
||||
let stall = this.stalls.find(s => s.id == obj.stall_id)
|
||||
obj.stallName = stall.name
|
||||
obj.images = [obj.image]
|
||||
if (obj.currency != 'sat') {
|
||||
obj.formatedPrice = this.getAmountFormated(obj.price, obj.currency)
|
||||
obj.priceInSats = this.getValueInSats(obj.price, obj.currency)
|
||||
}
|
||||
return obj
|
||||
})
|
||||
|
||||
pool.close(relays)
|
||||
},
|
||||
async getRates() {
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<customer-stall
|
||||
v-if="activeStall"
|
||||
v-if="!isLoading && activeStall"
|
||||
:stall="stalls.find(stall => stall.id == activeStall)"
|
||||
:products="filterProducts"
|
||||
:exchange-rates="exchangeRates"
|
||||
|
|
@ -163,6 +163,7 @@
|
|||
<script src="{{ url_for('nostrmarket_static', path='components/customer-market/customer-market.js') }}"></script>
|
||||
<script src="{{ url_for('nostrmarket_static', path='components/customer-stall/customer-stall.js') }}"></script>
|
||||
<script src="{{ url_for('nostrmarket_static', path='components/product-detail/product-detail.js') }}"></script>
|
||||
<script src="{{ url_for('nostrmarket_static', path='components/shopping-cart/shopping-cart.js') }}"></script>
|
||||
<script src="{{ url_for('nostrmarket_static', path='js/market.js') }}"></script>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue