feat: stuff

This commit is contained in:
Vlad Stan 2023-07-07 14:24:00 +03:00
parent b41e499591
commit 761a3137a6
9 changed files with 221 additions and 21 deletions

View file

@ -33,7 +33,7 @@
<q-tooltip>{{ publicKey }}</q-tooltip>
</q-item-section>
<q-item-section side>
<q-btn class="gt-xs" size="12px" flat dense round icon="delete" @click="removeMerchant(publicKey)" />
<q-btn size="12px" flat dense round icon="delete" @click="removeMerchant(publicKey)" />
</q-item-section>
</q-item>

View file

@ -4,7 +4,7 @@
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 v-if="isStall" round :disabled="product.quantity < 1" color="primary" icon="shopping_cart" size="lg" style="
<q-btn v-if="isStall" round :disabled="product.quantity < 1" color="primary" rounded icon="shopping_cart" size="lg" style="
position: absolute;
top: 0;
right: 0;

View file

@ -62,6 +62,7 @@
<q-btn
class="q-mt-md"
color="primary"
rounded
icon="shopping_cart"
label="Add to cart"
@click="$emit('add-to-cart', product)"

View file

@ -0,0 +1,125 @@
<div>
<q-card v-if="cart" bordered class="q-mb-md">
<q-item>
<q-item-section avatar>
<q-avatar>
<img v-if="cart.merchant?.profile?.picture" :src="cart.merchant?.profile?.picture">
<img v-else src="/nostrmarket/static/images/blank-avatar.webp">
</q-avatar>
</q-item-section>
<q-item-section>
<q-item-label>
<strong>
<span v-text="cart.products[0]?.stallName"></span>
</strong>
</q-item-label>
<q-item-label caption>
By <span v-text="cart.merchant?.profile?.name || cart.merchant?.publicKey"></span>
</q-item-label>
</q-item-section>
<q-item-section side>
</q-item-section>
</q-item>
<q-separator />
<q-card-section horizontal>
<q-card-section class="col-7">
<div class="row q-mt-md">
<div class="col-xs-12 col-sm-12 col-md-4">
<strong>Subtotal:</strong>
</div>
<div class="col-xs-12 col-sm-12 col-md-4">
</div>
<div class="col-xs-12 col-sm-12 col-md-4">
<strong>{{formatCurrency(cartTotal,
cart.products[0]?.currency)}}</strong>
</div>
</div>
<div class="row q-mt-md">
<div class="col-xs-12 col-sm-12 col-md-4">
<strong>Shipping:</strong>
</div>
<div class="col-xs-12 col-sm-12 col-md-4">
</div>
<div class="col-xs-12 col-sm-12 col-md-4">
<strong>00.00</strong>
</div>
</div>
<q-separator class="q-mt-sm" />
<div class="row q-mt-md">
<div class="col-xs-12 col-sm-12 col-md-4">
<strong>Total:</strong>
</div>
<div class="col-xs-12 col-sm-12 col-md-4">
</div>
<div class="col-xs-12 col-sm-12 col-md-4">
<strong>00.00</strong>
</div>
</div>
<!-- <q-item>
<q-item-section>
<q-item-label>
<strong>Subtotal:</strong>
</q-item-label>
</q-item-section>
<q-item-section>
<q-item-label> <strong>{{formatCurrency(cartTotal,
cart.products[0]?.currency)}}</strong></q-item-label>
</q-item-section>
<q-item-section>
<q-item-label> xx</q-item-label>
</q-item-section>
</q-item>
<q-item>
<q-item-section>
<q-item-label>
<strong>Shipping:</strong>
</q-item-label>
</q-item-section>
<q-item-section>
<q-item-label> 0.00</q-item-label>
</q-item-section>
<q-item-section>
<q-item-label> xx</q-item-label>
</q-item-section>
</q-item>
<q-separator />
<q-item>
<q-item-section>
<q-item-label>
<strong>Total:</strong>
</q-item-label>
</q-item-section>
<q-item-section>
<q-item-label> </q-item-label>
</q-item-section>
</q-item> -->
</q-card-section>
<q-separator vertical />
<q-card-section>
<strong>Payment Method</strong>
<q-option-group v-model="paymentMethod" :options="paymentOptions" color="green" disable />
</q-card-section>
</q-card-section>
<q-separator />
<q-card-actions align="right">
<q-btn @click="requestInvoice(cart)" flat color="primary">
Request Invoice
</q-btn>
</q-card-actions>
</q-card>
</div>

