feat: Add MarketTest page and enhance error handling in market components

- Introduce MarketTest.vue for testing market loading and state management.
- Update error handling in Market.vue and useMarket composable to utilize marketStore for consistent error reporting.
- Enhance logging throughout market loading processes for better debugging and user feedback.
This commit is contained in:
padreug 2025-08-02 18:03:25 +02:00
parent 1a3510becb
commit 1ed8759162
6 changed files with 144 additions and 10 deletions

View file

@ -29,6 +29,7 @@ const navigation = computed<NavigationItem[]>(() => [
{ name: t('nav.home'), href: '/' }, { name: t('nav.home'), href: '/' },
{ name: t('nav.events'), href: '/events' }, { name: t('nav.events'), href: '/events' },
{ name: t('nav.market'), href: '/market' }, { name: t('nav.market'), href: '/market' },
{ name: 'Market Test', href: '/market-test' },
]) ])
// Compute total wallet balance // Compute total wallet balance

View file

@ -17,7 +17,6 @@ export function useMarket() {
const marketStore = useMarketStore() const marketStore = useMarketStore()
const isLoading = ref(false) const isLoading = ref(false)
const error = ref<string | null>(null)
const isConnected = ref(false) const isConnected = ref(false)
// Market loading state // Market loading state
@ -25,7 +24,7 @@ export function useMarket() {
try { try {
isLoading.value = true isLoading.value = true
marketStore.setLoading(true) marketStore.setLoading(true)
error.value = null marketStore.setError(null)
console.log('Loading market with naddr:', naddr) console.log('Loading market with naddr:', naddr)
@ -37,12 +36,14 @@ export function useMarket() {
throw new Error('Invalid market naddr') throw new Error('Invalid market naddr')
} }
console.log('About to load market data...')
// Load market data from Nostr // Load market data from Nostr
await loadMarketData(data) await loadMarketData(data)
console.log('Market data loaded successfully')
} catch (err) { } catch (err) {
console.error('Error loading market:', err) console.error('Error loading market:', err)
error.value = err instanceof Error ? err.message : 'Failed to load market' marketStore.setError(err instanceof Error ? err.message : 'Failed to load market')
// Don't throw error, let the UI handle it gracefully // Don't throw error, let the UI handle it gracefully
} finally { } finally {
isLoading.value = false isLoading.value = false
@ -52,20 +53,35 @@ export function useMarket() {
const loadMarketData = async (marketData: any) => { const loadMarketData = async (marketData: any) => {
try { try {
console.log('Starting loadMarketData...')
// Get Nostr client // Get Nostr client
const client = nostrStore.getClient() const client = nostrStore.getClient()
console.log('Got Nostr client')
// Load market configuration // Load market configuration
console.log('Loading market config...')
await loadMarketConfig(marketData) await loadMarketConfig(marketData)
console.log('Market config loaded')
// Load stalls for this market // Load stalls for this market
console.log('Loading stalls...')
await loadStalls(marketData.pubkey) await loadStalls(marketData.pubkey)
console.log('Stalls loaded')
// Load products for all stalls // Load products for all stalls
console.log('Loading products...')
await loadProducts() await loadProducts()
console.log('Products loaded')
// Subscribe to real-time updates // Subscribe to real-time updates
console.log('Subscribing to updates...')
try {
subscribeToMarketUpdates() subscribeToMarketUpdates()
console.log('Subscribed to updates')
} catch (err) {
console.warn('Failed to subscribe to updates:', err)
// Don't fail the entire load process if subscription fails
}
} catch (err) { } catch (err) {
console.error('Error loading market data:', err) console.error('Error loading market data:', err)
@ -113,7 +129,8 @@ export function useMarket() {
opts: { opts: {
name: 'Default Market', name: 'Default Market',
description: 'A default market', description: 'A default market',
merchants: [] merchants: [],
ui: {}
} }
} }
@ -132,7 +149,8 @@ export function useMarket() {
opts: { opts: {
name: 'Default Market', name: 'Default Market',
description: 'A default market', description: 'A default market',
merchants: [] merchants: [],
ui: {}
} }
} }
@ -340,6 +358,8 @@ export function useMarket() {
} catch (err) { } catch (err) {
console.error('Error subscribing to market updates:', err) console.error('Error subscribing to market updates:', err)
// Return a no-op function if subscription fails
return () => {}
} }
} }
@ -462,11 +482,17 @@ export function useMarket() {
const connectToMarket = async () => { const connectToMarket = async () => {
try { try {
console.log('Checking Nostr connection...')
console.log('Current connection state:', nostrStore.isConnected)
if (!nostrStore.isConnected) { if (!nostrStore.isConnected) {
console.log('Connecting to Nostr relays...')
await nostrStore.connect() await nostrStore.connect()
console.log('Connected to Nostr relays')
} }
isConnected.value = nostrStore.isConnected isConnected.value = nostrStore.isConnected
console.log('Final connection state:', isConnected.value)
if (!isConnected.value) { if (!isConnected.value) {
throw new Error('Failed to connect to Nostr relays') throw new Error('Failed to connect to Nostr relays')
@ -486,7 +512,6 @@ export function useMarket() {
return { return {
// State // State
isLoading: readonly(isLoading), isLoading: readonly(isLoading),
error: readonly(error),
isConnected: readonly(isConnected), isConnected: readonly(isConnected),
// Actions // Actions

View file

@ -9,10 +9,10 @@
</div> </div>
<!-- Error State --> <!-- Error State -->
<div v-else-if="market.error" class="flex justify-center items-center min-h-64"> <div v-else-if="marketStore.error" class="flex justify-center items-center min-h-64">
<div class="text-center"> <div class="text-center">
<h2 class="text-2xl font-bold text-red-600 mb-4">Failed to load market</h2> <h2 class="text-2xl font-bold text-red-600 mb-4">Failed to load market</h2>
<p class="text-gray-600 mb-4">{{ market.error }}</p> <p class="text-gray-600 mb-4">{{ marketStore.error }}</p>
<Button @click="retryLoadMarket" variant="outline"> <Button @click="retryLoadMarket" variant="outline">
Try Again Try Again
</Button> </Button>
@ -117,18 +117,25 @@ const loadMarket = async () => {
throw new Error('No market naddr configured') throw new Error('No market naddr configured')
} }
console.log('Connecting to market...')
await market.connectToMarket() await market.connectToMarket()
console.log('Connected to market')
console.log('Loading market...')
await market.loadMarket(naddr) await market.loadMarket(naddr)
console.log('Market loaded')
// Subscribe to real-time updates // Subscribe to real-time updates
unsubscribe = market.subscribeToMarketUpdates() unsubscribe = market.subscribeToMarketUpdates()
} catch (error) { } catch (error) {
console.error('Failed to load market:', error) console.error('Failed to load market:', error)
marketStore.setError(error instanceof Error ? error.message : 'Failed to load market')
} }
} }
const retryLoadMarket = () => { const retryLoadMarket = () => {
marketStore.setError(null)
loadMarket() loadMarket()
} }

85
src/pages/MarketTest.vue Normal file
View file

@ -0,0 +1,85 @@
<template>
<div class="container mx-auto px-4 py-8">
<h1 class="text-2xl font-bold mb-4">Market Loading Test</h1>
<div class="space-y-4">
<div>
<strong>Loading State:</strong> {{ marketStore.isLoading }}
</div>
<div>
<strong>Error State:</strong> {{ marketStore.error }}
</div>
<div>
<strong>Connected:</strong> {{ market.isConnected }}
</div>
<div>
<strong>Active Market:</strong> {{ marketStore.activeMarket ? 'Yes' : 'No' }}
</div>
<div>
<strong>Products Count:</strong> {{ marketStore.products.length }}
</div>
<div>
<strong>Stalls Count:</strong> {{ marketStore.stalls.length }}
</div>
<Button @click="testLoadMarket" :disabled="marketStore.isLoading">
{{ marketStore.isLoading ? 'Loading...' : 'Test Load Market' }}
</Button>
<Button @click="clearError" variant="outline">
Clear Error
</Button>
</div>
<div v-if="marketStore.error" class="mt-4 p-4 bg-red-100 border border-red-400 rounded">
<strong>Error:</strong> {{ marketStore.error }}
</div>
</div>
</template>
<script setup lang="ts">
import { useMarketStore } from '@/stores/market'
import { useMarket } from '@/composables/useMarket'
import { config } from '@/lib/config'
import { Button } from '@/components/ui/button'
const marketStore = useMarketStore()
const market = useMarket()
const testLoadMarket = async () => {
try {
console.log('=== Starting Market Test ===')
const naddr = config.market.defaultNaddr
console.log('Naddr:', naddr)
if (!naddr) {
marketStore.setError('No market naddr configured')
return
}
console.log('Connecting to market...')
await market.connectToMarket()
console.log('Connected to market')
console.log('Loading market...')
await market.loadMarket(naddr)
console.log('Market loaded')
console.log('=== Market Test Complete ===')
} catch (error) {
console.error('Test failed:', error)
marketStore.setError(error instanceof Error ? error.message : 'Test failed')
}
}
const clearError = () => {
marketStore.setError(null)
}
</script>

View file

@ -48,6 +48,15 @@ const router = createRouter({
title: 'Market', title: 'Market',
requiresAuth: true requiresAuth: true
} }
},
{
path: '/market-test',
name: 'market-test',
component: () => import('@/pages/MarketTest.vue'),
meta: {
title: 'Market Test',
requiresAuth: true
}
} }
] ]
}) })

