@fluid-app/portal-sdk 0.1.405 → 0.1.407
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-BOxI7p-f.cjs → OrdersScreen-BlNndMxv.cjs} +207 -216
- package/dist/OrdersScreen-BlNndMxv.cjs.map +1 -0
- package/dist/{OrdersScreen-BxLCkJhu.cjs → OrdersScreen-CXy2Vp_2.cjs} +1 -1
- package/dist/{OrdersScreen-BUTD4UlS.mjs → OrdersScreen-Cy2M0ZKk.mjs} +207 -216
- package/dist/OrdersScreen-Cy2M0ZKk.mjs.map +1 -0
- package/dist/{OrdersScreen-CL8oO1kU.mjs → OrdersScreen-DbORjbmv.mjs} +1 -1
- package/dist/adapters/orders-api-adapter.d.ts.map +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.mjs +3 -3
- package/dist/screens/orders/PortalOrdersList.d.ts.map +1 -1
- package/dist/screens/orders/portal-orders-list-helpers.d.ts +7 -17
- package/dist/screens/orders/portal-orders-list-helpers.d.ts.map +1 -1
- package/package.json +11 -11
- package/dist/OrdersScreen-BOxI7p-f.cjs.map +0 -1
- package/dist/OrdersScreen-BUTD4UlS.mjs.map +0 -1
|
@@ -203,6 +203,7 @@ function mapToPortalTenantOrder(raw) {
|
|
|
203
203
|
token: raw.token ?? "",
|
|
204
204
|
order_number: typeof rawOrderNumber === "string" && rawOrderNumber.length > 0 ? rawOrderNumber : null,
|
|
205
205
|
status: raw.status ?? "pending",
|
|
206
|
+
fulfillment_status: typeof raw.fulfillment_status === "string" ? raw.fulfillment_status : "unfulfilled",
|
|
206
207
|
subtotal,
|
|
207
208
|
subtotal_in_currency: raw.subtotal_in_currency ?? subtotal,
|
|
208
209
|
discount,
|
|
@@ -359,127 +360,226 @@ function OrdersTranslationBridge({ children }) {
|
|
|
359
360
|
});
|
|
360
361
|
}
|
|
361
362
|
//#endregion
|
|
362
|
-
//#region src/
|
|
363
|
-
const
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
labelKey: "status_fulfilled"
|
|
371
|
-
},
|
|
372
|
-
partially_fulfilled: {
|
|
373
|
-
kind: "preparing",
|
|
374
|
-
labelKey: "status_preparing"
|
|
375
|
-
},
|
|
376
|
-
in_progress: {
|
|
377
|
-
kind: "preparing",
|
|
378
|
-
labelKey: "status_preparing"
|
|
379
|
-
},
|
|
380
|
-
on_hold: {
|
|
381
|
-
kind: "preparing",
|
|
382
|
-
labelKey: "status_preparing"
|
|
383
|
-
},
|
|
384
|
-
scheduled: {
|
|
385
|
-
kind: "preparing",
|
|
386
|
-
labelKey: "status_preparing"
|
|
387
|
-
},
|
|
388
|
-
preparing: {
|
|
389
|
-
kind: "preparing",
|
|
390
|
-
labelKey: "status_preparing"
|
|
391
|
-
},
|
|
392
|
-
shipped: {
|
|
393
|
-
kind: "shipped",
|
|
394
|
-
labelKey: "status_shipped"
|
|
395
|
-
},
|
|
396
|
-
cancelled: { kind: "cancelled" },
|
|
397
|
-
returned: { kind: "cancelled" },
|
|
398
|
-
refunded: { kind: "cancelled" },
|
|
399
|
-
pending: {
|
|
400
|
-
kind: "pending",
|
|
401
|
-
labelKey: "status_processing"
|
|
402
|
-
},
|
|
403
|
-
unfulfilled: {
|
|
404
|
-
kind: "pending",
|
|
405
|
-
labelKey: "status_processing"
|
|
406
|
-
},
|
|
407
|
-
processing: {
|
|
408
|
-
kind: "pending",
|
|
409
|
-
labelKey: "status_processing"
|
|
410
|
-
}
|
|
363
|
+
//#region ../../orders/ui/src/components/status-badge.tsx
|
|
364
|
+
const colorStyles = {
|
|
365
|
+
green: "bg-green-500/15 text-foreground",
|
|
366
|
+
yellow: "bg-yellow-500/15 text-foreground",
|
|
367
|
+
red: "bg-red-500/15 text-foreground",
|
|
368
|
+
blue: "bg-blue-500/15 text-foreground",
|
|
369
|
+
orange: "bg-orange-500/15 text-foreground",
|
|
370
|
+
gray: "bg-foreground/10 text-foreground"
|
|
411
371
|
};
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
*/
|
|
420
|
-
function mapStatus(orderStatus, t) {
|
|
421
|
-
const entry = STATUS_LOOKUP[(orderStatus || "").toLowerCase()];
|
|
422
|
-
const rawLabel = orderStatus ? orderStatus.charAt(0).toUpperCase() + orderStatus.slice(1) : "—";
|
|
423
|
-
if (!entry) return {
|
|
424
|
-
kind: "pending",
|
|
425
|
-
label: rawLabel
|
|
426
|
-
};
|
|
427
|
-
return {
|
|
428
|
-
kind: entry.kind,
|
|
429
|
-
label: entry.labelKey ? t(entry.labelKey) : rawLabel
|
|
430
|
-
};
|
|
431
|
-
}
|
|
432
|
-
const STATUS_STYLES = {
|
|
433
|
-
fulfilled: {
|
|
434
|
-
bg: "bg-emerald-50 dark:bg-emerald-950/40",
|
|
435
|
-
text: "text-emerald-700 dark:text-emerald-400",
|
|
436
|
-
dot: "bg-emerald-500"
|
|
437
|
-
},
|
|
438
|
-
shipped: {
|
|
439
|
-
bg: "bg-sky-50 dark:bg-sky-950/40",
|
|
440
|
-
text: "text-sky-700 dark:text-sky-400",
|
|
441
|
-
dot: "bg-sky-500"
|
|
442
|
-
},
|
|
443
|
-
preparing: {
|
|
444
|
-
bg: "bg-amber-50 dark:bg-amber-950/40",
|
|
445
|
-
text: "text-amber-700 dark:text-amber-400",
|
|
446
|
-
dot: "bg-amber-500"
|
|
447
|
-
},
|
|
448
|
-
pending: {
|
|
449
|
-
bg: "bg-muted",
|
|
450
|
-
text: "text-muted-foreground",
|
|
451
|
-
dot: "bg-muted-foreground"
|
|
452
|
-
},
|
|
453
|
-
cancelled: {
|
|
454
|
-
bg: "bg-destructive/10",
|
|
455
|
-
text: "text-destructive",
|
|
456
|
-
dot: "bg-destructive"
|
|
457
|
-
}
|
|
372
|
+
const dotColorStyles = {
|
|
373
|
+
green: "bg-green-500",
|
|
374
|
+
yellow: "bg-yellow-500",
|
|
375
|
+
red: "bg-red-500",
|
|
376
|
+
blue: "bg-blue-500",
|
|
377
|
+
orange: "bg-orange-500",
|
|
378
|
+
gray: "bg-gray-500"
|
|
458
379
|
};
|
|
459
|
-
const
|
|
380
|
+
const sizeStyles = {
|
|
381
|
+
xs: "px-1.5 py-0.5 text-[10px]",
|
|
382
|
+
sm: "px-2 py-0.5 text-xs",
|
|
383
|
+
md: "px-2.5 py-1 text-sm"
|
|
384
|
+
};
|
|
385
|
+
function StatusBadge({ color, dot, size = "md", className, children }) {
|
|
386
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
387
|
+
className: require_src.cn("inline-flex items-center gap-1 rounded-full font-medium whitespace-nowrap capitalize", colorStyles[color], sizeStyles[size], className),
|
|
388
|
+
children: [dot && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: require_src.cn("h-1.5 w-1.5 rounded-full", dotColorStyles[color]) }), children]
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
//#endregion
|
|
392
|
+
//#region ../../orders/ui/src/lib/format.ts
|
|
393
|
+
function startCase(str) {
|
|
394
|
+
if (!str) return "";
|
|
395
|
+
return str.replace(/_/g, " ").replace(/\b\w/g, (char) => char.toUpperCase());
|
|
396
|
+
}
|
|
397
|
+
//#endregion
|
|
398
|
+
//#region ../../orders/ui/src/lib/translate-status.ts
|
|
399
|
+
/** Status values that have a `status_*` translation key in the orders dictionary. */
|
|
400
|
+
const translatableStatuses = new Set([
|
|
460
401
|
"cancelled",
|
|
402
|
+
"completed",
|
|
403
|
+
"fulfilled",
|
|
404
|
+
"pending",
|
|
405
|
+
"preparing",
|
|
406
|
+
"processing",
|
|
461
407
|
"returned",
|
|
462
|
-
"
|
|
408
|
+
"shipped"
|
|
463
409
|
]);
|
|
464
410
|
/**
|
|
411
|
+
* Translate an order status using the orders `t()` function.
|
|
412
|
+
* Falls back to `startCase` for statuses without a dedicated translation key.
|
|
413
|
+
*/
|
|
414
|
+
function translateStatus(t, status) {
|
|
415
|
+
if (translatableStatuses.has(status)) return t(`status_${status}`);
|
|
416
|
+
return startCase(status);
|
|
417
|
+
}
|
|
418
|
+
//#endregion
|
|
419
|
+
//#region ../../orders/ui/src/lib/effective-order-date.ts
|
|
420
|
+
function effectiveOrderDate(order) {
|
|
421
|
+
return order.sale_date ?? order.created_at;
|
|
422
|
+
}
|
|
423
|
+
//#endregion
|
|
424
|
+
//#region ../../orders/ui/src/lib/fulfillment-status.ts
|
|
425
|
+
/**
|
|
426
|
+
* Canonical fulfillment-status → badge color mapping.
|
|
427
|
+
*
|
|
428
|
+
* This is a deliberate mirror of fluid-admin's fulfillment color config
|
|
429
|
+
* (`COLOR_CONFIG.fulfillment` + `getDefaultColorForUnknownStatus` in
|
|
430
|
+
* `apps/fluid-admin/components/Orders/utils/formatters.ts`) so the
|
|
431
|
+
* customer-facing portal renders order status tags with the SAME label
|
|
432
|
+
* and color as the admin — admin is the source of truth (CURRENT-1496).
|
|
433
|
+
*
|
|
434
|
+
* The `Commerce::Order#fulfillment_status` enum values are:
|
|
435
|
+
* `unfulfilled, in_progress, on_hold, partially_fulfilled, scheduled,
|
|
436
|
+
* fulfilled`.
|
|
437
|
+
*/
|
|
438
|
+
const FULFILLMENT_STATUS_COLORS = {
|
|
439
|
+
fulfilled: "gray",
|
|
440
|
+
unfulfilled: "yellow",
|
|
441
|
+
in_progress: "yellow",
|
|
442
|
+
on_hold: "orange",
|
|
443
|
+
partially_fulfilled: "yellow",
|
|
444
|
+
scheduled: "blue",
|
|
445
|
+
processing: "yellow"
|
|
446
|
+
};
|
|
447
|
+
/**
|
|
448
|
+
* Cancelled-family lifecycle values. These come from `order_status` (not
|
|
449
|
+
* `fulfillment_status`), and the portal orders list surfaces them on the
|
|
450
|
+
* same pill. Admin renders these red, so we match.
|
|
451
|
+
*/
|
|
452
|
+
const CANCELLED_FAMILY_COLORS = {
|
|
453
|
+
cancelled: "red",
|
|
454
|
+
returned: "red",
|
|
455
|
+
refunded: "red"
|
|
456
|
+
};
|
|
457
|
+
/**
|
|
458
|
+
* Fallback for statuses not in the explicit maps. Mirrors admin's
|
|
459
|
+
* `getDefaultColorForUnknownStatus` for the fulfillment type so unknown
|
|
460
|
+
* values still read consistently with admin rather than defaulting to a
|
|
461
|
+
* meaningless grey.
|
|
462
|
+
*/
|
|
463
|
+
function defaultColor(status) {
|
|
464
|
+
if (status.includes("fulfilled") || status.includes("complete")) return "gray";
|
|
465
|
+
if (status.includes("hold")) return "orange";
|
|
466
|
+
return "yellow";
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Cancelled-family lifecycle values, derived from the color map so there is
|
|
470
|
+
* a single source of truth. Membership is checked case-insensitively.
|
|
471
|
+
*/
|
|
472
|
+
const CANCELLED_FAMILY = new Set(Object.keys(CANCELLED_FAMILY_COLORS));
|
|
473
|
+
/**
|
|
474
|
+
* Resolve which status string should drive an order's pill. Cancelled-family
|
|
475
|
+
* lifecycle values (`cancelled` / `returned` / `refunded`) come from the
|
|
476
|
+
* order's lifecycle status; everything else reads off `fulfillment_status`
|
|
477
|
+
* (the source of truth per `Commerce::Order#fulfillment_status`).
|
|
478
|
+
*
|
|
479
|
+
* Both the orders list and the order detail page use this so a cancelled
|
|
480
|
+
* order renders red "Cancelled" instead of a misleading yellow "Unfulfilled"
|
|
481
|
+
* — `fulfillment_status` has no cancelled-family value, so a cancelled order
|
|
482
|
+
* typically carries `fulfillment_status: "unfulfilled"` (CURRENT-1496).
|
|
483
|
+
*
|
|
484
|
+
* lifecycleStatus - the order's lifecycle status (`order_status` on a list
|
|
485
|
+
* order, `status` on a portal-tenant detail order).
|
|
486
|
+
* fulfillmentStatus - the order's `fulfillment_status`.
|
|
487
|
+
*/
|
|
488
|
+
function resolveOrderStatus(lifecycleStatus, fulfillmentStatus) {
|
|
489
|
+
if (lifecycleStatus && CANCELLED_FAMILY.has(lifecycleStatus.toLowerCase())) return lifecycleStatus;
|
|
490
|
+
return fulfillmentStatus ?? lifecycleStatus ?? "";
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Resolve the badge color for an order status tag, matching admin exactly
|
|
494
|
+
* for every `fulfillment_status` enum value and the cancelled family.
|
|
495
|
+
*/
|
|
496
|
+
function fulfillmentStatusColor(status) {
|
|
497
|
+
if (!status) return "gray";
|
|
498
|
+
const normalized = status.toLowerCase();
|
|
499
|
+
return FULFILLMENT_STATUS_COLORS[normalized] ?? CANCELLED_FAMILY_COLORS[normalized] ?? defaultColor(normalized);
|
|
500
|
+
}
|
|
501
|
+
//#endregion
|
|
502
|
+
//#region ../../orders/ui/src/components/fulfillment-status-badge.tsx
|
|
503
|
+
/**
|
|
504
|
+
* Renders an order status tag whose label and color match the fluid-admin
|
|
505
|
+
* fulfillment pill exactly (CURRENT-1496). Admin is the source of truth:
|
|
506
|
+
* `fulfilled` is grey, `unfulfilled`/`in_progress`/`partially_fulfilled`
|
|
507
|
+
* are yellow, `on_hold` is orange, and `scheduled` is blue. Labels come
|
|
508
|
+
* from `translateStatus`, which yields the same start-cased text admin
|
|
509
|
+
* shows (`getStatusDisplayText`) while preserving the translated
|
|
510
|
+
* `status_fulfilled` copy where available.
|
|
511
|
+
*/
|
|
512
|
+
function FulfillmentStatusBadge({ status, className }) {
|
|
513
|
+
const { t } = useOrdersTranslation();
|
|
514
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatusBadge, {
|
|
515
|
+
color: fulfillmentStatusColor(status),
|
|
516
|
+
dot: true,
|
|
517
|
+
size: "sm",
|
|
518
|
+
className,
|
|
519
|
+
children: translateStatus(t, status)
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
//#endregion
|
|
523
|
+
//#region ../../orders/ui/src/components/static-map.tsx
|
|
524
|
+
function StaticMap({ apiKey, address, options, alt, className }) {
|
|
525
|
+
const { t } = useOrdersTranslation();
|
|
526
|
+
const [errored, setErrored] = (0, react.useState)(false);
|
|
527
|
+
const url = buildStaticMapUrl(apiKey, address, options);
|
|
528
|
+
if (!url || errored) return null;
|
|
529
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
530
|
+
src: url,
|
|
531
|
+
alt: alt ?? t("shipping_address_map"),
|
|
532
|
+
width: options?.width ?? 600,
|
|
533
|
+
height: options?.height ?? 300,
|
|
534
|
+
className: className ?? "border-border w-full rounded border object-cover shadow-xs",
|
|
535
|
+
onError: () => setErrored(true)
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
//#endregion
|
|
539
|
+
//#region src/screens/orders/portal-orders-list-helpers.ts
|
|
540
|
+
const STATUS_KIND_LOOKUP = {
|
|
541
|
+
fulfilled: "fulfilled",
|
|
542
|
+
completed: "fulfilled",
|
|
543
|
+
shipped: "shipped",
|
|
544
|
+
partially_fulfilled: "preparing",
|
|
545
|
+
in_progress: "preparing",
|
|
546
|
+
on_hold: "preparing",
|
|
547
|
+
scheduled: "preparing",
|
|
548
|
+
preparing: "preparing",
|
|
549
|
+
cancelled: "cancelled",
|
|
550
|
+
returned: "cancelled",
|
|
551
|
+
refunded: "cancelled",
|
|
552
|
+
pending: "pending",
|
|
553
|
+
unfulfilled: "pending",
|
|
554
|
+
processing: "pending"
|
|
555
|
+
};
|
|
556
|
+
/**
|
|
557
|
+
* Classify a raw status string onto the internal `StatusKind` vocabulary
|
|
558
|
+
* used to drive the filter tabs. This is intentionally coarser than the
|
|
559
|
+
* rendered pill — the pill's label and color come from
|
|
560
|
+
* `FulfillmentStatusBadge`. Unknown statuses fall back to `pending`.
|
|
561
|
+
*/
|
|
562
|
+
function statusKind(orderStatus) {
|
|
563
|
+
return STATUS_KIND_LOOKUP[(orderStatus || "").toLowerCase()] ?? "pending";
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
465
566
|
* Pick the right status string to drive the pill / filter for a list order.
|
|
466
567
|
* Cancelled-family lifecycle states come from `order_status`; everything
|
|
467
568
|
* else is read off `fulfillment_status` (the BFF source-of-truth per the
|
|
468
|
-
* `Commerce::Order#fulfillment_status` enum).
|
|
569
|
+
* `Commerce::Order#fulfillment_status` enum). Delegates to the shared
|
|
570
|
+
* `resolveOrderStatus` so the list and the order detail page stay in lockstep.
|
|
469
571
|
*/
|
|
470
572
|
function statusForOrder(order) {
|
|
471
|
-
|
|
472
|
-
return order.fulfillment_status ?? order.order_status;
|
|
573
|
+
return resolveOrderStatus(order.order_status, order.fulfillment_status);
|
|
473
574
|
}
|
|
474
575
|
function filterPredicate(filter, order) {
|
|
475
576
|
if (filter === "all") return true;
|
|
476
577
|
if (filter === "subscription") return order.subscription != null;
|
|
477
|
-
const
|
|
478
|
-
if (filter === "fulfilled") return
|
|
479
|
-
if (filter === "preparing") return
|
|
578
|
+
const kind = statusKind(statusForOrder(order));
|
|
579
|
+
if (filter === "fulfilled") return kind === "fulfilled" || kind === "shipped";
|
|
580
|
+
if (filter === "preparing") return kind === "preparing" || kind === "pending";
|
|
480
581
|
return true;
|
|
481
582
|
}
|
|
482
|
-
const identity = ((k) => k);
|
|
483
583
|
function countByFilter(list) {
|
|
484
584
|
return {
|
|
485
585
|
all: list.length,
|
|
@@ -728,7 +828,6 @@ function FilterPills({ active, counts, onChange, t }) {
|
|
|
728
828
|
});
|
|
729
829
|
}
|
|
730
830
|
function OrderRow({ order, onClick, t }) {
|
|
731
|
-
const status = mapStatus(statusForOrder(order), t);
|
|
732
831
|
const dateLabel = formatFriendlyDate(orderDisplayDate(order), t);
|
|
733
832
|
const total = formatOrderTotal(order);
|
|
734
833
|
const titleText = order.first_item?.title || `${t("order_number")}${order.order_number}`;
|
|
@@ -752,7 +851,7 @@ function OrderRow({ order, onClick, t }) {
|
|
|
752
851
|
className: "text-muted-foreground font-medium",
|
|
753
852
|
children: titleSuffix
|
|
754
853
|
})]
|
|
755
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
854
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FulfillmentStatusBadge, { status: statusForOrder(order) })]
|
|
756
855
|
}),
|
|
757
856
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
758
857
|
className: "text-muted-foreground mt-1 truncate text-xs",
|
|
@@ -808,13 +907,6 @@ function SubscriptionBadge({ t }) {
|
|
|
808
907
|
})
|
|
809
908
|
});
|
|
810
909
|
}
|
|
811
|
-
function StatusPill({ status }) {
|
|
812
|
-
const styles = STATUS_STYLES[status.kind];
|
|
813
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
814
|
-
className: `inline-flex shrink-0 items-center gap-1 rounded-md px-2 py-0.5 text-xs font-semibold ${styles.bg} ${styles.text}`,
|
|
815
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: `size-1.5 rounded-full ${styles.dot}` }), status.label]
|
|
816
|
-
});
|
|
817
|
-
}
|
|
818
910
|
function OrdersListSkeleton() {
|
|
819
911
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: Array(4).fill(0).map((_, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
820
912
|
className: `flex items-center gap-3 px-4 py-3.5 ${i < 3 ? "border-border border-b" : ""}`,
|
|
@@ -957,107 +1049,6 @@ function MaskedPaymentLabel({ label, className }) {
|
|
|
957
1049
|
});
|
|
958
1050
|
}
|
|
959
1051
|
//#endregion
|
|
960
|
-
//#region ../../orders/ui/src/components/status-badge.tsx
|
|
961
|
-
const colorStyles = {
|
|
962
|
-
green: "bg-green-500/15 text-foreground",
|
|
963
|
-
yellow: "bg-yellow-500/15 text-foreground",
|
|
964
|
-
red: "bg-red-500/15 text-foreground",
|
|
965
|
-
blue: "bg-blue-500/15 text-foreground",
|
|
966
|
-
gray: "bg-foreground/10 text-foreground"
|
|
967
|
-
};
|
|
968
|
-
const dotColorStyles = {
|
|
969
|
-
green: "bg-green-500",
|
|
970
|
-
yellow: "bg-yellow-500",
|
|
971
|
-
red: "bg-red-500",
|
|
972
|
-
blue: "bg-blue-500",
|
|
973
|
-
gray: "bg-gray-500"
|
|
974
|
-
};
|
|
975
|
-
const sizeStyles = {
|
|
976
|
-
xs: "px-1.5 py-0.5 text-[10px]",
|
|
977
|
-
sm: "px-2 py-0.5 text-xs",
|
|
978
|
-
md: "px-2.5 py-1 text-sm"
|
|
979
|
-
};
|
|
980
|
-
function StatusBadge({ color, dot, size = "md", className, children }) {
|
|
981
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
982
|
-
className: require_src.cn("inline-flex items-center gap-1 rounded-full font-medium whitespace-nowrap capitalize", colorStyles[color], sizeStyles[size], className),
|
|
983
|
-
children: [dot && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: require_src.cn("h-1.5 w-1.5 rounded-full", dotColorStyles[color]) }), children]
|
|
984
|
-
});
|
|
985
|
-
}
|
|
986
|
-
//#endregion
|
|
987
|
-
//#region ../../orders/ui/src/lib/format.ts
|
|
988
|
-
function startCase(str) {
|
|
989
|
-
if (!str) return "";
|
|
990
|
-
return str.replace(/_/g, " ").replace(/\b\w/g, (char) => char.toUpperCase());
|
|
991
|
-
}
|
|
992
|
-
//#endregion
|
|
993
|
-
//#region ../../orders/ui/src/lib/translate-status.ts
|
|
994
|
-
/** Status values that have a `status_*` translation key in the orders dictionary. */
|
|
995
|
-
const translatableStatuses = new Set([
|
|
996
|
-
"cancelled",
|
|
997
|
-
"completed",
|
|
998
|
-
"fulfilled",
|
|
999
|
-
"pending",
|
|
1000
|
-
"preparing",
|
|
1001
|
-
"processing",
|
|
1002
|
-
"returned",
|
|
1003
|
-
"shipped"
|
|
1004
|
-
]);
|
|
1005
|
-
/**
|
|
1006
|
-
* Translate an order status using the orders `t()` function.
|
|
1007
|
-
* Falls back to `startCase` for statuses without a dedicated translation key.
|
|
1008
|
-
*/
|
|
1009
|
-
function translateStatus(t, status) {
|
|
1010
|
-
if (translatableStatuses.has(status)) return t(`status_${status}`);
|
|
1011
|
-
return startCase(status);
|
|
1012
|
-
}
|
|
1013
|
-
//#endregion
|
|
1014
|
-
//#region ../../orders/ui/src/components/order-status-badge.tsx
|
|
1015
|
-
const statusColorMap = {
|
|
1016
|
-
paid: "green",
|
|
1017
|
-
fulfilled: "green",
|
|
1018
|
-
delivered: "green",
|
|
1019
|
-
complete: "green",
|
|
1020
|
-
pending: "yellow",
|
|
1021
|
-
unfulfilled: "yellow",
|
|
1022
|
-
partially_fulfilled: "yellow",
|
|
1023
|
-
processing: "yellow",
|
|
1024
|
-
refunded: "red",
|
|
1025
|
-
cancelled: "red",
|
|
1026
|
-
failed: "red",
|
|
1027
|
-
voided: "red"
|
|
1028
|
-
};
|
|
1029
|
-
function OrderStatusBadge({ status, className }) {
|
|
1030
|
-
const { t } = useOrdersTranslation();
|
|
1031
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatusBadge, {
|
|
1032
|
-
color: statusColorMap[status] ?? "gray",
|
|
1033
|
-
dot: true,
|
|
1034
|
-
size: "sm",
|
|
1035
|
-
className,
|
|
1036
|
-
children: translateStatus(t, status)
|
|
1037
|
-
});
|
|
1038
|
-
}
|
|
1039
|
-
//#endregion
|
|
1040
|
-
//#region ../../orders/ui/src/components/static-map.tsx
|
|
1041
|
-
function StaticMap({ apiKey, address, options, alt, className }) {
|
|
1042
|
-
const { t } = useOrdersTranslation();
|
|
1043
|
-
const [errored, setErrored] = (0, react.useState)(false);
|
|
1044
|
-
const url = buildStaticMapUrl(apiKey, address, options);
|
|
1045
|
-
if (!url || errored) return null;
|
|
1046
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
1047
|
-
src: url,
|
|
1048
|
-
alt: alt ?? t("shipping_address_map"),
|
|
1049
|
-
width: options?.width ?? 600,
|
|
1050
|
-
height: options?.height ?? 300,
|
|
1051
|
-
className: className ?? "border-border w-full rounded border object-cover shadow-xs",
|
|
1052
|
-
onError: () => setErrored(true)
|
|
1053
|
-
});
|
|
1054
|
-
}
|
|
1055
|
-
//#endregion
|
|
1056
|
-
//#region ../../orders/ui/src/lib/effective-order-date.ts
|
|
1057
|
-
function effectiveOrderDate(order) {
|
|
1058
|
-
return order.sale_date ?? order.created_at;
|
|
1059
|
-
}
|
|
1060
|
-
//#endregion
|
|
1061
1052
|
//#region ../../orders/ui/src/components/portal-order-detail.tsx
|
|
1062
1053
|
/** Capitalize the first letter for display in headings / sentence-leading copy. */
|
|
1063
1054
|
const capitalize = (value) => value.charAt(0).toUpperCase() + value.slice(1);
|
|
@@ -1441,7 +1432,7 @@ function DetailsSection({ order, googleMapsApiKey }) {
|
|
|
1441
1432
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1442
1433
|
className: "text-muted-foreground text-sm",
|
|
1443
1434
|
children: t("status_label")
|
|
1444
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1435
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FulfillmentStatusBadge, { status: resolveOrderStatus(order.status, order.fulfillment_status) })]
|
|
1445
1436
|
})
|
|
1446
1437
|
})
|
|
1447
1438
|
}),
|
|
@@ -1664,4 +1655,4 @@ Object.defineProperty(exports, "ordersScreenPropertySchema", {
|
|
|
1664
1655
|
}
|
|
1665
1656
|
});
|
|
1666
1657
|
|
|
1667
|
-
//# sourceMappingURL=OrdersScreen-
|
|
1658
|
+
//# sourceMappingURL=OrdersScreen-BlNndMxv.cjs.map
|