View file

@ -0,0 +1,46 @@
async function shoppingCartCheckout(path) {
const template = await loadTemplateAsync(path)
Vue.component('shopping-cart-checkout', {
name: 'shopping-cart-checkout',
template,
props: ['cart'],
data: function () {
return {
paymentMethod: 'ln',
paymentOptions: [
{
label: 'Lightning Network',
value: 'ln'
},
{
label: 'BTC Onchain',
value: 'btc'
},
{
label: 'Cashu',
value: 'cashu'
}
]
}
},
computed: {
cartTotal() {
if (!this.cart.products?.length) return 0
return this.cart.products.reduce((t, p) => p.price + t, 0)
},
},
methods: {
formatCurrency: function (value, unit) {
return formatCurrency(value, unit)
},
requestInvoice: function () {
}
},
created() {
console.log('### shoppingCartCheckout', this.cart)
}
})
}

View file

@ -1,4 +1,9 @@
<div>
<q-card v-if="!carts?.length" bordered class="q-mb-md">
<q-card-section>
<strong>No products in cart!</strong>
</q-card-section>
</q-card>
<div v-for="cart in carts">
<q-card bordered class="q-mb-md">
@ -21,7 +26,11 @@
</q-item-label>
</q-item-section>
<q-item-section side>
<div>
<q-btn @click="removeCart(cart.id)" flat color="pink">
Clear Cart
</q-btn>
</div>
</q-item-section>
</q-item>
@ -51,10 +60,10 @@
<q-item-label><strong>{{ formatCurrency(product.price, product.currency)}}</strong></q-item-label>
<q-item-label></q-item-label>
</q-item-section>
<!-- " -->
<q-item-section class="q-ma-sm">
<q-input v-model.number="product.orderedQuantity" @change="quantityChanged(product)" type="number" rounded outlined min="1"
:max="product.quantity"></q-input>
<q-input v-model.number="product.orderedQuantity" @change="quantityChanged(product)" type="number"
rounded outlined min="1" :max="product.quantity"></q-input>
</q-item-section>
<q-item-section>
@ -63,8 +72,7 @@
</q-item-section>
<q-item-section side>
<div>
<q-btn flat dense round icon="delete"
@click="removeProduct(product.stall_id, product.id)" />
<q-btn flat dense round icon="delete" @click="removeProduct(product.stall_id, product.id)" />
</div>
</q-item-section>
@ -75,9 +83,11 @@
</q-card-section>
<q-separator />
<q-card-actions align="right">
Total: <strong class="q-ma-md"> {{cartTotalFormatted(cart)}} </strong>
<q-btn flat color="primary">
<q-btn @click="proceedToCheckout(cart)" flat color="primary">
Proceed to Checkout
</q-btn>
</q-card-actions>

View file

@ -22,8 +22,14 @@ async function shoppingCartList(path) {
removeProduct: function (stallId, productId) {
this.$emit('remove-from-cart', { stallId, productId })
},
removeCart: function (stallId) {
this.$emit('remove-cart', stallId)
},
quantityChanged: function (product) {
this.$emit('add-to-cart', product)
},
proceedToCheckout: function(cart){
this.$emit('checkout-cart', cart)
}
},
created() { }

View file