View file

@ -14,7 +14,7 @@ export interface Market {
logo?: string logo?: string
banner?: string banner?: string
merchants: string[] merchants: string[]
ui: Record<string, any> ui?: Record<string, any>
} }
} }
@ -87,6 +87,7 @@ export const useMarketStore = defineStore('market', () => {
// UI state // UI state
const isLoading = ref(false) const isLoading = ref(false)
const error = ref<string | null>(null)
const searchText = ref('') const searchText = ref('')
const showFilterDetails = ref(false) const showFilterDetails = ref(false)
@ -215,6 +216,10 @@ export const useMarketStore = defineStore('market', () => {
isLoading.value = loading isLoading.value = loading
} }
const setError = (errorMessage: string | null) => {
error.value = errorMessage
}
const setSearchText = (text: string) => { const setSearchText = (text: string) => {
searchText.value = text searchText.value = text
} }
@ -335,6 +340,7 @@ export const useMarketStore = defineStore('market', () => {
activeStall: readonly(activeStall), activeStall: readonly(activeStall),
activeProduct: readonly(activeProduct), activeProduct: readonly(activeProduct),
isLoading: readonly(isLoading), isLoading: readonly(isLoading),
error: readonly(error),
searchText: readonly(searchText), searchText: readonly(searchText),
showFilterDetails: readonly(showFilterDetails), showFilterDetails: readonly(showFilterDetails),
filterData: readonly(filterData), filterData: readonly(filterData),
@ -349,6 +355,7 @@ export const useMarketStore = defineStore('market', () => {
// Actions // Actions
setLoading, setLoading,
setError,
setSearchText, setSearchText,
setActiveMarket, setActiveMarket,
setActiveStall, setActiveStall,