feat: add readNotes and clearAllData option

This commit is contained in:
Vlad Stan 2023-07-19 11:50:47 +03:00
parent bb2d68d7dc
commit ee3b161b47
6 changed files with 166 additions and 40 deletions

View file

@ -18,6 +18,43 @@
<q-tab-panels v-model="tab"> <q-tab-panels v-model="tab">
<q-tab-panel name="merchants"> <q-tab-panel name="merchants">
<q-list v-if="!readNotes.merchants" class="q-mb-lg" bordered>
<q-item>
<q-item-section avatar>
<q-avatar>
<q-icon color="primary" name="info" size="xl" />
</q-avatar>
</q-item-section>
<q-item-section class="q-mt-sm q-ml-lg">
<q-item-label><strong>Note</strong></q-item-label>
<q-item-label>
<div class="text-caption">
<ul>
<li><span class="text-subtitle1">
Here all the mercants of the marketplace are listed.
</span>
</li>
<li>
<span class="text-subtitle1">
You can easily add a new merchant by
entering its public key in the input below.
</span>
</li>
<li>
<span class="text-subtitle1">
When a merchant is added all its products and stalls will be available in the Market page.
</span>
</li>
</ul>
</div>
</q-item-label>
</q-item-section>
<q-item-section side>
<q-btn @click="markNoteAsRead('merchants')" size="lg" outline color="primary" label="Got it!"
icon="check_small" />
</q-item-section>
</q-item>
</q-list>
<div> <div>
<q-input outlined v-model="merchantPubkey" @keydown.enter="addMerchant" type="text" label="Pubkey/Npub" <q-input outlined v-model="merchantPubkey" @keydown.enter="addMerchant" type="text" label="Pubkey/Npub"
hint="Add merchants"> hint="Add merchants">
@ -66,12 +103,6 @@
</q-item-section> </q-item-section>
<q-item-section class="q-mt-sm"> <q-item-section class="q-mt-sm">
<q-item-label><strong>{{ relay}}</strong></q-item-label> <q-item-label><strong>{{ relay}}</strong></q-item-label>
<!-- <q-item-label>
<div class="text-caption text-grey ellipsis-2-lines">
<p>{{ publicKey }}</p>
</div>
</q-item-label> -->
<!-- <q-tooltip>{{ publicKey }}</q-tooltip> -->
</q-item-section> </q-item-section>
<q-item-section side> <q-item-section side>
<q-btn size="12px" flat dense round icon="delete" @click="removeRelay(relay)" /> <q-btn size="12px" flat dense round icon="delete" @click="removeRelay(relay)" />
@ -83,24 +114,59 @@
</div> </div>
</q-tab-panel> </q-tab-panel>
<q-tab-panel name="marketplace"> <q-tab-panel name="marketplace">
<q-list v-if="!readNotes.marketUi" class="q-mb-lg" bordered>
<q-item>
<q-item-section avatar>
<q-avatar>
<q-icon color="primary" name="info" size="xl" />
</q-avatar>
</q-item-section>
<q-item-section class="q-mt-sm q-ml-lg">
<q-item-label><strong>Note</strong></q-item-label>
<q-item-label>
<div class="text-caption">
<ul>
<li><span class="text-subtitle1">
Here one can customize the look and feel of the Market.
</span>
</li>
<li>
<span class="text-subtitle1">
When the Market Profile is shared (via <code>naddr</code> ) these customisations will be
available to the
customers.
</span>
</li>
</ul>
</div>
</q-item-label>
</q-item-section>
<q-item-section side>
<q-btn @click="markNoteAsRead('marketUi')" size="lg" outline color="primary" label="Got it!"
icon="check_small" />
</q-item-section>
</q-item>
</q-list>
<div class="q-mb-md"> <strong>Information</strong></div> <div class="q-mb-md"> <strong>Information</strong></div>
<q-input @change="updateUiConfig" outlined v-model="configData.name" type="text" label="Marketplace Name" <q-input @change="updateUiConfig" outlined v-model="configData.name" type="text" label="Market Name"
class="q-mb-md"> hint="Short name for the market" class="q-mb-md">
</q-input> </q-input>
<q-input @change="updateUiConfig" outlined v-model="configData.about" type="textarea" rows="3" <q-input @change="updateUiConfig" outlined v-model="configData.about" type="textarea" rows="3"
label="Marketplace Description" class="q-mb-lg"></q-input> label="Marketplace Description"
hint="It will be displayed on top of the banner image. Can be a longer text." class="q-mb-lg"></q-input>
<div class="q-mb-md q-mt-lg"> <div class="q-mb-md q-mt-lg">
<strong>UI Configurations</strong> <strong>UI Configurations</strong>
</div> </div>
<q-input @change="updateUiConfig" outlined v-model="configData.ui.picture" type="text" label="Logo" <q-input @change="updateUiConfig" outlined v-model="configData.ui.picture" type="text" label="Logo"
class="q-mb-md"> hint="It will be displayed next to the search input. Can be png, jpg, ico, gif, svg." class="q-mb-md">
</q-input> </q-input>
<q-input @change="updateUiConfig" outlined v-model="configData.ui.banner" type="text" label="Banner" <q-input @change="updateUiConfig" outlined v-model="configData.ui.banner" type="text" label="Banner"
class="q-mb-md"> hint="It represents the visual identity of the market. Can be png, jpg, ico, gif, svg." class="q-mb-md">
</q-input> </q-input>
<q-select @input="updateUiConfig" filled v-model="configData.ui.theme" hint="Choose marketplace theme" <q-select @input="updateUiConfig" filled v-model="configData.ui.theme"
hint="The colors of the market will vary based on the theme. It applies to all components (buttons, labels, inputs, etc)"
:options="themeOptions" label="Marketplace Theme"></q-select> :options="themeOptions" label="Marketplace Theme"></q-select>
<q-checkbox @input="updateUiConfig" v-model="configData.ui.darkMode" label="Dark Mode" <q-checkbox @input="updateUiConfig" v-model="configData.ui.darkMode" label="Dark Mode"
@ -116,6 +182,7 @@
<q-separator /> <q-separator />
<q-card-section> <q-card-section>
<div class="float-right"> <div class="float-right">
<q-btn @click="clearAllData" flat label="Clear All Data" icon="delete" class="q-ml-lg" color="negative"></q-btn>
<q-btn @click="publishNaddr" flat label="Share Market Profile" icon="share" class="q-ml-lg" <q-btn @click="publishNaddr" flat label="Share Market Profile" icon="share" class="q-ml-lg"
color="primary"></q-btn> color="primary"></q-btn>
</div> </div>

View file

@ -2,7 +2,7 @@ async function marketConfig(path) {
const template = await loadTemplateAsync(path) const template = await loadTemplateAsync(path)
Vue.component('market-config', { Vue.component('market-config', {
name: 'market-config', name: 'market-config',
props: ['merchants', 'relays', 'config-ui'], props: ['merchants', 'relays', 'config-ui', 'read-notes'],
template, template,
data: function () { data: function () {
@ -85,17 +85,26 @@ async function marketConfig(path) {
console.log('### this.info', { name, about, ui }) console.log('### this.info', { name, about, ui })
this.$emit('ui-config-update', { name, about, ui }) this.$emit('ui-config-update', { name, about, ui })
}, },
publishNaddr(){ publishNaddr() {
this.$emit('publish-naddr') this.$emit('publish-naddr')
},
clearAllData() {
this.$emit('clear-all-data')
},
markNoteAsRead(noteId) {
this.$emit('note-read', noteId)
} }
}, },
created: async function () { created: async function () {
console.log('### this.configData', this.configData)
console.log('### this.configUi', this.configUi)
if (this.configUi) { if (this.configUi) {
this.configData = { ...this.configData, ...this.configUi, ui: { ...this.configData.ui, ...(this.configUi.ui || {}) } } this.configData = {
...this.configData,
...this.configUi,
ui: {
...this.configData.ui, ...(this.configUi.ui || {})
}
}
} }
console.log('### this.configData', this.configData)
} }
}) })

View file

@ -19,23 +19,23 @@
<div class="row"> <div class="row">
<div class="col-10"> <div class="col-10">
<q-input v-model="account.nsec" readonly disbled outlined type="password" label="Private Key" <q-input v-model="account.nsec" readonly disbled outlined type="password" label="Private Key" class="q-mb-md">
class="q-mb-md">
<template v-slot:append> <template v-slot:append>
<q-btn @click="copyText(account.nsec)" icon="content_copy" label="Nsec" flat color="gray float-right q-mt-sm"></q-btn> <q-btn @click="copyText(account.nsec)" icon="content_copy" label="Nsec" flat
color="gray float-right q-mt-sm"></q-btn>
</template> </template>
</q-input> </q-input>
</div> </div>
<div class="col-2 auto-width"> <div class="col-2 auto-width">
<q-btn @click="copyText(account.privkey)" icon="content_copy" label="Hex" flat color="gray float-right q-mt-sm"></q-btn> <q-btn @click="copyText(account.privkey)" icon="content_copy" label="Hex" flat
color="gray float-right q-mt-sm"></q-btn>
</div> </div>
</div> </div>
</q-card-section> </q-card-section>
<q-separator /> <q-separator />
<q-card-section> <q-card-section>
<div v-if="account" class="float-right"> <div v-if="account" class="float-right">
<q-checkbox v-model="clearAllData" label="Clear All Data"></q-checkbox>
<q-btn @click="logout" flat label="Logout" icon="logout" class="q-ml-lg" color="primary"></q-btn> <q-btn @click="logout" flat label="Logout" icon="logout" class="q-ml-lg" color="primary"></q-btn>
</div> </div>
<div v-else> <div v-else>

View file

@ -7,7 +7,6 @@ async function userConfig(path) {
data: function () { data: function () {
return { return {
clearAllData: false
} }
}, },
methods: { methods: {
@ -17,7 +16,7 @@ async function userConfig(path) {
'Please make sure you save your private key! You will not be able to recover it later!' 'Please make sure you save your private key! You will not be able to recover it later!'
) )
.onOk(async () => { .onOk(async () => {
this.$emit('logout', { clearAllData: this.clearAllData }) this.$emit('logout')
}) })
}, },
copyText(text) { copyText(text) {

View file

@ -103,7 +103,11 @@ const market = async () => {
defaultBanner: '/nostrmarket/static/images/nostr-cover.png', defaultBanner: '/nostrmarket/static/images/nostr-cover.png',
defaultLogo: '/nostrmarket/static/images/nostr-avatar.png' defaultLogo: '/nostrmarket/static/images/nostr-avatar.png',
readNotes: {
merchants: false,
marketUi: false
}
} }
}, },
watch: { watch: {
@ -287,6 +291,9 @@ const market = async () => {
const relays = this.$q.localStorage.getItem('nostrmarket.relays') const relays = this.$q.localStorage.getItem('nostrmarket.relays')
this.relays = new Set(relays?.length ? relays : defaultRelays) this.relays = new Set(relays?.length ? relays : defaultRelays)
const readNotes = this.$q.localStorage.getItem('nostrmarket.readNotes') || {}
this.readNotes = { ...this.readNotes, ...readNotes }
}, },
applyUiConfigs(config = {}) { applyUiConfigs(config = {}) {
const { name, about, ui } = config?.opts || {} const { name, about, ui } = config?.opts || {}
@ -926,15 +933,38 @@ const market = async () => {
this.copyText(naddr) this.copyText(naddr)
}, },
logout(opts) { logout() {
window.localStorage.removeItem('nostrmarket.account') window.localStorage.removeItem('nostrmarket.account')
window.location.href = window.location.origin + window.location.pathname;
this.account = null this.account = null
if (opts?.clearAllData) { this.accountMetadata = null
this.$q.localStorage.getAllKeys().forEach(key => window.localStorage.removeItem(key)) },
window.location.href = window.location.origin + window.location.pathname;
}
clearAllData() {
LNbits.utils
.confirmDialog(
'This will remove all information about merchants, products, relays and others. ' +
'You will NOT be logged out. Do you want to proceed?'
)
.onOk(async () => {
this.$q.localStorage.getAllKeys()
.filter(key => key !== 'nostrmarket.account')
.forEach(key => window.localStorage.removeItem(key))
this.merchants = []
this.relays = []
this.orders = []
this.config = { opts: null }
this.shoppingCarts = []
this.checkoutCart = null
window.location.href = window.location.origin + window.location.pathname;
})
},
markNoteAsRead(noteId) {
this.readNotes[noteId] = true
this.$q.localStorage.set('nostrmarket.readNotes', this.readNotes)
} }
} }