@ -31,6 +31,7 @@ const market = async () => {
productDetail('static/components/product-detail/product-detail.html'),
shoppingCart('static/components/shopping-cart/shopping-cart.html'),
shoppingCartList('static/components/shopping-cart-list/shopping-cart-list.html'),
shoppingCartCheckout('static/components/shopping-cart-checkout/shopping-cart-checkout.html'),
chatDialog('static/components/chat-dialog/chat-dialog.html'),
marketConfig('static/components/market-config/market-config.html')
])
@ -52,6 +53,7 @@ const market = async () => {
merchants: [],
shoppingCarts: [],
shoppingCartCheckout: null,
activePage: 'market',
@ -592,7 +594,6 @@ const market = async () => {
product.orderedQuantity = Math.min(product.quantity, item.orderedQuantity || (product.orderedQuantity + 1))
this.$q.localStorage.set('nostrmarket.shoppingCarts', this.shoppingCarts)
console.log('### this.shoppingCarts', this.shoppingCarts)
},
removeProductFromCart(item) {
@ -604,6 +605,15 @@ const market = async () => {
}
this.$q.localStorage.set('nostrmarket.shoppingCarts', this.shoppingCarts)
}
},
removeCart(stallId) {
this.shoppingCarts = this.shoppingCarts.filter(s => s.id !== stallId)
this.$q.localStorage.set('nostrmarket.shoppingCarts', this.shoppingCarts)
},
checkoutCart(cart) {
this.shoppingCartCheckout = cart
this.setActivePage('shopping-cart-checkout')
}
}

View file

@ -211,7 +211,10 @@
<market-config v-if="activePage === 'market-config'" :merchants="merchants" @add-merchant="addMerchant"
@remove-merchant="removeMerchant"></market-config>
<shopping-cart-list v-else-if="activePage === 'shopping-cart-list'" :carts="shoppingCarts"
@add-to-cart="addProductToCart" @remove-from-cart="removeProductFromCart"></shopping-cart-list>
@add-to-cart="addProductToCart" @remove-from-cart="removeProductFromCart" @remove-cart="removeCart"
@checkout-cart="checkoutCart"></shopping-cart-list>
<shopping-cart-checkout v-else-if="activePage === 'shopping-cart-checkout'"
:cart="shoppingCartCheckout"></shopping-cart-checkout>
<customer-stall v-else-if="!isLoading && activeStall" :stall="stalls.find(stall => stall.id == activeStall)"
:products="filterProducts" :stall-products="products.filter(p => p.stall_id == activeStall)"
:product-detail="activeProduct" :relays="relays" :account="account" :pool="pool" :styles="config?.opts ?? {}"
@ -236,16 +239,13 @@
<q-card-section class="q-pt-none">
<q-input dense label="Nsec/Hex" v-model="accountDialog.data.key" autofocus @keyup.enter="createAccount"
:error="accountDialog.data.key && !isValidAccountKey"
hint="Enter you private key"></q-input>
:error="accountDialog.data.key && !isValidAccountKey" hint="Enter you private key"></q-input>
</q-card-section>
<q-card-actions align="right" class="text-primary">
<q-btn v-if="isValidAccountKey" label="Login" color="primary" @click="() => createAccount()"></q-btn>
<q-btn v-else flat label="Generate" @click="generateKeyPair"></q-btn>
<q-btn v-close-popup flat color="grey" class="q-ml-auto"
>Close</q-btn
>
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Close</q-btn>
</q-card-actions>
</q-card>
</q-dialog>
@ -292,6 +292,8 @@
<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='components/shopping-cart-list/shopping-cart-list.js') }}"></script>
<script
src="{{ url_for('nostrmarket_static', path='components/shopping-cart-checkout/shopping-cart-checkout.js') }}"></script>
<script src="{{ url_for('nostrmarket_static', path='components/chat-dialog/chat-dialog.js') }}"></script>
<script src="{{ url_for('nostrmarket_static', path='components/market-config/market-config.js') }}"></script>
<script src="{{ url_for('nostrmarket_static', path='js/market.js') }}"></script>