diff --git a/apps/web/src/mocks/handlers-marketplace.ts b/apps/web/src/mocks/handlers-marketplace.ts index bf3638ec1..a3192d092 100644 --- a/apps/web/src/mocks/handlers-marketplace.ts +++ b/apps/web/src/mocks/handlers-marketplace.ts @@ -273,6 +273,7 @@ export const handlersMarketplace = [ ); }), + // GET /marketplace/orders — user's orders (commerceService.getPurchases) http.get('*/api/v1/marketplace/orders', () => { return HttpResponse.json({ success: true, @@ -280,16 +281,33 @@ export const handlersMarketplace = [ { id: 'order-1', status: 'completed', + total_amount: 29.99, total: 29.99, created_at: '2024-01-01T00:00:00Z', items: [ { + id: 'item-1', product_id: 'prod-1', title: 'Cyberpunk Drum Kit', price: 29.99, }, ], }, + { + id: 'order-2', + status: 'completed', + total_amount: 49.99, + total: 49.99, + created_at: '2024-01-15T00:00:00Z', + items: [ + { + id: 'item-2', + product_id: 'prod-2', + title: 'Ethereal Pads Vol. 1', + price: 49.99, + }, + ], + }, ], }); }), diff --git a/apps/web/src/services/commerceService.ts b/apps/web/src/services/commerceService.ts index 5c00c15b7..16362f696 100644 --- a/apps/web/src/services/commerceService.ts +++ b/apps/web/src/services/commerceService.ts @@ -1,6 +1,22 @@ -import { apiClient } from './api/client'; +import { apiClient } from '@/services/api/client'; import { Purchase, Product } from '../types'; +interface OrderItemApi { + id?: string; + product_id: string; + price: number; + title?: string; +} + +interface OrderApi { + id: string; + status: string; + total_amount?: number; + total?: number; + created_at: string; + items?: OrderItemApi[]; +} + interface SellerSale { order_id: string; product_id: string; @@ -36,51 +52,63 @@ function formatRelativeDate(dateStr: string): string { return d.toLocaleDateString(); } -const MOCK_PURCHASES: Purchase[] = [ - { - id: 'p1', - orderId: 'ORD-9921', - date: '2023-10-24', - price: 29.99, - status: 'completed', - downloadUrl: '#', - license: { id: 'l1', name: 'Standard', price: 29.99, features: [] }, - product: { - id: 'prod1', - title: 'Cyberpunk 2077 Drums', - type: 'pack', - price: 29.99, - currency: 'USD', - rating: 5, - coverUrl: 'https://picsum.photos/id/120/100/100', - author: 'Neon Audio', - } as Partial as Product, - }, - { - id: 'p2', - orderId: 'ORD-9850', - date: '2023-10-15', - price: 49.99, - status: 'completed', - downloadUrl: '#', - license: { id: 'l2', name: 'Premium', price: 49.99, features: [] }, - product: { - id: 'prod2', - title: 'Ethereal Pads Vol. 1', - type: 'pack', - price: 49.99, - currency: 'USD', - rating: 4, - coverUrl: 'https://picsum.photos/id/140/100/100', - author: 'Soundscapes', - } as Partial as Product, - }, -]; +function mapOrderToPurchases(order: OrderApi): Purchase[] { + const orderId = typeof order.id === 'string' ? order.id : String(order.id); + const dateStr = order.created_at + ? new Date(order.created_at).toISOString().slice(0, 10) + : ''; + const items = order.items ?? []; + if (items.length === 0) { + const total = order.total_amount ?? order.total ?? 0; + return [ + { + id: orderId, + orderId, + date: dateStr, + price: total, + status: order.status, + downloadUrl: '#', + license: { id: 'lic-default', name: 'Standard', price: total, features: [] }, + product: { + id: 'unknown', + title: 'Order', + type: 'pack', + price: total, + currency: 'USD', + coverUrl: '', + } as Partial as Product, + }, + ]; + } + return items.map((item, idx) => { + const productId = item.product_id ?? 'unknown'; + const price = item.price ?? 0; + const title = item.title ?? productId; + return { + id: `${orderId}-${item.id ?? idx}`, + orderId, + date: dateStr, + price, + status: order.status, + downloadUrl: '#', + license: { id: `lic-${productId}`, name: 'Standard', price, features: [] }, + product: { + id: productId, + title, + type: 'pack', + price, + currency: 'USD', + coverUrl: '', + } as Partial as Product, + }; + }); +} export const commerceService = { - getPurchases: async () => { - await new Promise((resolve) => setTimeout(resolve, 600)); - return MOCK_PURCHASES; + getPurchases: async (): Promise => { + const response = await apiClient.get('/marketplace/orders'); + const orders = Array.isArray(response.data) ? response.data : []; + return orders.flatMap(mapOrderToPurchases); }, // v0.401 M3: Real API call to GET /sell/sales @@ -128,8 +156,11 @@ export const commerceService = { return (data as { top_products?: TopProductStats[] })?.top_products ?? []; }, - requestRefund: async (_orderId: string, _reason: string) => { - await new Promise((resolve) => setTimeout(resolve, 800)); + requestRefund: async (orderId: string, reason: string) => { + await apiClient.post(`/marketplace/orders/${orderId}/refund`, { + reason: reason || 'Requested by customer', + details: '', + }); return { success: true }; }, };