1.3.4 User-Scoped Storage Pattern: Add StorageService integration across modules for improved data management
- Introduced STORAGE_SERVICE token in the DI container for consistent service registration. - Updated BaseService to include storageService as a dependency, ensuring proper initialization and error handling. - Refactored ChatService to utilize storageService for managing unread messages and peers, replacing localStorage usage. - Enhanced MarketStore to save and load orders using storageService, improving data persistence and user experience. - Registered storageService in the base module, ensuring it is initialized and disposed of correctly. This integration streamlines data handling across the application, promoting better maintainability and consistency.
This commit is contained in:
parent
3abdd2d7d9
commit
3cf10b1db4
6 changed files with 285 additions and 103 deletions
|
|
@ -45,6 +45,7 @@ export abstract class BaseService {
|
||||||
protected relayHub: any = null
|
protected relayHub: any = null
|
||||||
protected authService: any = null
|
protected authService: any = null
|
||||||
protected visibilityService: any = null
|
protected visibilityService: any = null
|
||||||
|
protected storageService: any = null
|
||||||
|
|
||||||
// Service state
|
// Service state
|
||||||
public readonly isInitialized: Ref<boolean> = ref(false)
|
public readonly isInitialized: Ref<boolean> = ref(false)
|
||||||
|
|
@ -134,6 +135,7 @@ export abstract class BaseService {
|
||||||
this.relayHub = tryInjectService(SERVICE_TOKENS.RELAY_HUB)
|
this.relayHub = tryInjectService(SERVICE_TOKENS.RELAY_HUB)
|
||||||
this.authService = tryInjectService(SERVICE_TOKENS.AUTH_SERVICE)
|
this.authService = tryInjectService(SERVICE_TOKENS.AUTH_SERVICE)
|
||||||
this.visibilityService = tryInjectService(SERVICE_TOKENS.VISIBILITY_SERVICE)
|
this.visibilityService = tryInjectService(SERVICE_TOKENS.VISIBILITY_SERVICE)
|
||||||
|
this.storageService = tryInjectService(SERVICE_TOKENS.STORAGE_SERVICE)
|
||||||
|
|
||||||
// Check if all required dependencies are available
|
// Check if all required dependencies are available
|
||||||
const missingDeps = this.getMissingDependencies()
|
const missingDeps = this.getMissingDependencies()
|
||||||
|
|
@ -181,6 +183,9 @@ export abstract class BaseService {
|
||||||
if (deps.includes('VisibilityService') && !this.visibilityService) {
|
if (deps.includes('VisibilityService') && !this.visibilityService) {
|
||||||
missing.push('VisibilityService')
|
missing.push('VisibilityService')
|
||||||
}
|
}
|
||||||
|
if (deps.includes('StorageService') && !this.storageService) {
|
||||||
|
missing.push('StorageService')
|
||||||
|
}
|
||||||
|
|
||||||
return missing
|
return missing
|
||||||
}
|
}
|
||||||
|
|
@ -264,6 +269,8 @@ export abstract class BaseService {
|
||||||
this.isInitialized.value = false
|
this.isInitialized.value = false
|
||||||
this.relayHub = null
|
this.relayHub = null
|
||||||
this.authService = null
|
this.authService = null
|
||||||
|
this.visibilityService = null
|
||||||
|
this.storageService = null
|
||||||
|
|
||||||
console.log(`♻️ ${this.metadata.name} disposed`)
|
console.log(`♻️ ${this.metadata.name} disposed`)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,9 @@ export const SERVICE_TOKENS = {
|
||||||
// Visibility services
|
// Visibility services
|
||||||
VISIBILITY_SERVICE: Symbol('visibilityService'),
|
VISIBILITY_SERVICE: Symbol('visibilityService'),
|
||||||
|
|
||||||
|
// Storage services
|
||||||
|
STORAGE_SERVICE: Symbol('storageService'),
|
||||||
|
|
||||||
// Market services
|
// Market services
|
||||||
MARKET_STORE: Symbol('marketStore'),
|
MARKET_STORE: Symbol('marketStore'),
|
||||||
PAYMENT_MONITOR: Symbol('paymentMonitor'),
|
PAYMENT_MONITOR: Symbol('paymentMonitor'),
|
||||||
|
|
|
||||||
202
src/core/services/StorageService.ts
Normal file
202
src/core/services/StorageService.ts
Normal file
|
|
@ -0,0 +1,202 @@
|
||||||
|
import { BaseService } from '@/core/base/BaseService'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Centralized storage service providing user-scoped localStorage operations
|
||||||
|
*
|
||||||
|
* Features:
|
||||||
|
* - Automatic user-scoped key generation
|
||||||
|
* - Type-safe storage operations
|
||||||
|
* - Consistent data isolation between users
|
||||||
|
* - Fallback to global storage for anonymous users
|
||||||
|
* - Error handling with graceful degradation
|
||||||
|
*/
|
||||||
|
export class StorageService extends BaseService {
|
||||||
|
// Service metadata
|
||||||
|
protected readonly metadata = {
|
||||||
|
name: 'StorageService',
|
||||||
|
version: '1.0.0',
|
||||||
|
dependencies: ['AuthService'] // Depends on auth for user pubkey
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service-specific initialization (called by BaseService)
|
||||||
|
*/
|
||||||
|
protected async onInitialize(): Promise<void> {
|
||||||
|
this.debug('StorageService initialized')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate user-scoped storage key
|
||||||
|
* @param baseKey - Base key to scope to current user
|
||||||
|
* @returns User-scoped key or base key if no user
|
||||||
|
*/
|
||||||
|
private getUserStorageKey(baseKey: string): string {
|
||||||
|
if (!this.authService?.user?.value?.pubkey) {
|
||||||
|
// No user authenticated, use global key
|
||||||
|
return baseKey
|
||||||
|
}
|
||||||
|
|
||||||
|
const userPubkey = this.authService.user.value.pubkey
|
||||||
|
return `${baseKey}_${userPubkey}`
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store user-scoped data in localStorage
|
||||||
|
* @param key - Base storage key
|
||||||
|
* @param data - Data to store (will be JSON serialized)
|
||||||
|
*/
|
||||||
|
setUserData<T>(key: string, data: T): void {
|
||||||
|
try {
|
||||||
|
const storageKey = this.getUserStorageKey(key)
|
||||||
|
const serializedData = JSON.stringify(data)
|
||||||
|
localStorage.setItem(storageKey, serializedData)
|
||||||
|
|
||||||
|
this.debug(`Stored user data: ${storageKey}`)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to store user data for key "${key}":`, error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve user-scoped data from localStorage
|
||||||
|
* @param key - Base storage key
|
||||||
|
* @param defaultValue - Default value if not found
|
||||||
|
* @returns Stored data or default value
|
||||||
|
*/
|
||||||
|
getUserData<T>(key: string, defaultValue?: T): T | undefined {
|
||||||
|
try {
|
||||||
|
const storageKey = this.getUserStorageKey(key)
|
||||||
|
const stored = localStorage.getItem(storageKey)
|
||||||
|
|
||||||
|
if (stored === null) {
|
||||||
|
this.debug(`No stored data found for key: ${storageKey}`)
|
||||||
|
return defaultValue
|
||||||
|
}
|
||||||
|
|
||||||
|
const parsed = JSON.parse(stored) as T
|
||||||
|
this.debug(`Retrieved user data: ${storageKey}`)
|
||||||
|
return parsed
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to retrieve user data for key "${key}":`, error)
|
||||||
|
return defaultValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove user-scoped data from localStorage
|
||||||
|
* @param key - Base storage key
|
||||||
|
*/
|
||||||
|
clearUserData(key: string): void {
|
||||||
|
try {
|
||||||
|
const storageKey = this.getUserStorageKey(key)
|
||||||
|
localStorage.removeItem(storageKey)
|
||||||
|
|
||||||
|
this.debug(`Cleared user data: ${storageKey}`)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to clear user data for key "${key}":`, error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if user-scoped data exists
|
||||||
|
* @param key - Base storage key
|
||||||
|
* @returns True if data exists
|
||||||
|
*/
|
||||||
|
hasUserData(key: string): boolean {
|
||||||
|
try {
|
||||||
|
const storageKey = this.getUserStorageKey(key)
|
||||||
|
return localStorage.getItem(storageKey) !== null
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to check user data for key "${key}":`, error)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all keys for the current user (useful for cleanup)
|
||||||
|
* @returns Array of storage keys belonging to current user
|
||||||
|
*/
|
||||||
|
getUserKeys(): string[] {
|
||||||
|
try {
|
||||||
|
if (!this.authService?.user?.value?.pubkey) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
const userPubkey = this.authService.user.value.pubkey
|
||||||
|
const userKeys: string[] = []
|
||||||
|
|
||||||
|
// Scan localStorage for keys belonging to this user
|
||||||
|
for (let i = 0; i < localStorage.length; i++) {
|
||||||
|
const key = localStorage.key(i)
|
||||||
|
if (key && key.endsWith(`_${userPubkey}`)) {
|
||||||
|
userKeys.push(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return userKeys
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to get user keys:', error)
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all data for the current user (useful on logout)
|
||||||
|
*/
|
||||||
|
clearAllUserData(): void {
|
||||||
|
try {
|
||||||
|
const userKeys = this.getUserKeys()
|
||||||
|
|
||||||
|
for (const key of userKeys) {
|
||||||
|
localStorage.removeItem(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.debug(`Cleared all user data: ${userKeys.length} keys`)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to clear all user data:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrate data from old storage pattern to user-scoped pattern
|
||||||
|
* @param oldKey - Old global key
|
||||||
|
* @param newKey - New base key for user scoping
|
||||||
|
*/
|
||||||
|
migrateToUserScoped<T>(oldKey: string, newKey: string): void {
|
||||||
|
try {
|
||||||
|
// Only migrate if we have a user and old data exists
|
||||||
|
if (!this.authService?.user?.value?.pubkey) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const oldData = localStorage.getItem(oldKey)
|
||||||
|
if (oldData) {
|
||||||
|
const parsed = JSON.parse(oldData) as T
|
||||||
|
this.setUserData(newKey, parsed)
|
||||||
|
localStorage.removeItem(oldKey)
|
||||||
|
|
||||||
|
this.debug(`Migrated data from "${oldKey}" to user-scoped "${newKey}"`)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to migrate data from "${oldKey}" to "${newKey}":`, error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get current user pubkey (for debugging)
|
||||||
|
*/
|
||||||
|
getCurrentUserPubkey(): string | null {
|
||||||
|
return this.authService?.user?.value?.pubkey || null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleanup when service is disposed (called by BaseService)
|
||||||
|
*/
|
||||||
|
protected async onDispose(): Promise<void> {
|
||||||
|
this.debug('StorageService disposed')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export singleton instance
|
||||||
|
export const storageService = new StorageService()
|
||||||
|
|
@ -12,6 +12,7 @@ import { pwaService } from './pwa/pwa-service'
|
||||||
// Import core services
|
// Import core services
|
||||||
import { paymentService } from '@/core/services/PaymentService'
|
import { paymentService } from '@/core/services/PaymentService'
|
||||||
import { visibilityService } from '@/core/services/VisibilityService'
|
import { visibilityService } from '@/core/services/VisibilityService'
|
||||||
|
import { storageService } from '@/core/services/StorageService'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base Module Plugin
|
* Base Module Plugin
|
||||||
|
|
@ -36,6 +37,9 @@ export const baseModule: ModulePlugin = {
|
||||||
// Register visibility service
|
// Register visibility service
|
||||||
container.provide(SERVICE_TOKENS.VISIBILITY_SERVICE, visibilityService)
|
container.provide(SERVICE_TOKENS.VISIBILITY_SERVICE, visibilityService)
|
||||||
|
|
||||||
|
// Register storage service
|
||||||
|
container.provide(SERVICE_TOKENS.STORAGE_SERVICE, storageService)
|
||||||
|
|
||||||
// Register PWA service
|
// Register PWA service
|
||||||
container.provide('pwaService', pwaService)
|
container.provide('pwaService', pwaService)
|
||||||
|
|
||||||
|
|
@ -54,6 +58,10 @@ export const baseModule: ModulePlugin = {
|
||||||
waitForDependencies: false, // VisibilityService has no dependencies
|
waitForDependencies: false, // VisibilityService has no dependencies
|
||||||
maxRetries: 1
|
maxRetries: 1
|
||||||
})
|
})
|
||||||
|
await storageService.initialize({
|
||||||
|
waitForDependencies: true, // StorageService depends on AuthService
|
||||||
|
maxRetries: 3
|
||||||
|
})
|
||||||
|
|
||||||
console.log('✅ Base module installed successfully')
|
console.log('✅ Base module installed successfully')
|
||||||
},
|
},
|
||||||
|
|
@ -66,6 +74,7 @@ export const baseModule: ModulePlugin = {
|
||||||
await auth.dispose()
|
await auth.dispose()
|
||||||
await paymentService.dispose()
|
await paymentService.dispose()
|
||||||
await visibilityService.dispose()
|
await visibilityService.dispose()
|
||||||
|
await storageService.dispose()
|
||||||
|
|
||||||
console.log('✅ Base module uninstalled')
|
console.log('✅ Base module uninstalled')
|
||||||
},
|
},
|
||||||
|
|
@ -74,6 +83,8 @@ export const baseModule: ModulePlugin = {
|
||||||
relayHub,
|
relayHub,
|
||||||
auth,
|
auth,
|
||||||
paymentService,
|
paymentService,
|
||||||
|
visibilityService,
|
||||||
|
storageService,
|
||||||
pwaService
|
pwaService
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,15 +6,13 @@ import type { ChatMessage, ChatPeer, UnreadMessageData, ChatConfig } from '../ty
|
||||||
import { getAuthToken } from '@/lib/config/lnbits'
|
import { getAuthToken } from '@/lib/config/lnbits'
|
||||||
import { config } from '@/lib/config'
|
import { config } from '@/lib/config'
|
||||||
|
|
||||||
const UNREAD_MESSAGES_KEY = 'nostr-chat-unread-messages'
|
|
||||||
const PEERS_KEY = 'nostr-chat-peers'
|
|
||||||
|
|
||||||
export class ChatService extends BaseService {
|
export class ChatService extends BaseService {
|
||||||
// Service metadata
|
// Service metadata
|
||||||
protected readonly metadata = {
|
protected readonly metadata = {
|
||||||
name: 'ChatService',
|
name: 'ChatService',
|
||||||
version: '1.0.0',
|
version: '1.0.0',
|
||||||
dependencies: ['RelayHub', 'AuthService', 'VisibilityService']
|
dependencies: ['RelayHub', 'AuthService', 'VisibilityService', 'StorageService']
|
||||||
}
|
}
|
||||||
|
|
||||||
// Service-specific state
|
// Service-specific state
|
||||||
|
|
@ -64,6 +62,9 @@ export class ChatService extends BaseService {
|
||||||
* Complete the initialization once all dependencies are available
|
* Complete the initialization once all dependencies are available
|
||||||
*/
|
*/
|
||||||
private async completeInitialization(): Promise<void> {
|
private async completeInitialization(): Promise<void> {
|
||||||
|
// Load peers from storage first
|
||||||
|
this.loadPeersFromStorage()
|
||||||
|
|
||||||
// Load peers from API
|
// Load peers from API
|
||||||
await this.loadPeersFromAPI().catch(error => {
|
await this.loadPeersFromAPI().catch(error => {
|
||||||
console.warn('Failed to load peers from API:', error)
|
console.warn('Failed to load peers from API:', error)
|
||||||
|
|
@ -290,36 +291,24 @@ export class ChatService extends BaseService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private getUnreadData(peerPubkey: string): UnreadMessageData {
|
private getUnreadData(peerPubkey: string): UnreadMessageData {
|
||||||
try {
|
const data = this.storageService.getUserData(`chat-unread-messages-${peerPubkey}`, {
|
||||||
const stored = localStorage.getItem(`${UNREAD_MESSAGES_KEY}-${peerPubkey}`)
|
lastReadTimestamp: 0,
|
||||||
if (stored) {
|
unreadCount: 0,
|
||||||
const data = JSON.parse(stored)
|
processedMessageIds: []
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...data,
|
...data,
|
||||||
processedMessageIds: new Set(data.processedMessageIds || [])
|
processedMessageIds: new Set(data.processedMessageIds || [])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
console.warn('Failed to load unread data for peer:', peerPubkey, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
lastReadTimestamp: 0,
|
|
||||||
unreadCount: 0,
|
|
||||||
processedMessageIds: new Set()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private saveUnreadData(peerPubkey: string, data: UnreadMessageData): void {
|
private saveUnreadData(peerPubkey: string, data: UnreadMessageData): void {
|
||||||
try {
|
|
||||||
const serializable = {
|
const serializable = {
|
||||||
...data,
|
...data,
|
||||||
processedMessageIds: Array.from(data.processedMessageIds)
|
processedMessageIds: Array.from(data.processedMessageIds)
|
||||||
}
|
}
|
||||||
localStorage.setItem(`${UNREAD_MESSAGES_KEY}-${peerPubkey}`, JSON.stringify(serializable))
|
this.storageService.setUserData(`chat-unread-messages-${peerPubkey}`, serializable)
|
||||||
} catch (error) {
|
|
||||||
console.warn('Failed to save unread data for peer:', peerPubkey, error)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load peers from API
|
// Load peers from API
|
||||||
|
|
@ -369,26 +358,21 @@ export class ChatService extends BaseService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadPeersFromStorage(): void {
|
private loadPeersFromStorage(): void {
|
||||||
try {
|
// Skip loading peers in constructor as StorageService may not be available yet
|
||||||
const stored = localStorage.getItem(PEERS_KEY)
|
// This will be called later during initialization when dependencies are ready
|
||||||
if (stored) {
|
if (!this.isInitialized.value) {
|
||||||
const peersArray = JSON.parse(stored) as ChatPeer[]
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const peersArray = this.storageService.getUserData('chat-peers', []) as ChatPeer[]
|
||||||
peersArray.forEach(peer => {
|
peersArray.forEach(peer => {
|
||||||
this.peers.value.set(peer.pubkey, peer)
|
this.peers.value.set(peer.pubkey, peer)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
console.warn('Failed to load peers from storage:', error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private savePeersToStorage(): void {
|
private savePeersToStorage(): void {
|
||||||
try {
|
|
||||||
const peersArray = Array.from(this.peers.value.values())
|
const peersArray = Array.from(this.peers.value.values())
|
||||||
localStorage.setItem(PEERS_KEY, JSON.stringify(peersArray))
|
this.storageService.setUserData('chat-peers', peersArray)
|
||||||
} catch (error) {
|
|
||||||
console.warn('Failed to save peers to storage:', error)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load message history for known peers
|
// Load message history for known peers
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { invoiceService } from '@/lib/services/invoiceService'
|
||||||
import { paymentMonitor } from '@/lib/services/paymentMonitor'
|
import { paymentMonitor } from '@/lib/services/paymentMonitor'
|
||||||
import { nostrmarketService } from '../services/nostrmarketService'
|
import { nostrmarketService } from '../services/nostrmarketService'
|
||||||
import { useAuth } from '@/composables/useAuth'
|
import { useAuth } from '@/composables/useAuth'
|
||||||
|
import { injectService, SERVICE_TOKENS } from '@/core/di-container'
|
||||||
import type { LightningInvoice } from '@/lib/services/invoiceService'
|
import type { LightningInvoice } from '@/lib/services/invoiceService'
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -16,12 +17,7 @@ import type {
|
||||||
|
|
||||||
export const useMarketStore = defineStore('market', () => {
|
export const useMarketStore = defineStore('market', () => {
|
||||||
const auth = useAuth()
|
const auth = useAuth()
|
||||||
|
const storageService = injectService(SERVICE_TOKENS.STORAGE_SERVICE) as any
|
||||||
// Helper function to get user-specific storage key
|
|
||||||
const getUserStorageKey = (baseKey: string) => {
|
|
||||||
const userPubkey = auth.currentUser?.value?.pubkey
|
|
||||||
return userPubkey ? `${baseKey}_${userPubkey}` : baseKey
|
|
||||||
}
|
|
||||||
// Core market state
|
// Core market state
|
||||||
const markets = ref<Market[]>([])
|
const markets = ref<Market[]>([])
|
||||||
const stalls = ref<Stall[]>([])
|
const stalls = ref<Stall[]>([])
|
||||||
|
|
@ -681,16 +677,13 @@ export const useMarketStore = defineStore('market', () => {
|
||||||
|
|
||||||
// Persistence methods
|
// Persistence methods
|
||||||
const saveOrdersToStorage = () => {
|
const saveOrdersToStorage = () => {
|
||||||
try {
|
storageService.setUserData('market_orders', orders.value)
|
||||||
const storageKey = getUserStorageKey('market_orders')
|
|
||||||
localStorage.setItem(storageKey, JSON.stringify(orders.value))
|
|
||||||
|
|
||||||
// Debug: Check what's being saved
|
// Debug: Check what's being saved
|
||||||
const orderCount = Object.keys(orders.value).length
|
const orderCount = Object.keys(orders.value).length
|
||||||
const paidOrders = Object.values(orders.value).filter(o => o.paymentStatus === 'paid' || o.status === 'paid')
|
const paidOrders = Object.values(orders.value).filter(o => o.paymentStatus === 'paid' || o.status === 'paid')
|
||||||
|
|
||||||
console.log('💾 Saved orders to localStorage:', {
|
console.log('💾 Saved orders to storage:', {
|
||||||
storageKey,
|
|
||||||
totalOrders: orderCount,
|
totalOrders: orderCount,
|
||||||
paidOrders: paidOrders.length,
|
paidOrders: paidOrders.length,
|
||||||
orderStatuses: Object.values(orders.value).map(o => ({
|
orderStatuses: Object.values(orders.value).map(o => ({
|
||||||
|
|
@ -700,25 +693,17 @@ export const useMarketStore = defineStore('market', () => {
|
||||||
hasPaymentRequest: !!o.paymentRequest
|
hasPaymentRequest: !!o.paymentRequest
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
} catch (error) {
|
|
||||||
console.warn('Failed to save orders to localStorage:', error)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadOrdersFromStorage = () => {
|
const loadOrdersFromStorage = () => {
|
||||||
try {
|
const parsedOrders = storageService.getUserData('market_orders', {})
|
||||||
const storageKey = getUserStorageKey('market_orders')
|
|
||||||
const stored = localStorage.getItem(storageKey)
|
|
||||||
if (stored) {
|
|
||||||
const parsedOrders = JSON.parse(stored)
|
|
||||||
orders.value = parsedOrders
|
orders.value = parsedOrders
|
||||||
|
|
||||||
// Debug: Check payment status of loaded orders
|
// Debug: Check payment status of loaded orders
|
||||||
const orderCount = Object.keys(parsedOrders).length
|
const orderCount = Object.keys(parsedOrders).length
|
||||||
const paidOrders = Object.values(parsedOrders).filter((o: any) => o.paymentStatus === 'paid' || o.status === 'paid')
|
const paidOrders = Object.values(parsedOrders).filter((o: any) => o.paymentStatus === 'paid' || o.status === 'paid')
|
||||||
|
|
||||||
console.log('📦 Loaded orders from localStorage:', {
|
console.log('📦 Loaded orders from storage:', {
|
||||||
storageKey,
|
|
||||||
totalOrders: orderCount,
|
totalOrders: orderCount,
|
||||||
paidOrders: paidOrders.length,
|
paidOrders: paidOrders.length,
|
||||||
orderStatuses: Object.values(parsedOrders).map((o: any) => ({
|
orderStatuses: Object.values(parsedOrders).map((o: any) => ({
|
||||||
|
|
@ -728,16 +713,6 @@ export const useMarketStore = defineStore('market', () => {
|
||||||
hasPaymentRequest: !!o.paymentRequest
|
hasPaymentRequest: !!o.paymentRequest
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
} else {
|
|
||||||
console.log('No orders found in localStorage for key:', storageKey)
|
|
||||||
// Clear any existing orders when switching users
|
|
||||||
orders.value = {}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.warn('Failed to load orders from localStorage:', error)
|
|
||||||
// Clear orders on error
|
|
||||||
orders.value = {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear orders when user changes
|
// Clear orders when user changes
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue