Add NostrmarketAPI integration and enhance MerchantStore component

- Introduce NostrmarketAPI service for improved merchant profile management.
- Update MerchantStore component to handle loading and error states during merchant profile checks.
- Implement logic to check for merchant profiles using the new API, enhancing user experience.
- Refactor computed properties and lifecycle methods to accommodate the new API integration.

These changes streamline the process of checking and managing merchant profiles, providing users with real-time feedback and improving overall functionality.
This commit is contained in:
padreug 2025-09-08 13:42:27 +02:00
parent 8cf62076fd
commit b25e502c17
5 changed files with 319 additions and 28 deletions

View file

@ -1,7 +1,28 @@
<template>
<div class="space-y-6">
<!-- Loading State -->
<div v-if="isLoadingMerchant" class="flex flex-col items-center justify-center py-12">
<div class="w-16 h-16 mx-auto mb-4 bg-muted/50 rounded-full flex items-center justify-center">
<div class="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
</div>
<h3 class="text-lg font-medium text-foreground mb-2">Checking Merchant Status</h3>
<p class="text-muted-foreground">Loading your merchant profile...</p>
</div>
<!-- Error State -->
<div v-else-if="merchantCheckError" class="flex flex-col items-center justify-center py-12">
<div class="w-16 h-16 mx-auto mb-4 bg-red-500/10 rounded-full flex items-center justify-center">
<AlertCircle class="w-8 h-8 text-red-500" />
</div>
<h3 class="text-lg font-medium text-foreground mb-2">Error Loading Merchant Status</h3>
<p class="text-muted-foreground mb-4">{{ merchantCheckError }}</p>
<Button @click="checkMerchantProfile" variant="outline">
Try Again
</Button>
</div>
<!-- No Merchant Profile Empty State -->
<div v-if="!userHasMerchantProfile" class="flex flex-col items-center justify-center py-12">
<div v-else-if="!userHasMerchantProfile" 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">
<User class="w-12 h-12 text-muted-foreground" />
</div>
@ -332,7 +353,7 @@
</template>
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { ref, computed, onMounted, watch } from 'vue'
import { useRouter } from 'vue-router'
import { useMarketStore } from '@/modules/market/stores/market'
import { Button } from '@/components/ui/button'
@ -355,42 +376,25 @@ import {
} from 'lucide-vue-next'
import type { OrderStatus } from '@/modules/market/stores/market'
import type { NostrmarketService } from '../services/nostrmarketService'
import type { NostrmarketAPI, Merchant } from '../services/nostrmarketAPI'
import { auth } from '@/composables/useAuthService'
import { injectService, SERVICE_TOKENS } from '@/core/di-container'
const router = useRouter()
const marketStore = useMarketStore()
const nostrmarketService = injectService(SERVICE_TOKENS.NOSTRMARKET_SERVICE) as NostrmarketService
const nostrmarketAPI = injectService(SERVICE_TOKENS.NOSTRMARKET_API) as NostrmarketAPI
// Local state
const isGeneratingInvoice = ref<string | null>(null)
const merchantProfile = ref<Merchant | null>(null)
const isLoadingMerchant = ref(false)
const merchantCheckError = ref<string | null>(null)
// Computed properties
const userHasMerchantProfile = computed(() => {
const currentUserPubkey = auth.currentUser?.value?.pubkey
if (!currentUserPubkey) return false
// Check multiple indicators that suggest user has a merchant profile:
// 1. User has wallets with admin keys (required for merchant operations)
const userWallets = auth.currentUser?.value?.wallets || []
const hasAdminWallet = userWallets.some(wallet => wallet.adminkey)
// 2. User has stalls (indicates they've set up merchant infrastructure)
const userStalls = marketStore.stalls.filter(stall =>
stall.pubkey === currentUserPubkey
)
const hasStalls = userStalls.length > 0
// 3. User has been a seller in orders (indicates merchant activity)
const hasSellerOrders = Object.values(marketStore.orders).some(order =>
order.sellerPubkey === currentUserPubkey
)
// User is considered to have a merchant profile if they have at least:
// - An admin wallet AND (stalls OR seller orders)
// OR just have stalls (indicates successful merchant setup)
return hasStalls || (hasAdminWallet && hasSellerOrders)
// Use the actual API response to determine if user has merchant profile
return merchantProfile.value !== null
})
const userHasStalls = computed(() => {
@ -647,9 +651,58 @@ const getFirstWalletName = () => {
return 'N/A'
}
// Methods
const checkMerchantProfile = async () => {
const currentUser = auth.currentUser?.value
if (!currentUser) return
const userWallets = currentUser.wallets || []
if (userWallets.length === 0) {
console.warn('No wallets available for merchant check')
return
}
const wallet = userWallets[0] // Use first wallet
if (!wallet.inkey) {
console.warn('Wallet missing invoice key for merchant check')
return
}
isLoadingMerchant.value = true
merchantCheckError.value = null
try {
console.log('Checking for merchant profile...')
const merchant = await nostrmarketAPI.getMerchant(wallet.inkey)
merchantProfile.value = merchant
console.log('Merchant profile check result:', {
hasMerchant: !!merchant,
merchantId: merchant?.id,
active: merchant?.config?.active
})
} catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Failed to check merchant profile'
console.error('Error checking merchant profile:', error)
merchantCheckError.value = errorMessage
merchantProfile.value = null
} finally {
isLoadingMerchant.value = false
}
}
// Lifecycle
onMounted(() => {
onMounted(async () => {
console.log('Merchant Store component loaded')
await checkMerchantProfile()
})
// Watch for auth changes and re-check merchant profile
watch(() => auth.currentUser?.value?.pubkey, async (newPubkey, oldPubkey) => {
if (newPubkey !== oldPubkey) {
console.log('User changed, re-checking merchant profile')
await checkMerchantProfile()
}
})
</script>