View file

@ -129,8 +129,9 @@
<q-separator class="q-mt-sm q-mb-md"></q-separator> <q-separator class="q-mt-sm q-mb-md"></q-separator>
<market-config v-if="activePage === 'market-config'" :merchants="merchants" @add-merchant="addMerchant" <market-config v-if="activePage === 'market-config'" :merchants="merchants" @add-merchant="addMerchant"
@remove-merchant="removeMerchant" :relays="relays" @add-relay="addRelay" @remove-relay="removeRelay" @remove-merchant="removeMerchant" :relays="relays" :read-notes="readNotes" @add-relay="addRelay"
:config-ui="config?.opts" @ui-config-update="updateUiConfig" @publish-naddr="publishNaddr"></market-config> @remove-relay="removeRelay" :config-ui="config?.opts" @ui-config-update="updateUiConfig"
@publish-naddr="publishNaddr" @clear-all-data="clearAllData" @note-read="markNoteAsRead"></market-config>
<user-config v-else-if="activePage === 'user-config'" :account="account" @logout="logout" <user-config v-else-if="activePage === 'user-config'" :account="account" @logout="logout"
@copy-text="copyText"></user-config> @copy-text="copyText"></user-config>
@ -152,15 +153,35 @@
:stall="stalls.find(stall => stall.id == activeStall)" :products="filterProducts" :stall="stalls.find(stall => stall.id == activeStall)" :products="filterProducts"
:product-detail="activeProduct" @change-page="navigateTo" @add-to-cart="addProductToCart"></customer-stall> :product-detail="activeProduct" @change-page="navigateTo" @add-to-cart="addProductToCart"></customer-stall>
<div v-else-if="!merchants?.length" class="text-center"> <div v-else-if="!merchants?.length">
<q-list class="q-mt-md" bordered>
<q-item>
<q-item-section avatar>
<q-avatar>
<q-icon color="primary" name="info" size="xl" />
</q-avatar>
<span class="text-subtitle1"> <strong>You can start by adding a merchant public key </strong></span> </q-item-section>
<q-btn @click="setActivePage('market-config')" flat color="secondary" class="q-mb-xs">Here</q-btn>
<br>
<span class="text-subtitle1 q-pt-md"><strong>Or enter a nostr market profile ( <code>naddr</code>) in the
filter input.
</strong> </span>
<q-item-section class="q-mt-sm q-ml-lg">
<q-item-label><strong>Note</strong></q-item-label>
<q-item-label>
<div class="text-caption">
<span class="text-subtitle1"> You can start by adding a merchant public key </span>
<q-btn @click="setActivePage('market-config')" flat color="secondary" class="q-mb-xs">Here</q-btn>
<br>
<span class="text-subtitle1 q-pt-md">Or enter a nostr market profile ( <code>naddr</code>) in the
filter input.
</span>
</div>
</q-item-label>
</q-item-section>
<q-item-section side>
</q-item-section>
</q-item>
</q-list>
</div> </div>
<div v-else> <div v-else>