Enhance MerchantStore component with user store creation flow
- Introduce an empty state for users without a store, prompting them to create one. - Implement computed property to check if the user has a store based on their order history. - Update store statistics to reflect only the user's orders. - Add a placeholder function for future store creation functionality. These changes improve user experience by guiding new merchants to set up their stores effectively.
This commit is contained in:
parent
3679c719a3
commit
8e34f2c74e
2 changed files with 87 additions and 25 deletions
|
|
@ -1,23 +1,40 @@
|
|||
<template>
|
||||
<div class="space-y-6">
|
||||
<!-- Header -->
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<h2 class="text-2xl font-bold text-foreground">My Store</h2>
|
||||
<p class="text-muted-foreground mt-1">Manage incoming orders and your products</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<Button @click="navigateToMarket" variant="outline">
|
||||
<Store class="w-4 h-4 mr-2" />
|
||||
Browse Market
|
||||
</Button>
|
||||
<Button @click="addProduct" variant="default">
|
||||
<Plus class="w-4 h-4 mr-2" />
|
||||
Add Product
|
||||
</Button>
|
||||
<!-- No Store Empty State -->
|
||||
<div v-if="!userHasStore" class="flex flex-col items-center justify-center py-12">
|
||||
<div class="w-24 h-24 bg-muted rounded-full flex items-center justify-center mb-6">
|
||||
<Store class="w-12 h-12 text-muted-foreground" />
|
||||
</div>
|
||||
<h2 class="text-2xl font-bold text-foreground mb-2">Create Your Store</h2>
|
||||
<p class="text-muted-foreground text-center mb-6 max-w-md">
|
||||
You don't have a store yet. Set up your merchant profile to start selling products on the Nostr marketplace.
|
||||
</p>
|
||||
<Button @click="createStore" variant="default" size="lg">
|
||||
<Plus class="w-5 h-5 mr-2" />
|
||||
Create My Store
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<!-- Store Content (shown when user has a store) -->
|
||||
<div v-else>
|
||||
<!-- Header -->
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<h2 class="text-2xl font-bold text-foreground">My Store</h2>
|
||||
<p class="text-muted-foreground mt-1">Manage incoming orders and your products</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<Button @click="navigateToMarket" variant="outline">
|
||||
<Store class="w-4 h-4 mr-2" />
|
||||
Browse Market
|
||||
</Button>
|
||||
<Button @click="addProduct" variant="default">
|
||||
<Plus class="w-4 h-4 mr-2" />
|
||||
Add Product
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Store Stats -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-4 gap-6">
|
||||
<!-- Incoming Orders -->
|
||||
|
|
@ -295,6 +312,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- End of Store Content wrapper -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -332,29 +350,60 @@ const nostrmarketService = injectService(SERVICE_TOKENS.NOSTRMARKET_SERVICE) as
|
|||
const isGeneratingInvoice = ref<string | null>(null)
|
||||
|
||||
// Computed properties
|
||||
const userHasStore = computed(() => {
|
||||
// Check if user has any store/stall set up
|
||||
// For now, we'll check if they have ever been a seller on any order
|
||||
const currentUserPubkey = auth.currentUser?.value?.pubkey
|
||||
if (!currentUserPubkey) return false
|
||||
|
||||
// TODO: In the future, this should check if user has created a stall
|
||||
// For now, we'll show the create store prompt if they have no incoming orders
|
||||
const hasIncomingOrders = Object.values(marketStore.orders).some(order =>
|
||||
order.sellerPubkey === currentUserPubkey
|
||||
)
|
||||
return hasIncomingOrders
|
||||
})
|
||||
|
||||
const incomingOrders = computed(() => {
|
||||
// For now, show all orders as "incoming" since we don't have merchant filtering yet
|
||||
// In a real implementation, this would filter orders where the current user is the seller
|
||||
// Filter orders to only show those where the current user is the seller
|
||||
const currentUserPubkey = auth.currentUser?.value?.pubkey
|
||||
if (!currentUserPubkey) return []
|
||||
|
||||
return Object.values(marketStore.orders)
|
||||
.filter(order => order.status === 'pending')
|
||||
.filter(order => order.sellerPubkey === currentUserPubkey && order.status === 'pending')
|
||||
.sort((a, b) => b.createdAt - a.createdAt)
|
||||
})
|
||||
|
||||
const storeStats = computed(() => {
|
||||
const orders = Object.values(marketStore.orders)
|
||||
const currentUserPubkey = auth.currentUser?.value?.pubkey
|
||||
if (!currentUserPubkey) {
|
||||
return {
|
||||
incomingOrders: 0,
|
||||
pendingOrders: 0,
|
||||
paidOrders: 0,
|
||||
totalSales: 0,
|
||||
totalProducts: 0,
|
||||
activeProducts: 0,
|
||||
satisfaction: 0,
|
||||
totalReviews: 0
|
||||
}
|
||||
}
|
||||
|
||||
// Filter orders to only count those where current user is the seller
|
||||
const myOrders = Object.values(marketStore.orders).filter(o => o.sellerPubkey === currentUserPubkey)
|
||||
const now = Date.now() / 1000
|
||||
const thirtyDaysAgo = now - (30 * 24 * 60 * 60)
|
||||
|
||||
return {
|
||||
incomingOrders: orders.filter(o => o.status === 'pending').length,
|
||||
pendingOrders: orders.filter(o => o.status === 'pending').length,
|
||||
paidOrders: orders.filter(o => o.status === 'paid').length,
|
||||
totalSales: orders
|
||||
incomingOrders: myOrders.filter(o => o.status === 'pending').length,
|
||||
pendingOrders: myOrders.filter(o => o.status === 'pending').length,
|
||||
paidOrders: myOrders.filter(o => o.status === 'paid').length,
|
||||
totalSales: myOrders
|
||||
.filter(o => o.status === 'paid' && o.createdAt > thirtyDaysAgo)
|
||||
.reduce((sum, o) => sum + o.total, 0),
|
||||
totalProducts: 0, // TODO: Implement product management
|
||||
activeProducts: 0, // TODO: Implement product management
|
||||
satisfaction: 95, // TODO: Implement review system
|
||||
satisfaction: userHasStore.value ? 95 : 0, // TODO: Implement review system
|
||||
totalReviews: 0 // TODO: Implement review system
|
||||
}
|
||||
})
|
||||
|
|
@ -527,6 +576,11 @@ const addProduct = () => {
|
|||
console.log('Adding new product')
|
||||
}
|
||||
|
||||
const createStore = () => {
|
||||
// TODO: Implement store creation flow
|
||||
console.log('Create store functionality to be implemented')
|
||||
}
|
||||
|
||||
const navigateToMarket = () => router.push('/market')
|
||||
const viewAllOrders = () => router.push('/market-dashboard?tab=orders')
|
||||
const generateBulkInvoices = () => console.log('Generate bulk invoices')
|
||||
|
|
|
|||
|
|
@ -278,7 +278,15 @@ const statusFilter = ref('')
|
|||
const sortBy = ref('createdAt')
|
||||
|
||||
// Computed properties
|
||||
const allOrders = computed(() => Object.values(marketStore.orders))
|
||||
const allOrders = computed(() => {
|
||||
// Filter orders to only show those where the current user is the buyer
|
||||
const currentUserPubkey = auth.currentUser?.value?.pubkey
|
||||
if (!currentUserPubkey) return []
|
||||
|
||||
return Object.values(marketStore.orders).filter(order =>
|
||||
order.buyerPubkey === currentUserPubkey
|
||||
)
|
||||
})
|
||||
|
||||
const filteredOrders = computed(() => {
|
||||
if (!statusFilter.value) return allOrders.value
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue