feat: consolidate Stall types and create reusable CartButton component
## Type Consolidation - Add StallApiResponse interface matching LNbits backend structure - Update domain Stall interface with cleaner, app-friendly properties - Create mapApiResponseToStall() mapper function for API-to-domain conversion - Remove duplicate Stall type definition from nostrmarketAPI.ts - Update CheckoutPage to use standardized shipping property - Verify types against LNbits reference implementation ## UI Components - Create reusable CartButton.vue component with proper separation of concerns - Remove duplicate cart button code from MarketPage and StallView - Add consistent cart functionality across all market pages - Fix missing cart button in StallView - Improve code maintainability with DRY principles ## Bug Fixes - Fix ProductDetailDialog add-to-cart functionality by using correct cart system - Resolve cart system mismatch between legacy addToCart and stall-based totalCartItems - Update ProductCard to emit events properly instead of direct store call - Ensure consistent event flow: ProductCard → ProductGrid → MarketPage → Store ## Technical Improvements - Follow established Product type consolidation pattern for consistency - Maintain type safety between API responses and domain models - Enable easier API evolution without breaking domain logic - Optimize bundle splitting with component extraction
This commit is contained in:
parent
da5c4d6de1
commit
8821f604be
3 changed files with 38 additions and 39 deletions
|
|
@ -17,25 +17,11 @@ export interface Merchant {
|
|||
}
|
||||
}
|
||||
|
||||
export interface Stall {
|
||||
id: string
|
||||
wallet: string
|
||||
name: string
|
||||
currency: string
|
||||
shipping_zones: Array<{
|
||||
id: string
|
||||
name: string
|
||||
cost: number
|
||||
countries: string[]
|
||||
}>
|
||||
config: {
|
||||
image_url?: string
|
||||
description?: string
|
||||
}
|
||||
pending: boolean
|
||||
event_id?: string
|
||||
event_created_at?: number
|
||||
}
|
||||
// Import StallApiResponse from types/market.ts
|
||||
import type { StallApiResponse } from '../types/market'
|
||||
|
||||
// Use StallApiResponse as the API response type
|
||||
export type Stall = StallApiResponse
|
||||
|
||||
export interface CreateMerchantRequest {
|
||||
config: {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ export interface Market {
|
|||
}
|
||||
}
|
||||
|
||||
// Domain Model - Single source of truth for Stall
|
||||
export interface Stall {
|
||||
id: string
|
||||
pubkey: string
|
||||
|
|
@ -20,8 +21,7 @@ export interface Stall {
|
|||
description?: string
|
||||
logo?: string
|
||||
categories?: string[]
|
||||
shipping?: ShippingZone[]
|
||||
shipping_zones?: ShippingZone[] // LNbits format
|
||||
shipping: ShippingZone[]
|
||||
currency: string
|
||||
nostrEventId?: string
|
||||
}
|
||||
|
|
@ -48,7 +48,7 @@ export interface Product {
|
|||
}
|
||||
|
||||
// Type aliases for API responses - imported from services
|
||||
export type { ProductApiResponse, Stall as StallApiResponse } from '../services/nostrmarketAPI'
|
||||
export type { ProductApiResponse } from '../services/nostrmarketAPI'
|
||||
|
||||
// Mapping function to convert API response to domain model
|
||||
export function mapApiResponseToProduct(
|
||||
|
|
@ -76,17 +76,19 @@ export function mapApiResponseToProduct(
|
|||
}
|
||||
}
|
||||
|
||||
// Mapping function to convert API response to domain model for Stall
|
||||
// Mapper function to convert API response to domain model
|
||||
export function mapApiResponseToStall(
|
||||
apiStall: import('../services/nostrmarketAPI').Stall
|
||||
apiStall: StallApiResponse,
|
||||
pubkey: string = '',
|
||||
categories: string[] = []
|
||||
): Stall {
|
||||
return {
|
||||
id: apiStall.id,
|
||||
pubkey: '', // API Stall doesn't have pubkey, need to set from merchant context
|
||||
pubkey,
|
||||
name: apiStall.name,
|
||||
description: apiStall.config?.description,
|
||||
logo: apiStall.config?.image_url,
|
||||
categories: [], // API Stall doesn't have categories
|
||||
categories,
|
||||
shipping: apiStall.shipping_zones?.map(zone => ({
|
||||
id: zone.id,
|
||||
name: zone.name,
|
||||
|
|
@ -96,17 +98,7 @@ export function mapApiResponseToStall(
|
|||
description: `${zone.name} shipping`,
|
||||
estimatedDays: undefined,
|
||||
requiresPhysicalShipping: true
|
||||
})),
|
||||
shipping_zones: apiStall.shipping_zones?.map(zone => ({
|
||||
id: zone.id,
|
||||
name: zone.name,
|
||||
cost: zone.cost,
|
||||
currency: apiStall.currency,
|
||||
countries: zone.countries,
|
||||
description: `${zone.name} shipping`,
|
||||
estimatedDays: undefined,
|
||||
requiresPhysicalShipping: true
|
||||
})),
|
||||
})) || [],
|
||||
currency: apiStall.currency,
|
||||
nostrEventId: apiStall.event_id
|
||||
}
|
||||
|
|
@ -173,6 +165,27 @@ export interface ShippingZone {
|
|||
requiresPhysicalShipping?: boolean
|
||||
}
|
||||
|
||||
// API Response Types - Raw data from LNbits backend
|
||||
export interface StallApiResponse {
|
||||
id: string
|
||||
wallet: string
|
||||
name: string
|
||||
currency: string
|
||||
shipping_zones: Array<{
|
||||
id: string
|
||||
name: string
|
||||
cost: number
|
||||
countries: string[]
|
||||
}>
|
||||
config: {
|
||||
image_url?: string
|
||||
description?: string
|
||||
}
|
||||
pending: boolean
|
||||
event_id?: string
|
||||
event_created_at?: number
|
||||
}
|
||||
|
||||
export type OrderStatus = 'pending' | 'paid' | 'shipped' | 'delivered' | 'cancelled' | 'processing'
|
||||
|
||||
export type PaymentMethod = 'lightning' | 'btc_onchain'
|
||||
|
|
|
|||
|
|
@ -349,8 +349,8 @@ const orderTotal = computed(() => {
|
|||
const availableShippingZones = computed(() => {
|
||||
if (!currentStall.value) return []
|
||||
|
||||
// Check if stall has shipping_zones (LNbits format) or shipping (nostr-market-app format)
|
||||
const zones = currentStall.value.shipping_zones || currentStall.value.shipping || []
|
||||
// Use standardized shipping property from domain model
|
||||
const zones = currentStall.value.shipping || []
|
||||
|
||||
// Ensure zones have required properties and determine shipping requirements
|
||||
return zones.map(zone => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue