@fluid-app/portal-sdk 0.1.243 → 0.1.244
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{OrdersScreen-DPcp2dLW.cjs → OrdersScreen-BxaJw-Kq.cjs} +84 -39
- package/dist/OrdersScreen-BxaJw-Kq.cjs.map +1 -0
- package/dist/{OrdersScreen-BV3vJ7xy.mjs → OrdersScreen-CPKRShbP.mjs} +84 -39
- package/dist/OrdersScreen-CPKRShbP.mjs.map +1 -0
- package/dist/{OrdersScreen-Cuch7aki.cjs → OrdersScreen-CQGCZLYf.cjs} +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.mjs +3 -3
- package/package.json +12 -12
- package/dist/OrdersScreen-BV3vJ7xy.mjs.map +0 -1
- package/dist/OrdersScreen-DPcp2dLW.cjs.map +0 -1
|
@@ -44,28 +44,45 @@ function mapPaymentMethod(raw) {
|
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
46
|
function mapToPortalTenantOrder(raw) {
|
|
47
|
+
const subtotal = requireMoneyField(raw.subtotal, "subtotal");
|
|
48
|
+
const discount = requireMoneyField(raw.discount, "discount");
|
|
49
|
+
const shipping = requireMoneyField(raw.shipping, "shipping");
|
|
50
|
+
const tax = requireMoneyField(raw.tax, "tax");
|
|
51
|
+
const total = requireMoneyField(raw.total, "total");
|
|
47
52
|
return {
|
|
48
53
|
id: raw.id ?? 0,
|
|
49
54
|
token: raw.token ?? "",
|
|
50
55
|
status: raw.status ?? "pending",
|
|
51
|
-
subtotal
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
+
subtotal,
|
|
57
|
+
subtotal_in_currency: raw.subtotal_in_currency ?? subtotal,
|
|
58
|
+
discount,
|
|
59
|
+
discount_in_currency: raw.discount_in_currency ?? discount,
|
|
60
|
+
shipping,
|
|
61
|
+
shipping_in_currency: raw.shipping_in_currency ?? shipping,
|
|
62
|
+
tax,
|
|
63
|
+
tax_in_currency: raw.tax_in_currency ?? tax,
|
|
64
|
+
total,
|
|
65
|
+
total_in_currency: raw.total_in_currency ?? total,
|
|
56
66
|
currency: raw.currency ?? "",
|
|
57
|
-
line_items: (raw.line_items ?? []).map((li) =>
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
line_items: (raw.line_items ?? []).map((li) => {
|
|
68
|
+
const liPrice = li.price ?? "0";
|
|
69
|
+
const liTotal = li.total ?? "0";
|
|
70
|
+
return {
|
|
71
|
+
id: li.id ?? 0,
|
|
72
|
+
product_id: li.product_id ?? 0,
|
|
73
|
+
product_name: li.product_name ?? "",
|
|
74
|
+
variant_id: li.variant_id ?? null,
|
|
75
|
+
variant_name: li.variant_name ?? null,
|
|
76
|
+
sku: li.sku ?? null,
|
|
77
|
+
image_url: li.image_url ?? null,
|
|
78
|
+
quantity: li.quantity ?? 0,
|
|
79
|
+
price: liPrice,
|
|
80
|
+
price_in_currency: li.price_in_currency ?? liPrice,
|
|
81
|
+
total: liTotal,
|
|
82
|
+
total_in_currency: li.total_in_currency ?? liTotal,
|
|
83
|
+
source_subscription: li.source_subscription?.subscription_token ? { subscription_token: li.source_subscription.subscription_token } : null
|
|
84
|
+
};
|
|
85
|
+
}),
|
|
69
86
|
customer_name: raw.customer_name ?? null,
|
|
70
87
|
customer_email: raw.customer_email ?? null,
|
|
71
88
|
address: mapAddress(raw.address),
|
|
@@ -99,7 +116,7 @@ function mapToListOrder(raw) {
|
|
|
99
116
|
source: "web",
|
|
100
117
|
created_at: raw.created_at ?? "",
|
|
101
118
|
updated_at: raw.updated_at ?? "",
|
|
102
|
-
total_display_amount:
|
|
119
|
+
total_display_amount: raw.total_in_currency ?? raw.total ?? "0",
|
|
103
120
|
total_cv: 0,
|
|
104
121
|
total_qv: 0,
|
|
105
122
|
currency_symbol: raw.currency ?? "",
|
|
@@ -293,6 +310,22 @@ function SummaryRow({ label, value }) {
|
|
|
293
310
|
})]
|
|
294
311
|
});
|
|
295
312
|
}
|
|
313
|
+
/**
|
|
314
|
+
* Display a positive money string as a deduction (prefixed with "-").
|
|
315
|
+
* Idempotent: if the value already starts with "-" we leave it alone, so
|
|
316
|
+
* a future BFF that returns signed discounts can't produce "--$10.00".
|
|
317
|
+
*/
|
|
318
|
+
function asNegative(value) {
|
|
319
|
+
return value.startsWith("-") ? value : `-${value}`;
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Pick the formatted currency string when present, falling back to the raw
|
|
323
|
+
* decimal so the row still renders something for orders where the BFF left
|
|
324
|
+
* the field nil (e.g. a checkout where shipping was never set).
|
|
325
|
+
*/
|
|
326
|
+
function moneyDisplay(formatted, fallback) {
|
|
327
|
+
return formatted ?? fallback;
|
|
328
|
+
}
|
|
296
329
|
function formatAddressLines(address) {
|
|
297
330
|
const lines = [];
|
|
298
331
|
if (address.name) lines.push(address.name);
|
|
@@ -350,7 +383,8 @@ function LineItemImage({ src, alt }) {
|
|
|
350
383
|
onError: () => setErrored(true)
|
|
351
384
|
});
|
|
352
385
|
}
|
|
353
|
-
function ItemRow({ item }) {
|
|
386
|
+
function ItemRow({ item, onSubscriptionClick }) {
|
|
387
|
+
const subscriptionToken = item.source_subscription?.subscription_token;
|
|
354
388
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
355
389
|
className: "flex items-center space-x-4 py-4",
|
|
356
390
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -383,21 +417,28 @@ function ItemRow({ item }) {
|
|
|
383
417
|
}),
|
|
384
418
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
385
419
|
className: "text-foreground text-sm font-medium",
|
|
386
|
-
children: item.total
|
|
420
|
+
children: moneyDisplay(item.total_in_currency, item.total)
|
|
387
421
|
}),
|
|
388
422
|
item.quantity > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
389
423
|
className: "text-muted-foreground text-xs",
|
|
390
424
|
children: [
|
|
391
|
-
item.price,
|
|
425
|
+
moneyDisplay(item.price_in_currency, item.price),
|
|
392
426
|
" x ",
|
|
393
427
|
item.quantity
|
|
394
428
|
]
|
|
429
|
+
}),
|
|
430
|
+
subscriptionToken && onSubscriptionClick && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
431
|
+
type: "button",
|
|
432
|
+
title: subscriptionToken,
|
|
433
|
+
className: "mt-1 max-w-full cursor-pointer truncate text-left text-xs text-blue-600 transition-colors duration-200 hover:text-blue-700 hover:underline",
|
|
434
|
+
onClick: () => onSubscriptionClick(subscriptionToken),
|
|
435
|
+
children: ["Subscription #", subscriptionToken]
|
|
395
436
|
})
|
|
396
437
|
]
|
|
397
438
|
})]
|
|
398
439
|
});
|
|
399
440
|
}
|
|
400
|
-
function ItemsSection({ order }) {
|
|
441
|
+
function ItemsSection({ order, onSubscriptionClick }) {
|
|
401
442
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
|
|
402
443
|
className: "bg-muted flex w-full flex-col items-center px-8 lg:col-span-4",
|
|
403
444
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -416,39 +457,38 @@ function ItemsSection({ order }) {
|
|
|
416
457
|
}),
|
|
417
458
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
418
459
|
className: "divide-border divide-y",
|
|
419
|
-
children: order.line_items.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ItemRow, {
|
|
460
|
+
children: order.line_items.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ItemRow, {
|
|
461
|
+
item,
|
|
462
|
+
onSubscriptionClick
|
|
463
|
+
}, item.id))
|
|
420
464
|
}),
|
|
421
465
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
422
466
|
className: "border-border mb-4 space-y-1 border-t pt-4",
|
|
423
467
|
children: [
|
|
424
468
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SummaryRow, {
|
|
425
469
|
label: "Subtotal",
|
|
426
|
-
value:
|
|
470
|
+
value: moneyDisplay(order.subtotal_in_currency, order.subtotal)
|
|
427
471
|
}),
|
|
428
472
|
parseFloat(order.discount) > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SummaryRow, {
|
|
429
473
|
label: "Discount",
|
|
430
|
-
value:
|
|
474
|
+
value: asNegative(moneyDisplay(order.discount_in_currency, order.discount))
|
|
431
475
|
}),
|
|
432
476
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SummaryRow, {
|
|
433
477
|
label: "Shipping",
|
|
434
|
-
value:
|
|
478
|
+
value: moneyDisplay(order.shipping_in_currency, order.shipping)
|
|
435
479
|
}),
|
|
436
480
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SummaryRow, {
|
|
437
481
|
label: "Tax",
|
|
438
|
-
value:
|
|
482
|
+
value: moneyDisplay(order.tax_in_currency, order.tax)
|
|
439
483
|
}),
|
|
440
484
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
441
485
|
className: "mt-2 flex items-center justify-between text-base font-medium",
|
|
442
486
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
443
487
|
className: "text-muted-foreground text-sm font-medium",
|
|
444
488
|
children: "Total"
|
|
445
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.
|
|
489
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
446
490
|
className: "text-foreground text-base font-bold",
|
|
447
|
-
children:
|
|
448
|
-
order.currency,
|
|
449
|
-
" ",
|
|
450
|
-
order.total
|
|
451
|
-
]
|
|
491
|
+
children: moneyDisplay(order.total_in_currency, order.total)
|
|
452
492
|
})]
|
|
453
493
|
})
|
|
454
494
|
]
|
|
@@ -559,7 +599,7 @@ function DetailsSection({ order }) {
|
|
|
559
599
|
})
|
|
560
600
|
});
|
|
561
601
|
}
|
|
562
|
-
function PortalOrderDetail({ id, onNotFound, onError }) {
|
|
602
|
+
function PortalOrderDetail({ id, onNotFound, onError, onSubscriptionClick }) {
|
|
563
603
|
const { data, isLoading, error } = require_order_status_badge.usePortalTenantOrder(id);
|
|
564
604
|
const order = data?.order;
|
|
565
605
|
(0, react.useEffect)(() => {
|
|
@@ -581,12 +621,15 @@ function PortalOrderDetail({ id, onNotFound, onError }) {
|
|
|
581
621
|
if (!order) return null;
|
|
582
622
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
583
623
|
className: "flex flex-col lg:grid lg:grid-cols-8",
|
|
584
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ItemsSection, {
|
|
624
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ItemsSection, {
|
|
625
|
+
order,
|
|
626
|
+
onSubscriptionClick
|
|
627
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DetailsSection, { order })]
|
|
585
628
|
});
|
|
586
629
|
}
|
|
587
630
|
//#endregion
|
|
588
631
|
//#region ../../orders/ui/src/screens/PortalOrderDetailScreen.tsx
|
|
589
|
-
function PortalOrderDetailScreen({ id, onNavigateToList, onNotFound, onError }) {
|
|
632
|
+
function PortalOrderDetailScreen({ id, onNavigateToList, onNotFound, onError, onSubscriptionClick }) {
|
|
590
633
|
require_ScreenHeaderContext.useScreenHeaderBreadcrumbs((0, react.useMemo)(() => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Breadcrumb, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.BreadcrumbList, {
|
|
591
634
|
className: "text-lg",
|
|
592
635
|
children: [
|
|
@@ -610,7 +653,8 @@ function PortalOrderDetailScreen({ id, onNavigateToList, onNotFound, onError })
|
|
|
610
653
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PortalOrderDetail, {
|
|
611
654
|
id,
|
|
612
655
|
onNotFound,
|
|
613
|
-
onError
|
|
656
|
+
onError,
|
|
657
|
+
onSubscriptionClick
|
|
614
658
|
})
|
|
615
659
|
});
|
|
616
660
|
}
|
|
@@ -627,7 +671,8 @@ function OrderDetailScreen({ token, onToast }) {
|
|
|
627
671
|
},
|
|
628
672
|
onError: (err) => {
|
|
629
673
|
onToast(`Failed to load order: ${err instanceof Error ? err.message : "An error occurred"}`, "error");
|
|
630
|
-
}
|
|
674
|
+
},
|
|
675
|
+
onSubscriptionClick: (subscriptionToken) => navigate(`subscriptions/${subscriptionToken}`)
|
|
631
676
|
});
|
|
632
677
|
}
|
|
633
678
|
//#endregion
|
|
@@ -677,4 +722,4 @@ Object.defineProperty(exports, "ordersScreenPropertySchema", {
|
|
|
677
722
|
}
|
|
678
723
|
});
|
|
679
724
|
|
|
680
|
-
//# sourceMappingURL=OrdersScreen-
|
|
725
|
+
//# sourceMappingURL=OrdersScreen-BxaJw-Kq.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OrdersScreen-BxaJw-Kq.cjs","names":["usePortalTenantClient","OrdersCoreProvider","OrdersListScreen","Breadcrumb","BreadcrumbList","BreadcrumbItem","BreadcrumbPage","OrdersList","useAppNavigation","OrdersListScreenContent","Skeleton","OrderStatusBadge","usePortalTenantOrder","Breadcrumb","BreadcrumbList","BreadcrumbItem","BreadcrumbLink","BreadcrumbSeparator","BreadcrumbPage","useAppNavigation","PortalOrderDetailScreenContent","useAppNavigation"],"sources":["../src/adapters/orders-api-adapter.ts","../src/orders/PortalOrdersApiProvider.tsx","../../../orders/ui/src/screens/OrdersListScreen.tsx","../src/screens/OrdersListScreen.tsx","../../../orders/ui/src/components/portal-order-detail.tsx","../../../orders/ui/src/screens/PortalOrderDetailScreen.tsx","../src/screens/OrderDetailScreen.tsx","../src/screens/OrdersScreen.tsx"],"sourcesContent":["import type { FetchClient } from \"@fluid-app/portal-tenant-api-client\";\nimport type { OrdersApi } from \"@fluid-app/orders-core\";\nimport type { orders } from \"@fluid-app/orders-core\";\nimport { portalTenant } from \"@fluid-app/portal-tenant-api-client\";\n\n/**\n * Creates an OrdersApi adapter backed by the portal-tenant BFF.\n *\n * Provides two methods:\n * - fetchOrderById -> PortalTenantOrderResponse (for PortalOrderDetail screen)\n * - fetchCustomerOrders -> CustomerOrdersResponse with ListOrder[] (for shared OrdersList)\n *\n * The BFF uses a single Order schema for both endpoints, but consumers need\n * different shapes: the detail screen works with PortalTenantOrder (matches the\n * BFF's limited data), while the list screen needs the canonical ListOrder so\n * the shared OrdersList component works unchanged.\n */\n\ntype RawOrder = NonNullable<\n Awaited<ReturnType<typeof portalTenant.orders_show>>[\"order\"]\n>;\n\ntype RawAddress = RawOrder[\"address\"];\ntype RawPaymentMethod = RawOrder[\"payment_method\"];\n\n/**\n * Requires a BFF money field to be present. The BFF contract guarantees\n * subtotal/discount/shipping/tax on every Order, so a missing value signals\n * a broken contract. Mirrors the fail-loud pattern in subscriptions-api-adapter\n * (see the `BFF returned a successful response but subscription data was\n * missing` throw) and avoids silently rendering $0.00 in the UI, which a\n * customer cannot distinguish from a legitimately free line.\n */\nfunction requireMoneyField(\n value: string | null | undefined,\n field: string,\n): string {\n if (value == null) {\n throw new Error(\n `BFF returned an order without required money field \"${field}\"`,\n );\n }\n return value;\n}\n\nfunction mapAddress(raw: RawAddress): orders.PortalTenantAddress | null {\n if (!raw) return null;\n return {\n id: raw.id ?? 0,\n name: raw.name ?? null,\n address1: raw.address1 ?? null,\n address2: raw.address2 ?? null,\n city: raw.city ?? null,\n state: raw.state ?? null,\n postal_code: raw.postal_code ?? null,\n country_code: raw.country_code ?? null,\n } satisfies orders.PortalTenantAddress;\n}\n\nfunction mapPaymentMethod(\n raw: RawPaymentMethod,\n): orders.PortalTenantPaymentMethod | null {\n if (!raw) return null;\n return {\n id: raw.id ?? 0,\n source: raw.source ?? \"\",\n payment_type: raw.payment_type ?? \"\",\n card_type: raw.card_type ?? null,\n last4: raw.last4 ?? null,\n } satisfies orders.PortalTenantPaymentMethod;\n}\n\nfunction mapToPortalTenantOrder(raw: RawOrder): orders.PortalTenantOrder {\n const subtotal = requireMoneyField(raw.subtotal, \"subtotal\");\n const discount = requireMoneyField(raw.discount, \"discount\");\n const shipping = requireMoneyField(raw.shipping, \"shipping\");\n const tax = requireMoneyField(raw.tax, \"tax\");\n const total = requireMoneyField(raw.total, \"total\");\n return {\n id: raw.id ?? 0,\n token: raw.token ?? \"\",\n status: (raw.status ?? \"pending\") as orders.PortalTenantOrderStatus,\n subtotal,\n subtotal_in_currency: raw.subtotal_in_currency ?? subtotal,\n discount,\n discount_in_currency: raw.discount_in_currency ?? discount,\n shipping,\n shipping_in_currency: raw.shipping_in_currency ?? shipping,\n tax,\n tax_in_currency: raw.tax_in_currency ?? tax,\n total,\n total_in_currency: raw.total_in_currency ?? total,\n currency: raw.currency ?? \"\",\n line_items: (raw.line_items ?? []).map((li) => {\n const liPrice = li.price ?? \"0\";\n const liTotal = li.total ?? \"0\";\n return {\n id: li.id ?? 0,\n product_id: li.product_id ?? 0,\n product_name: li.product_name ?? \"\",\n variant_id: li.variant_id ?? null,\n variant_name: li.variant_name ?? null,\n sku: li.sku ?? null,\n image_url: li.image_url ?? null,\n quantity: li.quantity ?? 0,\n price: liPrice,\n price_in_currency: li.price_in_currency ?? liPrice,\n total: liTotal,\n total_in_currency: li.total_in_currency ?? liTotal,\n source_subscription: li.source_subscription?.subscription_token\n ? { subscription_token: li.source_subscription.subscription_token }\n : null,\n };\n }),\n customer_name: raw.customer_name ?? null,\n customer_email: raw.customer_email ?? null,\n address: mapAddress(raw.address),\n payment_method: mapPaymentMethod(raw.payment_method),\n subscription_order: raw.subscription_order ?? false,\n subscription_token: raw.subscription_token ?? null,\n // These fields are returned by the BFF but not yet in the OpenAPI spec.\n total_points_credited:\n typeof (raw as Record<string, unknown>).total_points_credited === \"number\"\n ? ((raw as Record<string, unknown>).total_points_credited as number)\n : undefined,\n customer_points_balance:\n typeof (raw as Record<string, unknown>).customer_points_balance ===\n \"number\"\n ? ((raw as Record<string, unknown>).customer_points_balance as number)\n : undefined,\n created_at: raw.created_at ?? \"\",\n updated_at: raw.updated_at ?? \"\",\n } satisfies orders.PortalTenantOrder;\n}\n\nfunction mapToListOrder(raw: RawOrder): orders.ListOrder {\n const firstLineItem = raw.line_items?.[0];\n return {\n id: raw.id ?? 0,\n external_id: null,\n order_number: \"\",\n email: raw.customer_email ?? null,\n first_name: raw.customer_name?.split(\" \")[0] ?? null,\n last_name: raw.customer_name?.split(\" \").slice(1).join(\" \") || null,\n amount: raw.total ?? \"0\",\n status: raw.status ?? \"pending\",\n order_status: raw.status ?? \"pending\",\n fulfillment_status: \"unfulfilled\",\n financial_status: \"pending\",\n currency_code: raw.currency ?? \"\",\n note: null,\n token: raw.token ?? \"\",\n warehouse_id: null,\n source: \"web\",\n created_at: raw.created_at ?? \"\",\n updated_at: raw.updated_at ?? \"\",\n total_display_amount: raw.total_in_currency ?? raw.total ?? \"0\",\n total_cv: 0,\n total_qv: 0,\n currency_symbol: raw.currency ?? \"\",\n items_count: raw.line_items?.length ?? 0,\n quantity_count:\n raw.line_items?.reduce((sum, li) => sum + (li.quantity ?? 0), 0) ?? 0,\n order_on_behalf_of: false,\n sale_date: null,\n customer: null,\n first_item: firstLineItem\n ? {\n title: firstLineItem.product_name ?? \"\",\n image_url: firstLineItem.image_url ?? \"\",\n }\n : null,\n // The BFF indicates subscription_order but doesn't expose the\n // subscription's lifecycle status. We set \"active\" because the order's\n // existence implies the subscription was active at purchase time. The\n // real status is shown on the subscription detail screen.\n subscription:\n raw.subscription_order && raw.subscription_token\n ? { subscription_token: raw.subscription_token, status: \"active\" }\n : raw.subscription_order\n ? { subscription_token: \"\", status: \"active\" }\n : null,\n };\n}\n\nexport function createPortalOrdersAdapter(\n client: FetchClient,\n): Required<Pick<OrdersApi, \"fetchOrderById\" | \"fetchCustomerOrders\">> {\n return {\n fetchOrderById: async (id: string | number) => {\n const response = await portalTenant.orders_show(client, id);\n return {\n order: mapToPortalTenantOrder(response.order ?? {}),\n meta: {\n request_id: response.meta?.request_id ?? \"\",\n timestamp: response.meta?.timestamp ?? \"\",\n },\n } satisfies orders.PortalTenantOrderResponse;\n },\n\n fetchCustomerOrders: async (params: orders.FetchOrdersParams) => {\n const response = await portalTenant.orders_list(client, {\n \"page[cursor]\": params.cursor,\n \"page[limit]\": params.limit,\n status: params.status,\n q: params.search,\n });\n return {\n orders: (response.orders ?? []).map(mapToListOrder),\n meta: {\n request_id: response.meta?.request_id ?? \"\",\n timestamp: response.meta?.timestamp ?? \"\",\n pagination: {\n cursor: response.meta?.pagination?.cursor ?? null,\n limit: response.meta?.pagination?.limit ?? 25,\n next_cursor: response.meta?.pagination?.next_cursor ?? null,\n prev_cursor: response.meta?.pagination?.prev_cursor ?? null,\n },\n },\n } satisfies orders.CustomerOrdersResponse;\n },\n };\n}\n","import { useMemo, type ReactElement, type ReactNode } from \"react\";\nimport { OrdersCoreProvider } from \"@fluid-app/orders-core\";\nimport { usePortalTenantClient } from \"../providers/PortalTenantClientProvider\";\nimport { createPortalOrdersAdapter } from \"../adapters/orders-api-adapter\";\n\nexport function PortalOrdersApiProvider({\n children,\n}: {\n children: ReactNode;\n}): ReactElement {\n const client = usePortalTenantClient();\n\n const api = useMemo(() => createPortalOrdersAdapter(client), [client]);\n\n return <OrdersCoreProvider api={api}>{children}</OrdersCoreProvider>;\n}\n","\"use client\";\n\nimport { useMemo } from \"react\";\nimport type { orders } from \"@fluid-app/orders-core\";\nimport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbPage,\n} from \"@fluid-app/ui-primitives\";\nimport { useScreenHeaderBreadcrumbs } from \"@fluid-app/portal-react/shell/ScreenHeaderContext\";\nimport { OrdersList } from \"../components/orders-list\";\n\nexport interface OrdersListScreenProps {\n customerId: number | undefined;\n onOrderClick: (order: orders.ListOrder) => void;\n onSubscriptionClick?: (subscriptionToken: string) => void;\n t: (key: string) => string;\n isLoadingCustomer?: boolean;\n}\n\nexport function OrdersListScreen({\n customerId,\n onOrderClick,\n onSubscriptionClick,\n t,\n isLoadingCustomer,\n}: OrdersListScreenProps) {\n const headerBreadcrumbs = useMemo(\n () => (\n <Breadcrumb>\n <BreadcrumbList className=\"text-lg\">\n <BreadcrumbItem>\n <BreadcrumbPage className=\"font-semibold\">Orders</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n ),\n [],\n );\n useScreenHeaderBreadcrumbs(headerBreadcrumbs);\n\n if (isLoadingCustomer) {\n return (\n <div className=\"mx-auto max-w-7xl px-4 py-4 sm:px-6 sm:py-6 lg:px-10 lg:py-8\">\n <div className=\"space-y-3\">\n <div className=\"bg-muted h-10 animate-pulse rounded\" />\n <div className=\"bg-muted h-64 animate-pulse rounded\" />\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"mx-auto max-w-7xl px-4 py-4 sm:px-6 sm:py-6 lg:px-10 lg:py-8\">\n <OrdersList\n customerId={customerId}\n onOrderClick={onOrderClick}\n onSubscriptionClick={onSubscriptionClick}\n t={t}\n />\n </div>\n );\n}\n","import type { orders } from \"@fluid-app/orders-core\";\nimport { OrdersListScreen as OrdersListScreenContent } from \"@fluid-app/orders-ui/screens/OrdersListScreen\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\n\nconst translations: Record<string, string> = {\n search_orders: \"Search orders...\",\n order_number: \"Order #\",\n date: \"Date\",\n status: \"Status\",\n product: \"Product\",\n no_orders_found: \"No orders found\",\n no_matching_orders: \"No matching orders\",\n no_image_available: \"No image available\",\n this_product_no_longer_exists: \"This product no longer exists\",\n subscription: \"Subscription\",\n view_subscription: \"View Subscription\",\n total: \"Total\",\n results: \"results\",\n previous: \"Previous\",\n next: \"Next\",\n pagination: \"Pagination\",\n};\n\n// The portal-tenant BFF scopes orders to the logged-in user server-side,\n// so customerId is not used by the adapter. We pass a sentinel value to\n// satisfy the enabled guard in useCustomerOrders.\nconst BFF_SCOPED_CUSTOMER_ID = 1;\n\nexport function OrdersListScreen(): React.JSX.Element {\n const { navigate } = useAppNavigation();\n\n const handleOrderClick = (order: orders.ListOrder) => {\n navigate(`orders/${order.token}`);\n };\n\n const handleSubscriptionClick = (subscriptionToken: string) => {\n navigate(`subscriptions/${subscriptionToken}`);\n };\n\n return (\n <OrdersListScreenContent\n customerId={BFF_SCOPED_CUSTOMER_ID}\n onOrderClick={handleOrderClick}\n onSubscriptionClick={handleSubscriptionClick}\n t={(key) => translations[key] ?? key}\n />\n );\n}\n","import { useEffect, useState } from \"react\";\nimport type { orders } from \"@fluid-app/orders-core\";\nimport { usePortalTenantOrder } from \"@fluid-app/orders-core\";\nimport { Skeleton } from \"@fluid-app/ui-primitives\";\nimport { OrderStatusBadge } from \"./order-status-badge\";\n\n// Human-readable labels for the non-card entries of PaymentMethod.payment_type.\n// Card payments render via card_type (uppercased) and bypass this map entirely.\nconst PAYMENT_TYPE_LABELS: Record<string, string> = {\n apple_pay: \"Apple Pay\",\n google_pay: \"Google Pay\",\n paypal: \"PayPal\",\n braintree_paypal: \"PayPal\",\n affirm: \"Affirm\",\n klarna: \"Klarna\",\n bread: \"Bread\",\n iap: \"In-App Purchase\",\n citcon: \"Citcon\",\n ppro: \"PPRO\",\n dlocal: \"dLocal\",\n droplet: \"Droplet\",\n};\n\nexport interface PortalOrderDetailProps {\n id: string | number;\n onNotFound?: () => void;\n onError?: (error: Error) => void;\n onSubscriptionClick?: (subscriptionToken: string) => void;\n}\n\nfunction DetailSkeleton() {\n return (\n <div className=\"flex flex-col lg:grid lg:grid-cols-8\">\n <div className=\"bg-muted flex flex-col items-center px-8 lg:col-span-4\">\n <div className=\"w-full max-w-lg py-6\">\n <Skeleton className=\"mb-4 h-6 w-48\" />\n <div className=\"space-y-4\">\n <div className=\"flex items-center space-x-4\">\n <Skeleton className=\"h-24 w-24 rounded\" />\n <div className=\"flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-3/4\" />\n <Skeleton className=\"h-4 w-1/2\" />\n </div>\n </div>\n </div>\n <div className=\"mt-6 space-y-2\">\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-5 w-full\" />\n </div>\n </div>\n </div>\n <div className=\"bg-background px-8 pt-4 lg:col-span-4\">\n <div className=\"mx-auto max-w-lg lg:mx-0 lg:mr-auto\">\n <Skeleton className=\"mb-4 h-10 w-full rounded\" />\n <div className=\"mt-6 space-y-4\">\n <Skeleton className=\"h-5 w-40\" />\n <Skeleton className=\"h-16 w-full rounded\" />\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nfunction SummaryRow({ label, value }: { label: string; value: string }) {\n return (\n <div className=\"flex items-center justify-between text-sm\">\n <p className=\"text-muted-foreground\">{label}</p>\n <p className=\"text-foreground\">{value}</p>\n </div>\n );\n}\n\n/**\n * Display a positive money string as a deduction (prefixed with \"-\").\n * Idempotent: if the value already starts with \"-\" we leave it alone, so\n * a future BFF that returns signed discounts can't produce \"--$10.00\".\n */\nfunction asNegative(value: string): string {\n return value.startsWith(\"-\") ? value : `-${value}`;\n}\n\n/**\n * Pick the formatted currency string when present, falling back to the raw\n * decimal so the row still renders something for orders where the BFF left\n * the field nil (e.g. a checkout where shipping was never set).\n */\nfunction moneyDisplay(formatted: string | null, fallback: string): string {\n return formatted ?? fallback;\n}\n\nfunction formatAddressLines(address: orders.PortalTenantAddress): string[] {\n const lines: string[] = [];\n if (address.name) lines.push(address.name);\n if (address.address1) lines.push(address.address1);\n if (address.address2) lines.push(address.address2);\n const cityLine = [address.city, address.state, address.postal_code]\n .filter(Boolean)\n .join(\", \");\n if (cityLine) lines.push(cityLine);\n if (address.country_code) lines.push(address.country_code);\n return lines;\n}\n\nfunction AddressSection({ address }: { address: orders.PortalTenantAddress }) {\n const lines = formatAddressLines(address);\n if (lines.length === 0) return null;\n return (\n <div className=\"border-border mb-6 border-b pb-6\">\n <h3 className=\"text-foreground mb-3 text-sm/6 font-semibold\">\n Shipping Address\n </h3>\n <div className=\"text-foreground space-y-0.5 text-sm\">\n {lines.map((line, index) => (\n <p key={index}>{line}</p>\n ))}\n </div>\n </div>\n );\n}\n\nfunction PaymentMethodSection({\n paymentMethod,\n}: {\n paymentMethod: orders.PortalTenantPaymentMethod;\n}) {\n const { card_type, last4 } = paymentMethod;\n const brand = card_type\n ? card_type.toUpperCase()\n : (PAYMENT_TYPE_LABELS[paymentMethod.payment_type] ??\n paymentMethod.payment_type);\n const label = last4 ? `${brand} ending in ${last4}` : brand;\n if (!label) return null;\n return (\n <div className=\"border-border mb-6 border-b pb-6\">\n <h3 className=\"text-foreground mb-3 text-sm/6 font-semibold\">\n Payment Method\n </h3>\n <p className=\"text-foreground text-sm\">{label}</p>\n </div>\n );\n}\n\nfunction LineItemImage({ src, alt }: { src: string; alt: string }) {\n const [errored, setErrored] = useState(false);\n if (errored) return <span className=\"text-xs\">No image</span>;\n return (\n <img\n src={src}\n alt={alt}\n className=\"h-full w-full object-cover\"\n onError={() => setErrored(true)}\n />\n );\n}\n\nfunction ItemRow({\n item,\n onSubscriptionClick,\n}: {\n item: orders.PortalTenantOrderLineItem;\n onSubscriptionClick?: (subscriptionToken: string) => void;\n}) {\n const subscriptionToken = item.source_subscription?.subscription_token;\n return (\n <div className=\"flex items-center space-x-4 py-4\">\n <div className=\"relative shrink-0\">\n <div className=\"bg-muted text-muted-foreground flex h-24 w-24 items-center justify-center overflow-hidden rounded\">\n {item.image_url ? (\n <LineItemImage src={item.image_url} alt={item.product_name} />\n ) : (\n <span className=\"text-xs\">No image</span>\n )}\n </div>\n {item.quantity > 1 && (\n <span className=\"bg-foreground text-background absolute -top-2 -right-2 z-10 flex h-6 w-6 items-center justify-center rounded-full text-xs font-medium\">\n {item.quantity}\n </span>\n )}\n </div>\n <div className=\"flex min-w-0 flex-1 flex-col space-y-0.5\">\n <p\n className=\"text-foreground truncate text-sm font-medium\"\n title={item.product_name}\n >\n {item.product_name}\n </p>\n {item.variant_name && (\n <p\n className=\"text-muted-foreground truncate text-xs\"\n title={item.variant_name}\n >\n {item.variant_name}\n </p>\n )}\n <p className=\"text-foreground text-sm font-medium\">\n {moneyDisplay(item.total_in_currency, item.total)}\n </p>\n {item.quantity > 1 && (\n <p className=\"text-muted-foreground text-xs\">\n {moneyDisplay(item.price_in_currency, item.price)} x {item.quantity}\n </p>\n )}\n {subscriptionToken && onSubscriptionClick && (\n <button\n type=\"button\"\n title={subscriptionToken}\n className=\"mt-1 max-w-full cursor-pointer truncate text-left text-xs text-blue-600 transition-colors duration-200 hover:text-blue-700 hover:underline\"\n onClick={() => onSubscriptionClick(subscriptionToken)}\n >\n Subscription #{subscriptionToken}\n </button>\n )}\n </div>\n </div>\n );\n}\n\nfunction ItemsSection({\n order,\n onSubscriptionClick,\n}: {\n order: orders.PortalTenantOrder;\n onSubscriptionClick?: (subscriptionToken: string) => void;\n}) {\n return (\n <section className=\"bg-muted flex w-full flex-col items-center px-8 lg:col-span-4\">\n <div className=\"flex w-full max-w-lg flex-col\">\n <div className=\"mt-4\">\n <h2 className=\"text-foreground mb-2 text-lg font-medium\">\n Items ({order.line_items.length})\n </h2>\n <hr className=\"border-border\" />\n </div>\n\n <div className=\"divide-border divide-y\">\n {order.line_items.map((item) => (\n <ItemRow\n key={item.id}\n item={item}\n onSubscriptionClick={onSubscriptionClick}\n />\n ))}\n </div>\n\n <div className=\"border-border mb-4 space-y-1 border-t pt-4\">\n <SummaryRow\n label=\"Subtotal\"\n value={moneyDisplay(order.subtotal_in_currency, order.subtotal)}\n />\n {parseFloat(order.discount) > 0 && (\n <SummaryRow\n label=\"Discount\"\n value={asNegative(\n moneyDisplay(order.discount_in_currency, order.discount),\n )}\n />\n )}\n <SummaryRow\n label=\"Shipping\"\n value={moneyDisplay(order.shipping_in_currency, order.shipping)}\n />\n <SummaryRow\n label=\"Tax\"\n value={moneyDisplay(order.tax_in_currency, order.tax)}\n />\n <div className=\"mt-2 flex items-center justify-between text-base font-medium\">\n <p className=\"text-muted-foreground text-sm font-medium\">Total</p>\n <p className=\"text-foreground text-base font-bold\">\n {moneyDisplay(order.total_in_currency, order.total)}\n </p>\n </div>\n </div>\n\n {/* TODO: i18n */}\n {/* TODO: gate on reward_points_enabled when available on PortalTenantOrder */}\n {order.total_points_credited != null &&\n order.total_points_credited > 0 && (\n <div className=\"border-border mb-4 border-t pt-4\">\n <div className=\"flex items-baseline justify-between\">\n <div>\n <p className=\"text-foreground text-sm font-semibold\">\n Points Earned on This Order!\n </p>\n {order.customer_points_balance != null && (\n <p className=\"text-muted-foreground text-xs\">\n {order.customer_points_balance.toLocaleString()} points\n total\n </p>\n )}\n </div>\n <div className=\"text-right\">\n <p className=\"text-foreground text-sm font-semibold\">\n +{order.total_points_credited.toLocaleString()}\n </p>\n <p className=\"text-muted-foreground text-xs\">points</p>\n </div>\n </div>\n </div>\n )}\n </div>\n </section>\n );\n}\n\nfunction DetailsSection({ order }: { order: orders.PortalTenantOrder }) {\n return (\n <div className=\"bg-background px-8 pt-4 lg:col-span-4\">\n <div className=\"mx-auto max-w-lg lg:mx-0 lg:mr-auto\">\n {/* Order Status */}\n <div className=\"border-border mb-6 border-b pb-6\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-muted-foreground text-sm\">Status:</span>\n <OrderStatusBadge status={order.status} />\n </div>\n </div>\n </div>\n\n {/* Order Info */}\n <div className=\"border-border mb-6 border-b pb-6\">\n <h3 className=\"text-foreground mb-3 text-sm/6 font-semibold\">\n Order Info\n </h3>\n <div className=\"divide-border flex divide-x\">\n <div className=\"flex-1 pr-4\">\n <div className=\"text-muted-foreground text-sm\">Order</div>\n <div className=\"text-foreground font-medium\">#{order.id}</div>\n </div>\n <div className=\"flex-1 pl-4 text-right\">\n <div className=\"text-muted-foreground text-sm\">Date</div>\n <div className=\"text-foreground font-medium\">\n {new Date(order.created_at).toLocaleDateString(\"en-US\", {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n })}\n </div>\n </div>\n </div>\n {order.customer_email && (\n <div className=\"mt-3\">\n <div className=\"text-muted-foreground text-sm\">Email</div>\n <div className=\"text-foreground text-sm font-medium\">\n {order.customer_email}\n </div>\n </div>\n )}\n {order.customer_name && (\n <div className=\"mt-3\">\n <div className=\"text-muted-foreground text-sm\">Customer</div>\n <div className=\"text-foreground text-sm font-medium\">\n {order.customer_name}\n </div>\n </div>\n )}\n </div>\n\n {order.address && <AddressSection address={order.address} />}\n {order.payment_method && (\n <PaymentMethodSection paymentMethod={order.payment_method} />\n )}\n </div>\n </div>\n );\n}\n\nexport function PortalOrderDetail({\n id,\n onNotFound,\n onError,\n onSubscriptionClick,\n}: PortalOrderDetailProps) {\n const { data, isLoading, error } = usePortalTenantOrder(id);\n const order = data?.order;\n\n useEffect(() => {\n if (!isLoading && error) {\n onError?.(error as Error);\n }\n }, [isLoading, error, onError]);\n\n useEffect(() => {\n if (!isLoading && !error && !order) {\n onNotFound?.();\n }\n }, [isLoading, error, order, onNotFound]);\n\n if (isLoading) {\n return <DetailSkeleton />;\n }\n\n if (!order) {\n return null;\n }\n\n return (\n <div className=\"flex flex-col lg:grid lg:grid-cols-8\">\n <ItemsSection order={order} onSubscriptionClick={onSubscriptionClick} />\n <DetailsSection order={order} />\n </div>\n );\n}\n","\"use client\";\n\nimport { useMemo } from \"react\";\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@fluid-app/ui-primitives\";\nimport { useScreenHeaderBreadcrumbs } from \"@fluid-app/portal-react/shell/ScreenHeaderContext\";\nimport { PortalOrderDetail } from \"../components/portal-order-detail\";\n\nexport interface PortalOrderDetailScreenProps {\n id: string | number;\n onNavigateToList: () => void;\n onNotFound?: () => void;\n onError?: (error: Error) => void;\n onSubscriptionClick?: (subscriptionToken: string) => void;\n}\n\nexport function PortalOrderDetailScreen({\n id,\n onNavigateToList,\n onNotFound,\n onError,\n onSubscriptionClick,\n}: PortalOrderDetailScreenProps) {\n const headerBreadcrumbs = useMemo(\n () => (\n <Breadcrumb>\n <BreadcrumbList className=\"text-lg\">\n <BreadcrumbItem>\n <BreadcrumbLink\n href=\"#\"\n onClick={(e) => {\n e.preventDefault();\n onNavigateToList();\n }}\n >\n Orders\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage className=\"font-semibold\">\n Order #{id}\n </BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n ),\n [id, onNavigateToList],\n );\n useScreenHeaderBreadcrumbs(headerBreadcrumbs);\n\n return (\n <div className=\"mx-auto max-w-7xl px-4 py-4 sm:px-6 sm:py-6 lg:px-10 lg:py-8\">\n <PortalOrderDetail\n id={id}\n onNotFound={onNotFound}\n onError={onError}\n onSubscriptionClick={onSubscriptionClick}\n />\n </div>\n );\n}\n","import { PortalOrderDetailScreen as PortalOrderDetailScreenContent } from \"@fluid-app/orders-ui/screens/PortalOrderDetailScreen\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\n\ninterface OrderDetailScreenProps {\n token: string;\n onToast: (message: string, type: \"success\" | \"error\" | \"warning\") => void;\n}\n\nexport function OrderDetailScreen({\n token,\n onToast,\n}: OrderDetailScreenProps): React.JSX.Element {\n const { navigate } = useAppNavigation();\n\n return (\n <PortalOrderDetailScreenContent\n id={token}\n onNavigateToList={() => navigate(\"orders\")}\n onNotFound={() => {\n onToast(\"Order not found\", \"warning\");\n navigate(\"orders\");\n }}\n onError={(err) => {\n const message =\n err instanceof Error ? err.message : \"An error occurred\";\n onToast(`Failed to load order: ${message}`, \"error\");\n }}\n onSubscriptionClick={(subscriptionToken) =>\n navigate(`subscriptions/${subscriptionToken}`)\n }\n />\n );\n}\n","import type { ComponentProps } from \"react\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { PortalOrdersApiProvider } from \"../orders/PortalOrdersApiProvider\";\nimport { OrdersListScreen } from \"./OrdersListScreen\";\nimport { OrderDetailScreen } from \"./OrderDetailScreen\";\n\ntype OrdersScreenProps = ComponentProps<\"div\"> & {\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n onToast?: (message: string, type: \"success\" | \"error\" | \"warning\") => void;\n};\n\nfunction defaultToast(message: string, type: \"success\" | \"error\" | \"warning\") {\n fluidToast({ title: message, type });\n}\n\nexport function OrdersScreen({\n onToast,\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: OrdersScreenProps): React.JSX.Element {\n const { currentSlug } = useAppNavigation();\n const effectiveToast = onToast ?? defaultToast;\n\n // Parse slug: \"orders\" → list, \"orders/{token}\" → detail\n const detailToken = currentSlug.split(\"/\")[1];\n const isDetailView = detailToken !== undefined;\n\n if (isDetailView) {\n return (\n <div {...divProps}>\n <PortalOrdersApiProvider>\n <OrderDetailScreen token={detailToken} onToast={effectiveToast} />\n </PortalOrdersApiProvider>\n </div>\n );\n }\n\n return (\n <div {...divProps}>\n <PortalOrdersApiProvider>\n <OrdersListScreen />\n </PortalOrdersApiProvider>\n </div>\n );\n}\n\nexport const ordersScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"OrdersScreen\",\n displayName: \"Orders Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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"}
|
|
@@ -44,28 +44,45 @@ function mapPaymentMethod(raw) {
|
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
46
|
function mapToPortalTenantOrder(raw) {
|
|
47
|
+
const subtotal = requireMoneyField(raw.subtotal, "subtotal");
|
|
48
|
+
const discount = requireMoneyField(raw.discount, "discount");
|
|
49
|
+
const shipping = requireMoneyField(raw.shipping, "shipping");
|
|
50
|
+
const tax = requireMoneyField(raw.tax, "tax");
|
|
51
|
+
const total = requireMoneyField(raw.total, "total");
|
|
47
52
|
return {
|
|
48
53
|
id: raw.id ?? 0,
|
|
49
54
|
token: raw.token ?? "",
|
|
50
55
|
status: raw.status ?? "pending",
|
|
51
|
-
subtotal
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
+
subtotal,
|
|
57
|
+
subtotal_in_currency: raw.subtotal_in_currency ?? subtotal,
|
|
58
|
+
discount,
|
|
59
|
+
discount_in_currency: raw.discount_in_currency ?? discount,
|
|
60
|
+
shipping,
|
|
61
|
+
shipping_in_currency: raw.shipping_in_currency ?? shipping,
|
|
62
|
+
tax,
|
|
63
|
+
tax_in_currency: raw.tax_in_currency ?? tax,
|
|
64
|
+
total,
|
|
65
|
+
total_in_currency: raw.total_in_currency ?? total,
|
|
56
66
|
currency: raw.currency ?? "",
|
|
57
|
-
line_items: (raw.line_items ?? []).map((li) =>
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
line_items: (raw.line_items ?? []).map((li) => {
|
|
68
|
+
const liPrice = li.price ?? "0";
|
|
69
|
+
const liTotal = li.total ?? "0";
|
|
70
|
+
return {
|
|
71
|
+
id: li.id ?? 0,
|
|
72
|
+
product_id: li.product_id ?? 0,
|
|
73
|
+
product_name: li.product_name ?? "",
|
|
74
|
+
variant_id: li.variant_id ?? null,
|
|
75
|
+
variant_name: li.variant_name ?? null,
|
|
76
|
+
sku: li.sku ?? null,
|
|
77
|
+
image_url: li.image_url ?? null,
|
|
78
|
+
quantity: li.quantity ?? 0,
|
|
79
|
+
price: liPrice,
|
|
80
|
+
price_in_currency: li.price_in_currency ?? liPrice,
|
|
81
|
+
total: liTotal,
|
|
82
|
+
total_in_currency: li.total_in_currency ?? liTotal,
|
|
83
|
+
source_subscription: li.source_subscription?.subscription_token ? { subscription_token: li.source_subscription.subscription_token } : null
|
|
84
|
+
};
|
|
85
|
+
}),
|
|
69
86
|
customer_name: raw.customer_name ?? null,
|
|
70
87
|
customer_email: raw.customer_email ?? null,
|
|
71
88
|
address: mapAddress(raw.address),
|
|
@@ -99,7 +116,7 @@ function mapToListOrder(raw) {
|
|
|
99
116
|
source: "web",
|
|
100
117
|
created_at: raw.created_at ?? "",
|
|
101
118
|
updated_at: raw.updated_at ?? "",
|
|
102
|
-
total_display_amount:
|
|
119
|
+
total_display_amount: raw.total_in_currency ?? raw.total ?? "0",
|
|
103
120
|
total_cv: 0,
|
|
104
121
|
total_qv: 0,
|
|
105
122
|
currency_symbol: raw.currency ?? "",
|
|
@@ -293,6 +310,22 @@ function SummaryRow({ label, value }) {
|
|
|
293
310
|
})]
|
|
294
311
|
});
|
|
295
312
|
}
|
|
313
|
+
/**
|
|
314
|
+
* Display a positive money string as a deduction (prefixed with "-").
|
|
315
|
+
* Idempotent: if the value already starts with "-" we leave it alone, so
|
|
316
|
+
* a future BFF that returns signed discounts can't produce "--$10.00".
|
|
317
|
+
*/
|
|
318
|
+
function asNegative(value) {
|
|
319
|
+
return value.startsWith("-") ? value : `-${value}`;
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Pick the formatted currency string when present, falling back to the raw
|
|
323
|
+
* decimal so the row still renders something for orders where the BFF left
|
|
324
|
+
* the field nil (e.g. a checkout where shipping was never set).
|
|
325
|
+
*/
|
|
326
|
+
function moneyDisplay(formatted, fallback) {
|
|
327
|
+
return formatted ?? fallback;
|
|
328
|
+
}
|
|
296
329
|
function formatAddressLines(address) {
|
|
297
330
|
const lines = [];
|
|
298
331
|
if (address.name) lines.push(address.name);
|
|
@@ -350,7 +383,8 @@ function LineItemImage({ src, alt }) {
|
|
|
350
383
|
onError: () => setErrored(true)
|
|
351
384
|
});
|
|
352
385
|
}
|
|
353
|
-
function ItemRow({ item }) {
|
|
386
|
+
function ItemRow({ item, onSubscriptionClick }) {
|
|
387
|
+
const subscriptionToken = item.source_subscription?.subscription_token;
|
|
354
388
|
return /* @__PURE__ */ jsxs("div", {
|
|
355
389
|
className: "flex items-center space-x-4 py-4",
|
|
356
390
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
@@ -383,21 +417,28 @@ function ItemRow({ item }) {
|
|
|
383
417
|
}),
|
|
384
418
|
/* @__PURE__ */ jsx("p", {
|
|
385
419
|
className: "text-foreground text-sm font-medium",
|
|
386
|
-
children: item.total
|
|
420
|
+
children: moneyDisplay(item.total_in_currency, item.total)
|
|
387
421
|
}),
|
|
388
422
|
item.quantity > 1 && /* @__PURE__ */ jsxs("p", {
|
|
389
423
|
className: "text-muted-foreground text-xs",
|
|
390
424
|
children: [
|
|
391
|
-
item.price,
|
|
425
|
+
moneyDisplay(item.price_in_currency, item.price),
|
|
392
426
|
" x ",
|
|
393
427
|
item.quantity
|
|
394
428
|
]
|
|
429
|
+
}),
|
|
430
|
+
subscriptionToken && onSubscriptionClick && /* @__PURE__ */ jsxs("button", {
|
|
431
|
+
type: "button",
|
|
432
|
+
title: subscriptionToken,
|
|
433
|
+
className: "mt-1 max-w-full cursor-pointer truncate text-left text-xs text-blue-600 transition-colors duration-200 hover:text-blue-700 hover:underline",
|
|
434
|
+
onClick: () => onSubscriptionClick(subscriptionToken),
|
|
435
|
+
children: ["Subscription #", subscriptionToken]
|
|
395
436
|
})
|
|
396
437
|
]
|
|
397
438
|
})]
|
|
398
439
|
});
|
|
399
440
|
}
|
|
400
|
-
function ItemsSection({ order }) {
|
|
441
|
+
function ItemsSection({ order, onSubscriptionClick }) {
|
|
401
442
|
return /* @__PURE__ */ jsx("section", {
|
|
402
443
|
className: "bg-muted flex w-full flex-col items-center px-8 lg:col-span-4",
|
|
403
444
|
children: /* @__PURE__ */ jsxs("div", {
|
|
@@ -416,39 +457,38 @@ function ItemsSection({ order }) {
|
|
|
416
457
|
}),
|
|
417
458
|
/* @__PURE__ */ jsx("div", {
|
|
418
459
|
className: "divide-border divide-y",
|
|
419
|
-
children: order.line_items.map((item) => /* @__PURE__ */ jsx(ItemRow, {
|
|
460
|
+
children: order.line_items.map((item) => /* @__PURE__ */ jsx(ItemRow, {
|
|
461
|
+
item,
|
|
462
|
+
onSubscriptionClick
|
|
463
|
+
}, item.id))
|
|
420
464
|
}),
|
|
421
465
|
/* @__PURE__ */ jsxs("div", {
|
|
422
466
|
className: "border-border mb-4 space-y-1 border-t pt-4",
|
|
423
467
|
children: [
|
|
424
468
|
/* @__PURE__ */ jsx(SummaryRow, {
|
|
425
469
|
label: "Subtotal",
|
|
426
|
-
value:
|
|
470
|
+
value: moneyDisplay(order.subtotal_in_currency, order.subtotal)
|
|
427
471
|
}),
|
|
428
472
|
parseFloat(order.discount) > 0 && /* @__PURE__ */ jsx(SummaryRow, {
|
|
429
473
|
label: "Discount",
|
|
430
|
-
value:
|
|
474
|
+
value: asNegative(moneyDisplay(order.discount_in_currency, order.discount))
|
|
431
475
|
}),
|
|
432
476
|
/* @__PURE__ */ jsx(SummaryRow, {
|
|
433
477
|
label: "Shipping",
|
|
434
|
-
value:
|
|
478
|
+
value: moneyDisplay(order.shipping_in_currency, order.shipping)
|
|
435
479
|
}),
|
|
436
480
|
/* @__PURE__ */ jsx(SummaryRow, {
|
|
437
481
|
label: "Tax",
|
|
438
|
-
value:
|
|
482
|
+
value: moneyDisplay(order.tax_in_currency, order.tax)
|
|
439
483
|
}),
|
|
440
484
|
/* @__PURE__ */ jsxs("div", {
|
|
441
485
|
className: "mt-2 flex items-center justify-between text-base font-medium",
|
|
442
486
|
children: [/* @__PURE__ */ jsx("p", {
|
|
443
487
|
className: "text-muted-foreground text-sm font-medium",
|
|
444
488
|
children: "Total"
|
|
445
|
-
}), /* @__PURE__ */
|
|
489
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
446
490
|
className: "text-foreground text-base font-bold",
|
|
447
|
-
children:
|
|
448
|
-
order.currency,
|
|
449
|
-
" ",
|
|
450
|
-
order.total
|
|
451
|
-
]
|
|
491
|
+
children: moneyDisplay(order.total_in_currency, order.total)
|
|
452
492
|
})]
|
|
453
493
|
})
|
|
454
494
|
]
|
|
@@ -559,7 +599,7 @@ function DetailsSection({ order }) {
|
|
|
559
599
|
})
|
|
560
600
|
});
|
|
561
601
|
}
|
|
562
|
-
function PortalOrderDetail({ id, onNotFound, onError }) {
|
|
602
|
+
function PortalOrderDetail({ id, onNotFound, onError, onSubscriptionClick }) {
|
|
563
603
|
const { data, isLoading, error } = usePortalTenantOrder(id);
|
|
564
604
|
const order = data?.order;
|
|
565
605
|
useEffect(() => {
|
|
@@ -581,12 +621,15 @@ function PortalOrderDetail({ id, onNotFound, onError }) {
|
|
|
581
621
|
if (!order) return null;
|
|
582
622
|
return /* @__PURE__ */ jsxs("div", {
|
|
583
623
|
className: "flex flex-col lg:grid lg:grid-cols-8",
|
|
584
|
-
children: [/* @__PURE__ */ jsx(ItemsSection, {
|
|
624
|
+
children: [/* @__PURE__ */ jsx(ItemsSection, {
|
|
625
|
+
order,
|
|
626
|
+
onSubscriptionClick
|
|
627
|
+
}), /* @__PURE__ */ jsx(DetailsSection, { order })]
|
|
585
628
|
});
|
|
586
629
|
}
|
|
587
630
|
//#endregion
|
|
588
631
|
//#region ../../orders/ui/src/screens/PortalOrderDetailScreen.tsx
|
|
589
|
-
function PortalOrderDetailScreen({ id, onNavigateToList, onNotFound, onError }) {
|
|
632
|
+
function PortalOrderDetailScreen({ id, onNavigateToList, onNotFound, onError, onSubscriptionClick }) {
|
|
590
633
|
useScreenHeaderBreadcrumbs(useMemo(() => /* @__PURE__ */ jsx(Breadcrumb, { children: /* @__PURE__ */ jsxs(BreadcrumbList, {
|
|
591
634
|
className: "text-lg",
|
|
592
635
|
children: [
|
|
@@ -610,7 +653,8 @@ function PortalOrderDetailScreen({ id, onNavigateToList, onNotFound, onError })
|
|
|
610
653
|
children: /* @__PURE__ */ jsx(PortalOrderDetail, {
|
|
611
654
|
id,
|
|
612
655
|
onNotFound,
|
|
613
|
-
onError
|
|
656
|
+
onError,
|
|
657
|
+
onSubscriptionClick
|
|
614
658
|
})
|
|
615
659
|
});
|
|
616
660
|
}
|
|
@@ -627,7 +671,8 @@ function OrderDetailScreen({ token, onToast }) {
|
|
|
627
671
|
},
|
|
628
672
|
onError: (err) => {
|
|
629
673
|
onToast(`Failed to load order: ${err instanceof Error ? err.message : "An error occurred"}`, "error");
|
|
630
|
-
}
|
|
674
|
+
},
|
|
675
|
+
onSubscriptionClick: (subscriptionToken) => navigate(`subscriptions/${subscriptionToken}`)
|
|
631
676
|
});
|
|
632
677
|
}
|
|
633
678
|
//#endregion
|
|
@@ -670,4 +715,4 @@ const ordersScreenPropertySchema = {
|
|
|
670
715
|
//#endregion
|
|
671
716
|
export { OrdersScreen_exports as n, ordersScreenPropertySchema as r, OrdersScreen as t };
|
|
672
717
|
|
|
673
|
-
//# sourceMappingURL=OrdersScreen-
|
|
718
|
+
//# sourceMappingURL=OrdersScreen-CPKRShbP.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OrdersScreen-CPKRShbP.mjs","names":["portalTenant.orders_show","portalTenant.orders_list","OrdersListScreen","OrdersListScreenContent","PortalOrderDetailScreenContent"],"sources":["../src/adapters/orders-api-adapter.ts","../src/orders/PortalOrdersApiProvider.tsx","../../../orders/ui/src/screens/OrdersListScreen.tsx","../src/screens/OrdersListScreen.tsx","../../../orders/ui/src/components/portal-order-detail.tsx","../../../orders/ui/src/screens/PortalOrderDetailScreen.tsx","../src/screens/OrderDetailScreen.tsx","../src/screens/OrdersScreen.tsx"],"sourcesContent":["import type { FetchClient } from \"@fluid-app/portal-tenant-api-client\";\nimport type { OrdersApi } from \"@fluid-app/orders-core\";\nimport type { orders } from \"@fluid-app/orders-core\";\nimport { portalTenant } from \"@fluid-app/portal-tenant-api-client\";\n\n/**\n * Creates an OrdersApi adapter backed by the portal-tenant BFF.\n *\n * Provides two methods:\n * - fetchOrderById -> PortalTenantOrderResponse (for PortalOrderDetail screen)\n * - fetchCustomerOrders -> CustomerOrdersResponse with ListOrder[] (for shared OrdersList)\n *\n * The BFF uses a single Order schema for both endpoints, but consumers need\n * different shapes: the detail screen works with PortalTenantOrder (matches the\n * BFF's limited data), while the list screen needs the canonical ListOrder so\n * the shared OrdersList component works unchanged.\n */\n\ntype RawOrder = NonNullable<\n Awaited<ReturnType<typeof portalTenant.orders_show>>[\"order\"]\n>;\n\ntype RawAddress = RawOrder[\"address\"];\ntype RawPaymentMethod = RawOrder[\"payment_method\"];\n\n/**\n * Requires a BFF money field to be present. The BFF contract guarantees\n * subtotal/discount/shipping/tax on every Order, so a missing value signals\n * a broken contract. Mirrors the fail-loud pattern in subscriptions-api-adapter\n * (see the `BFF returned a successful response but subscription data was\n * missing` throw) and avoids silently rendering $0.00 in the UI, which a\n * customer cannot distinguish from a legitimately free line.\n */\nfunction requireMoneyField(\n value: string | null | undefined,\n field: string,\n): string {\n if (value == null) {\n throw new Error(\n `BFF returned an order without required money field \"${field}\"`,\n );\n }\n return value;\n}\n\nfunction mapAddress(raw: RawAddress): orders.PortalTenantAddress | null {\n if (!raw) return null;\n return {\n id: raw.id ?? 0,\n name: raw.name ?? null,\n address1: raw.address1 ?? null,\n address2: raw.address2 ?? null,\n city: raw.city ?? null,\n state: raw.state ?? null,\n postal_code: raw.postal_code ?? null,\n country_code: raw.country_code ?? null,\n } satisfies orders.PortalTenantAddress;\n}\n\nfunction mapPaymentMethod(\n raw: RawPaymentMethod,\n): orders.PortalTenantPaymentMethod | null {\n if (!raw) return null;\n return {\n id: raw.id ?? 0,\n source: raw.source ?? \"\",\n payment_type: raw.payment_type ?? \"\",\n card_type: raw.card_type ?? null,\n last4: raw.last4 ?? null,\n } satisfies orders.PortalTenantPaymentMethod;\n}\n\nfunction mapToPortalTenantOrder(raw: RawOrder): orders.PortalTenantOrder {\n const subtotal = requireMoneyField(raw.subtotal, \"subtotal\");\n const discount = requireMoneyField(raw.discount, \"discount\");\n const shipping = requireMoneyField(raw.shipping, \"shipping\");\n const tax = requireMoneyField(raw.tax, \"tax\");\n const total = requireMoneyField(raw.total, \"total\");\n return {\n id: raw.id ?? 0,\n token: raw.token ?? \"\",\n status: (raw.status ?? \"pending\") as orders.PortalTenantOrderStatus,\n subtotal,\n subtotal_in_currency: raw.subtotal_in_currency ?? subtotal,\n discount,\n discount_in_currency: raw.discount_in_currency ?? discount,\n shipping,\n shipping_in_currency: raw.shipping_in_currency ?? shipping,\n tax,\n tax_in_currency: raw.tax_in_currency ?? tax,\n total,\n total_in_currency: raw.total_in_currency ?? total,\n currency: raw.currency ?? \"\",\n line_items: (raw.line_items ?? []).map((li) => {\n const liPrice = li.price ?? \"0\";\n const liTotal = li.total ?? \"0\";\n return {\n id: li.id ?? 0,\n product_id: li.product_id ?? 0,\n product_name: li.product_name ?? \"\",\n variant_id: li.variant_id ?? null,\n variant_name: li.variant_name ?? null,\n sku: li.sku ?? null,\n image_url: li.image_url ?? null,\n quantity: li.quantity ?? 0,\n price: liPrice,\n price_in_currency: li.price_in_currency ?? liPrice,\n total: liTotal,\n total_in_currency: li.total_in_currency ?? liTotal,\n source_subscription: li.source_subscription?.subscription_token\n ? { subscription_token: li.source_subscription.subscription_token }\n : null,\n };\n }),\n customer_name: raw.customer_name ?? null,\n customer_email: raw.customer_email ?? null,\n address: mapAddress(raw.address),\n payment_method: mapPaymentMethod(raw.payment_method),\n subscription_order: raw.subscription_order ?? false,\n subscription_token: raw.subscription_token ?? null,\n // These fields are returned by the BFF but not yet in the OpenAPI spec.\n total_points_credited:\n typeof (raw as Record<string, unknown>).total_points_credited === \"number\"\n ? ((raw as Record<string, unknown>).total_points_credited as number)\n : undefined,\n customer_points_balance:\n typeof (raw as Record<string, unknown>).customer_points_balance ===\n \"number\"\n ? ((raw as Record<string, unknown>).customer_points_balance as number)\n : undefined,\n created_at: raw.created_at ?? \"\",\n updated_at: raw.updated_at ?? \"\",\n } satisfies orders.PortalTenantOrder;\n}\n\nfunction mapToListOrder(raw: RawOrder): orders.ListOrder {\n const firstLineItem = raw.line_items?.[0];\n return {\n id: raw.id ?? 0,\n external_id: null,\n order_number: \"\",\n email: raw.customer_email ?? null,\n first_name: raw.customer_name?.split(\" \")[0] ?? null,\n last_name: raw.customer_name?.split(\" \").slice(1).join(\" \") || null,\n amount: raw.total ?? \"0\",\n status: raw.status ?? \"pending\",\n order_status: raw.status ?? \"pending\",\n fulfillment_status: \"unfulfilled\",\n financial_status: \"pending\",\n currency_code: raw.currency ?? \"\",\n note: null,\n token: raw.token ?? \"\",\n warehouse_id: null,\n source: \"web\",\n created_at: raw.created_at ?? \"\",\n updated_at: raw.updated_at ?? \"\",\n total_display_amount: raw.total_in_currency ?? raw.total ?? \"0\",\n total_cv: 0,\n total_qv: 0,\n currency_symbol: raw.currency ?? \"\",\n items_count: raw.line_items?.length ?? 0,\n quantity_count:\n raw.line_items?.reduce((sum, li) => sum + (li.quantity ?? 0), 0) ?? 0,\n order_on_behalf_of: false,\n sale_date: null,\n customer: null,\n first_item: firstLineItem\n ? {\n title: firstLineItem.product_name ?? \"\",\n image_url: firstLineItem.image_url ?? \"\",\n }\n : null,\n // The BFF indicates subscription_order but doesn't expose the\n // subscription's lifecycle status. We set \"active\" because the order's\n // existence implies the subscription was active at purchase time. The\n // real status is shown on the subscription detail screen.\n subscription:\n raw.subscription_order && raw.subscription_token\n ? { subscription_token: raw.subscription_token, status: \"active\" }\n : raw.subscription_order\n ? { subscription_token: \"\", status: \"active\" }\n : null,\n };\n}\n\nexport function createPortalOrdersAdapter(\n client: FetchClient,\n): Required<Pick<OrdersApi, \"fetchOrderById\" | \"fetchCustomerOrders\">> {\n return {\n fetchOrderById: async (id: string | number) => {\n const response = await portalTenant.orders_show(client, id);\n return {\n order: mapToPortalTenantOrder(response.order ?? {}),\n meta: {\n request_id: response.meta?.request_id ?? \"\",\n timestamp: response.meta?.timestamp ?? \"\",\n },\n } satisfies orders.PortalTenantOrderResponse;\n },\n\n fetchCustomerOrders: async (params: orders.FetchOrdersParams) => {\n const response = await portalTenant.orders_list(client, {\n \"page[cursor]\": params.cursor,\n \"page[limit]\": params.limit,\n status: params.status,\n q: params.search,\n });\n return {\n orders: (response.orders ?? []).map(mapToListOrder),\n meta: {\n request_id: response.meta?.request_id ?? \"\",\n timestamp: response.meta?.timestamp ?? \"\",\n pagination: {\n cursor: response.meta?.pagination?.cursor ?? null,\n limit: response.meta?.pagination?.limit ?? 25,\n next_cursor: response.meta?.pagination?.next_cursor ?? null,\n prev_cursor: response.meta?.pagination?.prev_cursor ?? null,\n },\n },\n } satisfies orders.CustomerOrdersResponse;\n },\n };\n}\n","import { useMemo, type ReactElement, type ReactNode } from \"react\";\nimport { OrdersCoreProvider } from \"@fluid-app/orders-core\";\nimport { usePortalTenantClient } from \"../providers/PortalTenantClientProvider\";\nimport { createPortalOrdersAdapter } from \"../adapters/orders-api-adapter\";\n\nexport function PortalOrdersApiProvider({\n children,\n}: {\n children: ReactNode;\n}): ReactElement {\n const client = usePortalTenantClient();\n\n const api = useMemo(() => createPortalOrdersAdapter(client), [client]);\n\n return <OrdersCoreProvider api={api}>{children}</OrdersCoreProvider>;\n}\n","\"use client\";\n\nimport { useMemo } from \"react\";\nimport type { orders } from \"@fluid-app/orders-core\";\nimport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbPage,\n} from \"@fluid-app/ui-primitives\";\nimport { useScreenHeaderBreadcrumbs } from \"@fluid-app/portal-react/shell/ScreenHeaderContext\";\nimport { OrdersList } from \"../components/orders-list\";\n\nexport interface OrdersListScreenProps {\n customerId: number | undefined;\n onOrderClick: (order: orders.ListOrder) => void;\n onSubscriptionClick?: (subscriptionToken: string) => void;\n t: (key: string) => string;\n isLoadingCustomer?: boolean;\n}\n\nexport function OrdersListScreen({\n customerId,\n onOrderClick,\n onSubscriptionClick,\n t,\n isLoadingCustomer,\n}: OrdersListScreenProps) {\n const headerBreadcrumbs = useMemo(\n () => (\n <Breadcrumb>\n <BreadcrumbList className=\"text-lg\">\n <BreadcrumbItem>\n <BreadcrumbPage className=\"font-semibold\">Orders</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n ),\n [],\n );\n useScreenHeaderBreadcrumbs(headerBreadcrumbs);\n\n if (isLoadingCustomer) {\n return (\n <div className=\"mx-auto max-w-7xl px-4 py-4 sm:px-6 sm:py-6 lg:px-10 lg:py-8\">\n <div className=\"space-y-3\">\n <div className=\"bg-muted h-10 animate-pulse rounded\" />\n <div className=\"bg-muted h-64 animate-pulse rounded\" />\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"mx-auto max-w-7xl px-4 py-4 sm:px-6 sm:py-6 lg:px-10 lg:py-8\">\n <OrdersList\n customerId={customerId}\n onOrderClick={onOrderClick}\n onSubscriptionClick={onSubscriptionClick}\n t={t}\n />\n </div>\n );\n}\n","import type { orders } from \"@fluid-app/orders-core\";\nimport { OrdersListScreen as OrdersListScreenContent } from \"@fluid-app/orders-ui/screens/OrdersListScreen\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\n\nconst translations: Record<string, string> = {\n search_orders: \"Search orders...\",\n order_number: \"Order #\",\n date: \"Date\",\n status: \"Status\",\n product: \"Product\",\n no_orders_found: \"No orders found\",\n no_matching_orders: \"No matching orders\",\n no_image_available: \"No image available\",\n this_product_no_longer_exists: \"This product no longer exists\",\n subscription: \"Subscription\",\n view_subscription: \"View Subscription\",\n total: \"Total\",\n results: \"results\",\n previous: \"Previous\",\n next: \"Next\",\n pagination: \"Pagination\",\n};\n\n// The portal-tenant BFF scopes orders to the logged-in user server-side,\n// so customerId is not used by the adapter. We pass a sentinel value to\n// satisfy the enabled guard in useCustomerOrders.\nconst BFF_SCOPED_CUSTOMER_ID = 1;\n\nexport function OrdersListScreen(): React.JSX.Element {\n const { navigate } = useAppNavigation();\n\n const handleOrderClick = (order: orders.ListOrder) => {\n navigate(`orders/${order.token}`);\n };\n\n const handleSubscriptionClick = (subscriptionToken: string) => {\n navigate(`subscriptions/${subscriptionToken}`);\n };\n\n return (\n <OrdersListScreenContent\n customerId={BFF_SCOPED_CUSTOMER_ID}\n onOrderClick={handleOrderClick}\n onSubscriptionClick={handleSubscriptionClick}\n t={(key) => translations[key] ?? key}\n />\n );\n}\n","import { useEffect, useState } from \"react\";\nimport type { orders } from \"@fluid-app/orders-core\";\nimport { usePortalTenantOrder } from \"@fluid-app/orders-core\";\nimport { Skeleton } from \"@fluid-app/ui-primitives\";\nimport { OrderStatusBadge } from \"./order-status-badge\";\n\n// Human-readable labels for the non-card entries of PaymentMethod.payment_type.\n// Card payments render via card_type (uppercased) and bypass this map entirely.\nconst PAYMENT_TYPE_LABELS: Record<string, string> = {\n apple_pay: \"Apple Pay\",\n google_pay: \"Google Pay\",\n paypal: \"PayPal\",\n braintree_paypal: \"PayPal\",\n affirm: \"Affirm\",\n klarna: \"Klarna\",\n bread: \"Bread\",\n iap: \"In-App Purchase\",\n citcon: \"Citcon\",\n ppro: \"PPRO\",\n dlocal: \"dLocal\",\n droplet: \"Droplet\",\n};\n\nexport interface PortalOrderDetailProps {\n id: string | number;\n onNotFound?: () => void;\n onError?: (error: Error) => void;\n onSubscriptionClick?: (subscriptionToken: string) => void;\n}\n\nfunction DetailSkeleton() {\n return (\n <div className=\"flex flex-col lg:grid lg:grid-cols-8\">\n <div className=\"bg-muted flex flex-col items-center px-8 lg:col-span-4\">\n <div className=\"w-full max-w-lg py-6\">\n <Skeleton className=\"mb-4 h-6 w-48\" />\n <div className=\"space-y-4\">\n <div className=\"flex items-center space-x-4\">\n <Skeleton className=\"h-24 w-24 rounded\" />\n <div className=\"flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-3/4\" />\n <Skeleton className=\"h-4 w-1/2\" />\n </div>\n </div>\n </div>\n <div className=\"mt-6 space-y-2\">\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-5 w-full\" />\n </div>\n </div>\n </div>\n <div className=\"bg-background px-8 pt-4 lg:col-span-4\">\n <div className=\"mx-auto max-w-lg lg:mx-0 lg:mr-auto\">\n <Skeleton className=\"mb-4 h-10 w-full rounded\" />\n <div className=\"mt-6 space-y-4\">\n <Skeleton className=\"h-5 w-40\" />\n <Skeleton className=\"h-16 w-full rounded\" />\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nfunction SummaryRow({ label, value }: { label: string; value: string }) {\n return (\n <div className=\"flex items-center justify-between text-sm\">\n <p className=\"text-muted-foreground\">{label}</p>\n <p className=\"text-foreground\">{value}</p>\n </div>\n );\n}\n\n/**\n * Display a positive money string as a deduction (prefixed with \"-\").\n * Idempotent: if the value already starts with \"-\" we leave it alone, so\n * a future BFF that returns signed discounts can't produce \"--$10.00\".\n */\nfunction asNegative(value: string): string {\n return value.startsWith(\"-\") ? value : `-${value}`;\n}\n\n/**\n * Pick the formatted currency string when present, falling back to the raw\n * decimal so the row still renders something for orders where the BFF left\n * the field nil (e.g. a checkout where shipping was never set).\n */\nfunction moneyDisplay(formatted: string | null, fallback: string): string {\n return formatted ?? fallback;\n}\n\nfunction formatAddressLines(address: orders.PortalTenantAddress): string[] {\n const lines: string[] = [];\n if (address.name) lines.push(address.name);\n if (address.address1) lines.push(address.address1);\n if (address.address2) lines.push(address.address2);\n const cityLine = [address.city, address.state, address.postal_code]\n .filter(Boolean)\n .join(\", \");\n if (cityLine) lines.push(cityLine);\n if (address.country_code) lines.push(address.country_code);\n return lines;\n}\n\nfunction AddressSection({ address }: { address: orders.PortalTenantAddress }) {\n const lines = formatAddressLines(address);\n if (lines.length === 0) return null;\n return (\n <div className=\"border-border mb-6 border-b pb-6\">\n <h3 className=\"text-foreground mb-3 text-sm/6 font-semibold\">\n Shipping Address\n </h3>\n <div className=\"text-foreground space-y-0.5 text-sm\">\n {lines.map((line, index) => (\n <p key={index}>{line}</p>\n ))}\n </div>\n </div>\n );\n}\n\nfunction PaymentMethodSection({\n paymentMethod,\n}: {\n paymentMethod: orders.PortalTenantPaymentMethod;\n}) {\n const { card_type, last4 } = paymentMethod;\n const brand = card_type\n ? card_type.toUpperCase()\n : (PAYMENT_TYPE_LABELS[paymentMethod.payment_type] ??\n paymentMethod.payment_type);\n const label = last4 ? `${brand} ending in ${last4}` : brand;\n if (!label) return null;\n return (\n <div className=\"border-border mb-6 border-b pb-6\">\n <h3 className=\"text-foreground mb-3 text-sm/6 font-semibold\">\n Payment Method\n </h3>\n <p className=\"text-foreground text-sm\">{label}</p>\n </div>\n );\n}\n\nfunction LineItemImage({ src, alt }: { src: string; alt: string }) {\n const [errored, setErrored] = useState(false);\n if (errored) return <span className=\"text-xs\">No image</span>;\n return (\n <img\n src={src}\n alt={alt}\n className=\"h-full w-full object-cover\"\n onError={() => setErrored(true)}\n />\n );\n}\n\nfunction ItemRow({\n item,\n onSubscriptionClick,\n}: {\n item: orders.PortalTenantOrderLineItem;\n onSubscriptionClick?: (subscriptionToken: string) => void;\n}) {\n const subscriptionToken = item.source_subscription?.subscription_token;\n return (\n <div className=\"flex items-center space-x-4 py-4\">\n <div className=\"relative shrink-0\">\n <div className=\"bg-muted text-muted-foreground flex h-24 w-24 items-center justify-center overflow-hidden rounded\">\n {item.image_url ? (\n <LineItemImage src={item.image_url} alt={item.product_name} />\n ) : (\n <span className=\"text-xs\">No image</span>\n )}\n </div>\n {item.quantity > 1 && (\n <span className=\"bg-foreground text-background absolute -top-2 -right-2 z-10 flex h-6 w-6 items-center justify-center rounded-full text-xs font-medium\">\n {item.quantity}\n </span>\n )}\n </div>\n <div className=\"flex min-w-0 flex-1 flex-col space-y-0.5\">\n <p\n className=\"text-foreground truncate text-sm font-medium\"\n title={item.product_name}\n >\n {item.product_name}\n </p>\n {item.variant_name && (\n <p\n className=\"text-muted-foreground truncate text-xs\"\n title={item.variant_name}\n >\n {item.variant_name}\n </p>\n )}\n <p className=\"text-foreground text-sm font-medium\">\n {moneyDisplay(item.total_in_currency, item.total)}\n </p>\n {item.quantity > 1 && (\n <p className=\"text-muted-foreground text-xs\">\n {moneyDisplay(item.price_in_currency, item.price)} x {item.quantity}\n </p>\n )}\n {subscriptionToken && onSubscriptionClick && (\n <button\n type=\"button\"\n title={subscriptionToken}\n className=\"mt-1 max-w-full cursor-pointer truncate text-left text-xs text-blue-600 transition-colors duration-200 hover:text-blue-700 hover:underline\"\n onClick={() => onSubscriptionClick(subscriptionToken)}\n >\n Subscription #{subscriptionToken}\n </button>\n )}\n </div>\n </div>\n );\n}\n\nfunction ItemsSection({\n order,\n onSubscriptionClick,\n}: {\n order: orders.PortalTenantOrder;\n onSubscriptionClick?: (subscriptionToken: string) => void;\n}) {\n return (\n <section className=\"bg-muted flex w-full flex-col items-center px-8 lg:col-span-4\">\n <div className=\"flex w-full max-w-lg flex-col\">\n <div className=\"mt-4\">\n <h2 className=\"text-foreground mb-2 text-lg font-medium\">\n Items ({order.line_items.length})\n </h2>\n <hr className=\"border-border\" />\n </div>\n\n <div className=\"divide-border divide-y\">\n {order.line_items.map((item) => (\n <ItemRow\n key={item.id}\n item={item}\n onSubscriptionClick={onSubscriptionClick}\n />\n ))}\n </div>\n\n <div className=\"border-border mb-4 space-y-1 border-t pt-4\">\n <SummaryRow\n label=\"Subtotal\"\n value={moneyDisplay(order.subtotal_in_currency, order.subtotal)}\n />\n {parseFloat(order.discount) > 0 && (\n <SummaryRow\n label=\"Discount\"\n value={asNegative(\n moneyDisplay(order.discount_in_currency, order.discount),\n )}\n />\n )}\n <SummaryRow\n label=\"Shipping\"\n value={moneyDisplay(order.shipping_in_currency, order.shipping)}\n />\n <SummaryRow\n label=\"Tax\"\n value={moneyDisplay(order.tax_in_currency, order.tax)}\n />\n <div className=\"mt-2 flex items-center justify-between text-base font-medium\">\n <p className=\"text-muted-foreground text-sm font-medium\">Total</p>\n <p className=\"text-foreground text-base font-bold\">\n {moneyDisplay(order.total_in_currency, order.total)}\n </p>\n </div>\n </div>\n\n {/* TODO: i18n */}\n {/* TODO: gate on reward_points_enabled when available on PortalTenantOrder */}\n {order.total_points_credited != null &&\n order.total_points_credited > 0 && (\n <div className=\"border-border mb-4 border-t pt-4\">\n <div className=\"flex items-baseline justify-between\">\n <div>\n <p className=\"text-foreground text-sm font-semibold\">\n Points Earned on This Order!\n </p>\n {order.customer_points_balance != null && (\n <p className=\"text-muted-foreground text-xs\">\n {order.customer_points_balance.toLocaleString()} points\n total\n </p>\n )}\n </div>\n <div className=\"text-right\">\n <p className=\"text-foreground text-sm font-semibold\">\n +{order.total_points_credited.toLocaleString()}\n </p>\n <p className=\"text-muted-foreground text-xs\">points</p>\n </div>\n </div>\n </div>\n )}\n </div>\n </section>\n );\n}\n\nfunction DetailsSection({ order }: { order: orders.PortalTenantOrder }) {\n return (\n <div className=\"bg-background px-8 pt-4 lg:col-span-4\">\n <div className=\"mx-auto max-w-lg lg:mx-0 lg:mr-auto\">\n {/* Order Status */}\n <div className=\"border-border mb-6 border-b pb-6\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-muted-foreground text-sm\">Status:</span>\n <OrderStatusBadge status={order.status} />\n </div>\n </div>\n </div>\n\n {/* Order Info */}\n <div className=\"border-border mb-6 border-b pb-6\">\n <h3 className=\"text-foreground mb-3 text-sm/6 font-semibold\">\n Order Info\n </h3>\n <div className=\"divide-border flex divide-x\">\n <div className=\"flex-1 pr-4\">\n <div className=\"text-muted-foreground text-sm\">Order</div>\n <div className=\"text-foreground font-medium\">#{order.id}</div>\n </div>\n <div className=\"flex-1 pl-4 text-right\">\n <div className=\"text-muted-foreground text-sm\">Date</div>\n <div className=\"text-foreground font-medium\">\n {new Date(order.created_at).toLocaleDateString(\"en-US\", {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n })}\n </div>\n </div>\n </div>\n {order.customer_email && (\n <div className=\"mt-3\">\n <div className=\"text-muted-foreground text-sm\">Email</div>\n <div className=\"text-foreground text-sm font-medium\">\n {order.customer_email}\n </div>\n </div>\n )}\n {order.customer_name && (\n <div className=\"mt-3\">\n <div className=\"text-muted-foreground text-sm\">Customer</div>\n <div className=\"text-foreground text-sm font-medium\">\n {order.customer_name}\n </div>\n </div>\n )}\n </div>\n\n {order.address && <AddressSection address={order.address} />}\n {order.payment_method && (\n <PaymentMethodSection paymentMethod={order.payment_method} />\n )}\n </div>\n </div>\n );\n}\n\nexport function PortalOrderDetail({\n id,\n onNotFound,\n onError,\n onSubscriptionClick,\n}: PortalOrderDetailProps) {\n const { data, isLoading, error } = usePortalTenantOrder(id);\n const order = data?.order;\n\n useEffect(() => {\n if (!isLoading && error) {\n onError?.(error as Error);\n }\n }, [isLoading, error, onError]);\n\n useEffect(() => {\n if (!isLoading && !error && !order) {\n onNotFound?.();\n }\n }, [isLoading, error, order, onNotFound]);\n\n if (isLoading) {\n return <DetailSkeleton />;\n }\n\n if (!order) {\n return null;\n }\n\n return (\n <div className=\"flex flex-col lg:grid lg:grid-cols-8\">\n <ItemsSection order={order} onSubscriptionClick={onSubscriptionClick} />\n <DetailsSection order={order} />\n </div>\n );\n}\n","\"use client\";\n\nimport { useMemo } from \"react\";\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@fluid-app/ui-primitives\";\nimport { useScreenHeaderBreadcrumbs } from \"@fluid-app/portal-react/shell/ScreenHeaderContext\";\nimport { PortalOrderDetail } from \"../components/portal-order-detail\";\n\nexport interface PortalOrderDetailScreenProps {\n id: string | number;\n onNavigateToList: () => void;\n onNotFound?: () => void;\n onError?: (error: Error) => void;\n onSubscriptionClick?: (subscriptionToken: string) => void;\n}\n\nexport function PortalOrderDetailScreen({\n id,\n onNavigateToList,\n onNotFound,\n onError,\n onSubscriptionClick,\n}: PortalOrderDetailScreenProps) {\n const headerBreadcrumbs = useMemo(\n () => (\n <Breadcrumb>\n <BreadcrumbList className=\"text-lg\">\n <BreadcrumbItem>\n <BreadcrumbLink\n href=\"#\"\n onClick={(e) => {\n e.preventDefault();\n onNavigateToList();\n }}\n >\n Orders\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage className=\"font-semibold\">\n Order #{id}\n </BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n ),\n [id, onNavigateToList],\n );\n useScreenHeaderBreadcrumbs(headerBreadcrumbs);\n\n return (\n <div className=\"mx-auto max-w-7xl px-4 py-4 sm:px-6 sm:py-6 lg:px-10 lg:py-8\">\n <PortalOrderDetail\n id={id}\n onNotFound={onNotFound}\n onError={onError}\n onSubscriptionClick={onSubscriptionClick}\n />\n </div>\n );\n}\n","import { PortalOrderDetailScreen as PortalOrderDetailScreenContent } from \"@fluid-app/orders-ui/screens/PortalOrderDetailScreen\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\n\ninterface OrderDetailScreenProps {\n token: string;\n onToast: (message: string, type: \"success\" | \"error\" | \"warning\") => void;\n}\n\nexport function OrderDetailScreen({\n token,\n onToast,\n}: OrderDetailScreenProps): React.JSX.Element {\n const { navigate } = useAppNavigation();\n\n return (\n <PortalOrderDetailScreenContent\n id={token}\n onNavigateToList={() => navigate(\"orders\")}\n onNotFound={() => {\n onToast(\"Order not found\", \"warning\");\n navigate(\"orders\");\n }}\n onError={(err) => {\n const message =\n err instanceof Error ? err.message : \"An error occurred\";\n onToast(`Failed to load order: ${message}`, \"error\");\n }}\n onSubscriptionClick={(subscriptionToken) =>\n navigate(`subscriptions/${subscriptionToken}`)\n }\n />\n );\n}\n","import type { ComponentProps } from \"react\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { PortalOrdersApiProvider } from \"../orders/PortalOrdersApiProvider\";\nimport { OrdersListScreen } from \"./OrdersListScreen\";\nimport { OrderDetailScreen } from \"./OrderDetailScreen\";\n\ntype OrdersScreenProps = ComponentProps<\"div\"> & {\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n onToast?: (message: string, type: \"success\" | \"error\" | \"warning\") => void;\n};\n\nfunction defaultToast(message: string, type: \"success\" | \"error\" | \"warning\") {\n fluidToast({ title: message, type });\n}\n\nexport function OrdersScreen({\n onToast,\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: OrdersScreenProps): React.JSX.Element {\n const { currentSlug } = useAppNavigation();\n const effectiveToast = onToast ?? defaultToast;\n\n // Parse slug: \"orders\" → list, \"orders/{token}\" → detail\n const detailToken = currentSlug.split(\"/\")[1];\n const isDetailView = detailToken !== undefined;\n\n if (isDetailView) {\n return (\n <div {...divProps}>\n <PortalOrdersApiProvider>\n <OrderDetailScreen token={detailToken} onToast={effectiveToast} />\n </PortalOrdersApiProvider>\n </div>\n );\n }\n\n return (\n <div {...divProps}>\n <PortalOrdersApiProvider>\n <OrdersListScreen />\n </PortalOrdersApiProvider>\n </div>\n );\n}\n\nexport const ordersScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"OrdersScreen\",\n displayName: \"Orders Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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"}
|
|
@@ -4,6 +4,6 @@ require("./ScreenHeaderContext-oIu5Bvhs.cjs");
|
|
|
4
4
|
require("./SearchSort-CeJqRK2c.cjs");
|
|
5
5
|
require("./InfiniteScrollSentinel-DeIL8UkW.cjs");
|
|
6
6
|
require("./order-status-badge-DHyaK6mU.cjs");
|
|
7
|
-
const require_OrdersScreen = require("./OrdersScreen-
|
|
7
|
+
const require_OrdersScreen = require("./OrdersScreen-BxaJw-Kq.cjs");
|
|
8
8
|
exports.OrdersScreen = require_OrdersScreen.OrdersScreen;
|
|
9
9
|
exports.ordersScreenPropertySchema = require_OrdersScreen.ordersScreenPropertySchema;
|
package/dist/index.cjs
CHANGED
|
@@ -59,7 +59,7 @@ require("./SearchSort-CeJqRK2c.cjs");
|
|
|
59
59
|
require("./InfiniteScrollSentinel-DeIL8UkW.cjs");
|
|
60
60
|
require("./dist-myuZC8sf.cjs");
|
|
61
61
|
require("./order-status-badge-DHyaK6mU.cjs");
|
|
62
|
-
const require_OrdersScreen = require("./OrdersScreen-
|
|
62
|
+
const require_OrdersScreen = require("./OrdersScreen-BxaJw-Kq.cjs");
|
|
63
63
|
require("./dist-BQZkLGL6.cjs");
|
|
64
64
|
const require_MySiteScreen = require("./MySiteScreen-CUyJteDm.cjs");
|
|
65
65
|
const require_ShareablesScreen = require("./ShareablesScreen-A69L0Nok.cjs");
|
|
@@ -2075,7 +2075,7 @@ function AccountManageLayout({ children }) {
|
|
|
2075
2075
|
//#endregion
|
|
2076
2076
|
//#region src/shell/system-screen-map.ts
|
|
2077
2077
|
const ProfileScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./ProfileScreen-CKcdtroU.cjs")).then((m) => ({ default: m.ProfileScreen })));
|
|
2078
|
-
const OrdersScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./OrdersScreen-
|
|
2078
|
+
const OrdersScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./OrdersScreen-CQGCZLYf.cjs")).then((m) => ({ default: m.OrdersScreen })));
|
|
2079
2079
|
const SubscriptionsScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./SubscriptionsScreen-t5wtDGfB.cjs")).then((m) => ({ default: m.SubscriptionsScreen })));
|
|
2080
2080
|
const MessagingScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./MessagingScreen-KYx6DSMx.cjs")).then((m) => ({ default: m.MessagingScreen })));
|
|
2081
2081
|
const ContactsScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./ContactsScreen-CH_P8WxC.cjs")).then((m) => ({ default: m.ContactsScreen })));
|
|
@@ -3780,7 +3780,7 @@ const screenPropertySchemas = {
|
|
|
3780
3780
|
ProfileScreen: () => Promise.resolve().then(() => require("./ProfileScreen-CKcdtroU.cjs")).then((m) => m.profileScreenPropertySchema),
|
|
3781
3781
|
MessagingScreen: () => Promise.resolve().then(() => require("./MessagingScreen-KYx6DSMx.cjs")).then((m) => m.messagingScreenPropertySchema),
|
|
3782
3782
|
ContactsScreen: () => Promise.resolve().then(() => require("./ContactsScreen-CH_P8WxC.cjs")).then((m) => m.contactsScreenPropertySchema),
|
|
3783
|
-
OrdersScreen: () => Promise.resolve().then(() => require("./OrdersScreen-
|
|
3783
|
+
OrdersScreen: () => Promise.resolve().then(() => require("./OrdersScreen-CQGCZLYf.cjs")).then((m) => m.ordersScreenPropertySchema),
|
|
3784
3784
|
SubscriptionsScreen: () => Promise.resolve().then(() => require("./SubscriptionsScreen-t5wtDGfB.cjs")).then((m) => m.subscriptionsScreenPropertySchema),
|
|
3785
3785
|
CustomersScreen: () => Promise.resolve().then(() => require("./CustomersScreen-DW3BuhBs.cjs")).then((n) => n.CustomersScreen_exports).then((m) => m.customersScreenPropertySchema),
|
|
3786
3786
|
MySiteScreen: () => Promise.resolve().then(() => require("./MySiteScreen-B_16cPgD.cjs")).then((m) => m.mySiteScreenPropertySchema),
|
package/dist/index.mjs
CHANGED
|
@@ -57,7 +57,7 @@ import "./SearchSort-CFHU38Er.mjs";
|
|
|
57
57
|
import "./InfiniteScrollSentinel-B_clNL9Y.mjs";
|
|
58
58
|
import "./dist-o2cjwzIa.mjs";
|
|
59
59
|
import "./order-status-badge-Dmo8lLnt.mjs";
|
|
60
|
-
import { r as ordersScreenPropertySchema, t as OrdersScreen } from "./OrdersScreen-
|
|
60
|
+
import { r as ordersScreenPropertySchema, t as OrdersScreen } from "./OrdersScreen-CPKRShbP.mjs";
|
|
61
61
|
import "./sortable.esm-C8G00cCP.mjs";
|
|
62
62
|
import { r as mySiteScreenPropertySchema, t as MySiteScreen } from "./MySiteScreen-CN0ZDBgy.mjs";
|
|
63
63
|
import { r as shareablesScreenPropertySchema, t as ShareablesScreen } from "./ShareablesScreen-sieWBlAl.mjs";
|
|
@@ -2073,7 +2073,7 @@ function AccountManageLayout({ children }) {
|
|
|
2073
2073
|
//#endregion
|
|
2074
2074
|
//#region src/shell/system-screen-map.ts
|
|
2075
2075
|
const ProfileScreen$1 = lazy(() => import("./ProfileScreen-CZAIUM2a.mjs").then((n) => n.n).then((m) => ({ default: m.ProfileScreen })));
|
|
2076
|
-
const OrdersScreen$1 = lazy(() => import("./OrdersScreen-
|
|
2076
|
+
const OrdersScreen$1 = lazy(() => import("./OrdersScreen-CPKRShbP.mjs").then((n) => n.n).then((m) => ({ default: m.OrdersScreen })));
|
|
2077
2077
|
const SubscriptionsScreen$1 = lazy(() => import("./SubscriptionsScreen-CXM2zmF7.mjs").then((n) => n.n).then((m) => ({ default: m.SubscriptionsScreen })));
|
|
2078
2078
|
const MessagingScreen$1 = lazy(() => import("./MessagingScreen-vb5P-7jP.mjs").then((n) => n.n).then((m) => ({ default: m.MessagingScreen })));
|
|
2079
2079
|
const ContactsScreen$1 = lazy(() => import("./ContactsScreen-CMBERzKU.mjs").then((n) => n.n).then((m) => ({ default: m.ContactsScreen })));
|
|
@@ -3778,7 +3778,7 @@ const screenPropertySchemas = {
|
|
|
3778
3778
|
ProfileScreen: () => import("./ProfileScreen-CZAIUM2a.mjs").then((n) => n.n).then((m) => m.profileScreenPropertySchema),
|
|
3779
3779
|
MessagingScreen: () => import("./MessagingScreen-vb5P-7jP.mjs").then((n) => n.n).then((m) => m.messagingScreenPropertySchema),
|
|
3780
3780
|
ContactsScreen: () => import("./ContactsScreen-CMBERzKU.mjs").then((n) => n.n).then((m) => m.contactsScreenPropertySchema),
|
|
3781
|
-
OrdersScreen: () => import("./OrdersScreen-
|
|
3781
|
+
OrdersScreen: () => import("./OrdersScreen-CPKRShbP.mjs").then((n) => n.n).then((m) => m.ordersScreenPropertySchema),
|
|
3782
3782
|
SubscriptionsScreen: () => import("./SubscriptionsScreen-CXM2zmF7.mjs").then((n) => n.n).then((m) => m.subscriptionsScreenPropertySchema),
|
|
3783
3783
|
CustomersScreen: () => import("./CustomersScreen-BJOBG5f5.mjs").then((n) => n.n).then((m) => m.customersScreenPropertySchema),
|
|
3784
3784
|
MySiteScreen: () => import("./MySiteScreen-CN0ZDBgy.mjs").then((n) => n.n).then((m) => m.mySiteScreenPropertySchema),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluid-app/portal-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.244",
|
|
4
4
|
"description": "SDK for building custom Fluid portals",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -72,47 +72,47 @@
|
|
|
72
72
|
"typescript": "^5",
|
|
73
73
|
"zod": "4.3.5",
|
|
74
74
|
"@fluid-app/api-client-core": "0.1.0",
|
|
75
|
-
"@fluid-app/auth": "0.1.0",
|
|
76
75
|
"@fluid-app/cart-ui": "0.1.17",
|
|
77
76
|
"@fluid-app/company-switcher-core": "0.1.0",
|
|
78
77
|
"@fluid-app/company-switcher-ui": "0.1.0",
|
|
78
|
+
"@fluid-app/auth": "0.1.0",
|
|
79
79
|
"@fluid-app/contacts-core": "0.1.0",
|
|
80
80
|
"@fluid-app/contacts-ui": "0.1.0",
|
|
81
|
-
"@fluid-app/fluid-pay-core": "0.1.0",
|
|
82
81
|
"@fluid-app/file-picker-api-client": "0.1.0",
|
|
83
|
-
"@fluid-app/fluidos-api-client": "0.1.0",
|
|
84
82
|
"@fluid-app/file-picker-core": "0.1.0",
|
|
83
|
+
"@fluid-app/fluid-pay-core": "0.1.0",
|
|
84
|
+
"@fluid-app/fluidos-api-client": "0.1.0",
|
|
85
85
|
"@fluid-app/messaging-api-client": "0.1.0",
|
|
86
|
+
"@fluid-app/messaging-core": "0.1.0",
|
|
86
87
|
"@fluid-app/messaging-ui": "0.1.0",
|
|
87
|
-
"@fluid-app/mysite-core": "0.1.0",
|
|
88
88
|
"@fluid-app/mysite-ui": "0.1.0",
|
|
89
|
-
"@fluid-app/
|
|
89
|
+
"@fluid-app/mysite-core": "0.1.0",
|
|
90
90
|
"@fluid-app/orders-core": "0.1.0",
|
|
91
|
-
"@fluid-app/orders-ui": "0.1.0",
|
|
92
91
|
"@fluid-app/permissions": "0.1.0",
|
|
93
|
-
"@fluid-app/
|
|
92
|
+
"@fluid-app/orders-ui": "0.1.0",
|
|
94
93
|
"@fluid-app/portal-app-download-ui": "0.1.0",
|
|
95
94
|
"@fluid-app/portal-preview": "0.1.0",
|
|
96
|
-
"@fluid-app/portal-react": "0.1.0",
|
|
97
95
|
"@fluid-app/portal-pro-upgrade-ui": "0.1.0",
|
|
98
96
|
"@fluid-app/portal-tenant-api-client": "0.1.0",
|
|
97
|
+
"@fluid-app/portal-core": "0.1.23",
|
|
98
|
+
"@fluid-app/portal-react": "0.1.0",
|
|
99
99
|
"@fluid-app/portal-tenant-contacts-api-client": "0.1.0",
|
|
100
100
|
"@fluid-app/portal-tenant-content-api-client": "0.1.0",
|
|
101
101
|
"@fluid-app/portal-tenant-mysite-api-client": "0.1.0",
|
|
102
102
|
"@fluid-app/portal-tenant-pay-api-client": "0.1.0",
|
|
103
103
|
"@fluid-app/portal-tenant-store-api-client": "0.1.0",
|
|
104
104
|
"@fluid-app/portal-widgets": "0.1.22",
|
|
105
|
-
"@fluid-app/products-core": "0.1.0",
|
|
106
105
|
"@fluid-app/products-api-client": "0.1.0",
|
|
106
|
+
"@fluid-app/products-core": "0.1.0",
|
|
107
107
|
"@fluid-app/profile-core": "0.1.0",
|
|
108
108
|
"@fluid-app/profile-ui": "0.1.0",
|
|
109
109
|
"@fluid-app/query-persister": "0.1.0",
|
|
110
110
|
"@fluid-app/shareables-core": "0.1.0",
|
|
111
|
+
"@fluid-app/store-api-client": "0.1.0",
|
|
111
112
|
"@fluid-app/shareables-ui": "0.1.0",
|
|
112
113
|
"@fluid-app/shop-ui": "0.1.0",
|
|
113
|
-
"@fluid-app/store-api-client": "0.1.0",
|
|
114
|
-
"@fluid-app/store-core": "0.1.0",
|
|
115
114
|
"@fluid-app/subscriptions-core": "0.1.0",
|
|
115
|
+
"@fluid-app/store-core": "0.1.0",
|
|
116
116
|
"@fluid-app/subscriptions-ui": "0.1.0",
|
|
117
117
|
"@fluid-app/typescript-config": "0.0.0",
|
|
118
118
|
"@fluid-app/ui-primitives": "0.1.13"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"OrdersScreen-BV3vJ7xy.mjs","names":["portalTenant.orders_show","portalTenant.orders_list","OrdersListScreen","OrdersListScreenContent","PortalOrderDetailScreenContent"],"sources":["../src/adapters/orders-api-adapter.ts","../src/orders/PortalOrdersApiProvider.tsx","../../../orders/ui/src/screens/OrdersListScreen.tsx","../src/screens/OrdersListScreen.tsx","../../../orders/ui/src/components/portal-order-detail.tsx","../../../orders/ui/src/screens/PortalOrderDetailScreen.tsx","../src/screens/OrderDetailScreen.tsx","../src/screens/OrdersScreen.tsx"],"sourcesContent":["import type { FetchClient } from \"@fluid-app/portal-tenant-api-client\";\nimport type { OrdersApi } from \"@fluid-app/orders-core\";\nimport type { orders } from \"@fluid-app/orders-core\";\nimport { portalTenant } from \"@fluid-app/portal-tenant-api-client\";\n\n/**\n * Creates an OrdersApi adapter backed by the portal-tenant BFF.\n *\n * Provides two methods:\n * - fetchOrderById -> PortalTenantOrderResponse (for PortalOrderDetail screen)\n * - fetchCustomerOrders -> CustomerOrdersResponse with ListOrder[] (for shared OrdersList)\n *\n * The BFF uses a single Order schema for both endpoints, but consumers need\n * different shapes: the detail screen works with PortalTenantOrder (matches the\n * BFF's limited data), while the list screen needs the canonical ListOrder so\n * the shared OrdersList component works unchanged.\n */\n\ntype RawOrder = NonNullable<\n Awaited<ReturnType<typeof portalTenant.orders_show>>[\"order\"]\n>;\n\ntype RawAddress = RawOrder[\"address\"];\ntype RawPaymentMethod = RawOrder[\"payment_method\"];\n\n/**\n * Requires a BFF money field to be present. The BFF contract guarantees\n * subtotal/discount/shipping/tax on every Order, so a missing value signals\n * a broken contract. Mirrors the fail-loud pattern in subscriptions-api-adapter\n * (see the `BFF returned a successful response but subscription data was\n * missing` throw) and avoids silently rendering $0.00 in the UI, which a\n * customer cannot distinguish from a legitimately free line.\n */\nfunction requireMoneyField(\n value: string | null | undefined,\n field: string,\n): string {\n if (value == null) {\n throw new Error(\n `BFF returned an order without required money field \"${field}\"`,\n );\n }\n return value;\n}\n\nfunction mapAddress(raw: RawAddress): orders.PortalTenantAddress | null {\n if (!raw) return null;\n return {\n id: raw.id ?? 0,\n name: raw.name ?? null,\n address1: raw.address1 ?? null,\n address2: raw.address2 ?? null,\n city: raw.city ?? null,\n state: raw.state ?? null,\n postal_code: raw.postal_code ?? null,\n country_code: raw.country_code ?? null,\n } satisfies orders.PortalTenantAddress;\n}\n\nfunction mapPaymentMethod(\n raw: RawPaymentMethod,\n): orders.PortalTenantPaymentMethod | null {\n if (!raw) return null;\n return {\n id: raw.id ?? 0,\n source: raw.source ?? \"\",\n payment_type: raw.payment_type ?? \"\",\n card_type: raw.card_type ?? null,\n last4: raw.last4 ?? null,\n } satisfies orders.PortalTenantPaymentMethod;\n}\n\nfunction mapToPortalTenantOrder(raw: RawOrder): orders.PortalTenantOrder {\n return {\n id: raw.id ?? 0,\n token: raw.token ?? \"\",\n status: (raw.status ?? \"pending\") as orders.PortalTenantOrderStatus,\n subtotal: requireMoneyField(raw.subtotal, \"subtotal\"),\n discount: requireMoneyField(raw.discount, \"discount\"),\n shipping: requireMoneyField(raw.shipping, \"shipping\"),\n tax: requireMoneyField(raw.tax, \"tax\"),\n total: requireMoneyField(raw.total, \"total\"),\n currency: raw.currency ?? \"\",\n line_items: (raw.line_items ?? []).map((li) => ({\n id: li.id ?? 0,\n product_id: li.product_id ?? 0,\n product_name: li.product_name ?? \"\",\n variant_id: li.variant_id ?? null,\n variant_name: li.variant_name ?? null,\n sku: li.sku ?? null,\n image_url: li.image_url ?? null,\n quantity: li.quantity ?? 0,\n price: li.price ?? \"0\",\n total: li.total ?? \"0\",\n })),\n customer_name: raw.customer_name ?? null,\n customer_email: raw.customer_email ?? null,\n address: mapAddress(raw.address),\n payment_method: mapPaymentMethod(raw.payment_method),\n subscription_order: raw.subscription_order ?? false,\n subscription_token: raw.subscription_token ?? null,\n // These fields are returned by the BFF but not yet in the OpenAPI spec.\n total_points_credited:\n typeof (raw as Record<string, unknown>).total_points_credited === \"number\"\n ? ((raw as Record<string, unknown>).total_points_credited as number)\n : undefined,\n customer_points_balance:\n typeof (raw as Record<string, unknown>).customer_points_balance ===\n \"number\"\n ? ((raw as Record<string, unknown>).customer_points_balance as number)\n : undefined,\n created_at: raw.created_at ?? \"\",\n updated_at: raw.updated_at ?? \"\",\n } satisfies orders.PortalTenantOrder;\n}\n\nfunction mapToListOrder(raw: RawOrder): orders.ListOrder {\n const firstLineItem = raw.line_items?.[0];\n return {\n id: raw.id ?? 0,\n external_id: null,\n order_number: \"\",\n email: raw.customer_email ?? null,\n first_name: raw.customer_name?.split(\" \")[0] ?? null,\n last_name: raw.customer_name?.split(\" \").slice(1).join(\" \") || null,\n amount: raw.total ?? \"0\",\n status: raw.status ?? \"pending\",\n order_status: raw.status ?? \"pending\",\n fulfillment_status: \"unfulfilled\",\n financial_status: \"pending\",\n currency_code: raw.currency ?? \"\",\n note: null,\n token: raw.token ?? \"\",\n warehouse_id: null,\n source: \"web\",\n created_at: raw.created_at ?? \"\",\n updated_at: raw.updated_at ?? \"\",\n total_display_amount: `${raw.currency ?? \"\"} ${raw.total ?? \"0\"}`,\n total_cv: 0,\n total_qv: 0,\n currency_symbol: raw.currency ?? \"\",\n items_count: raw.line_items?.length ?? 0,\n quantity_count:\n raw.line_items?.reduce((sum, li) => sum + (li.quantity ?? 0), 0) ?? 0,\n order_on_behalf_of: false,\n sale_date: null,\n customer: null,\n first_item: firstLineItem\n ? {\n title: firstLineItem.product_name ?? \"\",\n image_url: firstLineItem.image_url ?? \"\",\n }\n : null,\n // The BFF indicates subscription_order but doesn't expose the\n // subscription's lifecycle status. We set \"active\" because the order's\n // existence implies the subscription was active at purchase time. The\n // real status is shown on the subscription detail screen.\n subscription:\n raw.subscription_order && raw.subscription_token\n ? { subscription_token: raw.subscription_token, status: \"active\" }\n : raw.subscription_order\n ? { subscription_token: \"\", status: \"active\" }\n : null,\n };\n}\n\nexport function createPortalOrdersAdapter(\n client: FetchClient,\n): Required<Pick<OrdersApi, \"fetchOrderById\" | \"fetchCustomerOrders\">> {\n return {\n fetchOrderById: async (id: string | number) => {\n const response = await portalTenant.orders_show(client, id);\n return {\n order: mapToPortalTenantOrder(response.order ?? {}),\n meta: {\n request_id: response.meta?.request_id ?? \"\",\n timestamp: response.meta?.timestamp ?? \"\",\n },\n } satisfies orders.PortalTenantOrderResponse;\n },\n\n fetchCustomerOrders: async (params: orders.FetchOrdersParams) => {\n const response = await portalTenant.orders_list(client, {\n \"page[cursor]\": params.cursor,\n \"page[limit]\": params.limit,\n status: params.status,\n q: params.search,\n });\n return {\n orders: (response.orders ?? []).map(mapToListOrder),\n meta: {\n request_id: response.meta?.request_id ?? \"\",\n timestamp: response.meta?.timestamp ?? \"\",\n pagination: {\n cursor: response.meta?.pagination?.cursor ?? null,\n limit: response.meta?.pagination?.limit ?? 25,\n next_cursor: response.meta?.pagination?.next_cursor ?? null,\n prev_cursor: response.meta?.pagination?.prev_cursor ?? null,\n },\n },\n } satisfies orders.CustomerOrdersResponse;\n },\n };\n}\n","import { useMemo, type ReactElement, type ReactNode } from \"react\";\nimport { OrdersCoreProvider } from \"@fluid-app/orders-core\";\nimport { usePortalTenantClient } from \"../providers/PortalTenantClientProvider\";\nimport { createPortalOrdersAdapter } from \"../adapters/orders-api-adapter\";\n\nexport function PortalOrdersApiProvider({\n children,\n}: {\n children: ReactNode;\n}): ReactElement {\n const client = usePortalTenantClient();\n\n const api = useMemo(() => createPortalOrdersAdapter(client), [client]);\n\n return <OrdersCoreProvider api={api}>{children}</OrdersCoreProvider>;\n}\n","\"use client\";\n\nimport { useMemo } from \"react\";\nimport type { orders } from \"@fluid-app/orders-core\";\nimport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbPage,\n} from \"@fluid-app/ui-primitives\";\nimport { useScreenHeaderBreadcrumbs } from \"@fluid-app/portal-react/shell/ScreenHeaderContext\";\nimport { OrdersList } from \"../components/orders-list\";\n\nexport interface OrdersListScreenProps {\n customerId: number | undefined;\n onOrderClick: (order: orders.ListOrder) => void;\n onSubscriptionClick?: (subscriptionToken: string) => void;\n t: (key: string) => string;\n isLoadingCustomer?: boolean;\n}\n\nexport function OrdersListScreen({\n customerId,\n onOrderClick,\n onSubscriptionClick,\n t,\n isLoadingCustomer,\n}: OrdersListScreenProps) {\n const headerBreadcrumbs = useMemo(\n () => (\n <Breadcrumb>\n <BreadcrumbList className=\"text-lg\">\n <BreadcrumbItem>\n <BreadcrumbPage className=\"font-semibold\">Orders</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n ),\n [],\n );\n useScreenHeaderBreadcrumbs(headerBreadcrumbs);\n\n if (isLoadingCustomer) {\n return (\n <div className=\"mx-auto max-w-7xl px-4 py-4 sm:px-6 sm:py-6 lg:px-10 lg:py-8\">\n <div className=\"space-y-3\">\n <div className=\"bg-muted h-10 animate-pulse rounded\" />\n <div className=\"bg-muted h-64 animate-pulse rounded\" />\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"mx-auto max-w-7xl px-4 py-4 sm:px-6 sm:py-6 lg:px-10 lg:py-8\">\n <OrdersList\n customerId={customerId}\n onOrderClick={onOrderClick}\n onSubscriptionClick={onSubscriptionClick}\n t={t}\n />\n </div>\n );\n}\n","import type { orders } from \"@fluid-app/orders-core\";\nimport { OrdersListScreen as OrdersListScreenContent } from \"@fluid-app/orders-ui/screens/OrdersListScreen\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\n\nconst translations: Record<string, string> = {\n search_orders: \"Search orders...\",\n order_number: \"Order #\",\n date: \"Date\",\n status: \"Status\",\n product: \"Product\",\n no_orders_found: \"No orders found\",\n no_matching_orders: \"No matching orders\",\n no_image_available: \"No image available\",\n this_product_no_longer_exists: \"This product no longer exists\",\n subscription: \"Subscription\",\n view_subscription: \"View Subscription\",\n total: \"Total\",\n results: \"results\",\n previous: \"Previous\",\n next: \"Next\",\n pagination: \"Pagination\",\n};\n\n// The portal-tenant BFF scopes orders to the logged-in user server-side,\n// so customerId is not used by the adapter. We pass a sentinel value to\n// satisfy the enabled guard in useCustomerOrders.\nconst BFF_SCOPED_CUSTOMER_ID = 1;\n\nexport function OrdersListScreen(): React.JSX.Element {\n const { navigate } = useAppNavigation();\n\n const handleOrderClick = (order: orders.ListOrder) => {\n navigate(`orders/${order.token}`);\n };\n\n const handleSubscriptionClick = (subscriptionToken: string) => {\n navigate(`subscriptions/${subscriptionToken}`);\n };\n\n return (\n <OrdersListScreenContent\n customerId={BFF_SCOPED_CUSTOMER_ID}\n onOrderClick={handleOrderClick}\n onSubscriptionClick={handleSubscriptionClick}\n t={(key) => translations[key] ?? key}\n />\n );\n}\n","import { useEffect, useState } from \"react\";\nimport type { orders } from \"@fluid-app/orders-core\";\nimport { usePortalTenantOrder } from \"@fluid-app/orders-core\";\nimport { Skeleton } from \"@fluid-app/ui-primitives\";\nimport { OrderStatusBadge } from \"./order-status-badge\";\n\n// Human-readable labels for the non-card entries of PaymentMethod.payment_type.\n// Card payments render via card_type (uppercased) and bypass this map entirely.\nconst PAYMENT_TYPE_LABELS: Record<string, string> = {\n apple_pay: \"Apple Pay\",\n google_pay: \"Google Pay\",\n paypal: \"PayPal\",\n braintree_paypal: \"PayPal\",\n affirm: \"Affirm\",\n klarna: \"Klarna\",\n bread: \"Bread\",\n iap: \"In-App Purchase\",\n citcon: \"Citcon\",\n ppro: \"PPRO\",\n dlocal: \"dLocal\",\n droplet: \"Droplet\",\n};\n\nexport interface PortalOrderDetailProps {\n id: string | number;\n onNotFound?: () => void;\n onError?: (error: Error) => void;\n}\n\nfunction DetailSkeleton() {\n return (\n <div className=\"flex flex-col lg:grid lg:grid-cols-8\">\n <div className=\"bg-muted flex flex-col items-center px-8 lg:col-span-4\">\n <div className=\"w-full max-w-lg py-6\">\n <Skeleton className=\"mb-4 h-6 w-48\" />\n <div className=\"space-y-4\">\n <div className=\"flex items-center space-x-4\">\n <Skeleton className=\"h-24 w-24 rounded\" />\n <div className=\"flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-3/4\" />\n <Skeleton className=\"h-4 w-1/2\" />\n </div>\n </div>\n </div>\n <div className=\"mt-6 space-y-2\">\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-5 w-full\" />\n </div>\n </div>\n </div>\n <div className=\"bg-background px-8 pt-4 lg:col-span-4\">\n <div className=\"mx-auto max-w-lg lg:mx-0 lg:mr-auto\">\n <Skeleton className=\"mb-4 h-10 w-full rounded\" />\n <div className=\"mt-6 space-y-4\">\n <Skeleton className=\"h-5 w-40\" />\n <Skeleton className=\"h-16 w-full rounded\" />\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nfunction SummaryRow({ label, value }: { label: string; value: string }) {\n return (\n <div className=\"flex items-center justify-between text-sm\">\n <p className=\"text-muted-foreground\">{label}</p>\n <p className=\"text-foreground\">{value}</p>\n </div>\n );\n}\n\nfunction formatAddressLines(address: orders.PortalTenantAddress): string[] {\n const lines: string[] = [];\n if (address.name) lines.push(address.name);\n if (address.address1) lines.push(address.address1);\n if (address.address2) lines.push(address.address2);\n const cityLine = [address.city, address.state, address.postal_code]\n .filter(Boolean)\n .join(\", \");\n if (cityLine) lines.push(cityLine);\n if (address.country_code) lines.push(address.country_code);\n return lines;\n}\n\nfunction AddressSection({ address }: { address: orders.PortalTenantAddress }) {\n const lines = formatAddressLines(address);\n if (lines.length === 0) return null;\n return (\n <div className=\"border-border mb-6 border-b pb-6\">\n <h3 className=\"text-foreground mb-3 text-sm/6 font-semibold\">\n Shipping Address\n </h3>\n <div className=\"text-foreground space-y-0.5 text-sm\">\n {lines.map((line, index) => (\n <p key={index}>{line}</p>\n ))}\n </div>\n </div>\n );\n}\n\nfunction PaymentMethodSection({\n paymentMethod,\n}: {\n paymentMethod: orders.PortalTenantPaymentMethod;\n}) {\n const { card_type, last4 } = paymentMethod;\n const brand = card_type\n ? card_type.toUpperCase()\n : (PAYMENT_TYPE_LABELS[paymentMethod.payment_type] ??\n paymentMethod.payment_type);\n const label = last4 ? `${brand} ending in ${last4}` : brand;\n if (!label) return null;\n return (\n <div className=\"border-border mb-6 border-b pb-6\">\n <h3 className=\"text-foreground mb-3 text-sm/6 font-semibold\">\n Payment Method\n </h3>\n <p className=\"text-foreground text-sm\">{label}</p>\n </div>\n );\n}\n\nfunction LineItemImage({ src, alt }: { src: string; alt: string }) {\n const [errored, setErrored] = useState(false);\n if (errored) return <span className=\"text-xs\">No image</span>;\n return (\n <img\n src={src}\n alt={alt}\n className=\"h-full w-full object-cover\"\n onError={() => setErrored(true)}\n />\n );\n}\n\nfunction ItemRow({ item }: { item: orders.PortalTenantOrderLineItem }) {\n return (\n <div className=\"flex items-center space-x-4 py-4\">\n <div className=\"relative shrink-0\">\n <div className=\"bg-muted text-muted-foreground flex h-24 w-24 items-center justify-center overflow-hidden rounded\">\n {item.image_url ? (\n <LineItemImage src={item.image_url} alt={item.product_name} />\n ) : (\n <span className=\"text-xs\">No image</span>\n )}\n </div>\n {item.quantity > 1 && (\n <span className=\"bg-foreground text-background absolute -top-2 -right-2 z-10 flex h-6 w-6 items-center justify-center rounded-full text-xs font-medium\">\n {item.quantity}\n </span>\n )}\n </div>\n <div className=\"flex min-w-0 flex-1 flex-col space-y-0.5\">\n <p\n className=\"text-foreground truncate text-sm font-medium\"\n title={item.product_name}\n >\n {item.product_name}\n </p>\n {item.variant_name && (\n <p\n className=\"text-muted-foreground truncate text-xs\"\n title={item.variant_name}\n >\n {item.variant_name}\n </p>\n )}\n <p className=\"text-foreground text-sm font-medium\">{item.total}</p>\n {item.quantity > 1 && (\n <p className=\"text-muted-foreground text-xs\">\n {item.price} x {item.quantity}\n </p>\n )}\n </div>\n </div>\n );\n}\n\nfunction ItemsSection({ order }: { order: orders.PortalTenantOrder }) {\n return (\n <section className=\"bg-muted flex w-full flex-col items-center px-8 lg:col-span-4\">\n <div className=\"flex w-full max-w-lg flex-col\">\n <div className=\"mt-4\">\n <h2 className=\"text-foreground mb-2 text-lg font-medium\">\n Items ({order.line_items.length})\n </h2>\n <hr className=\"border-border\" />\n </div>\n\n <div className=\"divide-border divide-y\">\n {order.line_items.map((item) => (\n <ItemRow key={item.id} item={item} />\n ))}\n </div>\n\n <div className=\"border-border mb-4 space-y-1 border-t pt-4\">\n <SummaryRow\n label=\"Subtotal\"\n value={`${order.currency} ${order.subtotal}`}\n />\n {parseFloat(order.discount) > 0 && (\n <SummaryRow\n label=\"Discount\"\n value={`${order.currency} -${order.discount}`}\n />\n )}\n <SummaryRow\n label=\"Shipping\"\n value={`${order.currency} ${order.shipping}`}\n />\n <SummaryRow label=\"Tax\" value={`${order.currency} ${order.tax}`} />\n <div className=\"mt-2 flex items-center justify-between text-base font-medium\">\n <p className=\"text-muted-foreground text-sm font-medium\">Total</p>\n <p className=\"text-foreground text-base font-bold\">\n {order.currency} {order.total}\n </p>\n </div>\n </div>\n\n {/* TODO: i18n */}\n {/* TODO: gate on reward_points_enabled when available on PortalTenantOrder */}\n {order.total_points_credited != null &&\n order.total_points_credited > 0 && (\n <div className=\"border-border mb-4 border-t pt-4\">\n <div className=\"flex items-baseline justify-between\">\n <div>\n <p className=\"text-foreground text-sm font-semibold\">\n Points Earned on This Order!\n </p>\n {order.customer_points_balance != null && (\n <p className=\"text-muted-foreground text-xs\">\n {order.customer_points_balance.toLocaleString()} points\n total\n </p>\n )}\n </div>\n <div className=\"text-right\">\n <p className=\"text-foreground text-sm font-semibold\">\n +{order.total_points_credited.toLocaleString()}\n </p>\n <p className=\"text-muted-foreground text-xs\">points</p>\n </div>\n </div>\n </div>\n )}\n </div>\n </section>\n );\n}\n\nfunction DetailsSection({ order }: { order: orders.PortalTenantOrder }) {\n return (\n <div className=\"bg-background px-8 pt-4 lg:col-span-4\">\n <div className=\"mx-auto max-w-lg lg:mx-0 lg:mr-auto\">\n {/* Order Status */}\n <div className=\"border-border mb-6 border-b pb-6\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-muted-foreground text-sm\">Status:</span>\n <OrderStatusBadge status={order.status} />\n </div>\n </div>\n </div>\n\n {/* Order Info */}\n <div className=\"border-border mb-6 border-b pb-6\">\n <h3 className=\"text-foreground mb-3 text-sm/6 font-semibold\">\n Order Info\n </h3>\n <div className=\"divide-border flex divide-x\">\n <div className=\"flex-1 pr-4\">\n <div className=\"text-muted-foreground text-sm\">Order</div>\n <div className=\"text-foreground font-medium\">#{order.id}</div>\n </div>\n <div className=\"flex-1 pl-4 text-right\">\n <div className=\"text-muted-foreground text-sm\">Date</div>\n <div className=\"text-foreground font-medium\">\n {new Date(order.created_at).toLocaleDateString(\"en-US\", {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n })}\n </div>\n </div>\n </div>\n {order.customer_email && (\n <div className=\"mt-3\">\n <div className=\"text-muted-foreground text-sm\">Email</div>\n <div className=\"text-foreground text-sm font-medium\">\n {order.customer_email}\n </div>\n </div>\n )}\n {order.customer_name && (\n <div className=\"mt-3\">\n <div className=\"text-muted-foreground text-sm\">Customer</div>\n <div className=\"text-foreground text-sm font-medium\">\n {order.customer_name}\n </div>\n </div>\n )}\n </div>\n\n {order.address && <AddressSection address={order.address} />}\n {order.payment_method && (\n <PaymentMethodSection paymentMethod={order.payment_method} />\n )}\n </div>\n </div>\n );\n}\n\nexport function PortalOrderDetail({\n id,\n onNotFound,\n onError,\n}: PortalOrderDetailProps) {\n const { data, isLoading, error } = usePortalTenantOrder(id);\n const order = data?.order;\n\n useEffect(() => {\n if (!isLoading && error) {\n onError?.(error as Error);\n }\n }, [isLoading, error, onError]);\n\n useEffect(() => {\n if (!isLoading && !error && !order) {\n onNotFound?.();\n }\n }, [isLoading, error, order, onNotFound]);\n\n if (isLoading) {\n return <DetailSkeleton />;\n }\n\n if (!order) {\n return null;\n }\n\n return (\n <div className=\"flex flex-col lg:grid lg:grid-cols-8\">\n <ItemsSection order={order} />\n <DetailsSection order={order} />\n </div>\n );\n}\n","\"use client\";\n\nimport { useMemo } from \"react\";\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@fluid-app/ui-primitives\";\nimport { useScreenHeaderBreadcrumbs } from \"@fluid-app/portal-react/shell/ScreenHeaderContext\";\nimport { PortalOrderDetail } from \"../components/portal-order-detail\";\n\nexport interface PortalOrderDetailScreenProps {\n id: string | number;\n onNavigateToList: () => void;\n onNotFound?: () => void;\n onError?: (error: Error) => void;\n}\n\nexport function PortalOrderDetailScreen({\n id,\n onNavigateToList,\n onNotFound,\n onError,\n}: PortalOrderDetailScreenProps) {\n const headerBreadcrumbs = useMemo(\n () => (\n <Breadcrumb>\n <BreadcrumbList className=\"text-lg\">\n <BreadcrumbItem>\n <BreadcrumbLink\n href=\"#\"\n onClick={(e) => {\n e.preventDefault();\n onNavigateToList();\n }}\n >\n Orders\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage className=\"font-semibold\">\n Order #{id}\n </BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n ),\n [id, onNavigateToList],\n );\n useScreenHeaderBreadcrumbs(headerBreadcrumbs);\n\n return (\n <div className=\"mx-auto max-w-7xl px-4 py-4 sm:px-6 sm:py-6 lg:px-10 lg:py-8\">\n <PortalOrderDetail id={id} onNotFound={onNotFound} onError={onError} />\n </div>\n );\n}\n","import { PortalOrderDetailScreen as PortalOrderDetailScreenContent } from \"@fluid-app/orders-ui/screens/PortalOrderDetailScreen\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\n\ninterface OrderDetailScreenProps {\n token: string;\n onToast: (message: string, type: \"success\" | \"error\" | \"warning\") => void;\n}\n\nexport function OrderDetailScreen({\n token,\n onToast,\n}: OrderDetailScreenProps): React.JSX.Element {\n const { navigate } = useAppNavigation();\n\n return (\n <PortalOrderDetailScreenContent\n id={token}\n onNavigateToList={() => navigate(\"orders\")}\n onNotFound={() => {\n onToast(\"Order not found\", \"warning\");\n navigate(\"orders\");\n }}\n onError={(err) => {\n const message =\n err instanceof Error ? err.message : \"An error occurred\";\n onToast(`Failed to load order: ${message}`, \"error\");\n }}\n />\n );\n}\n","import type { ComponentProps } from \"react\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { PortalOrdersApiProvider } from \"../orders/PortalOrdersApiProvider\";\nimport { OrdersListScreen } from \"./OrdersListScreen\";\nimport { OrderDetailScreen } from \"./OrderDetailScreen\";\n\ntype OrdersScreenProps = ComponentProps<\"div\"> & {\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n onToast?: (message: string, type: \"success\" | \"error\" | \"warning\") => void;\n};\n\nfunction defaultToast(message: string, type: \"success\" | \"error\" | \"warning\") {\n fluidToast({ title: message, type });\n}\n\nexport function OrdersScreen({\n onToast,\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: OrdersScreenProps): React.JSX.Element {\n const { currentSlug } = useAppNavigation();\n const effectiveToast = onToast ?? defaultToast;\n\n // Parse slug: \"orders\" → list, \"orders/{token}\" → detail\n const detailToken = currentSlug.split(\"/\")[1];\n const isDetailView = detailToken !== undefined;\n\n if (isDetailView) {\n return (\n <div {...divProps}>\n <PortalOrdersApiProvider>\n <OrderDetailScreen token={detailToken} onToast={effectiveToast} />\n </PortalOrdersApiProvider>\n </div>\n );\n }\n\n return (\n <div {...divProps}>\n <PortalOrdersApiProvider>\n <OrdersListScreen />\n </PortalOrdersApiProvider>\n </div>\n );\n}\n\nexport const ordersScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"OrdersScreen\",\n displayName: \"Orders Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"OrdersScreen-DPcp2dLW.cjs","names":["usePortalTenantClient","OrdersCoreProvider","OrdersListScreen","Breadcrumb","BreadcrumbList","BreadcrumbItem","BreadcrumbPage","OrdersList","useAppNavigation","OrdersListScreenContent","Skeleton","OrderStatusBadge","usePortalTenantOrder","Breadcrumb","BreadcrumbList","BreadcrumbItem","BreadcrumbLink","BreadcrumbSeparator","BreadcrumbPage","useAppNavigation","PortalOrderDetailScreenContent","useAppNavigation"],"sources":["../src/adapters/orders-api-adapter.ts","../src/orders/PortalOrdersApiProvider.tsx","../../../orders/ui/src/screens/OrdersListScreen.tsx","../src/screens/OrdersListScreen.tsx","../../../orders/ui/src/components/portal-order-detail.tsx","../../../orders/ui/src/screens/PortalOrderDetailScreen.tsx","../src/screens/OrderDetailScreen.tsx","../src/screens/OrdersScreen.tsx"],"sourcesContent":["import type { FetchClient } from \"@fluid-app/portal-tenant-api-client\";\nimport type { OrdersApi } from \"@fluid-app/orders-core\";\nimport type { orders } from \"@fluid-app/orders-core\";\nimport { portalTenant } from \"@fluid-app/portal-tenant-api-client\";\n\n/**\n * Creates an OrdersApi adapter backed by the portal-tenant BFF.\n *\n * Provides two methods:\n * - fetchOrderById -> PortalTenantOrderResponse (for PortalOrderDetail screen)\n * - fetchCustomerOrders -> CustomerOrdersResponse with ListOrder[] (for shared OrdersList)\n *\n * The BFF uses a single Order schema for both endpoints, but consumers need\n * different shapes: the detail screen works with PortalTenantOrder (matches the\n * BFF's limited data), while the list screen needs the canonical ListOrder so\n * the shared OrdersList component works unchanged.\n */\n\ntype RawOrder = NonNullable<\n Awaited<ReturnType<typeof portalTenant.orders_show>>[\"order\"]\n>;\n\ntype RawAddress = RawOrder[\"address\"];\ntype RawPaymentMethod = RawOrder[\"payment_method\"];\n\n/**\n * Requires a BFF money field to be present. The BFF contract guarantees\n * subtotal/discount/shipping/tax on every Order, so a missing value signals\n * a broken contract. Mirrors the fail-loud pattern in subscriptions-api-adapter\n * (see the `BFF returned a successful response but subscription data was\n * missing` throw) and avoids silently rendering $0.00 in the UI, which a\n * customer cannot distinguish from a legitimately free line.\n */\nfunction requireMoneyField(\n value: string | null | undefined,\n field: string,\n): string {\n if (value == null) {\n throw new Error(\n `BFF returned an order without required money field \"${field}\"`,\n );\n }\n return value;\n}\n\nfunction mapAddress(raw: RawAddress): orders.PortalTenantAddress | null {\n if (!raw) return null;\n return {\n id: raw.id ?? 0,\n name: raw.name ?? null,\n address1: raw.address1 ?? null,\n address2: raw.address2 ?? null,\n city: raw.city ?? null,\n state: raw.state ?? null,\n postal_code: raw.postal_code ?? null,\n country_code: raw.country_code ?? null,\n } satisfies orders.PortalTenantAddress;\n}\n\nfunction mapPaymentMethod(\n raw: RawPaymentMethod,\n): orders.PortalTenantPaymentMethod | null {\n if (!raw) return null;\n return {\n id: raw.id ?? 0,\n source: raw.source ?? \"\",\n payment_type: raw.payment_type ?? \"\",\n card_type: raw.card_type ?? null,\n last4: raw.last4 ?? null,\n } satisfies orders.PortalTenantPaymentMethod;\n}\n\nfunction mapToPortalTenantOrder(raw: RawOrder): orders.PortalTenantOrder {\n return {\n id: raw.id ?? 0,\n token: raw.token ?? \"\",\n status: (raw.status ?? \"pending\") as orders.PortalTenantOrderStatus,\n subtotal: requireMoneyField(raw.subtotal, \"subtotal\"),\n discount: requireMoneyField(raw.discount, \"discount\"),\n shipping: requireMoneyField(raw.shipping, \"shipping\"),\n tax: requireMoneyField(raw.tax, \"tax\"),\n total: requireMoneyField(raw.total, \"total\"),\n currency: raw.currency ?? \"\",\n line_items: (raw.line_items ?? []).map((li) => ({\n id: li.id ?? 0,\n product_id: li.product_id ?? 0,\n product_name: li.product_name ?? \"\",\n variant_id: li.variant_id ?? null,\n variant_name: li.variant_name ?? null,\n sku: li.sku ?? null,\n image_url: li.image_url ?? null,\n quantity: li.quantity ?? 0,\n price: li.price ?? \"0\",\n total: li.total ?? \"0\",\n })),\n customer_name: raw.customer_name ?? null,\n customer_email: raw.customer_email ?? null,\n address: mapAddress(raw.address),\n payment_method: mapPaymentMethod(raw.payment_method),\n subscription_order: raw.subscription_order ?? false,\n subscription_token: raw.subscription_token ?? null,\n // These fields are returned by the BFF but not yet in the OpenAPI spec.\n total_points_credited:\n typeof (raw as Record<string, unknown>).total_points_credited === \"number\"\n ? ((raw as Record<string, unknown>).total_points_credited as number)\n : undefined,\n customer_points_balance:\n typeof (raw as Record<string, unknown>).customer_points_balance ===\n \"number\"\n ? ((raw as Record<string, unknown>).customer_points_balance as number)\n : undefined,\n created_at: raw.created_at ?? \"\",\n updated_at: raw.updated_at ?? \"\",\n } satisfies orders.PortalTenantOrder;\n}\n\nfunction mapToListOrder(raw: RawOrder): orders.ListOrder {\n const firstLineItem = raw.line_items?.[0];\n return {\n id: raw.id ?? 0,\n external_id: null,\n order_number: \"\",\n email: raw.customer_email ?? null,\n first_name: raw.customer_name?.split(\" \")[0] ?? null,\n last_name: raw.customer_name?.split(\" \").slice(1).join(\" \") || null,\n amount: raw.total ?? \"0\",\n status: raw.status ?? \"pending\",\n order_status: raw.status ?? \"pending\",\n fulfillment_status: \"unfulfilled\",\n financial_status: \"pending\",\n currency_code: raw.currency ?? \"\",\n note: null,\n token: raw.token ?? \"\",\n warehouse_id: null,\n source: \"web\",\n created_at: raw.created_at ?? \"\",\n updated_at: raw.updated_at ?? \"\",\n total_display_amount: `${raw.currency ?? \"\"} ${raw.total ?? \"0\"}`,\n total_cv: 0,\n total_qv: 0,\n currency_symbol: raw.currency ?? \"\",\n items_count: raw.line_items?.length ?? 0,\n quantity_count:\n raw.line_items?.reduce((sum, li) => sum + (li.quantity ?? 0), 0) ?? 0,\n order_on_behalf_of: false,\n sale_date: null,\n customer: null,\n first_item: firstLineItem\n ? {\n title: firstLineItem.product_name ?? \"\",\n image_url: firstLineItem.image_url ?? \"\",\n }\n : null,\n // The BFF indicates subscription_order but doesn't expose the\n // subscription's lifecycle status. We set \"active\" because the order's\n // existence implies the subscription was active at purchase time. The\n // real status is shown on the subscription detail screen.\n subscription:\n raw.subscription_order && raw.subscription_token\n ? { subscription_token: raw.subscription_token, status: \"active\" }\n : raw.subscription_order\n ? { subscription_token: \"\", status: \"active\" }\n : null,\n };\n}\n\nexport function createPortalOrdersAdapter(\n client: FetchClient,\n): Required<Pick<OrdersApi, \"fetchOrderById\" | \"fetchCustomerOrders\">> {\n return {\n fetchOrderById: async (id: string | number) => {\n const response = await portalTenant.orders_show(client, id);\n return {\n order: mapToPortalTenantOrder(response.order ?? {}),\n meta: {\n request_id: response.meta?.request_id ?? \"\",\n timestamp: response.meta?.timestamp ?? \"\",\n },\n } satisfies orders.PortalTenantOrderResponse;\n },\n\n fetchCustomerOrders: async (params: orders.FetchOrdersParams) => {\n const response = await portalTenant.orders_list(client, {\n \"page[cursor]\": params.cursor,\n \"page[limit]\": params.limit,\n status: params.status,\n q: params.search,\n });\n return {\n orders: (response.orders ?? []).map(mapToListOrder),\n meta: {\n request_id: response.meta?.request_id ?? \"\",\n timestamp: response.meta?.timestamp ?? \"\",\n pagination: {\n cursor: response.meta?.pagination?.cursor ?? null,\n limit: response.meta?.pagination?.limit ?? 25,\n next_cursor: response.meta?.pagination?.next_cursor ?? null,\n prev_cursor: response.meta?.pagination?.prev_cursor ?? null,\n },\n },\n } satisfies orders.CustomerOrdersResponse;\n },\n };\n}\n","import { useMemo, type ReactElement, type ReactNode } from \"react\";\nimport { OrdersCoreProvider } from \"@fluid-app/orders-core\";\nimport { usePortalTenantClient } from \"../providers/PortalTenantClientProvider\";\nimport { createPortalOrdersAdapter } from \"../adapters/orders-api-adapter\";\n\nexport function PortalOrdersApiProvider({\n children,\n}: {\n children: ReactNode;\n}): ReactElement {\n const client = usePortalTenantClient();\n\n const api = useMemo(() => createPortalOrdersAdapter(client), [client]);\n\n return <OrdersCoreProvider api={api}>{children}</OrdersCoreProvider>;\n}\n","\"use client\";\n\nimport { useMemo } from \"react\";\nimport type { orders } from \"@fluid-app/orders-core\";\nimport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbPage,\n} from \"@fluid-app/ui-primitives\";\nimport { useScreenHeaderBreadcrumbs } from \"@fluid-app/portal-react/shell/ScreenHeaderContext\";\nimport { OrdersList } from \"../components/orders-list\";\n\nexport interface OrdersListScreenProps {\n customerId: number | undefined;\n onOrderClick: (order: orders.ListOrder) => void;\n onSubscriptionClick?: (subscriptionToken: string) => void;\n t: (key: string) => string;\n isLoadingCustomer?: boolean;\n}\n\nexport function OrdersListScreen({\n customerId,\n onOrderClick,\n onSubscriptionClick,\n t,\n isLoadingCustomer,\n}: OrdersListScreenProps) {\n const headerBreadcrumbs = useMemo(\n () => (\n <Breadcrumb>\n <BreadcrumbList className=\"text-lg\">\n <BreadcrumbItem>\n <BreadcrumbPage className=\"font-semibold\">Orders</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n ),\n [],\n );\n useScreenHeaderBreadcrumbs(headerBreadcrumbs);\n\n if (isLoadingCustomer) {\n return (\n <div className=\"mx-auto max-w-7xl px-4 py-4 sm:px-6 sm:py-6 lg:px-10 lg:py-8\">\n <div className=\"space-y-3\">\n <div className=\"bg-muted h-10 animate-pulse rounded\" />\n <div className=\"bg-muted h-64 animate-pulse rounded\" />\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"mx-auto max-w-7xl px-4 py-4 sm:px-6 sm:py-6 lg:px-10 lg:py-8\">\n <OrdersList\n customerId={customerId}\n onOrderClick={onOrderClick}\n onSubscriptionClick={onSubscriptionClick}\n t={t}\n />\n </div>\n );\n}\n","import type { orders } from \"@fluid-app/orders-core\";\nimport { OrdersListScreen as OrdersListScreenContent } from \"@fluid-app/orders-ui/screens/OrdersListScreen\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\n\nconst translations: Record<string, string> = {\n search_orders: \"Search orders...\",\n order_number: \"Order #\",\n date: \"Date\",\n status: \"Status\",\n product: \"Product\",\n no_orders_found: \"No orders found\",\n no_matching_orders: \"No matching orders\",\n no_image_available: \"No image available\",\n this_product_no_longer_exists: \"This product no longer exists\",\n subscription: \"Subscription\",\n view_subscription: \"View Subscription\",\n total: \"Total\",\n results: \"results\",\n previous: \"Previous\",\n next: \"Next\",\n pagination: \"Pagination\",\n};\n\n// The portal-tenant BFF scopes orders to the logged-in user server-side,\n// so customerId is not used by the adapter. We pass a sentinel value to\n// satisfy the enabled guard in useCustomerOrders.\nconst BFF_SCOPED_CUSTOMER_ID = 1;\n\nexport function OrdersListScreen(): React.JSX.Element {\n const { navigate } = useAppNavigation();\n\n const handleOrderClick = (order: orders.ListOrder) => {\n navigate(`orders/${order.token}`);\n };\n\n const handleSubscriptionClick = (subscriptionToken: string) => {\n navigate(`subscriptions/${subscriptionToken}`);\n };\n\n return (\n <OrdersListScreenContent\n customerId={BFF_SCOPED_CUSTOMER_ID}\n onOrderClick={handleOrderClick}\n onSubscriptionClick={handleSubscriptionClick}\n t={(key) => translations[key] ?? key}\n />\n );\n}\n","import { useEffect, useState } from \"react\";\nimport type { orders } from \"@fluid-app/orders-core\";\nimport { usePortalTenantOrder } from \"@fluid-app/orders-core\";\nimport { Skeleton } from \"@fluid-app/ui-primitives\";\nimport { OrderStatusBadge } from \"./order-status-badge\";\n\n// Human-readable labels for the non-card entries of PaymentMethod.payment_type.\n// Card payments render via card_type (uppercased) and bypass this map entirely.\nconst PAYMENT_TYPE_LABELS: Record<string, string> = {\n apple_pay: \"Apple Pay\",\n google_pay: \"Google Pay\",\n paypal: \"PayPal\",\n braintree_paypal: \"PayPal\",\n affirm: \"Affirm\",\n klarna: \"Klarna\",\n bread: \"Bread\",\n iap: \"In-App Purchase\",\n citcon: \"Citcon\",\n ppro: \"PPRO\",\n dlocal: \"dLocal\",\n droplet: \"Droplet\",\n};\n\nexport interface PortalOrderDetailProps {\n id: string | number;\n onNotFound?: () => void;\n onError?: (error: Error) => void;\n}\n\nfunction DetailSkeleton() {\n return (\n <div className=\"flex flex-col lg:grid lg:grid-cols-8\">\n <div className=\"bg-muted flex flex-col items-center px-8 lg:col-span-4\">\n <div className=\"w-full max-w-lg py-6\">\n <Skeleton className=\"mb-4 h-6 w-48\" />\n <div className=\"space-y-4\">\n <div className=\"flex items-center space-x-4\">\n <Skeleton className=\"h-24 w-24 rounded\" />\n <div className=\"flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-3/4\" />\n <Skeleton className=\"h-4 w-1/2\" />\n </div>\n </div>\n </div>\n <div className=\"mt-6 space-y-2\">\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-5 w-full\" />\n </div>\n </div>\n </div>\n <div className=\"bg-background px-8 pt-4 lg:col-span-4\">\n <div className=\"mx-auto max-w-lg lg:mx-0 lg:mr-auto\">\n <Skeleton className=\"mb-4 h-10 w-full rounded\" />\n <div className=\"mt-6 space-y-4\">\n <Skeleton className=\"h-5 w-40\" />\n <Skeleton className=\"h-16 w-full rounded\" />\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nfunction SummaryRow({ label, value }: { label: string; value: string }) {\n return (\n <div className=\"flex items-center justify-between text-sm\">\n <p className=\"text-muted-foreground\">{label}</p>\n <p className=\"text-foreground\">{value}</p>\n </div>\n );\n}\n\nfunction formatAddressLines(address: orders.PortalTenantAddress): string[] {\n const lines: string[] = [];\n if (address.name) lines.push(address.name);\n if (address.address1) lines.push(address.address1);\n if (address.address2) lines.push(address.address2);\n const cityLine = [address.city, address.state, address.postal_code]\n .filter(Boolean)\n .join(\", \");\n if (cityLine) lines.push(cityLine);\n if (address.country_code) lines.push(address.country_code);\n return lines;\n}\n\nfunction AddressSection({ address }: { address: orders.PortalTenantAddress }) {\n const lines = formatAddressLines(address);\n if (lines.length === 0) return null;\n return (\n <div className=\"border-border mb-6 border-b pb-6\">\n <h3 className=\"text-foreground mb-3 text-sm/6 font-semibold\">\n Shipping Address\n </h3>\n <div className=\"text-foreground space-y-0.5 text-sm\">\n {lines.map((line, index) => (\n <p key={index}>{line}</p>\n ))}\n </div>\n </div>\n );\n}\n\nfunction PaymentMethodSection({\n paymentMethod,\n}: {\n paymentMethod: orders.PortalTenantPaymentMethod;\n}) {\n const { card_type, last4 } = paymentMethod;\n const brand = card_type\n ? card_type.toUpperCase()\n : (PAYMENT_TYPE_LABELS[paymentMethod.payment_type] ??\n paymentMethod.payment_type);\n const label = last4 ? `${brand} ending in ${last4}` : brand;\n if (!label) return null;\n return (\n <div className=\"border-border mb-6 border-b pb-6\">\n <h3 className=\"text-foreground mb-3 text-sm/6 font-semibold\">\n Payment Method\n </h3>\n <p className=\"text-foreground text-sm\">{label}</p>\n </div>\n );\n}\n\nfunction LineItemImage({ src, alt }: { src: string; alt: string }) {\n const [errored, setErrored] = useState(false);\n if (errored) return <span className=\"text-xs\">No image</span>;\n return (\n <img\n src={src}\n alt={alt}\n className=\"h-full w-full object-cover\"\n onError={() => setErrored(true)}\n />\n );\n}\n\nfunction ItemRow({ item }: { item: orders.PortalTenantOrderLineItem }) {\n return (\n <div className=\"flex items-center space-x-4 py-4\">\n <div className=\"relative shrink-0\">\n <div className=\"bg-muted text-muted-foreground flex h-24 w-24 items-center justify-center overflow-hidden rounded\">\n {item.image_url ? (\n <LineItemImage src={item.image_url} alt={item.product_name} />\n ) : (\n <span className=\"text-xs\">No image</span>\n )}\n </div>\n {item.quantity > 1 && (\n <span className=\"bg-foreground text-background absolute -top-2 -right-2 z-10 flex h-6 w-6 items-center justify-center rounded-full text-xs font-medium\">\n {item.quantity}\n </span>\n )}\n </div>\n <div className=\"flex min-w-0 flex-1 flex-col space-y-0.5\">\n <p\n className=\"text-foreground truncate text-sm font-medium\"\n title={item.product_name}\n >\n {item.product_name}\n </p>\n {item.variant_name && (\n <p\n className=\"text-muted-foreground truncate text-xs\"\n title={item.variant_name}\n >\n {item.variant_name}\n </p>\n )}\n <p className=\"text-foreground text-sm font-medium\">{item.total}</p>\n {item.quantity > 1 && (\n <p className=\"text-muted-foreground text-xs\">\n {item.price} x {item.quantity}\n </p>\n )}\n </div>\n </div>\n );\n}\n\nfunction ItemsSection({ order }: { order: orders.PortalTenantOrder }) {\n return (\n <section className=\"bg-muted flex w-full flex-col items-center px-8 lg:col-span-4\">\n <div className=\"flex w-full max-w-lg flex-col\">\n <div className=\"mt-4\">\n <h2 className=\"text-foreground mb-2 text-lg font-medium\">\n Items ({order.line_items.length})\n </h2>\n <hr className=\"border-border\" />\n </div>\n\n <div className=\"divide-border divide-y\">\n {order.line_items.map((item) => (\n <ItemRow key={item.id} item={item} />\n ))}\n </div>\n\n <div className=\"border-border mb-4 space-y-1 border-t pt-4\">\n <SummaryRow\n label=\"Subtotal\"\n value={`${order.currency} ${order.subtotal}`}\n />\n {parseFloat(order.discount) > 0 && (\n <SummaryRow\n label=\"Discount\"\n value={`${order.currency} -${order.discount}`}\n />\n )}\n <SummaryRow\n label=\"Shipping\"\n value={`${order.currency} ${order.shipping}`}\n />\n <SummaryRow label=\"Tax\" value={`${order.currency} ${order.tax}`} />\n <div className=\"mt-2 flex items-center justify-between text-base font-medium\">\n <p className=\"text-muted-foreground text-sm font-medium\">Total</p>\n <p className=\"text-foreground text-base font-bold\">\n {order.currency} {order.total}\n </p>\n </div>\n </div>\n\n {/* TODO: i18n */}\n {/* TODO: gate on reward_points_enabled when available on PortalTenantOrder */}\n {order.total_points_credited != null &&\n order.total_points_credited > 0 && (\n <div className=\"border-border mb-4 border-t pt-4\">\n <div className=\"flex items-baseline justify-between\">\n <div>\n <p className=\"text-foreground text-sm font-semibold\">\n Points Earned on This Order!\n </p>\n {order.customer_points_balance != null && (\n <p className=\"text-muted-foreground text-xs\">\n {order.customer_points_balance.toLocaleString()} points\n total\n </p>\n )}\n </div>\n <div className=\"text-right\">\n <p className=\"text-foreground text-sm font-semibold\">\n +{order.total_points_credited.toLocaleString()}\n </p>\n <p className=\"text-muted-foreground text-xs\">points</p>\n </div>\n </div>\n </div>\n )}\n </div>\n </section>\n );\n}\n\nfunction DetailsSection({ order }: { order: orders.PortalTenantOrder }) {\n return (\n <div className=\"bg-background px-8 pt-4 lg:col-span-4\">\n <div className=\"mx-auto max-w-lg lg:mx-0 lg:mr-auto\">\n {/* Order Status */}\n <div className=\"border-border mb-6 border-b pb-6\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-muted-foreground text-sm\">Status:</span>\n <OrderStatusBadge status={order.status} />\n </div>\n </div>\n </div>\n\n {/* Order Info */}\n <div className=\"border-border mb-6 border-b pb-6\">\n <h3 className=\"text-foreground mb-3 text-sm/6 font-semibold\">\n Order Info\n </h3>\n <div className=\"divide-border flex divide-x\">\n <div className=\"flex-1 pr-4\">\n <div className=\"text-muted-foreground text-sm\">Order</div>\n <div className=\"text-foreground font-medium\">#{order.id}</div>\n </div>\n <div className=\"flex-1 pl-4 text-right\">\n <div className=\"text-muted-foreground text-sm\">Date</div>\n <div className=\"text-foreground font-medium\">\n {new Date(order.created_at).toLocaleDateString(\"en-US\", {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n })}\n </div>\n </div>\n </div>\n {order.customer_email && (\n <div className=\"mt-3\">\n <div className=\"text-muted-foreground text-sm\">Email</div>\n <div className=\"text-foreground text-sm font-medium\">\n {order.customer_email}\n </div>\n </div>\n )}\n {order.customer_name && (\n <div className=\"mt-3\">\n <div className=\"text-muted-foreground text-sm\">Customer</div>\n <div className=\"text-foreground text-sm font-medium\">\n {order.customer_name}\n </div>\n </div>\n )}\n </div>\n\n {order.address && <AddressSection address={order.address} />}\n {order.payment_method && (\n <PaymentMethodSection paymentMethod={order.payment_method} />\n )}\n </div>\n </div>\n );\n}\n\nexport function PortalOrderDetail({\n id,\n onNotFound,\n onError,\n}: PortalOrderDetailProps) {\n const { data, isLoading, error } = usePortalTenantOrder(id);\n const order = data?.order;\n\n useEffect(() => {\n if (!isLoading && error) {\n onError?.(error as Error);\n }\n }, [isLoading, error, onError]);\n\n useEffect(() => {\n if (!isLoading && !error && !order) {\n onNotFound?.();\n }\n }, [isLoading, error, order, onNotFound]);\n\n if (isLoading) {\n return <DetailSkeleton />;\n }\n\n if (!order) {\n return null;\n }\n\n return (\n <div className=\"flex flex-col lg:grid lg:grid-cols-8\">\n <ItemsSection order={order} />\n <DetailsSection order={order} />\n </div>\n );\n}\n","\"use client\";\n\nimport { useMemo } from \"react\";\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@fluid-app/ui-primitives\";\nimport { useScreenHeaderBreadcrumbs } from \"@fluid-app/portal-react/shell/ScreenHeaderContext\";\nimport { PortalOrderDetail } from \"../components/portal-order-detail\";\n\nexport interface PortalOrderDetailScreenProps {\n id: string | number;\n onNavigateToList: () => void;\n onNotFound?: () => void;\n onError?: (error: Error) => void;\n}\n\nexport function PortalOrderDetailScreen({\n id,\n onNavigateToList,\n onNotFound,\n onError,\n}: PortalOrderDetailScreenProps) {\n const headerBreadcrumbs = useMemo(\n () => (\n <Breadcrumb>\n <BreadcrumbList className=\"text-lg\">\n <BreadcrumbItem>\n <BreadcrumbLink\n href=\"#\"\n onClick={(e) => {\n e.preventDefault();\n onNavigateToList();\n }}\n >\n Orders\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage className=\"font-semibold\">\n Order #{id}\n </BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n ),\n [id, onNavigateToList],\n );\n useScreenHeaderBreadcrumbs(headerBreadcrumbs);\n\n return (\n <div className=\"mx-auto max-w-7xl px-4 py-4 sm:px-6 sm:py-6 lg:px-10 lg:py-8\">\n <PortalOrderDetail id={id} onNotFound={onNotFound} onError={onError} />\n </div>\n );\n}\n","import { PortalOrderDetailScreen as PortalOrderDetailScreenContent } from \"@fluid-app/orders-ui/screens/PortalOrderDetailScreen\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\n\ninterface OrderDetailScreenProps {\n token: string;\n onToast: (message: string, type: \"success\" | \"error\" | \"warning\") => void;\n}\n\nexport function OrderDetailScreen({\n token,\n onToast,\n}: OrderDetailScreenProps): React.JSX.Element {\n const { navigate } = useAppNavigation();\n\n return (\n <PortalOrderDetailScreenContent\n id={token}\n onNavigateToList={() => navigate(\"orders\")}\n onNotFound={() => {\n onToast(\"Order not found\", \"warning\");\n navigate(\"orders\");\n }}\n onError={(err) => {\n const message =\n err instanceof Error ? err.message : \"An error occurred\";\n onToast(`Failed to load order: ${message}`, \"error\");\n }}\n />\n );\n}\n","import type { ComponentProps } from \"react\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { PortalOrdersApiProvider } from \"../orders/PortalOrdersApiProvider\";\nimport { OrdersListScreen } from \"./OrdersListScreen\";\nimport { OrderDetailScreen } from \"./OrderDetailScreen\";\n\ntype OrdersScreenProps = ComponentProps<\"div\"> & {\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n onToast?: (message: string, type: \"success\" | \"error\" | \"warning\") => void;\n};\n\nfunction defaultToast(message: string, type: \"success\" | \"error\" | \"warning\") {\n fluidToast({ title: message, type });\n}\n\nexport function OrdersScreen({\n onToast,\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: OrdersScreenProps): React.JSX.Element {\n const { currentSlug } = useAppNavigation();\n const effectiveToast = onToast ?? defaultToast;\n\n // Parse slug: \"orders\" → list, \"orders/{token}\" → detail\n const detailToken = currentSlug.split(\"/\")[1];\n const isDetailView = detailToken !== undefined;\n\n if (isDetailView) {\n return (\n <div {...divProps}>\n <PortalOrdersApiProvider>\n <OrderDetailScreen token={detailToken} onToast={effectiveToast} />\n </PortalOrdersApiProvider>\n </div>\n );\n }\n\n return (\n <div {...divProps}>\n <PortalOrdersApiProvider>\n <OrdersListScreen />\n </PortalOrdersApiProvider>\n </div>\n );\n}\n\nexport const ordersScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"OrdersScreen\",\n displayName: \"Orders Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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"}
|