order-management 0.0.101 → 0.0.103

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.
@@ -1,7 +1,4 @@
1
1
  "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
2
  const jsxRuntime = require("react/jsx-runtime");
6
3
  const adminSdk = require("@medusajs/admin-sdk");
7
4
  const react = require("react");
@@ -378,15 +375,14 @@ const s = {
378
375
  const OrderGiftItemsWidget = ({ data }) => {
379
376
  const [fetchedItems, setFetchedItems] = react.useState(null);
380
377
  react.useEffect(() => {
381
- if (!(data == null ? void 0 : data.id)) return;
378
+ if (!data?.id) return;
382
379
  fetch(
383
380
  `/admin/orders/${data.id}?fields=*items,items.metadata`
384
- ).then((r) => r.json()).then(({ order }) => setFetchedItems((order == null ? void 0 : order.items) ?? [])).catch(() => setFetchedItems((data == null ? void 0 : data.items) ?? []));
385
- }, [data == null ? void 0 : data.id]);
386
- const items = fetchedItems ?? (data == null ? void 0 : data.items) ?? [];
381
+ ).then((r) => r.json()).then(({ order }) => setFetchedItems(order?.items ?? [])).catch(() => setFetchedItems(data?.items ?? []));
382
+ }, [data?.id]);
383
+ const items = fetchedItems ?? data?.items ?? [];
387
384
  const giftedItems = items.filter((i) => {
388
- var _a;
389
- const flag = (_a = i.metadata) == null ? void 0 : _a.is_gift;
385
+ const flag = i.metadata?.is_gift;
390
386
  return flag === "true" || flag === true;
391
387
  });
392
388
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: s.widget, children: [
@@ -415,9 +411,9 @@ const OrderGiftItemsWidget = ({ data }) => {
415
411
  ),
416
412
  giftedItems.map((item) => {
417
413
  const meta = item.metadata;
418
- const from = meta == null ? void 0 : meta.gift_from;
419
- const to = meta == null ? void 0 : meta.gift_to;
420
- const message = meta == null ? void 0 : meta.gift_message;
414
+ const from = meta?.gift_from;
415
+ const to = meta?.gift_to;
416
+ const message = meta?.gift_message;
421
417
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: s.card, children: [
422
418
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: s.ribbon, children: [
423
419
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: s.bowCenter, children: "🎀" }),
@@ -481,7 +477,7 @@ function formatRefundCurrency(amount, currencyCode = "inr", options) {
481
477
  minimumFractionDigits: 2,
482
478
  maximumFractionDigits: 2
483
479
  }).format(amount);
484
- if ((options == null ? void 0 : options.signed) && amount > 0) {
480
+ if (options?.signed && amount > 0) {
485
481
  return `−${formatted}`;
486
482
  }
487
483
  return formatted;
@@ -536,8 +532,7 @@ function getOrderIdFromPath() {
536
532
  return m ? m[1] : void 0;
537
533
  }
538
534
  const OrderRefundContextWidget = (props) => {
539
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
540
- const orderId = ((_a = props.order) == null ? void 0 : _a.id) ?? ((_c = (_b = props.data) == null ? void 0 : _b.order) == null ? void 0 : _c.id) ?? getOrderIdFromPath();
535
+ const orderId = props.order?.id ?? props.data?.order?.id ?? getOrderIdFromPath();
541
536
  const [context, setContext] = react.useState(null);
542
537
  const [loading, setLoading] = react.useState(!!orderId);
543
538
  const [error, setError] = react.useState(null);
@@ -575,7 +570,7 @@ const OrderRefundContextWidget = (props) => {
575
570
  };
576
571
  }, [orderId]);
577
572
  const handleMarkRefunded = async () => {
578
- if (!(context == null ? void 0 : context.return_id) || !(context == null ? void 0 : context.refund_mapping) || context.refund_mapping.is_refunded || !context.can_process_refund) {
573
+ if (!context?.return_id || !context?.refund_mapping || context.refund_mapping.is_refunded || !context.can_process_refund) {
579
574
  return;
580
575
  }
581
576
  setMarking(true);
@@ -592,17 +587,14 @@ const OrderRefundContextWidget = (props) => {
592
587
  }
593
588
  const data = await res.json();
594
589
  setContext(
595
- (prev) => {
596
- var _a2;
597
- return prev && prev.refund_mapping ? {
598
- ...prev,
599
- can_process_refund: false,
600
- refund_mapping: {
601
- ...prev.refund_mapping,
602
- is_refunded: ((_a2 = data.refund_payment_mapping) == null ? void 0 : _a2.is_refunded) ?? true
603
- }
604
- } : prev;
605
- }
590
+ (prev) => prev && prev.refund_mapping ? {
591
+ ...prev,
592
+ can_process_refund: false,
593
+ refund_mapping: {
594
+ ...prev.refund_mapping,
595
+ is_refunded: data.refund_payment_mapping?.is_refunded ?? true
596
+ }
597
+ } : prev
606
598
  );
607
599
  } catch (e) {
608
600
  setMarkError(e instanceof Error ? e.message : "Failed to mark refunded");
@@ -611,20 +603,19 @@ const OrderRefundContextWidget = (props) => {
611
603
  }
612
604
  };
613
605
  const handleEditClick = () => {
614
- const mapping = context == null ? void 0 : context.refund_mapping;
615
- const mode = mapping == null ? void 0 : mapping.refund_mode;
606
+ const mapping = context?.refund_mapping;
607
+ const mode = mapping?.refund_mode;
616
608
  setEditRefundMode(
617
609
  mode === "offline" || mode === "online" ? mode : ""
618
610
  );
619
- setEditDetails((mapping == null ? void 0 : mapping.details) ?? "");
620
- setEditImageUrls((mapping == null ? void 0 : mapping.images) ?? []);
611
+ setEditDetails(mapping?.details ?? "");
612
+ setEditImageUrls(mapping?.images ?? []);
621
613
  setSaveError(null);
622
614
  setUploadError(null);
623
615
  setEditing(true);
624
616
  };
625
617
  const handleUploadImage = async (e) => {
626
- var _a2, _b2, _c2;
627
- const file = (_a2 = e.target.files) == null ? void 0 : _a2[0];
618
+ const file = e.target.files?.[0];
628
619
  if (!file) return;
629
620
  setUploading(true);
630
621
  setUploadError(null);
@@ -641,7 +632,7 @@ const OrderRefundContextWidget = (props) => {
641
632
  throw new Error(data2.message || "Upload failed");
642
633
  }
643
634
  const data = await res.json();
644
- const url = (_c2 = (_b2 = data.files) == null ? void 0 : _b2[0]) == null ? void 0 : _c2.url;
635
+ const url = data.files?.[0]?.url;
645
636
  if (url) setEditImageUrls((prev) => [...prev, url]);
646
637
  } catch (err) {
647
638
  setUploadError(err instanceof Error ? err.message : "Upload failed");
@@ -654,7 +645,7 @@ const OrderRefundContextWidget = (props) => {
654
645
  setEditImageUrls((prev) => prev.filter((_, i) => i !== index));
655
646
  };
656
647
  const handleSaveAdminFields = async () => {
657
- if (!(context == null ? void 0 : context.return_id)) return;
648
+ if (!context?.return_id) return;
658
649
  setSaving(true);
659
650
  setSaveError(null);
660
651
  try {
@@ -691,14 +682,14 @@ const OrderRefundContextWidget = (props) => {
691
682
  if (error) {
692
683
  return /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mt-6 divide-y p-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-error", children: error }) }) });
693
684
  }
694
- const hasReturn = !!(context == null ? void 0 : context.return_id);
695
- const hasMapping = !!(context == null ? void 0 : context.refund_mapping);
696
- const canMarkRefunded = Boolean(context == null ? void 0 : context.can_process_refund);
697
- const returnStatus = (context == null ? void 0 : context.return_status) ?? null;
698
- const showReceiveFirstHint = hasReturn && !((_d = context == null ? void 0 : context.refund_mapping) == null ? void 0 : _d.is_refunded) && returnStatus !== "received" && returnStatus !== "canceled";
699
- const paymentDetail = context == null ? void 0 : context.payment_detail;
700
- const paymentDetails = (context == null ? void 0 : context.payment_details) && context.payment_details.length > 0 ? context.payment_details : paymentDetail ? [paymentDetail] : [];
701
- const orderPayment = context == null ? void 0 : context.order_payment;
685
+ const hasReturn = !!context?.return_id;
686
+ const hasMapping = !!context?.refund_mapping;
687
+ const canMarkRefunded = Boolean(context?.can_process_refund);
688
+ const returnStatus = context?.return_status ?? null;
689
+ const showReceiveFirstHint = hasReturn && !context?.refund_mapping?.is_refunded && returnStatus !== "received" && returnStatus !== "canceled";
690
+ const paymentDetail = context?.payment_detail;
691
+ const paymentDetails = context?.payment_details && context.payment_details.length > 0 ? context.payment_details : paymentDetail ? [paymentDetail] : [];
692
+ const orderPayment = context?.order_payment;
702
693
  return /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mt-6 divide-y p-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4 py-4", children: [
703
694
  /* @__PURE__ */ jsxRuntime.jsxs(ui.Heading, { level: "h2", className: "flex items-center gap-2", children: [
704
695
  /* @__PURE__ */ jsxRuntime.jsx(icons.CashSolid, { className: "text-ui-fg-subtle" }),
@@ -710,7 +701,7 @@ const OrderRefundContextWidget = (props) => {
710
701
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
711
702
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "text-ui-fg-subtle", children: "Return" }),
712
703
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", children: context.return_id }),
713
- ((_e = context.refund_mapping) == null ? void 0 : _e.is_refunded) ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "green", children: "Refunded" }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "orange", children: "Not refunded" })
704
+ context.refund_mapping?.is_refunded ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "green", children: "Refunded" }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "orange", children: "Not refunded" })
714
705
  ] }),
715
706
  context.refund ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 border-t border-ui-border-base pt-3", children: /* @__PURE__ */ jsxRuntime.jsx(RefundCalculationBlock, { refund: context.refund }) }) : null,
716
707
  orderPayment && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 space-y-2 border-t border-ui-border-base pt-3", children: [
@@ -724,17 +715,17 @@ const OrderRefundContextWidget = (props) => {
724
715
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 space-y-2 border-t border-ui-border-base pt-3", children: [
725
716
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
726
717
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "text-ui-fg-subtle", children: "Payment method (refund destination)" }),
727
- ((_f = context.refund_mapping) == null ? void 0 : _f.payment_id) ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "green", children: "Customer specified" }) : paymentDetail ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "orange", children: "Customer default" }) : orderPayment && !orderPayment.is_cod ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "blue", children: "Original payment method" }) : null
718
+ context.refund_mapping?.payment_id ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "green", children: "Customer specified" }) : paymentDetail ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "orange", children: "Customer default" }) : orderPayment && !orderPayment.is_cod ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "blue", children: "Original payment method" }) : null
728
719
  ] }),
729
- ((_g = context.refund_mapping) == null ? void 0 : _g.payment_id) && !paymentDetail && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-orange-200 bg-orange-50 px-3 py-2", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: "The customer specified a payment method for this return, but that payment method has since been removed from their account. Ask the customer to update their refund payment method." }) }),
730
- !((_h = context.refund_mapping) == null ? void 0 : _h.payment_id) && (paymentDetail == null ? void 0 : paymentDetail.source) === "default" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-ui-border-base bg-ui-bg-subtle px-3 py-2", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: "The customer did not specify a payment method for this return. Showing their default payment method." }) }),
731
- !((_i = context.refund_mapping) == null ? void 0 : _i.payment_id) && !paymentDetail && orderPayment && !orderPayment.is_cod && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-ui-border-base bg-ui-bg-subtle px-3 py-2", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: [
720
+ context.refund_mapping?.payment_id && !paymentDetail && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-orange-200 bg-orange-50 px-3 py-2", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: "The customer specified a payment method for this return, but that payment method has since been removed from their account. Ask the customer to update their refund payment method." }) }),
721
+ !context.refund_mapping?.payment_id && paymentDetail?.source === "default" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-ui-border-base bg-ui-bg-subtle px-3 py-2", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: "The customer did not specify a payment method for this return. Showing their default payment method." }) }),
722
+ !context.refund_mapping?.payment_id && !paymentDetail && orderPayment && !orderPayment.is_cod && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-ui-border-base bg-ui-bg-subtle px-3 py-2", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: [
732
723
  "Refund will go to the original payment method (",
733
724
  orderPayment.label,
734
725
  ")."
735
726
  ] }) }),
736
- !((_j = context.refund_mapping) == null ? void 0 : _j.payment_id) && !paymentDetail && (context.is_cod || (orderPayment == null ? void 0 : orderPayment.is_cod)) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-ui-border-base bg-ui-bg-subtle px-3 py-2", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: "This order was paid with Cash on Delivery. No stored bank/UPI refund destination." }) }),
737
- !((_k = context.refund_mapping) == null ? void 0 : _k.payment_id) && !paymentDetail && !orderPayment && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-ui-border-base bg-ui-bg-subtle px-3 py-2", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: "No payment method found for this customer." }) }),
727
+ !context.refund_mapping?.payment_id && !paymentDetail && (context.is_cod || orderPayment?.is_cod) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-ui-border-base bg-ui-bg-subtle px-3 py-2", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: "This order was paid with Cash on Delivery. No stored bank/UPI refund destination." }) }),
728
+ !context.refund_mapping?.payment_id && !paymentDetail && !orderPayment && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-ui-border-base bg-ui-bg-subtle px-3 py-2", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: "No payment method found for this customer." }) }),
738
729
  paymentDetails.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: paymentDetails.map((detail) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
739
730
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
740
731
  /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { children: detail.type.toUpperCase() }),
@@ -746,7 +737,7 @@ const OrderRefundContextWidget = (props) => {
746
737
  ] }, `${detail.id}-${k}`)) })
747
738
  ] }, detail.id)) })
748
739
  ] }),
749
- (context == null ? void 0 : context.refund_mapping) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 space-y-3 border-t border-ui-border-base pt-3", children: [
740
+ context?.refund_mapping && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 space-y-3 border-t border-ui-border-base pt-3", children: [
750
741
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
751
742
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "text-ui-fg-subtle", children: "Refund mode, details & images" }),
752
743
  !editing ? /* @__PURE__ */ jsxRuntime.jsxs(
@@ -834,10 +825,7 @@ const OrderRefundContextWidget = (props) => {
834
825
  variant: "secondary",
835
826
  type: "button",
836
827
  disabled: uploading,
837
- onClick: () => {
838
- var _a2;
839
- return (_a2 = fileInputRef.current) == null ? void 0 : _a2.click();
840
- },
828
+ onClick: () => fileInputRef.current?.click(),
841
829
  children: uploading ? "Uploading…" : "Upload image"
842
830
  }
843
831
  ),
@@ -888,7 +876,7 @@ const OrderRefundContextWidget = (props) => {
888
876
  ] }),
889
877
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
890
878
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", weight: "plus", className: "text-ui-fg-muted", children: "Images" }),
891
- ((_l = context.refund_mapping.images) == null ? void 0 : _l.length) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 flex flex-wrap gap-2", children: context.refund_mapping.images.map((url, i) => /* @__PURE__ */ jsxRuntime.jsxs(
879
+ context.refund_mapping.images?.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 flex flex-wrap gap-2", children: context.refund_mapping.images.map((url, i) => /* @__PURE__ */ jsxRuntime.jsxs(
892
880
  "a",
893
881
  {
894
882
  href: url,
@@ -918,10 +906,10 @@ const OrderRefundContextWidget = (props) => {
918
906
  ),
919
907
  markError && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-error", children: markError })
920
908
  ] }),
921
- hasMapping && !canMarkRefunded && !((_m = context.refund_mapping) == null ? void 0 : _m.is_refunded) && showReceiveFirstHint && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-4 text-ui-fg-muted", children: "Mark refunded is available after the return is received." })
909
+ hasMapping && !canMarkRefunded && !context.refund_mapping?.is_refunded && showReceiveFirstHint && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-4 text-ui-fg-muted", children: "Mark refunded is available after the return is received." })
922
910
  ] }),
923
911
  hasReturn && !hasMapping && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-4", children: [
924
- (context == null ? void 0 : context.refund) ? /* @__PURE__ */ jsxRuntime.jsx(RefundCalculationBlock, { refund: context.refund }) : null,
912
+ context?.refund ? /* @__PURE__ */ jsxRuntime.jsx(RefundCalculationBlock, { refund: context.refund }) : null,
925
913
  orderPayment && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-3 space-y-1", children: [
926
914
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "text-ui-fg-subtle", children: "Order payment method" }),
927
915
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
@@ -1359,7 +1347,7 @@ function getEntityInfo(tableName) {
1359
1347
  const def = ENTITY_DEFINITIONS[tableName];
1360
1348
  return {
1361
1349
  tableName,
1362
- label: (def == null ? void 0 : def.label) ?? humanizeTableName(tableName),
1350
+ label: def?.label ?? humanizeTableName(tableName),
1363
1351
  category: def && CATEGORY_BY_ID.get(def.category) || SYSTEM_CATEGORY
1364
1352
  };
1365
1353
  }
@@ -1384,13 +1372,11 @@ function getTablesForCategory(id) {
1384
1372
  }
1385
1373
  const GROUPS = getEntitiesByCategory();
1386
1374
  function triggerLabel(entity, category) {
1387
- var _a;
1388
1375
  if (entity) return getEntityInfo(entity).label;
1389
- if (category) return `All ${((_a = getCategory(category)) == null ? void 0 : _a.label) ?? category}`;
1376
+ if (category) return `All ${getCategory(category)?.label ?? category}`;
1390
1377
  return "All entities";
1391
1378
  }
1392
1379
  const EntityPicker = ({ entity, category, onChange }) => {
1393
- var _a;
1394
1380
  const [open, setOpen] = react.useState(false);
1395
1381
  const [search, setSearch] = react.useState("");
1396
1382
  const searchRef = react.useRef(null);
@@ -1410,7 +1396,7 @@ const EntityPicker = ({ entity, category, onChange }) => {
1410
1396
  setOpen(false);
1411
1397
  setSearch("");
1412
1398
  };
1413
- const firstMatch = (_a = filteredGroups[0]) == null ? void 0 : _a.entities[0];
1399
+ const firstMatch = filteredGroups[0]?.entities[0];
1414
1400
  const isAll = !entity && !category;
1415
1401
  return /* @__PURE__ */ jsxRuntime.jsxs(
1416
1402
  ui.Popover,
@@ -1443,9 +1429,8 @@ const EntityPicker = ({ entity, category, onChange }) => {
1443
1429
  align: "start",
1444
1430
  className: "w-[min(360px,calc(100vw-2rem))] p-0",
1445
1431
  onOpenAutoFocus: (event) => {
1446
- var _a2;
1447
1432
  event.preventDefault();
1448
- (_a2 = searchRef.current) == null ? void 0 : _a2.focus();
1433
+ searchRef.current?.focus();
1449
1434
  },
1450
1435
  children: [
1451
1436
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b border-ui-border-base p-2", children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -1585,7 +1570,7 @@ function formatNumber(value) {
1585
1570
  return new Intl.NumberFormat().format(value);
1586
1571
  }
1587
1572
  function formatMoney(amount, currencyCode) {
1588
- const code = currencyCode == null ? void 0 : currencyCode.trim().toUpperCase();
1573
+ const code = currencyCode?.trim().toUpperCase();
1589
1574
  if (code && /^[A-Z]{3}$/.test(code)) {
1590
1575
  try {
1591
1576
  return new Intl.NumberFormat(void 0, { style: "currency", currency: code }).format(amount);
@@ -1652,9 +1637,9 @@ const SummaryCards = ({ stats, loading, failed }) => {
1652
1637
  };
1653
1638
  const BASE = "/admin/deleted-records-audit";
1654
1639
  class AuditApiError extends Error {
1640
+ status;
1655
1641
  constructor(message, status) {
1656
1642
  super(message);
1657
- __publicField(this, "status");
1658
1643
  this.status = status;
1659
1644
  }
1660
1645
  }
@@ -1719,10 +1704,7 @@ const URL_KEYS = {
1719
1704
  const DATE_PRESET_VALUES = new Set(DATE_PRESETS.map((p) => p.value));
1720
1705
  const DAY_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
1721
1706
  function filtersFromSearchParams(params) {
1722
- const read = (key) => {
1723
- var _a;
1724
- return ((_a = params.get(URL_KEYS[key])) == null ? void 0 : _a.trim()) ?? "";
1725
- };
1707
+ const read = (key) => params.get(URL_KEYS[key])?.trim() ?? "";
1726
1708
  const date = read("date");
1727
1709
  const from = read("from");
1728
1710
  const to = read("to");
@@ -1876,9 +1858,9 @@ const DeletedRecordsPage = () => {
1876
1858
  try {
1877
1859
  setStats(await fetchAuditStats(signal));
1878
1860
  } catch (e) {
1879
- if (!(signal == null ? void 0 : signal.aborted)) setStatsFailed(true);
1861
+ if (!signal?.aborted) setStatsFailed(true);
1880
1862
  } finally {
1881
- if (!(signal == null ? void 0 : signal.aborted)) setStatsLoading(false);
1863
+ if (!signal?.aborted) setStatsLoading(false);
1882
1864
  }
1883
1865
  }, []);
1884
1866
  react.useEffect(() => {
@@ -1935,7 +1917,7 @@ const DeletedRecordsPage = () => {
1935
1917
  const visible = Array.from(document.querySelectorAll(`[data-audit-row="${lastViewed}"]`)).find(
1936
1918
  (el) => el.offsetParent !== null
1937
1919
  );
1938
- visible == null ? void 0 : visible.scrollIntoView({ block: "center" });
1920
+ visible?.scrollIntoView({ block: "center" });
1939
1921
  });
1940
1922
  const handle = setTimeout(() => setHighlightId(null), 2500);
1941
1923
  return () => clearTimeout(handle);
@@ -1962,8 +1944,8 @@ const DeletedRecordsPage = () => {
1962
1944
  };
1963
1945
  const refresh = () => setReloadToken((t) => t + 1);
1964
1946
  const hasMore = items.length < count;
1965
- const knownSources = (stats == null ? void 0 : stats.sources) ?? [];
1966
- const knownDeletedBy = (stats == null ? void 0 : stats.deleted_by) ?? [];
1947
+ const knownSources = stats?.sources ?? [];
1948
+ const knownDeletedBy = stats?.deleted_by ?? [];
1967
1949
  const attributionMissing = !!stats && stats.total > 0 && knownSources.length === 0 && knownDeletedBy.length === 0;
1968
1950
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-3 md:p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-7xl flex-col gap-6 p-4 md:p-6", children: [
1969
1951
  /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-start md:justify-between", children: [
@@ -2227,7 +2209,7 @@ const ErrorState = ({ onRetry, detail }) => /* @__PURE__ */ jsxRuntime.jsxs("div
2227
2209
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "max-w-md font-mono text-ui-fg-muted", children: detail }),
2228
2210
  /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", size: "small", className: "mt-2", onClick: onRetry, children: "Try again" })
2229
2211
  ] });
2230
- const config$8 = adminSdk.defineRouteConfig({
2212
+ const config$9 = adminSdk.defineRouteConfig({
2231
2213
  label: "Deleted Records",
2232
2214
  icon: icons.Trash
2233
2215
  });
@@ -2247,19 +2229,27 @@ const getStatusBadgeClass$7 = (status) => {
2247
2229
  if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
2248
2230
  return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
2249
2231
  };
2250
- const PaymentsPage = () => {
2232
+ const RefundsPage = () => {
2251
2233
  const navigate = reactRouterDom.useNavigate();
2252
2234
  const [items, setItems] = react.useState([]);
2253
- const [statusFilter, setStatusFilter] = react.useState("all");
2254
2235
  const [orderIdSearch, setOrderIdSearch] = react.useState("");
2255
2236
  const debouncedOrderId = useDebounce$3(orderIdSearch, 300);
2237
+ const [paymentStatusFilter, setPaymentStatusFilter] = react.useState("all");
2238
+ const [providerSearch, setProviderSearch] = react.useState("");
2239
+ const debouncedProvider = useDebounce$3(providerSearch, 300);
2240
+ const [currencySearch, setCurrencySearch] = react.useState("");
2241
+ const debouncedCurrency = useDebounce$3(currencySearch, 300);
2242
+ const [dateFrom, setDateFrom] = react.useState("");
2243
+ const [dateTo, setDateTo] = react.useState("");
2244
+ const [amountMin, setAmountMin] = react.useState("");
2245
+ const [amountMax, setAmountMax] = react.useState("");
2256
2246
  const [isLoading, setIsLoading] = react.useState(true);
2257
2247
  const [isFetchingMore, setIsFetchingMore] = react.useState(false);
2258
2248
  const [error, setError] = react.useState(null);
2259
2249
  const [offset, setOffset] = react.useState(0);
2260
2250
  const [count, setCount] = react.useState(0);
2261
2251
  const limit = 50;
2262
- const loadTransactions = react.useCallback(
2252
+ const loadRefunds = react.useCallback(
2263
2253
  async (nextOffset, replace) => {
2264
2254
  try {
2265
2255
  if (replace) setIsLoading(true);
@@ -2268,18 +2258,25 @@ const PaymentsPage = () => {
2268
2258
  const params = new URLSearchParams();
2269
2259
  params.set("limit", String(limit));
2270
2260
  params.set("offset", String(nextOffset));
2271
- if (statusFilter !== "all") params.set("status", statusFilter);
2272
2261
  if (debouncedOrderId.trim()) params.set("order_id", debouncedOrderId.trim());
2273
- const response = await fetch(
2274
- `/admin/payment-transactions?${params.toString()}`,
2275
- { credentials: "include" }
2276
- );
2262
+ if (paymentStatusFilter !== "all") params.set("payment_status", paymentStatusFilter);
2263
+ if (debouncedProvider.trim()) params.set("provider_id", debouncedProvider.trim());
2264
+ if (debouncedCurrency.trim()) params.set("currency_code", debouncedCurrency.trim());
2265
+ if (dateFrom.trim()) params.set("date_from", dateFrom.trim());
2266
+ if (dateTo.trim()) params.set("date_to", dateTo.trim());
2267
+ const min = amountMin.trim() ? Number(amountMin) : void 0;
2268
+ const max = amountMax.trim() ? Number(amountMax) : void 0;
2269
+ if (min != null && !Number.isNaN(min)) params.set("amount_min", String(min));
2270
+ if (max != null && !Number.isNaN(max)) params.set("amount_max", String(max));
2271
+ const response = await fetch(`/admin/refunds?${params.toString()}`, {
2272
+ credentials: "include"
2273
+ });
2277
2274
  if (!response.ok) {
2278
2275
  const text = await response.text();
2279
- throw new Error(text || "Failed to load payment transactions");
2276
+ throw new Error(text || "Failed to load refunds");
2280
2277
  }
2281
2278
  const payload = await response.json();
2282
- const list = payload.transactions ?? [];
2279
+ const list = payload.refunds ?? [];
2283
2280
  setCount(payload.count ?? 0);
2284
2281
  setOffset(nextOffset + list.length);
2285
2282
  setItems((prev) => replace ? list : [...prev, ...list]);
@@ -2290,46 +2287,75 @@ const PaymentsPage = () => {
2290
2287
  setIsFetchingMore(false);
2291
2288
  }
2292
2289
  },
2293
- [statusFilter, debouncedOrderId]
2290
+ [
2291
+ debouncedOrderId,
2292
+ paymentStatusFilter,
2293
+ debouncedProvider,
2294
+ debouncedCurrency,
2295
+ dateFrom,
2296
+ dateTo,
2297
+ amountMin,
2298
+ amountMax
2299
+ ]
2294
2300
  );
2295
2301
  react.useEffect(() => {
2296
- void loadTransactions(0, true);
2297
- }, [loadTransactions]);
2302
+ void loadRefunds(0, true);
2303
+ }, [loadRefunds]);
2298
2304
  const hasMore = react.useMemo(() => offset < count, [offset, count]);
2299
- const displayStatus = (t) => {
2300
- const s2 = t.payment_id != null && t.payment_status != null && t.payment_status !== "" ? t.payment_status : t.session_status ?? "";
2301
- return s2 !== "" ? s2 : "—";
2305
+ const displayAmount = (r) => {
2306
+ const code = (r.currency_code ?? "USD").toUpperCase();
2307
+ return `${code} ${Number(r.amount)}`;
2302
2308
  };
2303
- const displayAmount = (t) => {
2304
- const code = (t.currency_code ?? "USD").toUpperCase();
2305
- return `${code} ${Number(t.amount)}`;
2309
+ const displayStatus = (r) => {
2310
+ const s2 = r.payment_status ?? "";
2311
+ return s2 !== "" ? s2 : "—";
2306
2312
  };
2307
2313
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-7xl flex-col gap-6 p-6", children: [
2308
2314
  /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
2309
2315
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
2310
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Payments" }),
2311
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "All payment attempts — completed, pending, failed, requires action" })
2316
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Refunds" }),
2317
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Refund records — amount, order, payment status" })
2312
2318
  ] }),
2313
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadTransactions(0, true), children: "Refresh" })
2319
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadRefunds(0, true), children: "Refresh" })
2314
2320
  ] }),
2315
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
2321
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
2316
2322
  /* @__PURE__ */ jsxRuntime.jsx(
2317
2323
  ui.Input,
2318
2324
  {
2319
- placeholder: "Search by Order ID",
2325
+ placeholder: "Order ID",
2320
2326
  value: orderIdSearch,
2321
2327
  onChange: (e) => setOrderIdSearch(e.target.value),
2322
- className: "md:max-w-sm",
2323
- "aria-label": "Search by order ID"
2328
+ className: "md:max-w-[180px]",
2329
+ "aria-label": "Filter by order ID"
2324
2330
  }
2325
2331
  ),
2326
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxRuntime.jsxs(
2332
+ /* @__PURE__ */ jsxRuntime.jsx(
2333
+ ui.Input,
2334
+ {
2335
+ placeholder: "Provider",
2336
+ value: providerSearch,
2337
+ onChange: (e) => setProviderSearch(e.target.value),
2338
+ className: "md:max-w-[140px]",
2339
+ "aria-label": "Filter by provider"
2340
+ }
2341
+ ),
2342
+ /* @__PURE__ */ jsxRuntime.jsx(
2343
+ ui.Input,
2344
+ {
2345
+ placeholder: "Currency",
2346
+ value: currencySearch,
2347
+ onChange: (e) => setCurrencySearch(e.target.value),
2348
+ className: "md:max-w-[100px]",
2349
+ "aria-label": "Filter by currency"
2350
+ }
2351
+ ),
2352
+ /* @__PURE__ */ jsxRuntime.jsxs(
2327
2353
  "select",
2328
2354
  {
2329
- value: statusFilter,
2330
- onChange: (e) => setStatusFilter(e.target.value),
2331
- className: "h-9 rounded-md border border-ui-border-base bg-transparent px-3 text-sm text-ui-fg-base outline-none transition focus:ring-2 focus:ring-ui-fg-interactive md:max-w-xs",
2332
- "aria-label": "Filter by status",
2355
+ value: paymentStatusFilter,
2356
+ onChange: (e) => setPaymentStatusFilter(e.target.value),
2357
+ className: "h-9 rounded-md border border-ui-border-base bg-transparent px-3 text-sm text-ui-fg-base outline-none transition focus:ring-2 focus:ring-ui-fg-interactive md:max-w-[160px]",
2358
+ "aria-label": "Filter by payment status",
2333
2359
  children: [
2334
2360
  /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All statuses" }),
2335
2361
  /* @__PURE__ */ jsxRuntime.jsx("option", { value: "pending", children: "Pending" }),
@@ -2340,52 +2366,103 @@ const PaymentsPage = () => {
2340
2366
  /* @__PURE__ */ jsxRuntime.jsx("option", { value: "captured", children: "Captured" })
2341
2367
  ]
2342
2368
  }
2343
- ) })
2344
- ] }),
2369
+ ),
2370
+ /* @__PURE__ */ jsxRuntime.jsx(
2371
+ ui.Input,
2372
+ {
2373
+ type: "date",
2374
+ placeholder: "From",
2375
+ value: dateFrom,
2376
+ onChange: (e) => setDateFrom(e.target.value),
2377
+ className: "md:max-w-[140px]",
2378
+ "aria-label": "Date from"
2379
+ }
2380
+ ),
2381
+ /* @__PURE__ */ jsxRuntime.jsx(
2382
+ ui.Input,
2383
+ {
2384
+ type: "date",
2385
+ placeholder: "To",
2386
+ value: dateTo,
2387
+ onChange: (e) => setDateTo(e.target.value),
2388
+ className: "md:max-w-[140px]",
2389
+ "aria-label": "Date to"
2390
+ }
2391
+ ),
2392
+ /* @__PURE__ */ jsxRuntime.jsx(
2393
+ ui.Input,
2394
+ {
2395
+ placeholder: "Amount min",
2396
+ value: amountMin,
2397
+ onChange: (e) => setAmountMin(e.target.value),
2398
+ type: "number",
2399
+ min: 0,
2400
+ className: "md:max-w-[100px]",
2401
+ "aria-label": "Refund amount minimum"
2402
+ }
2403
+ ),
2404
+ /* @__PURE__ */ jsxRuntime.jsx(
2405
+ ui.Input,
2406
+ {
2407
+ placeholder: "Amount max",
2408
+ value: amountMax,
2409
+ onChange: (e) => setAmountMax(e.target.value),
2410
+ type: "number",
2411
+ min: 0,
2412
+ className: "md:max-w-[100px]",
2413
+ "aria-label": "Refund amount maximum"
2414
+ }
2415
+ )
2416
+ ] }) }),
2345
2417
  error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
2346
2418
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
2347
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => loadTransactions(0, true), children: "Try again" }) })
2419
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => loadRefunds(0, true), children: "Try again" }) })
2348
2420
  ] }) : null,
2349
- isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading payments…" }) }) : items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
2350
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No payment transactions yet" }),
2351
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Payment attempts will appear here." })
2352
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
2421
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading refunds…" }) }) : items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
2422
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No refunds yet" }),
2423
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Refund records will appear here." })
2424
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full overflow-x-auto rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full table-fixed divide-y divide-ui-border-base", style: { minWidth: 0 }, children: [
2353
2425
  /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2354
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
2355
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Amount" }),
2356
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Provider" }),
2357
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
2358
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Finalized" }),
2359
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
2360
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
2426
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Refund ID" }),
2427
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
2428
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Payment ID" }),
2429
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[8%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Amount" }),
2430
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[6%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Currency" }),
2431
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[10%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Provider" }),
2432
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[10%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Payment Status" }),
2433
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[14%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Note" }),
2434
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
2435
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[8%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
2361
2436
  ] }) }),
2362
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((t) => /* @__PURE__ */ jsxRuntime.jsxs(
2437
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((r) => /* @__PURE__ */ jsxRuntime.jsxs(
2363
2438
  "tr",
2364
2439
  {
2365
- className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
2366
- onClick: () => navigate(`/payments/${t.payment_session_id}`),
2440
+ className: "cursor-pointer hover:bg-ui-bg-subtle/60",
2441
+ onClick: () => navigate(`/refunds/${r.refund_id}`),
2367
2442
  children: [
2368
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: t.order_id ?? "—" }),
2369
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: displayAmount(t) }),
2370
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: t.provider_id }),
2371
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
2443
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 font-mono text-sm text-ui-fg-base", title: r.refund_id, children: r.refund_id }),
2444
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 font-medium text-ui-fg-base", title: r.order_id ?? void 0, children: r.order_id ?? "—" }),
2445
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 font-mono text-sm text-ui-fg-subtle", title: r.payment_id, children: r.payment_id }),
2446
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle", children: displayAmount(r) }),
2447
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle uppercase", children: r.currency_code || "—" }),
2448
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle", title: r.provider_id || void 0, children: r.provider_id || "—" }),
2449
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 px-3 py-3", children: /* @__PURE__ */ jsxRuntime.jsx(
2372
2450
  ui.Badge,
2373
2451
  {
2374
2452
  size: "2xsmall",
2375
- className: `uppercase ${getStatusBadgeClass$7(displayStatus(t))}`,
2376
- children: displayStatus(t) !== "—" ? displayStatus(t).replace(/_/g, " ") : "—"
2453
+ className: `uppercase ${getStatusBadgeClass$7(displayStatus(r))}`,
2454
+ children: displayStatus(r) !== "—" ? displayStatus(r).replace(/_/g, " ") : "—"
2377
2455
  }
2378
2456
  ) }),
2379
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: t.payment_id != null ? "Yes" : "No" }),
2380
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(t.created_at).toLocaleDateString("en-US", {
2381
- year: "numeric",
2457
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle", title: r.note ?? void 0, children: r.note ?? "—" }),
2458
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle text-xs", children: new Date(r.created_at).toLocaleDateString("en-US", {
2382
2459
  month: "short",
2383
2460
  day: "numeric",
2384
2461
  hour: "numeric",
2385
2462
  minute: "2-digit",
2386
2463
  hour12: true
2387
2464
  }) }),
2388
- /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "px-4 py-4", children: [
2465
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 px-3 py-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-1", children: [
2389
2466
  /* @__PURE__ */ jsxRuntime.jsx(
2390
2467
  ui.Button,
2391
2468
  {
@@ -2393,27 +2470,27 @@ const PaymentsPage = () => {
2393
2470
  size: "small",
2394
2471
  onClick: (e) => {
2395
2472
  e.stopPropagation();
2396
- navigate(`/payments/${t.payment_session_id}`);
2473
+ navigate(`/refunds/${r.refund_id}`);
2397
2474
  },
2398
- children: "View details"
2475
+ children: "Details"
2399
2476
  }
2400
2477
  ),
2401
- t.order_id ? /* @__PURE__ */ jsxRuntime.jsx(
2478
+ r.order_id ? /* @__PURE__ */ jsxRuntime.jsx(
2402
2479
  ui.Button,
2403
2480
  {
2404
2481
  variant: "transparent",
2405
2482
  size: "small",
2406
2483
  onClick: (e) => {
2407
2484
  e.stopPropagation();
2408
- navigate(`/orders/${t.order_id}`);
2485
+ navigate(`/orders/${r.order_id}`);
2409
2486
  },
2410
2487
  children: "Order"
2411
2488
  }
2412
2489
  ) : null
2413
- ] })
2490
+ ] }) })
2414
2491
  ]
2415
2492
  },
2416
- t.payment_session_id
2493
+ r.refund_id
2417
2494
  )) })
2418
2495
  ] }) }),
2419
2496
  hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -2421,15 +2498,15 @@ const PaymentsPage = () => {
2421
2498
  {
2422
2499
  variant: "secondary",
2423
2500
  isLoading: isFetchingMore,
2424
- onClick: () => loadTransactions(offset, false),
2501
+ onClick: () => loadRefunds(offset, false),
2425
2502
  children: "Load more"
2426
2503
  }
2427
2504
  ) }) : null
2428
2505
  ] }) });
2429
2506
  };
2430
- const config$7 = adminSdk.defineRouteConfig({
2431
- label: "Payments",
2432
- icon: icons.CreditCard
2507
+ const config$8 = adminSdk.defineRouteConfig({
2508
+ label: "Refunds",
2509
+ icon: icons.Receipt
2433
2510
  });
2434
2511
  const useDebounce$2 = (value, delay) => {
2435
2512
  const [debouncedValue, setDebouncedValue] = react.useState(value);
@@ -2440,31 +2517,231 @@ const useDebounce$2 = (value, delay) => {
2440
2517
  return debouncedValue;
2441
2518
  };
2442
2519
  const getStatusBadgeClass$6 = (status) => {
2443
- const statusLower = status.toLowerCase();
2444
- if (statusLower === "requested") {
2445
- return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
2446
- }
2447
- if (statusLower === "received") {
2448
- return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
2449
- }
2450
- if (statusLower === "requires_action") {
2451
- return "bg-ui-tag-red-bg text-ui-tag-red-text";
2452
- }
2453
- if (statusLower === "completed") {
2454
- return "bg-ui-tag-green-bg text-ui-tag-green-text";
2455
- }
2456
- if (statusLower === "canceled") {
2457
- return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
2458
- }
2520
+ const s2 = status.toLowerCase();
2521
+ if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
2522
+ if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
2523
+ if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
2524
+ if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
2459
2525
  return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
2460
2526
  };
2461
- const ReturnsPage = () => {
2527
+ const PaymentsPage = () => {
2528
+ const navigate = reactRouterDom.useNavigate();
2529
+ const [items, setItems] = react.useState([]);
2530
+ const [statusFilter, setStatusFilter] = react.useState("all");
2531
+ const [orderIdSearch, setOrderIdSearch] = react.useState("");
2532
+ const debouncedOrderId = useDebounce$2(orderIdSearch, 300);
2533
+ const [isLoading, setIsLoading] = react.useState(true);
2534
+ const [isFetchingMore, setIsFetchingMore] = react.useState(false);
2535
+ const [error, setError] = react.useState(null);
2536
+ const [offset, setOffset] = react.useState(0);
2537
+ const [count, setCount] = react.useState(0);
2538
+ const limit = 50;
2539
+ const loadTransactions = react.useCallback(
2540
+ async (nextOffset, replace) => {
2541
+ try {
2542
+ if (replace) setIsLoading(true);
2543
+ else setIsFetchingMore(true);
2544
+ setError(null);
2545
+ const params = new URLSearchParams();
2546
+ params.set("limit", String(limit));
2547
+ params.set("offset", String(nextOffset));
2548
+ if (statusFilter !== "all") params.set("status", statusFilter);
2549
+ if (debouncedOrderId.trim()) params.set("order_id", debouncedOrderId.trim());
2550
+ const response = await fetch(
2551
+ `/admin/payment-transactions?${params.toString()}`,
2552
+ { credentials: "include" }
2553
+ );
2554
+ if (!response.ok) {
2555
+ const text = await response.text();
2556
+ throw new Error(text || "Failed to load payment transactions");
2557
+ }
2558
+ const payload = await response.json();
2559
+ const list = payload.transactions ?? [];
2560
+ setCount(payload.count ?? 0);
2561
+ setOffset(nextOffset + list.length);
2562
+ setItems((prev) => replace ? list : [...prev, ...list]);
2563
+ } catch (e) {
2564
+ setError(e instanceof Error ? e.message : "Failed to load");
2565
+ } finally {
2566
+ setIsLoading(false);
2567
+ setIsFetchingMore(false);
2568
+ }
2569
+ },
2570
+ [statusFilter, debouncedOrderId]
2571
+ );
2572
+ react.useEffect(() => {
2573
+ void loadTransactions(0, true);
2574
+ }, [loadTransactions]);
2575
+ const hasMore = react.useMemo(() => offset < count, [offset, count]);
2576
+ const displayStatus = (t) => {
2577
+ const s2 = t.payment_id != null && t.payment_status != null && t.payment_status !== "" ? t.payment_status : t.session_status ?? "";
2578
+ return s2 !== "" ? s2 : "—";
2579
+ };
2580
+ const displayAmount = (t) => {
2581
+ const code = (t.currency_code ?? "USD").toUpperCase();
2582
+ return `${code} ${Number(t.amount)}`;
2583
+ };
2584
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-7xl flex-col gap-6 p-6", children: [
2585
+ /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
2586
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
2587
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Payments" }),
2588
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "All payment attempts — completed, pending, failed, requires action" })
2589
+ ] }),
2590
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadTransactions(0, true), children: "Refresh" })
2591
+ ] }),
2592
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
2593
+ /* @__PURE__ */ jsxRuntime.jsx(
2594
+ ui.Input,
2595
+ {
2596
+ placeholder: "Search by Order ID",
2597
+ value: orderIdSearch,
2598
+ onChange: (e) => setOrderIdSearch(e.target.value),
2599
+ className: "md:max-w-sm",
2600
+ "aria-label": "Search by order ID"
2601
+ }
2602
+ ),
2603
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxRuntime.jsxs(
2604
+ "select",
2605
+ {
2606
+ value: statusFilter,
2607
+ onChange: (e) => setStatusFilter(e.target.value),
2608
+ className: "h-9 rounded-md border border-ui-border-base bg-transparent px-3 text-sm text-ui-fg-base outline-none transition focus:ring-2 focus:ring-ui-fg-interactive md:max-w-xs",
2609
+ "aria-label": "Filter by status",
2610
+ children: [
2611
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All statuses" }),
2612
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "pending", children: "Pending" }),
2613
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "requires_more", children: "Requires more" }),
2614
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "error", children: "Error" }),
2615
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "canceled", children: "Canceled" }),
2616
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "authorized", children: "Authorized" }),
2617
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "captured", children: "Captured" })
2618
+ ]
2619
+ }
2620
+ ) })
2621
+ ] }),
2622
+ error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
2623
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
2624
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => loadTransactions(0, true), children: "Try again" }) })
2625
+ ] }) : null,
2626
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading payments…" }) }) : items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
2627
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No payment transactions yet" }),
2628
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Payment attempts will appear here." })
2629
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
2630
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2631
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
2632
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Amount" }),
2633
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Provider" }),
2634
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
2635
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Finalized" }),
2636
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
2637
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
2638
+ ] }) }),
2639
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((t) => /* @__PURE__ */ jsxRuntime.jsxs(
2640
+ "tr",
2641
+ {
2642
+ className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
2643
+ onClick: () => navigate(`/payments/${t.payment_session_id}`),
2644
+ children: [
2645
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: t.order_id ?? "—" }),
2646
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: displayAmount(t) }),
2647
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: t.provider_id }),
2648
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
2649
+ ui.Badge,
2650
+ {
2651
+ size: "2xsmall",
2652
+ className: `uppercase ${getStatusBadgeClass$6(displayStatus(t))}`,
2653
+ children: displayStatus(t) !== "—" ? displayStatus(t).replace(/_/g, " ") : "—"
2654
+ }
2655
+ ) }),
2656
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: t.payment_id != null ? "Yes" : "No" }),
2657
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(t.created_at).toLocaleDateString("en-US", {
2658
+ year: "numeric",
2659
+ month: "short",
2660
+ day: "numeric",
2661
+ hour: "numeric",
2662
+ minute: "2-digit",
2663
+ hour12: true
2664
+ }) }),
2665
+ /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "px-4 py-4", children: [
2666
+ /* @__PURE__ */ jsxRuntime.jsx(
2667
+ ui.Button,
2668
+ {
2669
+ variant: "transparent",
2670
+ size: "small",
2671
+ onClick: (e) => {
2672
+ e.stopPropagation();
2673
+ navigate(`/payments/${t.payment_session_id}`);
2674
+ },
2675
+ children: "View details"
2676
+ }
2677
+ ),
2678
+ t.order_id ? /* @__PURE__ */ jsxRuntime.jsx(
2679
+ ui.Button,
2680
+ {
2681
+ variant: "transparent",
2682
+ size: "small",
2683
+ onClick: (e) => {
2684
+ e.stopPropagation();
2685
+ navigate(`/orders/${t.order_id}`);
2686
+ },
2687
+ children: "Order"
2688
+ }
2689
+ ) : null
2690
+ ] })
2691
+ ]
2692
+ },
2693
+ t.payment_session_id
2694
+ )) })
2695
+ ] }) }),
2696
+ hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
2697
+ ui.Button,
2698
+ {
2699
+ variant: "secondary",
2700
+ isLoading: isFetchingMore,
2701
+ onClick: () => loadTransactions(offset, false),
2702
+ children: "Load more"
2703
+ }
2704
+ ) }) : null
2705
+ ] }) });
2706
+ };
2707
+ const config$7 = adminSdk.defineRouteConfig({
2708
+ label: "Payments",
2709
+ icon: icons.CreditCard
2710
+ });
2711
+ const useDebounce$1 = (value, delay) => {
2712
+ const [debouncedValue, setDebouncedValue] = react.useState(value);
2713
+ react.useEffect(() => {
2714
+ const handler = setTimeout(() => setDebouncedValue(value), delay);
2715
+ return () => clearTimeout(handler);
2716
+ }, [value, delay]);
2717
+ return debouncedValue;
2718
+ };
2719
+ const getStatusBadgeClass$5 = (status) => {
2720
+ const statusLower = status.toLowerCase();
2721
+ if (statusLower === "requested") {
2722
+ return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
2723
+ }
2724
+ if (statusLower === "received") {
2725
+ return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
2726
+ }
2727
+ if (statusLower === "requires_action") {
2728
+ return "bg-ui-tag-red-bg text-ui-tag-red-text";
2729
+ }
2730
+ if (statusLower === "completed") {
2731
+ return "bg-ui-tag-green-bg text-ui-tag-green-text";
2732
+ }
2733
+ if (statusLower === "canceled") {
2734
+ return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
2735
+ }
2736
+ return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
2737
+ };
2738
+ const ReturnsPage = () => {
2462
2739
  const navigate = reactRouterDom.useNavigate();
2463
2740
  const [items, setItems] = react.useState([]);
2464
2741
  const [statusFilter, setStatusFilter] = react.useState("all");
2465
2742
  const [createdByFilter, setCreatedByFilter] = react.useState("all");
2466
2743
  const [searchQuery, setSearchQuery] = react.useState("");
2467
- const debouncedSearchQuery = useDebounce$2(searchQuery, 300);
2744
+ const debouncedSearchQuery = useDebounce$1(searchQuery, 300);
2468
2745
  const [isLoading, setIsLoading] = react.useState(true);
2469
2746
  const [isFetchingMore, setIsFetchingMore] = react.useState(false);
2470
2747
  const [error, setError] = react.useState(null);
@@ -2473,7 +2750,6 @@ const ReturnsPage = () => {
2473
2750
  const limit = 50;
2474
2751
  const loadReturns = react.useCallback(
2475
2752
  async (nextOffset, replace = false) => {
2476
- var _a;
2477
2753
  try {
2478
2754
  if (replace) {
2479
2755
  setIsLoading(true);
@@ -2504,7 +2780,7 @@ const ReturnsPage = () => {
2504
2780
  }
2505
2781
  const payload = await response.json();
2506
2782
  setCount(payload.count ?? 0);
2507
- setOffset(nextOffset + (((_a = payload.returns) == null ? void 0 : _a.length) ?? 0));
2783
+ setOffset(nextOffset + (payload.returns?.length ?? 0));
2508
2784
  setItems(
2509
2785
  (prev) => replace ? payload.returns ?? [] : [...prev, ...payload.returns ?? []]
2510
2786
  );
@@ -2610,13 +2886,13 @@ const ReturnsPage = () => {
2610
2886
  ui.Badge,
2611
2887
  {
2612
2888
  size: "2xsmall",
2613
- className: `uppercase ${getStatusBadgeClass$6(returnOrder.status)}`,
2889
+ className: `uppercase ${getStatusBadgeClass$5(returnOrder.status)}`,
2614
2890
  children: returnOrder.status.replace(/_/g, " ")
2615
2891
  }
2616
2892
  ) }),
2617
2893
  /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
2618
2894
  const calc = returnOrder.refund;
2619
- if ((calc == null ? void 0 : calc.is_processed) && calc.final_refund_amount != null) {
2895
+ if (calc?.is_processed && calc.final_refund_amount != null) {
2620
2896
  return formatRefundCurrency(
2621
2897
  calc.final_refund_amount,
2622
2898
  calc.currency_code || returnOrder.currency_code
@@ -2673,1276 +2949,1169 @@ const config$6 = adminSdk.defineRouteConfig({
2673
2949
  label: "Return Orders",
2674
2950
  icon: icons.ArrowPath
2675
2951
  });
2676
- const MASKED_VALUE = "••••••••••••";
2677
- const SENSITIVE_KEY_PATTERNS = [
2678
- /password|passwd|passphrase/i,
2679
- /secret/i,
2680
- /token/i,
2681
- /api_?key$/i,
2682
- /private_?key/i,
2683
- /access_?key/i,
2684
- /(^|_)hash(ed)?($|_)/i,
2685
- /(^|_)salt$/i,
2686
- /^cvv$|^cvc$|security_code/i,
2687
- /card_?number/i,
2688
- /account_?number/i,
2689
- /credential/i,
2690
- /authorization/i,
2691
- /recovery_?code/i,
2692
- /(^|_)otp($|_)/i,
2693
- /verification_?code/i,
2694
- /^code_hash$/i,
2695
- /webhook_?signature/i
2696
- ];
2697
- const TABLE_SENSITIVE_KEYS = {
2698
- otp_verification: /* @__PURE__ */ new Set(["code", "value"]),
2699
- auth_verification: /* @__PURE__ */ new Set(["code", "value"]),
2700
- auth_mfa_factor: /* @__PURE__ */ new Set(["value", "config"])
2952
+ const useDebounce = (value, delay) => {
2953
+ const [debouncedValue, setDebouncedValue] = react.useState(value);
2954
+ react.useEffect(() => {
2955
+ const handler = setTimeout(() => setDebouncedValue(value), delay);
2956
+ return () => clearTimeout(handler);
2957
+ }, [value, delay]);
2958
+ return debouncedValue;
2701
2959
  };
2702
- const SAFE_KEYS = /* @__PURE__ */ new Set([
2703
- "token_type",
2704
- "redacted",
2705
- "api_key_id",
2706
- "token_id",
2707
- "notification_token_id"
2708
- ]);
2709
- function isSensitiveKey(key) {
2710
- const normalized = key.trim().toLowerCase();
2711
- if (SAFE_KEYS.has(normalized)) return false;
2712
- return SENSITIVE_KEY_PATTERNS.some((pattern) => pattern.test(normalized));
2713
- }
2714
- const FULLY_SECRET_TABLES = /* @__PURE__ */ new Set(["auth_mfa_recovery_code", "auth_password_reset_token"]);
2715
- const ALWAYS_VISIBLE_KEYS = /* @__PURE__ */ new Set(["id", "created_at", "updated_at", "deleted_at", "expires_at", "used_at"]);
2716
- function maskValue(value, ctx, depth) {
2717
- var _a;
2718
- if (Array.isArray(value)) return value.map((item) => maskValue(item, ctx, depth + 1));
2719
- if (value !== null && typeof value === "object") {
2720
- const out = {};
2721
- for (const [key, inner] of Object.entries(value)) {
2722
- const topLevel = depth === 0;
2723
- const secret = inner !== null && inner !== void 0 && inner !== "" && (isSensitiveKey(key) || topLevel && ((_a = ctx.tableKeys) == null ? void 0 : _a.has(key.toLowerCase())) === true || topLevel && ctx.maskAll && !ALWAYS_VISIBLE_KEYS.has(key) && !key.endsWith("_id"));
2724
- if (secret) {
2725
- ctx.count += 1;
2726
- out[key] = MASKED_VALUE;
2727
- } else {
2728
- out[key] = maskValue(inner, ctx, depth + 1);
2729
- }
2730
- }
2731
- return out;
2960
+ const getStatusBadgeClass$4 = (status) => {
2961
+ const statusLower = status.toLowerCase();
2962
+ if (statusLower === "requested") {
2963
+ return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
2732
2964
  }
2733
- return value;
2734
- }
2735
- function maskSensitiveData(data, tableName) {
2736
- const ctx = {
2737
- count: 0,
2738
- maskAll: tableName ? FULLY_SECRET_TABLES.has(tableName) : false,
2739
- tableKeys: tableName ? TABLE_SENSITIVE_KEYS[tableName] : void 0
2740
- };
2741
- const value = maskValue(data, ctx, 0);
2742
- return { value, maskedCount: ctx.count };
2743
- }
2744
- const AUTO_EXPAND_DEPTH = 1;
2745
- const LONG_STRING = 200;
2746
- const JsonViewer = ({ data }) => {
2747
- const [generation, setGeneration] = react.useState(0);
2748
- const [expandAll, setExpandAll] = react.useState(null);
2749
- const setAll = (value) => {
2750
- setExpandAll(value);
2751
- setGeneration((g) => g + 1);
2752
- };
2753
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
2754
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
2755
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => setAll(true), children: "Expand all" }),
2756
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => setAll(false), children: "Collapse all" })
2757
- ] }),
2758
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-h-[560px] overflow-auto rounded-lg border border-ui-border-base bg-ui-bg-subtle p-3 font-mono text-xs leading-5", children: /* @__PURE__ */ jsxRuntime.jsx(JsonNode, { value: data, depth: 0, forceExpand: expandAll }, generation) })
2759
- ] });
2760
- };
2761
- const JsonNode = ({ name, value, depth, forceExpand }) => {
2762
- const isContainer = value !== null && typeof value === "object";
2763
- const [open, setOpen] = react.useState(forceExpand ?? depth < AUTO_EXPAND_DEPTH);
2764
- const label = name !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-ui-fg-subtle", children: [
2765
- name,
2766
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-fg-muted", children: ": " })
2767
- ] }) : null;
2768
- if (!isContainer) {
2769
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 items-start", style: { paddingLeft: depth ? 16 : 0 }, children: [
2770
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-4 shrink-0" }),
2771
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0 break-words [overflow-wrap:anywhere]", children: [
2772
- label,
2773
- /* @__PURE__ */ jsxRuntime.jsx(Primitive, { value })
2774
- ] })
2775
- ] });
2965
+ if (statusLower === "approved") {
2966
+ return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
2776
2967
  }
2777
- const entries = Array.isArray(value) ? value.map((v, i) => [String(i), v]) : Object.entries(value);
2778
- const [openBracket, closeBracket] = Array.isArray(value) ? ["[", "]"] : ["{", "}"];
2779
- const summary = Array.isArray(value) ? `${entries.length} items` : `${entries.length} keys`;
2780
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { paddingLeft: depth ? 16 : 0 }, children: [
2781
- /* @__PURE__ */ jsxRuntime.jsxs(
2782
- "button",
2783
- {
2784
- type: "button",
2785
- onClick: () => setOpen((o) => !o),
2786
- className: "flex items-start text-left hover:bg-ui-bg-base-hover",
2787
- "aria-expanded": open,
2788
- children: [
2789
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex w-4 shrink-0 items-center pt-0.5 text-ui-fg-muted", children: entries.length ? open ? /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronDownMini, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronRightMini, {}) : null }),
2790
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
2791
- label,
2792
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-fg-muted", children: openBracket }),
2793
- !open || entries.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2794
- entries.length ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-1 italic text-ui-fg-muted", children: summary }) : null,
2795
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-fg-muted", children: closeBracket })
2796
- ] }) : null
2797
- ] })
2798
- ]
2799
- }
2800
- ),
2801
- open && entries.length ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2802
- entries.map(([key, child]) => /* @__PURE__ */ jsxRuntime.jsx(JsonNode, { name: key, value: child, depth: depth + 1, forceExpand }, key)),
2803
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { paddingLeft: 16 }, className: "text-ui-fg-muted", children: closeBracket })
2804
- ] }) : null
2805
- ] });
2806
- };
2807
- const Primitive = ({ value }) => {
2808
- const [showFull, setShowFull] = react.useState(false);
2809
- if (value === MASKED_VALUE) {
2810
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded bg-ui-tag-orange-bg px-1 text-ui-tag-orange-text", title: "Hidden for security", children: MASKED_VALUE });
2968
+ if (statusLower === "rejected") {
2969
+ return "bg-ui-tag-red-bg text-ui-tag-red-text";
2811
2970
  }
2812
- if (value === null || value === void 0) return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-fg-muted", children: "null" });
2813
- if (typeof value === "boolean") return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-tag-purple-text", children: String(value) });
2814
- if (typeof value === "number") return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-tag-blue-text", children: value });
2815
- const text = String(value);
2816
- const truncated = !showFull && text.length > LONG_STRING;
2817
- return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: ui.clx("text-ui-tag-green-text"), children: [
2818
- '"',
2819
- truncated ? `${text.slice(0, LONG_STRING)}…` : text,
2820
- '"',
2821
- text.length > LONG_STRING ? /* @__PURE__ */ jsxRuntime.jsx(
2822
- "button",
2823
- {
2824
- type: "button",
2825
- onClick: () => setShowFull((s2) => !s2),
2826
- className: "ml-1 font-sans text-ui-fg-interactive hover:underline",
2827
- children: showFull ? "show less" : `show all (${text.length} chars)`
2828
- }
2829
- ) : null
2830
- ] });
2831
- };
2832
- const GUIDANCE = {
2833
- orders: {
2834
- headline: "Order data affects customers, payments and reports.",
2835
- recreate: "Orders can’t be recreated identically from the admin. If this deletion was not intended, ask a developer to restore it from a database backup using the snapshot on this page.",
2836
- adminSection: { label: "Go to Orders", path: "/orders" }
2837
- },
2838
- carts: {
2839
- headline: "Carts are usually cleaned up automatically.",
2840
- recreate: "No action is normally needed. Customers can simply add items to a new cart."
2841
- },
2842
- customers: {
2843
- headline: "Customer data may be needed for orders, support and compliance.",
2844
- recreate: "If it was deleted by mistake, recreate it from Customers using the values shown above. A recreated customer gets a new ID and must reset their password.",
2845
- adminSection: { label: "Go to Customers", path: "/customers" }
2846
- },
2847
- catalog: {
2848
- headline: "Catalog changes affect what customers can see and buy.",
2849
- recreate: "If it was deleted by mistake, recreate it from Products using the values shown above. It will get a new ID.",
2850
- adminSection: { label: "Go to Products", path: "/products" }
2851
- },
2852
- pricing: {
2853
- headline: "Pricing and promotions affect what customers pay.",
2854
- recreate: "If it was deleted by mistake, recreate it from Promotions or Price Lists using the values shown above.",
2855
- adminSection: { label: "Go to Promotions", path: "/promotions" }
2856
- },
2857
- payments: {
2858
- headline: "Payment records are financial data.",
2859
- recreate: "Do not recreate payment records by hand—this can make balances inconsistent. If this deletion was not expected, escalate to a developer or your finance team."
2860
- },
2861
- fulfillment: {
2862
- headline: "Shipping and fulfillment settings affect checkout and delivery.",
2863
- recreate: "If it was deleted by mistake, recreate it from Settings → Locations & Shipping using the values shown above.",
2864
- adminSection: { label: "Go to Settings", path: "/settings" }
2865
- },
2866
- inventory: {
2867
- headline: "Inventory changes can affect stock levels and availability.",
2868
- recreate: "If it was deleted by mistake, recreate it from Inventory using the values shown above and re-check stock quantities.",
2869
- adminSection: { label: "Go to Inventory", path: "/inventory" }
2870
- },
2871
- wallet: {
2872
- headline: "Wallet and credit records are financial data.",
2873
- recreate: "Do not recreate balances by hand. If this deletion was not expected, escalate to a developer or your finance team so balances can be verified."
2874
- },
2875
- access: {
2876
- headline: "Access records control who can sign in.",
2877
- recreate: "Secrets such as passwords and keys can’t be restored. Re-invite the user or create a new API key if access is still needed.",
2878
- adminSection: { label: "Go to Settings", path: "/settings" }
2879
- },
2880
- store: {
2881
- headline: "Store settings affect regions, currencies and taxes.",
2882
- recreate: "If it was deleted by mistake, recreate it from Settings using the values shown above.",
2883
- adminSection: { label: "Go to Settings", path: "/settings" }
2884
- },
2885
- engagement: {
2886
- headline: "Customer-generated content.",
2887
- recreate: "These usually can’t be recreated on the customer’s behalf. Keep the snapshot on this page if you need a record of it."
2888
- },
2889
- notifications: {
2890
- headline: "Notification records are usually cleaned up automatically.",
2891
- recreate: "No action is normally needed."
2892
- },
2893
- system: {
2894
- headline: "Internal system data, usually removed automatically by the platform.",
2895
- recreate: "No action is normally needed. If you suspect a problem, share this page with a developer."
2971
+ if (statusLower === "completed") {
2972
+ return "bg-ui-tag-green-bg text-ui-tag-green-text";
2896
2973
  }
2974
+ if (statusLower === "cancelled") {
2975
+ return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
2976
+ }
2977
+ return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
2897
2978
  };
2898
- function getNextSteps(category) {
2899
- return GUIDANCE[category];
2900
- }
2901
- const RELATED_LINKS = [
2902
- { key: "order_id", label: "Order", path: (id) => `/orders/${id}`, selfTables: ["order"] },
2903
- { key: "customer_id", label: "Customer", path: (id) => `/customers/${id}`, selfTables: ["customer"] },
2904
- { key: "product_id", label: "Product", path: (id) => `/products/${id}`, selfTables: ["product"] }
2905
- ];
2906
- function getRelatedLinks(tableName, oldData) {
2907
- if (!oldData) return [];
2908
- return RELATED_LINKS.flatMap((link) => {
2909
- const id = oldData[link.key];
2910
- if (link.selfTables.includes(tableName) || typeof id !== "string" || !id.trim()) return [];
2911
- return [{ label: link.label, id, path: link.path(id) }];
2912
- });
2913
- }
2914
- const fullName = (row) => {
2915
- const parts = [row.first_name, row.last_name].filter(
2916
- (part) => typeof part === "string" && part.trim() !== ""
2917
- );
2918
- return parts.length ? parts.join(" ") : void 0;
2919
- };
2920
- const addressLine = (row) => {
2921
- const parts = [row.address_1, row.address_2, row.city, row.province, row.postal_code, row.country_code].filter((part) => typeof part === "string" && part.trim() !== "").map((part) => part.trim());
2922
- return parts.length ? parts.join(", ") : void 0;
2923
- };
2924
- const NAME = { key: "name", label: "Name", derive: fullName };
2925
- const ADDRESS = { key: "address", label: "Address", derive: addressLine };
2926
- const CREATED = { key: "created_at", label: "Created", kind: "date" };
2927
- const ENTITY_FIELDS = {
2928
- order: [
2929
- { key: "display_id", label: "Order number" },
2930
- { key: "status", label: "Status", kind: "status" },
2931
- { key: "email", label: "Customer email" },
2932
- { key: "customer_id", label: "Customer ID", kind: "id" },
2933
- { key: "currency_code", label: "Currency" },
2934
- { key: "region_id", label: "Region ID", kind: "id" },
2935
- { key: "sales_channel_id", label: "Sales channel ID", kind: "id" },
2936
- { key: "canceled_at", label: "Canceled", kind: "date" },
2937
- CREATED
2938
- ],
2939
- order_line_item: [
2940
- { key: "title", label: "Item" },
2941
- { key: "variant_title", label: "Variant" },
2942
- { key: "variant_sku", label: "SKU" },
2943
- { key: "unit_price", label: "Unit price", kind: "money" },
2944
- { key: "product_id", label: "Product ID", kind: "id" },
2945
- { key: "variant_id", label: "Variant ID", kind: "id" },
2946
- CREATED
2947
- ],
2948
- cart_line_item: [
2949
- { key: "title", label: "Item" },
2950
- { key: "variant_sku", label: "SKU" },
2951
- { key: "quantity", label: "Quantity", kind: "number" },
2952
- { key: "unit_price", label: "Unit price", kind: "money" },
2953
- { key: "cart_id", label: "Cart ID", kind: "id" },
2954
- { key: "variant_id", label: "Variant ID", kind: "id" },
2955
- CREATED
2956
- ],
2957
- cart: [
2958
- { key: "email", label: "Email" },
2959
- { key: "customer_id", label: "Customer ID", kind: "id" },
2960
- { key: "currency_code", label: "Currency" },
2961
- { key: "region_id", label: "Region ID", kind: "id" },
2962
- { key: "completed_at", label: "Completed", kind: "date" },
2963
- CREATED
2964
- ],
2965
- customer: [
2966
- NAME,
2967
- { key: "email", label: "Email" },
2968
- { key: "phone", label: "Phone" },
2969
- { key: "company_name", label: "Company" },
2970
- { key: "has_account", label: "Registered account", kind: "boolean" },
2971
- CREATED
2972
- ],
2973
- customer_address: [
2974
- { key: "address_name", label: "Label" },
2975
- NAME,
2976
- ADDRESS,
2977
- { key: "phone", label: "Phone" },
2978
- { key: "customer_id", label: "Customer ID", kind: "id" },
2979
- { key: "is_default_shipping", label: "Default shipping", kind: "boolean" },
2980
- CREATED
2981
- ],
2982
- order_address: [NAME, ADDRESS, { key: "phone", label: "Phone" }, CREATED],
2983
- cart_address: [NAME, ADDRESS, { key: "phone", label: "Phone" }, CREATED],
2984
- product: [
2985
- { key: "title", label: "Title" },
2986
- { key: "status", label: "Status", kind: "status" },
2987
- { key: "handle", label: "Handle" },
2988
- { key: "subtitle", label: "Subtitle" },
2989
- { key: "collection_id", label: "Collection ID", kind: "id" },
2990
- { key: "is_giftcard", label: "Gift card", kind: "boolean" },
2991
- CREATED
2992
- ],
2993
- product_variant: [
2994
- { key: "title", label: "Title" },
2995
- { key: "sku", label: "SKU" },
2996
- { key: "barcode", label: "Barcode" },
2997
- { key: "product_id", label: "Product ID", kind: "id" },
2998
- { key: "manage_inventory", label: "Manages inventory", kind: "boolean" },
2999
- CREATED
3000
- ],
3001
- product_category: [
3002
- { key: "name", label: "Name" },
3003
- { key: "handle", label: "Handle" },
3004
- { key: "is_active", label: "Active", kind: "boolean" },
3005
- { key: "parent_category_id", label: "Parent category ID", kind: "id" },
3006
- CREATED
3007
- ],
3008
- product_collection: [{ key: "title", label: "Title" }, { key: "handle", label: "Handle" }, CREATED],
3009
- payment: [
3010
- { key: "amount", label: "Amount", kind: "money" },
3011
- { key: "currency_code", label: "Currency" },
3012
- { key: "provider_id", label: "Provider" },
3013
- { key: "captured_at", label: "Captured", kind: "date" },
3014
- { key: "canceled_at", label: "Canceled", kind: "date" },
3015
- { key: "payment_collection_id", label: "Payment collection ID", kind: "id" },
3016
- CREATED
3017
- ],
3018
- payment_session: [
3019
- { key: "amount", label: "Amount", kind: "money" },
3020
- { key: "currency_code", label: "Currency" },
3021
- { key: "provider_id", label: "Provider" },
3022
- { key: "status", label: "Status", kind: "status" },
3023
- { key: "payment_collection_id", label: "Payment collection ID", kind: "id" },
3024
- CREATED
3025
- ],
3026
- payment_collection: [
3027
- { key: "amount", label: "Amount", kind: "money" },
3028
- { key: "currency_code", label: "Currency" },
3029
- { key: "status", label: "Status", kind: "status" },
3030
- CREATED
3031
- ],
3032
- refund: [
3033
- { key: "amount", label: "Amount", kind: "money" },
3034
- { key: "payment_id", label: "Payment ID", kind: "id" },
3035
- { key: "refund_reason_id", label: "Refund reason ID", kind: "id" },
3036
- { key: "note", label: "Note" },
3037
- { key: "created_by", label: "Created by" },
3038
- CREATED
3039
- ],
3040
- return: [
3041
- { key: "display_id", label: "Return number" },
3042
- { key: "status", label: "Status", kind: "status" },
3043
- { key: "order_id", label: "Order ID", kind: "id" },
3044
- { key: "refund_amount", label: "Refund amount", kind: "money" },
3045
- { key: "received_at", label: "Received", kind: "date" },
3046
- CREATED
3047
- ],
3048
- payment_detail: [
3049
- { key: "type", label: "Method type" },
3050
- { key: "customer_id", label: "Customer ID", kind: "id" },
3051
- { key: "is_default", label: "Default method", kind: "boolean" },
3052
- CREATED
3053
- ],
3054
- user: [NAME, { key: "email", label: "Email" }, CREATED],
3055
- invite: [
3056
- { key: "email", label: "Email" },
3057
- { key: "accepted", label: "Accepted", kind: "boolean" },
3058
- { key: "expires_at", label: "Expires", kind: "date" },
3059
- CREATED
3060
- ],
3061
- api_key: [
3062
- { key: "title", label: "Title" },
3063
- { key: "type", label: "Type" },
3064
- { key: "redacted", label: "Key (redacted)" },
3065
- { key: "revoked_at", label: "Revoked", kind: "date" },
3066
- CREATED
3067
- ],
3068
- promotion: [
3069
- { key: "code", label: "Promotion code" },
3070
- { key: "type", label: "Type" },
3071
- { key: "status", label: "Status", kind: "status" },
3072
- { key: "is_automatic", label: "Automatic", kind: "boolean" },
3073
- CREATED
3074
- ],
3075
- fulfillment: [
3076
- { key: "provider_id", label: "Provider" },
3077
- { key: "location_id", label: "Location ID", kind: "id" },
3078
- { key: "shipped_at", label: "Shipped", kind: "date" },
3079
- { key: "delivered_at", label: "Delivered", kind: "date" },
3080
- { key: "canceled_at", label: "Canceled", kind: "date" },
3081
- CREATED
3082
- ],
3083
- inventory_item: [
3084
- { key: "sku", label: "SKU" },
3085
- { key: "title", label: "Title" },
3086
- { key: "requires_shipping", label: "Requires shipping", kind: "boolean" },
3087
- CREATED
3088
- ],
3089
- inventory_level: [
3090
- { key: "inventory_item_id", label: "Inventory item ID", kind: "id" },
3091
- { key: "location_id", label: "Location ID", kind: "id" },
3092
- { key: "stocked_quantity", label: "Stocked", kind: "number" },
3093
- { key: "reserved_quantity", label: "Reserved", kind: "number" },
3094
- CREATED
3095
- ],
3096
- review: [
3097
- { key: "title", label: "Title" },
3098
- { key: "rating", label: "Rating", kind: "number" },
3099
- { key: "status", label: "Status", kind: "status" },
3100
- { key: "product_id", label: "Product ID", kind: "id" },
3101
- { key: "customer_id", label: "Customer ID", kind: "id" },
3102
- CREATED
3103
- ]
2979
+ const SwapsPage = () => {
2980
+ const navigate = reactRouterDom.useNavigate();
2981
+ const [items, setItems] = react.useState([]);
2982
+ const [statusFilter, setStatusFilter] = react.useState("all");
2983
+ const [createdByFilter, setCreatedByFilter] = react.useState("all");
2984
+ const [searchQuery, setSearchQuery] = react.useState("");
2985
+ const debouncedSearchQuery = useDebounce(searchQuery, 300);
2986
+ const [isLoading, setIsLoading] = react.useState(true);
2987
+ const [isFetchingMore, setIsFetchingMore] = react.useState(false);
2988
+ const [error, setError] = react.useState(null);
2989
+ const [offset, setOffset] = react.useState(0);
2990
+ const [count, setCount] = react.useState(0);
2991
+ const limit = 50;
2992
+ const loadSwaps = react.useCallback(
2993
+ async (nextOffset, replace = false) => {
2994
+ try {
2995
+ if (replace) {
2996
+ setIsLoading(true);
2997
+ } else {
2998
+ setIsFetchingMore(true);
2999
+ }
3000
+ setError(null);
3001
+ const params = new URLSearchParams();
3002
+ params.set("limit", String(limit));
3003
+ params.set("offset", String(nextOffset));
3004
+ if (statusFilter !== "all") {
3005
+ params.set("status", statusFilter);
3006
+ }
3007
+ if (debouncedSearchQuery.trim()) {
3008
+ params.set("order_id", debouncedSearchQuery.trim());
3009
+ }
3010
+ if (createdByFilter !== "all") {
3011
+ params.set("created_by", createdByFilter);
3012
+ }
3013
+ const response = await fetch(
3014
+ `/admin/swaps?${params.toString()}`,
3015
+ { credentials: "include" }
3016
+ );
3017
+ if (!response.ok) {
3018
+ const message = await response.text();
3019
+ throw new Error(message || "Unable to load swaps");
3020
+ }
3021
+ const payload = await response.json();
3022
+ setCount(payload.count ?? 0);
3023
+ setOffset(nextOffset + (payload.swaps?.length ?? 0));
3024
+ setItems(
3025
+ (prev) => replace ? payload.swaps ?? [] : [...prev, ...payload.swaps ?? []]
3026
+ );
3027
+ } catch (loadError) {
3028
+ const message = loadError instanceof Error ? loadError.message : "Unable to load swaps";
3029
+ setError(message);
3030
+ } finally {
3031
+ setIsLoading(false);
3032
+ setIsFetchingMore(false);
3033
+ }
3034
+ },
3035
+ [statusFilter, createdByFilter, debouncedSearchQuery]
3036
+ );
3037
+ react.useEffect(() => {
3038
+ void loadSwaps(0, true);
3039
+ }, [statusFilter, createdByFilter, debouncedSearchQuery, loadSwaps]);
3040
+ const hasMore = react.useMemo(() => offset < count, [offset, count]);
3041
+ const availableStatuses = react.useMemo(() => {
3042
+ const statuses = /* @__PURE__ */ new Set();
3043
+ items.forEach((item) => statuses.add(item.status));
3044
+ return Array.from(statuses).sort();
3045
+ }, [items]);
3046
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-7xl flex-col gap-6 p-6", children: [
3047
+ /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
3048
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
3049
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Exchanges" }),
3050
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer exchange requests" })
3051
+ ] }),
3052
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadSwaps(0, true), children: "Refresh" })
3053
+ ] }),
3054
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
3055
+ /* @__PURE__ */ jsxRuntime.jsx(
3056
+ ui.Input,
3057
+ {
3058
+ placeholder: "Search by swap ID or order ID",
3059
+ value: searchQuery,
3060
+ onChange: (event) => setSearchQuery(event.target.value),
3061
+ className: "md:max-w-sm"
3062
+ }
3063
+ ),
3064
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
3065
+ /* @__PURE__ */ jsxRuntime.jsxs(
3066
+ "select",
3067
+ {
3068
+ value: createdByFilter,
3069
+ onChange: (event) => setCreatedByFilter(event.target.value),
3070
+ className: "h-9 rounded-md border border-ui-border-base bg-transparent px-3 text-sm text-ui-fg-base outline-none transition focus:ring-2 focus:ring-ui-fg-interactive md:max-w-xs",
3071
+ children: [
3072
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All (Created by)" }),
3073
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "customer", children: "Customer" }),
3074
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "admin", children: "Admin" })
3075
+ ]
3076
+ }
3077
+ ),
3078
+ /* @__PURE__ */ jsxRuntime.jsxs(
3079
+ "select",
3080
+ {
3081
+ value: statusFilter,
3082
+ onChange: (event) => setStatusFilter(event.target.value),
3083
+ className: "h-9 rounded-md border border-ui-border-base bg-transparent px-3 text-sm text-ui-fg-base outline-none transition focus:ring-2 focus:ring-ui-fg-interactive md:max-w-xs",
3084
+ children: [
3085
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All Statuses" }),
3086
+ availableStatuses.map((status) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
3087
+ ]
3088
+ }
3089
+ )
3090
+ ] })
3091
+ ] }),
3092
+ error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
3093
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
3094
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
3095
+ ui.Button,
3096
+ {
3097
+ variant: "secondary",
3098
+ onClick: () => loadSwaps(0, true),
3099
+ children: "Try again"
3100
+ }
3101
+ ) })
3102
+ ] }) : null,
3103
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading swaps..." }) }) : items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
3104
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No exchanges yet" }),
3105
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Exchange requests created by customers will appear here." })
3106
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
3107
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
3108
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Exchange ID" }),
3109
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
3110
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
3111
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Difference Due" }),
3112
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
3113
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
3114
+ ] }) }),
3115
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((swap) => /* @__PURE__ */ jsxRuntime.jsxs(
3116
+ "tr",
3117
+ {
3118
+ className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
3119
+ onClick: () => navigate(`/swaps/${swap.id}`),
3120
+ children: [
3121
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-0.5", children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: swap.id }) }) }),
3122
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: swap.order_id }),
3123
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
3124
+ ui.Badge,
3125
+ {
3126
+ size: "2xsmall",
3127
+ className: `uppercase ${getStatusBadgeClass$4(swap.status)}`,
3128
+ children: swap.status.replace(/_/g, " ")
3129
+ }
3130
+ ) }),
3131
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
3132
+ const amount = swap.difference_due;
3133
+ if (amount == null || amount === void 0) {
3134
+ return "—";
3135
+ }
3136
+ const displayAmount = Number(amount) / 100;
3137
+ const currency = swap.currency_code || "$";
3138
+ const sign = displayAmount >= 0 ? "+" : "";
3139
+ return `${sign}${currency}${displayAmount.toFixed(2)}`;
3140
+ })() }),
3141
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(swap.created_at).toLocaleDateString("en-US", {
3142
+ year: "numeric",
3143
+ month: "short",
3144
+ day: "numeric",
3145
+ hour: "numeric",
3146
+ minute: "2-digit",
3147
+ hour12: true
3148
+ }) }),
3149
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
3150
+ ui.Button,
3151
+ {
3152
+ variant: "transparent",
3153
+ size: "small",
3154
+ onClick: (e) => {
3155
+ e.stopPropagation();
3156
+ navigate(`/app/orders/${swap.order_id}`);
3157
+ },
3158
+ children: "Go to order"
3159
+ }
3160
+ ) })
3161
+ ]
3162
+ },
3163
+ swap.id
3164
+ )) })
3165
+ ] }) }),
3166
+ hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
3167
+ ui.Button,
3168
+ {
3169
+ variant: "secondary",
3170
+ isLoading: isFetchingMore,
3171
+ onClick: () => loadSwaps(offset, false),
3172
+ children: "Load more"
3173
+ }
3174
+ ) }) : null
3175
+ ] }) });
3104
3176
  };
3105
- const GENERIC_FIELDS = [
3106
- { key: "display_id", label: "Number" },
3107
- { key: "title", label: "Title" },
3108
- { key: "name", label: "Name" },
3109
- NAME,
3110
- { key: "email", label: "Email" },
3111
- { key: "phone", label: "Phone" },
3112
- { key: "handle", label: "Handle" },
3113
- { key: "sku", label: "SKU" },
3114
- { key: "code", label: "Code" },
3115
- { key: "status", label: "Status", kind: "status" },
3116
- { key: "type", label: "Type" },
3117
- { key: "amount", label: "Amount", kind: "money" },
3118
- { key: "quantity", label: "Quantity", kind: "number" },
3119
- { key: "currency_code", label: "Currency" },
3120
- { key: "order_id", label: "Order ID", kind: "id" },
3121
- { key: "customer_id", label: "Customer ID", kind: "id" },
3122
- { key: "product_id", label: "Product ID", kind: "id" },
3123
- { key: "payment_id", label: "Payment ID", kind: "id" },
3124
- { key: "provider_id", label: "Provider" },
3125
- CREATED,
3126
- { key: "updated_at", label: "Last updated", kind: "date" }
3177
+ const config$5 = adminSdk.defineRouteConfig({
3178
+ label: "Exchanges",
3179
+ icon: icons.ArrowPath
3180
+ });
3181
+ const MASKED_VALUE = "••••••••••••";
3182
+ const SENSITIVE_KEY_PATTERNS = [
3183
+ /password|passwd|passphrase/i,
3184
+ /secret/i,
3185
+ /token/i,
3186
+ /api_?key$/i,
3187
+ /private_?key/i,
3188
+ /access_?key/i,
3189
+ /(^|_)hash(ed)?($|_)/i,
3190
+ /(^|_)salt$/i,
3191
+ /^cvv$|^cvc$|security_code/i,
3192
+ /card_?number/i,
3193
+ /account_?number/i,
3194
+ /credential/i,
3195
+ /authorization/i,
3196
+ /recovery_?code/i,
3197
+ /(^|_)otp($|_)/i,
3198
+ /verification_?code/i,
3199
+ /^code_hash$/i,
3200
+ /webhook_?signature/i
3127
3201
  ];
3128
- const MAX_GENERIC_FIELDS = 8;
3129
- function amountOf(value) {
3130
- if (typeof value === "number" && Number.isFinite(value)) return value;
3131
- if (typeof value === "string" && value.trim() !== "" && Number.isFinite(Number(value))) return Number(value);
3132
- if (value !== null && typeof value === "object" && "value" in value) {
3133
- return amountOf(value.value);
3134
- }
3135
- return null;
3202
+ const TABLE_SENSITIVE_KEYS = {
3203
+ otp_verification: /* @__PURE__ */ new Set(["code", "value"]),
3204
+ auth_verification: /* @__PURE__ */ new Set(["code", "value"]),
3205
+ auth_mfa_factor: /* @__PURE__ */ new Set(["value", "config"])
3206
+ };
3207
+ const SAFE_KEYS = /* @__PURE__ */ new Set([
3208
+ "token_type",
3209
+ "redacted",
3210
+ "api_key_id",
3211
+ "token_id",
3212
+ "notification_token_id"
3213
+ ]);
3214
+ function isSensitiveKey(key) {
3215
+ const normalized = key.trim().toLowerCase();
3216
+ if (SAFE_KEYS.has(normalized)) return false;
3217
+ return SENSITIVE_KEY_PATTERNS.some((pattern) => pattern.test(normalized));
3136
3218
  }
3137
- function formatValue(raw, kind, row) {
3138
- if (raw === null || raw === void 0 || raw === "") return null;
3139
- if (raw === MASKED_VALUE) return { value: MASKED_VALUE, kind: "masked" };
3140
- switch (kind) {
3141
- case "money": {
3142
- const amount = amountOf(raw);
3143
- if (amount === null) return null;
3144
- const currency = typeof row.currency_code === "string" ? row.currency_code : null;
3145
- return { value: formatMoney(amount, currency), kind };
3146
- }
3147
- case "date":
3148
- return typeof raw === "string" || raw instanceof Date ? { value: formatDate(raw), kind } : null;
3149
- case "boolean":
3150
- return { value: raw === true || raw === "true" ? "Yes" : "No", kind };
3151
- case "number": {
3152
- const n = amountOf(raw);
3153
- return n === null ? null : { value: formatNumber(n), kind };
3219
+ const FULLY_SECRET_TABLES = /* @__PURE__ */ new Set(["auth_mfa_recovery_code", "auth_password_reset_token"]);
3220
+ const ALWAYS_VISIBLE_KEYS = /* @__PURE__ */ new Set(["id", "created_at", "updated_at", "deleted_at", "expires_at", "used_at"]);
3221
+ function maskValue(value, ctx, depth) {
3222
+ if (Array.isArray(value)) return value.map((item) => maskValue(item, ctx, depth + 1));
3223
+ if (value !== null && typeof value === "object") {
3224
+ const out = {};
3225
+ for (const [key, inner] of Object.entries(value)) {
3226
+ const topLevel = depth === 0;
3227
+ const secret = inner !== null && inner !== void 0 && inner !== "" && (isSensitiveKey(key) || topLevel && ctx.tableKeys?.has(key.toLowerCase()) === true || topLevel && ctx.maskAll && !ALWAYS_VISIBLE_KEYS.has(key) && !key.endsWith("_id"));
3228
+ if (secret) {
3229
+ ctx.count += 1;
3230
+ out[key] = MASKED_VALUE;
3231
+ } else {
3232
+ out[key] = maskValue(inner, ctx, depth + 1);
3233
+ }
3154
3234
  }
3155
- case "status":
3156
- return { value: String(raw).replace(/_/g, " "), kind };
3157
- default:
3158
- if (typeof raw === "object") return null;
3159
- if (typeof raw === "string" && raw.length > 160) return { value: `${raw.slice(0, 157)}…`, kind };
3160
- return { value: String(raw), kind };
3161
- }
3162
- }
3163
- function summarizeOldData(tableName, oldData) {
3164
- if (!oldData) return [];
3165
- const { value: row } = maskSensitiveData(oldData, tableName);
3166
- const specific = ENTITY_FIELDS[tableName];
3167
- const specs = specific ?? GENERIC_FIELDS;
3168
- const fields = [];
3169
- const seenLabels = /* @__PURE__ */ new Set();
3170
- for (const spec of specs) {
3171
- const raw = spec.derive ? spec.derive(row) : row[spec.key];
3172
- const formatted = formatValue(raw, spec.kind ?? "text", row);
3173
- if (!formatted || seenLabels.has(spec.label)) continue;
3174
- seenLabels.add(spec.label);
3175
- const value = spec.key === "currency_code" ? formatted.value.toUpperCase() : formatted.value;
3176
- fields.push({ key: spec.key, label: spec.label, value, kind: formatted.kind });
3177
- if (!specific && fields.length >= MAX_GENERIC_FIELDS) break;
3178
- }
3179
- return fields;
3180
- }
3181
- function readLastListSearch() {
3182
- try {
3183
- return window.sessionStorage.getItem(LAST_LIST_URL_KEY) ?? "";
3184
- } catch {
3185
- return "";
3235
+ return out;
3186
3236
  }
3237
+ return value;
3187
3238
  }
3188
- const DeletedRecordDetailPage = () => {
3189
- var _a;
3190
- const navigate = reactRouterDom.useNavigate();
3191
- const location = reactRouterDom.useLocation();
3192
- const { id = "" } = reactRouterDom.useParams();
3193
- const [state, setState] = react.useState({ status: "loading" });
3194
- const [reloadToken, setReloadToken] = react.useState(0);
3195
- const cameFromList = ((_a = location.state) == null ? void 0 : _a.fromList) === true;
3196
- const goBack = () => {
3197
- if (cameFromList) navigate(-1);
3198
- else navigate(`/deleted-records-audit${readLastListSearch()}`);
3239
+ function maskSensitiveData(data, tableName) {
3240
+ const ctx = {
3241
+ count: 0,
3242
+ maskAll: tableName ? FULLY_SECRET_TABLES.has(tableName) : false,
3243
+ tableKeys: tableName ? TABLE_SENSITIVE_KEYS[tableName] : void 0
3199
3244
  };
3200
- react.useEffect(() => {
3201
- const controller = new AbortController();
3202
- setState({ status: "loading" });
3203
- fetchAuditDetail(id, controller.signal).then((audit) => setState({ status: "ready", audit })).catch((e) => {
3204
- if (controller.signal.aborted) return;
3205
- setState({
3206
- status: "error",
3207
- message: e instanceof Error ? e.message : "Unknown error",
3208
- notFound: e instanceof AuditApiError && e.status === 404
3209
- });
3210
- });
3211
- return () => controller.abort();
3212
- }, [id, reloadToken]);
3213
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-3 md:p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-4 md:p-6", children: [
3214
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: "transparent", size: "small", onClick: goBack, className: "-ml-2", children: [
3215
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, {}),
3216
- "Back to Deleted Records"
3217
- ] }) }),
3218
- state.status === "loading" ? /* @__PURE__ */ jsxRuntime.jsx(DetailSkeleton, {}) : state.status === "error" ? /* @__PURE__ */ jsxRuntime.jsx(
3219
- DetailError,
3220
- {
3221
- notFound: state.notFound,
3222
- message: state.message,
3223
- onRetry: () => setReloadToken((t) => t + 1),
3224
- onBack: goBack
3225
- }
3226
- ) : /* @__PURE__ */ jsxRuntime.jsx(DetailContent, { audit: state.audit })
3227
- ] }) });
3228
- };
3229
- const DetailContent = ({ audit }) => {
3230
- const navigate = reactRouterDom.useNavigate();
3231
- const entity = getEntityInfo(audit.table_name);
3232
- const source = describeSource(audit.source);
3233
- const summary = react.useMemo(() => summarizeOldData(audit.table_name, audit.old_data), [audit]);
3234
- const masked = react.useMemo(() => maskSensitiveData(audit.old_data, audit.table_name), [audit]);
3235
- const guidance = getNextSteps(entity.category.id);
3236
- const related = getRelatedLinks(audit.table_name, audit.old_data);
3237
- const [showRaw, setShowRaw] = react.useState(false);
3238
- const copyJson = async () => {
3239
- try {
3240
- await navigator.clipboard.writeText(JSON.stringify(masked.value, null, 2));
3241
- ui.toast.success("Record data copied", {
3242
- description: masked.maskedCount ? "Sensitive values were left hidden." : void 0
3243
- });
3244
- } catch {
3245
- ui.toast.error("Couldn’t copy to clipboard");
3246
- }
3245
+ const value = maskValue(data, ctx, 0);
3246
+ return { value, maskedCount: ctx.count };
3247
+ }
3248
+ const AUTO_EXPAND_DEPTH = 1;
3249
+ const LONG_STRING = 200;
3250
+ const JsonViewer = ({ data }) => {
3251
+ const [generation, setGeneration] = react.useState(0);
3252
+ const [expandAll, setExpandAll] = react.useState(null);
3253
+ const setAll = (value) => {
3254
+ setExpandAll(value);
3255
+ setGeneration((g) => g + 1);
3247
3256
  };
3248
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3249
- /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
3250
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
3251
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { size: "small", color: "red", children: [
3252
- /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, {}),
3253
- "Deleted"
3254
- ] }),
3255
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: entity.category.label })
3256
- ] }),
3257
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Heading, { level: "h1", children: [
3258
- "Deleted ",
3259
- entity.label
3260
- ] }),
3261
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
3262
- /* @__PURE__ */ jsxRuntime.jsx(CopyableId, { value: audit.record_id, emptyLabel: "This record type has no ID column", className: "text-sm" }),
3263
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: [
3264
- "Database table: ",
3265
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono", children: audit.table_name })
3266
- ] })
3267
- ] })
3257
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
3258
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
3259
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => setAll(true), children: "Expand all" }),
3260
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => setAll(false), children: "Collapse all" })
3268
3261
  ] }),
3269
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3 rounded-lg border border-ui-tag-orange-border bg-ui-tag-orange-bg px-4 py-3", children: [
3270
- /* @__PURE__ */ jsxRuntime.jsx(icons.InformationCircle, { className: "mt-0.5 shrink-0 text-ui-tag-orange-icon" }),
3271
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-tag-orange-text", children: [
3272
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "This is a historical snapshot" }),
3273
- " captured immediately before deletion. The record no longer exists in the database, so changes elsewhere in the admin are not reflected here."
3262
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-h-[560px] overflow-auto rounded-lg border border-ui-border-base bg-ui-bg-subtle p-3 font-mono text-xs leading-5", children: /* @__PURE__ */ jsxRuntime.jsx(JsonNode, { value: data, depth: 0, forceExpand: expandAll }, generation) })
3263
+ ] });
3264
+ };
3265
+ const JsonNode = ({ name, value, depth, forceExpand }) => {
3266
+ const isContainer = value !== null && typeof value === "object";
3267
+ const [open, setOpen] = react.useState(forceExpand ?? depth < AUTO_EXPAND_DEPTH);
3268
+ const label = name !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-ui-fg-subtle", children: [
3269
+ name,
3270
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-fg-muted", children: ": " })
3271
+ ] }) : null;
3272
+ if (!isContainer) {
3273
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 items-start", style: { paddingLeft: depth ? 16 : 0 }, children: [
3274
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-4 shrink-0" }),
3275
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0 break-words [overflow-wrap:anywhere]", children: [
3276
+ label,
3277
+ /* @__PURE__ */ jsxRuntime.jsx(Primitive, { value })
3274
3278
  ] })
3275
- ] }),
3276
- /* @__PURE__ */ jsxRuntime.jsx(Section, { title: "Deletion information", children: /* @__PURE__ */ jsxRuntime.jsxs("dl", { className: "grid grid-cols-1 gap-x-6 gap-y-4 sm:grid-cols-2", children: [
3277
- /* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Deleted", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
3278
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: formatExactDateTime(audit.occurred_at) }),
3279
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1 text-xs text-ui-fg-muted", children: [
3280
- /* @__PURE__ */ jsxRuntime.jsx(icons.ClockSolid, { className: "size-3" }),
3281
- formatRelativeTime(audit.occurred_at)
3282
- ] })
3283
- ] }) }),
3284
- /* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Deleted by", children: audit.deleted_by ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "break-all text-sm text-ui-fg-base", children: audit.deleted_by }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-muted", children: "Not recorded" }) }),
3285
- /* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Source", children: source.kind === "unknown" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-muted", children: "Unknown" }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { size: "small", color: sourceBadgeColor(source.kind), children: source.label }) }),
3286
- /* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Action", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Permanently deleted" }) })
3287
- ] }) }),
3288
- /* @__PURE__ */ jsxRuntime.jsx(
3289
- Section,
3279
+ ] });
3280
+ }
3281
+ const entries = Array.isArray(value) ? value.map((v, i) => [String(i), v]) : Object.entries(value);
3282
+ const [openBracket, closeBracket] = Array.isArray(value) ? ["[", "]"] : ["{", "}"];
3283
+ const summary = Array.isArray(value) ? `${entries.length} items` : `${entries.length} keys`;
3284
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { paddingLeft: depth ? 16 : 0 }, children: [
3285
+ /* @__PURE__ */ jsxRuntime.jsxs(
3286
+ "button",
3290
3287
  {
3291
- title: "Record summary",
3292
- description: `Key details of this ${entity.label.toLowerCase()} at the moment it was deleted.`,
3293
- children: summary.length ? /* @__PURE__ */ jsxRuntime.jsx("dl", { className: "grid grid-cols-1 gap-x-6 gap-y-4 sm:grid-cols-2", children: summary.map((field) => /* @__PURE__ */ jsxRuntime.jsx(Field, { label: field.label, children: field.kind === "id" ? /* @__PURE__ */ jsxRuntime.jsx(CopyableId, { value: field.value }) : field.kind === "status" ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { size: "2xsmall", color: "grey", className: "capitalize", children: field.value }) : field.kind === "masked" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-muted", children: "Hidden for security" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "break-words text-sm text-ui-fg-base", children: field.value }) }, field.label)) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No key details could be extracted for this record type. See the original record data below." })
3288
+ type: "button",
3289
+ onClick: () => setOpen((o) => !o),
3290
+ className: "flex items-start text-left hover:bg-ui-bg-base-hover",
3291
+ "aria-expanded": open,
3292
+ children: [
3293
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex w-4 shrink-0 items-center pt-0.5 text-ui-fg-muted", children: entries.length ? open ? /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronDownMini, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronRightMini, {}) : null }),
3294
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
3295
+ label,
3296
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-fg-muted", children: openBracket }),
3297
+ !open || entries.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3298
+ entries.length ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-1 italic text-ui-fg-muted", children: summary }) : null,
3299
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-fg-muted", children: closeBracket })
3300
+ ] }) : null
3301
+ ] })
3302
+ ]
3294
3303
  }
3295
3304
  ),
3296
- /* @__PURE__ */ jsxRuntime.jsx(
3297
- Section,
3305
+ open && entries.length ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3306
+ entries.map(([key, child]) => /* @__PURE__ */ jsxRuntime.jsx(JsonNode, { name: key, value: child, depth: depth + 1, forceExpand }, key)),
3307
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { paddingLeft: 16 }, className: "text-ui-fg-muted", children: closeBracket })
3308
+ ] }) : null
3309
+ ] });
3310
+ };
3311
+ const Primitive = ({ value }) => {
3312
+ const [showFull, setShowFull] = react.useState(false);
3313
+ if (value === MASKED_VALUE) {
3314
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded bg-ui-tag-orange-bg px-1 text-ui-tag-orange-text", title: "Hidden for security", children: MASKED_VALUE });
3315
+ }
3316
+ if (value === null || value === void 0) return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-fg-muted", children: "null" });
3317
+ if (typeof value === "boolean") return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-tag-purple-text", children: String(value) });
3318
+ if (typeof value === "number") return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-tag-blue-text", children: value });
3319
+ const text = String(value);
3320
+ const truncated = !showFull && text.length > LONG_STRING;
3321
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: ui.clx("text-ui-tag-green-text"), children: [
3322
+ '"',
3323
+ truncated ? `${text.slice(0, LONG_STRING)}…` : text,
3324
+ '"',
3325
+ text.length > LONG_STRING ? /* @__PURE__ */ jsxRuntime.jsx(
3326
+ "button",
3298
3327
  {
3299
- title: "Original record data",
3300
- description: "The complete data captured before deletion.",
3301
- actions: showRaw && audit.old_data ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: "secondary", size: "small", onClick: copyJson, children: [
3302
- /* @__PURE__ */ jsxRuntime.jsx(icons.SquareTwoStack, {}),
3303
- "Copy JSON"
3304
- ] }) : null,
3305
- children: audit.old_data ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
3306
- masked.maskedCount > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
3307
- /* @__PURE__ */ jsxRuntime.jsx(icons.ShieldCheck, { className: "shrink-0 text-ui-fg-muted" }),
3308
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
3309
- masked.maskedCount,
3310
- " sensitive ",
3311
- masked.maskedCount === 1 ? "value is" : "values are",
3312
- " hidden for security (passwords, tokens, card or account numbers)."
3313
- ] })
3314
- ] }) : null,
3315
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: "secondary", size: "small", onClick: () => setShowRaw((s2) => !s2), "aria-expanded": showRaw, children: [
3316
- showRaw ? /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronDownMini, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronRightMini, {}),
3317
- showRaw ? "Hide full record" : "View full record"
3318
- ] }) }),
3319
- showRaw ? /* @__PURE__ */ jsxRuntime.jsx(JsonViewer, { data: masked.value }) : null
3320
- ] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No data was captured for this deletion." })
3328
+ type: "button",
3329
+ onClick: () => setShowFull((s2) => !s2),
3330
+ className: "ml-1 font-sans text-ui-fg-interactive hover:underline",
3331
+ children: showFull ? "show less" : `show all (${text.length} chars)`
3321
3332
  }
3322
- ),
3323
- /* @__PURE__ */ jsxRuntime.jsx(Section, { title: "What you can do now", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
3324
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-base", children: [
3325
- "This record was permanently deleted. ",
3326
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Automatic restoration is not available" }),
3327
- " ",
3328
- "from this screen."
3329
- ] }),
3330
- /* @__PURE__ */ jsxRuntime.jsxs("ol", { className: "flex list-decimal flex-col gap-3 pl-5 text-sm text-ui-fg-subtle marker:text-ui-fg-muted", children: [
3331
- /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
3332
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-ui-fg-base", children: "Check whether this was expected." }),
3333
- " ",
3334
- audit.deleted_by || source.kind !== "unknown" ? "Confirm with the person or system shown above." : `Who deleted it wasn’t recorded—check with your team or integrations active around ${formatExactDateTime(audit.occurred_at)}.`,
3335
- " ",
3336
- guidance.headline
3337
- ] }),
3338
- /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
3339
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-ui-fg-base", children: "If it needs to come back:" }),
3340
- " ",
3341
- guidance.recreate
3342
- ] }),
3343
- /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
3344
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-ui-fg-base", children: "Need the details?" }),
3345
- " Use “View full record” above to see or copy everything that was stored. Sensitive values stay hidden."
3346
- ] })
3347
- ] }),
3348
- guidance.adminSection || related.length ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
3349
- guidance.adminSection ? /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", size: "small", onClick: () => navigate(guidance.adminSection.path), children: guidance.adminSection.label }) : null,
3350
- related.map((link) => /* @__PURE__ */ jsxRuntime.jsxs(
3351
- ui.Button,
3352
- {
3353
- variant: "transparent",
3354
- size: "small",
3355
- onClick: () => navigate(link.path),
3356
- title: `Opens ${link.label.toLowerCase()} ${link.id} if it still exists`,
3357
- children: [
3358
- "Open related ",
3359
- link.label.toLowerCase(),
3360
- /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronRightMini, {})
3361
- ]
3362
- },
3363
- link.path
3364
- ))
3365
- ] }) : null,
3366
- related.length ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: "Related records open only if they haven’t been deleted too." }) : null
3367
- ] }) })
3333
+ ) : null
3368
3334
  ] });
3369
3335
  };
3370
- const Section = ({
3371
- title,
3372
- description,
3373
- actions,
3374
- children
3375
- }) => /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "flex flex-col gap-4 rounded-lg border border-ui-border-base p-5", children: [
3376
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-start justify-between gap-2", children: [
3377
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [
3378
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: title }),
3379
- description ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: description }) : null
3380
- ] }),
3381
- actions
3382
- ] }),
3383
- children
3384
- ] });
3385
- const Field = ({ label, children }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-col gap-1", children: [
3386
- /* @__PURE__ */ jsxRuntime.jsx("dt", { className: "text-xs font-medium uppercase tracking-wide text-ui-fg-muted", children: label }),
3387
- /* @__PURE__ */ jsxRuntime.jsx("dd", { className: "min-w-0", children })
3388
- ] });
3389
- const DetailSkeleton = () => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", "aria-busy": "true", children: [
3390
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
3391
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-5 w-24 rounded-full" }),
3392
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-8 w-64" }),
3393
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-4 w-48" })
3394
- ] }),
3395
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-14 w-full" }),
3396
- Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4 rounded-lg border border-ui-border-base p-5", children: [
3397
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-5 w-40" }),
3398
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: Array.from({ length: 4 }).map((__, j) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
3399
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-3 w-20" }),
3400
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-4 w-36" })
3401
- ] }, j)) })
3402
- ] }, i))
3403
- ] });
3404
- const DetailError = ({
3405
- notFound,
3406
- message,
3407
- onRetry,
3408
- onBack
3409
- }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-2 rounded-lg border border-ui-border-base px-6 py-12 text-center", children: [
3410
- /* @__PURE__ */ jsxRuntime.jsx(icons.ExclamationCircle, { className: ui.clx(notFound ? "text-ui-fg-muted" : "text-ui-fg-error") }),
3411
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", children: notFound ? "Audit entry not found" : "Unable to load this deleted record" }),
3412
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "max-w-md text-ui-fg-subtle", children: notFound ? "This audit entry doesn’t exist. The link may be incorrect." : "We couldn’t retrieve the audit entry right now. Check your connection and try again." }),
3413
- !notFound ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "max-w-md font-mono text-ui-fg-muted", children: message }) : null,
3414
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 flex gap-2", children: [
3415
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", size: "small", onClick: onBack, children: "Back to Deleted Records" }),
3416
- !notFound ? /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", size: "small", onClick: onRetry, children: "Try again" }) : null
3417
- ] })
3418
- ] });
3419
- adminSdk.defineRouteConfig({});
3420
- const useDebounce$1 = (value, delay) => {
3421
- const [debouncedValue, setDebouncedValue] = react.useState(value);
3422
- react.useEffect(() => {
3423
- const handler = setTimeout(() => setDebouncedValue(value), delay);
3424
- return () => clearTimeout(handler);
3425
- }, [value, delay]);
3426
- return debouncedValue;
3427
- };
3428
- const getStatusBadgeClass$5 = (status) => {
3429
- const statusLower = status.toLowerCase();
3430
- if (statusLower === "requested") {
3431
- return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
3432
- }
3433
- if (statusLower === "approved") {
3434
- return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
3336
+ const GUIDANCE = {
3337
+ orders: {
3338
+ headline: "Order data affects customers, payments and reports.",
3339
+ recreate: "Orders can’t be recreated identically from the admin. If this deletion was not intended, ask a developer to restore it from a database backup using the snapshot on this page.",
3340
+ adminSection: { label: "Go to Orders", path: "/orders" }
3341
+ },
3342
+ carts: {
3343
+ headline: "Carts are usually cleaned up automatically.",
3344
+ recreate: "No action is normally needed. Customers can simply add items to a new cart."
3345
+ },
3346
+ customers: {
3347
+ headline: "Customer data may be needed for orders, support and compliance.",
3348
+ recreate: "If it was deleted by mistake, recreate it from Customers using the values shown above. A recreated customer gets a new ID and must reset their password.",
3349
+ adminSection: { label: "Go to Customers", path: "/customers" }
3350
+ },
3351
+ catalog: {
3352
+ headline: "Catalog changes affect what customers can see and buy.",
3353
+ recreate: "If it was deleted by mistake, recreate it from Products using the values shown above. It will get a new ID.",
3354
+ adminSection: { label: "Go to Products", path: "/products" }
3355
+ },
3356
+ pricing: {
3357
+ headline: "Pricing and promotions affect what customers pay.",
3358
+ recreate: "If it was deleted by mistake, recreate it from Promotions or Price Lists using the values shown above.",
3359
+ adminSection: { label: "Go to Promotions", path: "/promotions" }
3360
+ },
3361
+ payments: {
3362
+ headline: "Payment records are financial data.",
3363
+ recreate: "Do not recreate payment records by hand—this can make balances inconsistent. If this deletion was not expected, escalate to a developer or your finance team."
3364
+ },
3365
+ fulfillment: {
3366
+ headline: "Shipping and fulfillment settings affect checkout and delivery.",
3367
+ recreate: "If it was deleted by mistake, recreate it from Settings → Locations & Shipping using the values shown above.",
3368
+ adminSection: { label: "Go to Settings", path: "/settings" }
3369
+ },
3370
+ inventory: {
3371
+ headline: "Inventory changes can affect stock levels and availability.",
3372
+ recreate: "If it was deleted by mistake, recreate it from Inventory using the values shown above and re-check stock quantities.",
3373
+ adminSection: { label: "Go to Inventory", path: "/inventory" }
3374
+ },
3375
+ wallet: {
3376
+ headline: "Wallet and credit records are financial data.",
3377
+ recreate: "Do not recreate balances by hand. If this deletion was not expected, escalate to a developer or your finance team so balances can be verified."
3378
+ },
3379
+ access: {
3380
+ headline: "Access records control who can sign in.",
3381
+ recreate: "Secrets such as passwords and keys can’t be restored. Re-invite the user or create a new API key if access is still needed.",
3382
+ adminSection: { label: "Go to Settings", path: "/settings" }
3383
+ },
3384
+ store: {
3385
+ headline: "Store settings affect regions, currencies and taxes.",
3386
+ recreate: "If it was deleted by mistake, recreate it from Settings using the values shown above.",
3387
+ adminSection: { label: "Go to Settings", path: "/settings" }
3388
+ },
3389
+ engagement: {
3390
+ headline: "Customer-generated content.",
3391
+ recreate: "These usually can’t be recreated on the customer’s behalf. Keep the snapshot on this page if you need a record of it."
3392
+ },
3393
+ notifications: {
3394
+ headline: "Notification records are usually cleaned up automatically.",
3395
+ recreate: "No action is normally needed."
3396
+ },
3397
+ system: {
3398
+ headline: "Internal system data, usually removed automatically by the platform.",
3399
+ recreate: "No action is normally needed. If you suspect a problem, share this page with a developer."
3435
3400
  }
3436
- if (statusLower === "rejected") {
3437
- return "bg-ui-tag-red-bg text-ui-tag-red-text";
3401
+ };
3402
+ function getNextSteps(category) {
3403
+ return GUIDANCE[category];
3404
+ }
3405
+ const RELATED_LINKS = [
3406
+ { key: "order_id", label: "Order", path: (id) => `/orders/${id}`, selfTables: ["order"] },
3407
+ { key: "customer_id", label: "Customer", path: (id) => `/customers/${id}`, selfTables: ["customer"] },
3408
+ { key: "product_id", label: "Product", path: (id) => `/products/${id}`, selfTables: ["product"] }
3409
+ ];
3410
+ function getRelatedLinks(tableName, oldData) {
3411
+ if (!oldData) return [];
3412
+ return RELATED_LINKS.flatMap((link) => {
3413
+ const id = oldData[link.key];
3414
+ if (link.selfTables.includes(tableName) || typeof id !== "string" || !id.trim()) return [];
3415
+ return [{ label: link.label, id, path: link.path(id) }];
3416
+ });
3417
+ }
3418
+ const fullName = (row) => {
3419
+ const parts = [row.first_name, row.last_name].filter(
3420
+ (part) => typeof part === "string" && part.trim() !== ""
3421
+ );
3422
+ return parts.length ? parts.join(" ") : void 0;
3423
+ };
3424
+ const addressLine = (row) => {
3425
+ const parts = [row.address_1, row.address_2, row.city, row.province, row.postal_code, row.country_code].filter((part) => typeof part === "string" && part.trim() !== "").map((part) => part.trim());
3426
+ return parts.length ? parts.join(", ") : void 0;
3427
+ };
3428
+ const NAME = { key: "name", label: "Name", derive: fullName };
3429
+ const ADDRESS = { key: "address", label: "Address", derive: addressLine };
3430
+ const CREATED = { key: "created_at", label: "Created", kind: "date" };
3431
+ const ENTITY_FIELDS = {
3432
+ order: [
3433
+ { key: "display_id", label: "Order number" },
3434
+ { key: "status", label: "Status", kind: "status" },
3435
+ { key: "email", label: "Customer email" },
3436
+ { key: "customer_id", label: "Customer ID", kind: "id" },
3437
+ { key: "currency_code", label: "Currency" },
3438
+ { key: "region_id", label: "Region ID", kind: "id" },
3439
+ { key: "sales_channel_id", label: "Sales channel ID", kind: "id" },
3440
+ { key: "canceled_at", label: "Canceled", kind: "date" },
3441
+ CREATED
3442
+ ],
3443
+ order_line_item: [
3444
+ { key: "title", label: "Item" },
3445
+ { key: "variant_title", label: "Variant" },
3446
+ { key: "variant_sku", label: "SKU" },
3447
+ { key: "unit_price", label: "Unit price", kind: "money" },
3448
+ { key: "product_id", label: "Product ID", kind: "id" },
3449
+ { key: "variant_id", label: "Variant ID", kind: "id" },
3450
+ CREATED
3451
+ ],
3452
+ cart_line_item: [
3453
+ { key: "title", label: "Item" },
3454
+ { key: "variant_sku", label: "SKU" },
3455
+ { key: "quantity", label: "Quantity", kind: "number" },
3456
+ { key: "unit_price", label: "Unit price", kind: "money" },
3457
+ { key: "cart_id", label: "Cart ID", kind: "id" },
3458
+ { key: "variant_id", label: "Variant ID", kind: "id" },
3459
+ CREATED
3460
+ ],
3461
+ cart: [
3462
+ { key: "email", label: "Email" },
3463
+ { key: "customer_id", label: "Customer ID", kind: "id" },
3464
+ { key: "currency_code", label: "Currency" },
3465
+ { key: "region_id", label: "Region ID", kind: "id" },
3466
+ { key: "completed_at", label: "Completed", kind: "date" },
3467
+ CREATED
3468
+ ],
3469
+ customer: [
3470
+ NAME,
3471
+ { key: "email", label: "Email" },
3472
+ { key: "phone", label: "Phone" },
3473
+ { key: "company_name", label: "Company" },
3474
+ { key: "has_account", label: "Registered account", kind: "boolean" },
3475
+ CREATED
3476
+ ],
3477
+ customer_address: [
3478
+ { key: "address_name", label: "Label" },
3479
+ NAME,
3480
+ ADDRESS,
3481
+ { key: "phone", label: "Phone" },
3482
+ { key: "customer_id", label: "Customer ID", kind: "id" },
3483
+ { key: "is_default_shipping", label: "Default shipping", kind: "boolean" },
3484
+ CREATED
3485
+ ],
3486
+ order_address: [NAME, ADDRESS, { key: "phone", label: "Phone" }, CREATED],
3487
+ cart_address: [NAME, ADDRESS, { key: "phone", label: "Phone" }, CREATED],
3488
+ product: [
3489
+ { key: "title", label: "Title" },
3490
+ { key: "status", label: "Status", kind: "status" },
3491
+ { key: "handle", label: "Handle" },
3492
+ { key: "subtitle", label: "Subtitle" },
3493
+ { key: "collection_id", label: "Collection ID", kind: "id" },
3494
+ { key: "is_giftcard", label: "Gift card", kind: "boolean" },
3495
+ CREATED
3496
+ ],
3497
+ product_variant: [
3498
+ { key: "title", label: "Title" },
3499
+ { key: "sku", label: "SKU" },
3500
+ { key: "barcode", label: "Barcode" },
3501
+ { key: "product_id", label: "Product ID", kind: "id" },
3502
+ { key: "manage_inventory", label: "Manages inventory", kind: "boolean" },
3503
+ CREATED
3504
+ ],
3505
+ product_category: [
3506
+ { key: "name", label: "Name" },
3507
+ { key: "handle", label: "Handle" },
3508
+ { key: "is_active", label: "Active", kind: "boolean" },
3509
+ { key: "parent_category_id", label: "Parent category ID", kind: "id" },
3510
+ CREATED
3511
+ ],
3512
+ product_collection: [{ key: "title", label: "Title" }, { key: "handle", label: "Handle" }, CREATED],
3513
+ payment: [
3514
+ { key: "amount", label: "Amount", kind: "money" },
3515
+ { key: "currency_code", label: "Currency" },
3516
+ { key: "provider_id", label: "Provider" },
3517
+ { key: "captured_at", label: "Captured", kind: "date" },
3518
+ { key: "canceled_at", label: "Canceled", kind: "date" },
3519
+ { key: "payment_collection_id", label: "Payment collection ID", kind: "id" },
3520
+ CREATED
3521
+ ],
3522
+ payment_session: [
3523
+ { key: "amount", label: "Amount", kind: "money" },
3524
+ { key: "currency_code", label: "Currency" },
3525
+ { key: "provider_id", label: "Provider" },
3526
+ { key: "status", label: "Status", kind: "status" },
3527
+ { key: "payment_collection_id", label: "Payment collection ID", kind: "id" },
3528
+ CREATED
3529
+ ],
3530
+ payment_collection: [
3531
+ { key: "amount", label: "Amount", kind: "money" },
3532
+ { key: "currency_code", label: "Currency" },
3533
+ { key: "status", label: "Status", kind: "status" },
3534
+ CREATED
3535
+ ],
3536
+ refund: [
3537
+ { key: "amount", label: "Amount", kind: "money" },
3538
+ { key: "payment_id", label: "Payment ID", kind: "id" },
3539
+ { key: "refund_reason_id", label: "Refund reason ID", kind: "id" },
3540
+ { key: "note", label: "Note" },
3541
+ { key: "created_by", label: "Created by" },
3542
+ CREATED
3543
+ ],
3544
+ return: [
3545
+ { key: "display_id", label: "Return number" },
3546
+ { key: "status", label: "Status", kind: "status" },
3547
+ { key: "order_id", label: "Order ID", kind: "id" },
3548
+ { key: "refund_amount", label: "Refund amount", kind: "money" },
3549
+ { key: "received_at", label: "Received", kind: "date" },
3550
+ CREATED
3551
+ ],
3552
+ payment_detail: [
3553
+ { key: "type", label: "Method type" },
3554
+ { key: "customer_id", label: "Customer ID", kind: "id" },
3555
+ { key: "is_default", label: "Default method", kind: "boolean" },
3556
+ CREATED
3557
+ ],
3558
+ user: [NAME, { key: "email", label: "Email" }, CREATED],
3559
+ invite: [
3560
+ { key: "email", label: "Email" },
3561
+ { key: "accepted", label: "Accepted", kind: "boolean" },
3562
+ { key: "expires_at", label: "Expires", kind: "date" },
3563
+ CREATED
3564
+ ],
3565
+ api_key: [
3566
+ { key: "title", label: "Title" },
3567
+ { key: "type", label: "Type" },
3568
+ { key: "redacted", label: "Key (redacted)" },
3569
+ { key: "revoked_at", label: "Revoked", kind: "date" },
3570
+ CREATED
3571
+ ],
3572
+ promotion: [
3573
+ { key: "code", label: "Promotion code" },
3574
+ { key: "type", label: "Type" },
3575
+ { key: "status", label: "Status", kind: "status" },
3576
+ { key: "is_automatic", label: "Automatic", kind: "boolean" },
3577
+ CREATED
3578
+ ],
3579
+ fulfillment: [
3580
+ { key: "provider_id", label: "Provider" },
3581
+ { key: "location_id", label: "Location ID", kind: "id" },
3582
+ { key: "shipped_at", label: "Shipped", kind: "date" },
3583
+ { key: "delivered_at", label: "Delivered", kind: "date" },
3584
+ { key: "canceled_at", label: "Canceled", kind: "date" },
3585
+ CREATED
3586
+ ],
3587
+ inventory_item: [
3588
+ { key: "sku", label: "SKU" },
3589
+ { key: "title", label: "Title" },
3590
+ { key: "requires_shipping", label: "Requires shipping", kind: "boolean" },
3591
+ CREATED
3592
+ ],
3593
+ inventory_level: [
3594
+ { key: "inventory_item_id", label: "Inventory item ID", kind: "id" },
3595
+ { key: "location_id", label: "Location ID", kind: "id" },
3596
+ { key: "stocked_quantity", label: "Stocked", kind: "number" },
3597
+ { key: "reserved_quantity", label: "Reserved", kind: "number" },
3598
+ CREATED
3599
+ ],
3600
+ review: [
3601
+ { key: "title", label: "Title" },
3602
+ { key: "rating", label: "Rating", kind: "number" },
3603
+ { key: "status", label: "Status", kind: "status" },
3604
+ { key: "product_id", label: "Product ID", kind: "id" },
3605
+ { key: "customer_id", label: "Customer ID", kind: "id" },
3606
+ CREATED
3607
+ ]
3608
+ };
3609
+ const GENERIC_FIELDS = [
3610
+ { key: "display_id", label: "Number" },
3611
+ { key: "title", label: "Title" },
3612
+ { key: "name", label: "Name" },
3613
+ NAME,
3614
+ { key: "email", label: "Email" },
3615
+ { key: "phone", label: "Phone" },
3616
+ { key: "handle", label: "Handle" },
3617
+ { key: "sku", label: "SKU" },
3618
+ { key: "code", label: "Code" },
3619
+ { key: "status", label: "Status", kind: "status" },
3620
+ { key: "type", label: "Type" },
3621
+ { key: "amount", label: "Amount", kind: "money" },
3622
+ { key: "quantity", label: "Quantity", kind: "number" },
3623
+ { key: "currency_code", label: "Currency" },
3624
+ { key: "order_id", label: "Order ID", kind: "id" },
3625
+ { key: "customer_id", label: "Customer ID", kind: "id" },
3626
+ { key: "product_id", label: "Product ID", kind: "id" },
3627
+ { key: "payment_id", label: "Payment ID", kind: "id" },
3628
+ { key: "provider_id", label: "Provider" },
3629
+ CREATED,
3630
+ { key: "updated_at", label: "Last updated", kind: "date" }
3631
+ ];
3632
+ const MAX_GENERIC_FIELDS = 8;
3633
+ function amountOf(value) {
3634
+ if (typeof value === "number" && Number.isFinite(value)) return value;
3635
+ if (typeof value === "string" && value.trim() !== "" && Number.isFinite(Number(value))) return Number(value);
3636
+ if (value !== null && typeof value === "object" && "value" in value) {
3637
+ return amountOf(value.value);
3438
3638
  }
3439
- if (statusLower === "completed") {
3440
- return "bg-ui-tag-green-bg text-ui-tag-green-text";
3639
+ return null;
3640
+ }
3641
+ function formatValue(raw, kind, row) {
3642
+ if (raw === null || raw === void 0 || raw === "") return null;
3643
+ if (raw === MASKED_VALUE) return { value: MASKED_VALUE, kind: "masked" };
3644
+ switch (kind) {
3645
+ case "money": {
3646
+ const amount = amountOf(raw);
3647
+ if (amount === null) return null;
3648
+ const currency = typeof row.currency_code === "string" ? row.currency_code : null;
3649
+ return { value: formatMoney(amount, currency), kind };
3650
+ }
3651
+ case "date":
3652
+ return typeof raw === "string" || raw instanceof Date ? { value: formatDate(raw), kind } : null;
3653
+ case "boolean":
3654
+ return { value: raw === true || raw === "true" ? "Yes" : "No", kind };
3655
+ case "number": {
3656
+ const n = amountOf(raw);
3657
+ return n === null ? null : { value: formatNumber(n), kind };
3658
+ }
3659
+ case "status":
3660
+ return { value: String(raw).replace(/_/g, " "), kind };
3661
+ default:
3662
+ if (typeof raw === "object") return null;
3663
+ if (typeof raw === "string" && raw.length > 160) return { value: `${raw.slice(0, 157)}…`, kind };
3664
+ return { value: String(raw), kind };
3441
3665
  }
3442
- if (statusLower === "cancelled") {
3443
- return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
3666
+ }
3667
+ function summarizeOldData(tableName, oldData) {
3668
+ if (!oldData) return [];
3669
+ const { value: row } = maskSensitiveData(oldData, tableName);
3670
+ const specific = ENTITY_FIELDS[tableName];
3671
+ const specs = specific ?? GENERIC_FIELDS;
3672
+ const fields = [];
3673
+ const seenLabels = /* @__PURE__ */ new Set();
3674
+ for (const spec of specs) {
3675
+ const raw = spec.derive ? spec.derive(row) : row[spec.key];
3676
+ const formatted = formatValue(raw, spec.kind ?? "text", row);
3677
+ if (!formatted || seenLabels.has(spec.label)) continue;
3678
+ seenLabels.add(spec.label);
3679
+ const value = spec.key === "currency_code" ? formatted.value.toUpperCase() : formatted.value;
3680
+ fields.push({ key: spec.key, label: spec.label, value, kind: formatted.kind });
3681
+ if (!specific && fields.length >= MAX_GENERIC_FIELDS) break;
3444
3682
  }
3445
- return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
3446
- };
3447
- const SwapsPage = () => {
3683
+ return fields;
3684
+ }
3685
+ function readLastListSearch() {
3686
+ try {
3687
+ return window.sessionStorage.getItem(LAST_LIST_URL_KEY) ?? "";
3688
+ } catch {
3689
+ return "";
3690
+ }
3691
+ }
3692
+ const DeletedRecordDetailPage = () => {
3448
3693
  const navigate = reactRouterDom.useNavigate();
3449
- const [items, setItems] = react.useState([]);
3450
- const [statusFilter, setStatusFilter] = react.useState("all");
3451
- const [createdByFilter, setCreatedByFilter] = react.useState("all");
3452
- const [searchQuery, setSearchQuery] = react.useState("");
3453
- const debouncedSearchQuery = useDebounce$1(searchQuery, 300);
3454
- const [isLoading, setIsLoading] = react.useState(true);
3455
- const [isFetchingMore, setIsFetchingMore] = react.useState(false);
3456
- const [error, setError] = react.useState(null);
3457
- const [offset, setOffset] = react.useState(0);
3458
- const [count, setCount] = react.useState(0);
3459
- const limit = 50;
3460
- const loadSwaps = react.useCallback(
3461
- async (nextOffset, replace = false) => {
3462
- var _a;
3463
- try {
3464
- if (replace) {
3465
- setIsLoading(true);
3466
- } else {
3467
- setIsFetchingMore(true);
3468
- }
3469
- setError(null);
3470
- const params = new URLSearchParams();
3471
- params.set("limit", String(limit));
3472
- params.set("offset", String(nextOffset));
3473
- if (statusFilter !== "all") {
3474
- params.set("status", statusFilter);
3475
- }
3476
- if (debouncedSearchQuery.trim()) {
3477
- params.set("order_id", debouncedSearchQuery.trim());
3478
- }
3479
- if (createdByFilter !== "all") {
3480
- params.set("created_by", createdByFilter);
3481
- }
3482
- const response = await fetch(
3483
- `/admin/swaps?${params.toString()}`,
3484
- { credentials: "include" }
3485
- );
3486
- if (!response.ok) {
3487
- const message = await response.text();
3488
- throw new Error(message || "Unable to load swaps");
3489
- }
3490
- const payload = await response.json();
3491
- setCount(payload.count ?? 0);
3492
- setOffset(nextOffset + (((_a = payload.swaps) == null ? void 0 : _a.length) ?? 0));
3493
- setItems(
3494
- (prev) => replace ? payload.swaps ?? [] : [...prev, ...payload.swaps ?? []]
3495
- );
3496
- } catch (loadError) {
3497
- const message = loadError instanceof Error ? loadError.message : "Unable to load swaps";
3498
- setError(message);
3499
- } finally {
3500
- setIsLoading(false);
3501
- setIsFetchingMore(false);
3502
- }
3503
- },
3504
- [statusFilter, createdByFilter, debouncedSearchQuery]
3505
- );
3694
+ const location = reactRouterDom.useLocation();
3695
+ const { id = "" } = reactRouterDom.useParams();
3696
+ const [state, setState] = react.useState({ status: "loading" });
3697
+ const [reloadToken, setReloadToken] = react.useState(0);
3698
+ const cameFromList = location.state?.fromList === true;
3699
+ const goBack = () => {
3700
+ if (cameFromList) navigate(-1);
3701
+ else navigate(`/deleted-records-audit${readLastListSearch()}`);
3702
+ };
3506
3703
  react.useEffect(() => {
3507
- void loadSwaps(0, true);
3508
- }, [statusFilter, createdByFilter, debouncedSearchQuery, loadSwaps]);
3509
- const hasMore = react.useMemo(() => offset < count, [offset, count]);
3510
- const availableStatuses = react.useMemo(() => {
3511
- const statuses = /* @__PURE__ */ new Set();
3512
- items.forEach((item) => statuses.add(item.status));
3513
- return Array.from(statuses).sort();
3514
- }, [items]);
3515
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-7xl flex-col gap-6 p-6", children: [
3516
- /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
3517
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
3518
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Exchanges" }),
3519
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer exchange requests" })
3520
- ] }),
3521
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadSwaps(0, true), children: "Refresh" })
3522
- ] }),
3523
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
3524
- /* @__PURE__ */ jsxRuntime.jsx(
3525
- ui.Input,
3526
- {
3527
- placeholder: "Search by swap ID or order ID",
3528
- value: searchQuery,
3529
- onChange: (event) => setSearchQuery(event.target.value),
3530
- className: "md:max-w-sm"
3531
- }
3532
- ),
3533
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
3534
- /* @__PURE__ */ jsxRuntime.jsxs(
3535
- "select",
3536
- {
3537
- value: createdByFilter,
3538
- onChange: (event) => setCreatedByFilter(event.target.value),
3539
- className: "h-9 rounded-md border border-ui-border-base bg-transparent px-3 text-sm text-ui-fg-base outline-none transition focus:ring-2 focus:ring-ui-fg-interactive md:max-w-xs",
3540
- children: [
3541
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All (Created by)" }),
3542
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "customer", children: "Customer" }),
3543
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "admin", children: "Admin" })
3544
- ]
3545
- }
3546
- ),
3547
- /* @__PURE__ */ jsxRuntime.jsxs(
3548
- "select",
3549
- {
3550
- value: statusFilter,
3551
- onChange: (event) => setStatusFilter(event.target.value),
3552
- className: "h-9 rounded-md border border-ui-border-base bg-transparent px-3 text-sm text-ui-fg-base outline-none transition focus:ring-2 focus:ring-ui-fg-interactive md:max-w-xs",
3553
- children: [
3554
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All Statuses" }),
3555
- availableStatuses.map((status) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
3556
- ]
3557
- }
3558
- )
3559
- ] })
3560
- ] }),
3561
- error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
3562
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
3563
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
3564
- ui.Button,
3565
- {
3566
- variant: "secondary",
3567
- onClick: () => loadSwaps(0, true),
3568
- children: "Try again"
3569
- }
3570
- ) })
3571
- ] }) : null,
3572
- isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading swaps..." }) }) : items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
3573
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No exchanges yet" }),
3574
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Exchange requests created by customers will appear here." })
3575
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
3576
- /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
3577
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Exchange ID" }),
3578
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
3579
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
3580
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Difference Due" }),
3581
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
3582
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
3583
- ] }) }),
3584
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((swap) => /* @__PURE__ */ jsxRuntime.jsxs(
3585
- "tr",
3586
- {
3587
- className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
3588
- onClick: () => navigate(`/swaps/${swap.id}`),
3589
- children: [
3590
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-0.5", children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: swap.id }) }) }),
3591
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: swap.order_id }),
3592
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
3593
- ui.Badge,
3594
- {
3595
- size: "2xsmall",
3596
- className: `uppercase ${getStatusBadgeClass$5(swap.status)}`,
3597
- children: swap.status.replace(/_/g, " ")
3598
- }
3599
- ) }),
3600
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
3601
- const amount = swap.difference_due;
3602
- if (amount == null || amount === void 0) {
3603
- return "—";
3604
- }
3605
- const displayAmount = Number(amount) / 100;
3606
- const currency = swap.currency_code || "$";
3607
- const sign = displayAmount >= 0 ? "+" : "";
3608
- return `${sign}${currency}${displayAmount.toFixed(2)}`;
3609
- })() }),
3610
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(swap.created_at).toLocaleDateString("en-US", {
3611
- year: "numeric",
3612
- month: "short",
3613
- day: "numeric",
3614
- hour: "numeric",
3615
- minute: "2-digit",
3616
- hour12: true
3617
- }) }),
3618
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
3619
- ui.Button,
3620
- {
3621
- variant: "transparent",
3622
- size: "small",
3623
- onClick: (e) => {
3624
- e.stopPropagation();
3625
- navigate(`/app/orders/${swap.order_id}`);
3626
- },
3627
- children: "Go to order"
3628
- }
3629
- ) })
3630
- ]
3631
- },
3632
- swap.id
3633
- )) })
3704
+ const controller = new AbortController();
3705
+ setState({ status: "loading" });
3706
+ fetchAuditDetail(id, controller.signal).then((audit) => setState({ status: "ready", audit })).catch((e) => {
3707
+ if (controller.signal.aborted) return;
3708
+ setState({
3709
+ status: "error",
3710
+ message: e instanceof Error ? e.message : "Unknown error",
3711
+ notFound: e instanceof AuditApiError && e.status === 404
3712
+ });
3713
+ });
3714
+ return () => controller.abort();
3715
+ }, [id, reloadToken]);
3716
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-3 md:p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-4 md:p-6", children: [
3717
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: "transparent", size: "small", onClick: goBack, className: "-ml-2", children: [
3718
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, {}),
3719
+ "Back to Deleted Records"
3634
3720
  ] }) }),
3635
- hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
3636
- ui.Button,
3721
+ state.status === "loading" ? /* @__PURE__ */ jsxRuntime.jsx(DetailSkeleton, {}) : state.status === "error" ? /* @__PURE__ */ jsxRuntime.jsx(
3722
+ DetailError,
3637
3723
  {
3638
- variant: "secondary",
3639
- isLoading: isFetchingMore,
3640
- onClick: () => loadSwaps(offset, false),
3641
- children: "Load more"
3724
+ notFound: state.notFound,
3725
+ message: state.message,
3726
+ onRetry: () => setReloadToken((t) => t + 1),
3727
+ onBack: goBack
3642
3728
  }
3643
- ) }) : null
3729
+ ) : /* @__PURE__ */ jsxRuntime.jsx(DetailContent, { audit: state.audit })
3644
3730
  ] }) });
3645
3731
  };
3646
- const config$5 = adminSdk.defineRouteConfig({
3647
- label: "Exchanges",
3648
- icon: icons.ArrowPath
3649
- });
3650
- const useDebounce = (value, delay) => {
3651
- const [debouncedValue, setDebouncedValue] = react.useState(value);
3652
- react.useEffect(() => {
3653
- const handler = setTimeout(() => setDebouncedValue(value), delay);
3654
- return () => clearTimeout(handler);
3655
- }, [value, delay]);
3656
- return debouncedValue;
3657
- };
3658
- const getStatusBadgeClass$4 = (status) => {
3659
- const s2 = status.toLowerCase();
3660
- if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
3661
- if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
3662
- if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
3663
- if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
3664
- return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
3665
- };
3666
- const RefundsPage = () => {
3732
+ const DetailContent = ({ audit }) => {
3667
3733
  const navigate = reactRouterDom.useNavigate();
3668
- const [items, setItems] = react.useState([]);
3669
- const [orderIdSearch, setOrderIdSearch] = react.useState("");
3670
- const debouncedOrderId = useDebounce(orderIdSearch, 300);
3671
- const [paymentStatusFilter, setPaymentStatusFilter] = react.useState("all");
3672
- const [providerSearch, setProviderSearch] = react.useState("");
3673
- const debouncedProvider = useDebounce(providerSearch, 300);
3674
- const [currencySearch, setCurrencySearch] = react.useState("");
3675
- const debouncedCurrency = useDebounce(currencySearch, 300);
3676
- const [dateFrom, setDateFrom] = react.useState("");
3677
- const [dateTo, setDateTo] = react.useState("");
3678
- const [amountMin, setAmountMin] = react.useState("");
3679
- const [amountMax, setAmountMax] = react.useState("");
3680
- const [isLoading, setIsLoading] = react.useState(true);
3681
- const [isFetchingMore, setIsFetchingMore] = react.useState(false);
3682
- const [error, setError] = react.useState(null);
3683
- const [offset, setOffset] = react.useState(0);
3684
- const [count, setCount] = react.useState(0);
3685
- const limit = 50;
3686
- const loadRefunds = react.useCallback(
3687
- async (nextOffset, replace) => {
3688
- try {
3689
- if (replace) setIsLoading(true);
3690
- else setIsFetchingMore(true);
3691
- setError(null);
3692
- const params = new URLSearchParams();
3693
- params.set("limit", String(limit));
3694
- params.set("offset", String(nextOffset));
3695
- if (debouncedOrderId.trim()) params.set("order_id", debouncedOrderId.trim());
3696
- if (paymentStatusFilter !== "all") params.set("payment_status", paymentStatusFilter);
3697
- if (debouncedProvider.trim()) params.set("provider_id", debouncedProvider.trim());
3698
- if (debouncedCurrency.trim()) params.set("currency_code", debouncedCurrency.trim());
3699
- if (dateFrom.trim()) params.set("date_from", dateFrom.trim());
3700
- if (dateTo.trim()) params.set("date_to", dateTo.trim());
3701
- const min = amountMin.trim() ? Number(amountMin) : void 0;
3702
- const max = amountMax.trim() ? Number(amountMax) : void 0;
3703
- if (min != null && !Number.isNaN(min)) params.set("amount_min", String(min));
3704
- if (max != null && !Number.isNaN(max)) params.set("amount_max", String(max));
3705
- const response = await fetch(`/admin/refunds?${params.toString()}`, {
3706
- credentials: "include"
3707
- });
3708
- if (!response.ok) {
3709
- const text = await response.text();
3710
- throw new Error(text || "Failed to load refunds");
3711
- }
3712
- const payload = await response.json();
3713
- const list = payload.refunds ?? [];
3714
- setCount(payload.count ?? 0);
3715
- setOffset(nextOffset + list.length);
3716
- setItems((prev) => replace ? list : [...prev, ...list]);
3717
- } catch (e) {
3718
- setError(e instanceof Error ? e.message : "Failed to load");
3719
- } finally {
3720
- setIsLoading(false);
3721
- setIsFetchingMore(false);
3722
- }
3723
- },
3724
- [
3725
- debouncedOrderId,
3726
- paymentStatusFilter,
3727
- debouncedProvider,
3728
- debouncedCurrency,
3729
- dateFrom,
3730
- dateTo,
3731
- amountMin,
3732
- amountMax
3733
- ]
3734
- );
3735
- react.useEffect(() => {
3736
- void loadRefunds(0, true);
3737
- }, [loadRefunds]);
3738
- const hasMore = react.useMemo(() => offset < count, [offset, count]);
3739
- const displayAmount = (r) => {
3740
- const code = (r.currency_code ?? "USD").toUpperCase();
3741
- return `${code} ${Number(r.amount)}`;
3742
- };
3743
- const displayStatus = (r) => {
3744
- const s2 = r.payment_status ?? "";
3745
- return s2 !== "" ? s2 : "—";
3734
+ const entity = getEntityInfo(audit.table_name);
3735
+ const source = describeSource(audit.source);
3736
+ const summary = react.useMemo(() => summarizeOldData(audit.table_name, audit.old_data), [audit]);
3737
+ const masked = react.useMemo(() => maskSensitiveData(audit.old_data, audit.table_name), [audit]);
3738
+ const guidance = getNextSteps(entity.category.id);
3739
+ const related = getRelatedLinks(audit.table_name, audit.old_data);
3740
+ const [showRaw, setShowRaw] = react.useState(false);
3741
+ const copyJson = async () => {
3742
+ try {
3743
+ await navigator.clipboard.writeText(JSON.stringify(masked.value, null, 2));
3744
+ ui.toast.success("Record data copied", {
3745
+ description: masked.maskedCount ? "Sensitive values were left hidden." : void 0
3746
+ });
3747
+ } catch {
3748
+ ui.toast.error("Couldn’t copy to clipboard");
3749
+ }
3746
3750
  };
3747
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-7xl flex-col gap-6 p-6", children: [
3748
- /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
3751
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3752
+ /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
3753
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
3754
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { size: "small", color: "red", children: [
3755
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, {}),
3756
+ "Deleted"
3757
+ ] }),
3758
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: entity.category.label })
3759
+ ] }),
3760
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Heading, { level: "h1", children: [
3761
+ "Deleted ",
3762
+ entity.label
3763
+ ] }),
3749
3764
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
3750
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Refunds" }),
3751
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Refund records — amount, order, payment status" })
3765
+ /* @__PURE__ */ jsxRuntime.jsx(CopyableId, { value: audit.record_id, emptyLabel: "This record type has no ID column", className: "text-sm" }),
3766
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: [
3767
+ "Database table: ",
3768
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono", children: audit.table_name })
3769
+ ] })
3770
+ ] })
3771
+ ] }),
3772
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3 rounded-lg border border-ui-tag-orange-border bg-ui-tag-orange-bg px-4 py-3", children: [
3773
+ /* @__PURE__ */ jsxRuntime.jsx(icons.InformationCircle, { className: "mt-0.5 shrink-0 text-ui-tag-orange-icon" }),
3774
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-tag-orange-text", children: [
3775
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "This is a historical snapshot" }),
3776
+ " captured immediately before deletion. The record no longer exists in the database, so changes elsewhere in the admin are not reflected here."
3777
+ ] })
3778
+ ] }),
3779
+ /* @__PURE__ */ jsxRuntime.jsx(Section, { title: "Deletion information", children: /* @__PURE__ */ jsxRuntime.jsxs("dl", { className: "grid grid-cols-1 gap-x-6 gap-y-4 sm:grid-cols-2", children: [
3780
+ /* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Deleted", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
3781
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: formatExactDateTime(audit.occurred_at) }),
3782
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1 text-xs text-ui-fg-muted", children: [
3783
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ClockSolid, { className: "size-3" }),
3784
+ formatRelativeTime(audit.occurred_at)
3785
+ ] })
3786
+ ] }) }),
3787
+ /* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Deleted by", children: audit.deleted_by ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "break-all text-sm text-ui-fg-base", children: audit.deleted_by }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-muted", children: "Not recorded" }) }),
3788
+ /* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Source", children: source.kind === "unknown" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-muted", children: "Unknown" }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { size: "small", color: sourceBadgeColor(source.kind), children: source.label }) }),
3789
+ /* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Action", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Permanently deleted" }) })
3790
+ ] }) }),
3791
+ /* @__PURE__ */ jsxRuntime.jsx(
3792
+ Section,
3793
+ {
3794
+ title: "Record summary",
3795
+ description: `Key details of this ${entity.label.toLowerCase()} at the moment it was deleted.`,
3796
+ children: summary.length ? /* @__PURE__ */ jsxRuntime.jsx("dl", { className: "grid grid-cols-1 gap-x-6 gap-y-4 sm:grid-cols-2", children: summary.map((field) => /* @__PURE__ */ jsxRuntime.jsx(Field, { label: field.label, children: field.kind === "id" ? /* @__PURE__ */ jsxRuntime.jsx(CopyableId, { value: field.value }) : field.kind === "status" ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { size: "2xsmall", color: "grey", className: "capitalize", children: field.value }) : field.kind === "masked" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-muted", children: "Hidden for security" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "break-words text-sm text-ui-fg-base", children: field.value }) }, field.label)) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No key details could be extracted for this record type. See the original record data below." })
3797
+ }
3798
+ ),
3799
+ /* @__PURE__ */ jsxRuntime.jsx(
3800
+ Section,
3801
+ {
3802
+ title: "Original record data",
3803
+ description: "The complete data captured before deletion.",
3804
+ actions: showRaw && audit.old_data ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: "secondary", size: "small", onClick: copyJson, children: [
3805
+ /* @__PURE__ */ jsxRuntime.jsx(icons.SquareTwoStack, {}),
3806
+ "Copy JSON"
3807
+ ] }) : null,
3808
+ children: audit.old_data ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
3809
+ masked.maskedCount > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
3810
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ShieldCheck, { className: "shrink-0 text-ui-fg-muted" }),
3811
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
3812
+ masked.maskedCount,
3813
+ " sensitive ",
3814
+ masked.maskedCount === 1 ? "value is" : "values are",
3815
+ " hidden for security (passwords, tokens, card or account numbers)."
3816
+ ] })
3817
+ ] }) : null,
3818
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: "secondary", size: "small", onClick: () => setShowRaw((s2) => !s2), "aria-expanded": showRaw, children: [
3819
+ showRaw ? /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronDownMini, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronRightMini, {}),
3820
+ showRaw ? "Hide full record" : "View full record"
3821
+ ] }) }),
3822
+ showRaw ? /* @__PURE__ */ jsxRuntime.jsx(JsonViewer, { data: masked.value }) : null
3823
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No data was captured for this deletion." })
3824
+ }
3825
+ ),
3826
+ /* @__PURE__ */ jsxRuntime.jsx(Section, { title: "What you can do now", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
3827
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-base", children: [
3828
+ "This record was permanently deleted. ",
3829
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Automatic restoration is not available" }),
3830
+ " ",
3831
+ "from this screen."
3752
3832
  ] }),
3753
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadRefunds(0, true), children: "Refresh" })
3833
+ /* @__PURE__ */ jsxRuntime.jsxs("ol", { className: "flex list-decimal flex-col gap-3 pl-5 text-sm text-ui-fg-subtle marker:text-ui-fg-muted", children: [
3834
+ /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
3835
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-ui-fg-base", children: "Check whether this was expected." }),
3836
+ " ",
3837
+ audit.deleted_by || source.kind !== "unknown" ? "Confirm with the person or system shown above." : `Who deleted it wasn’t recorded—check with your team or integrations active around ${formatExactDateTime(audit.occurred_at)}.`,
3838
+ " ",
3839
+ guidance.headline
3840
+ ] }),
3841
+ /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
3842
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-ui-fg-base", children: "If it needs to come back:" }),
3843
+ " ",
3844
+ guidance.recreate
3845
+ ] }),
3846
+ /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
3847
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-ui-fg-base", children: "Need the details?" }),
3848
+ " Use “View full record” above to see or copy everything that was stored. Sensitive values stay hidden."
3849
+ ] })
3850
+ ] }),
3851
+ guidance.adminSection || related.length ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
3852
+ guidance.adminSection ? /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", size: "small", onClick: () => navigate(guidance.adminSection.path), children: guidance.adminSection.label }) : null,
3853
+ related.map((link) => /* @__PURE__ */ jsxRuntime.jsxs(
3854
+ ui.Button,
3855
+ {
3856
+ variant: "transparent",
3857
+ size: "small",
3858
+ onClick: () => navigate(link.path),
3859
+ title: `Opens ${link.label.toLowerCase()} ${link.id} if it still exists`,
3860
+ children: [
3861
+ "Open related ",
3862
+ link.label.toLowerCase(),
3863
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronRightMini, {})
3864
+ ]
3865
+ },
3866
+ link.path
3867
+ ))
3868
+ ] }) : null,
3869
+ related.length ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: "Related records open only if they haven’t been deleted too." }) : null
3870
+ ] }) })
3871
+ ] });
3872
+ };
3873
+ const Section = ({
3874
+ title,
3875
+ description,
3876
+ actions,
3877
+ children
3878
+ }) => /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "flex flex-col gap-4 rounded-lg border border-ui-border-base p-5", children: [
3879
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-start justify-between gap-2", children: [
3880
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [
3881
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: title }),
3882
+ description ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: description }) : null
3754
3883
  ] }),
3755
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
3756
- /* @__PURE__ */ jsxRuntime.jsx(
3757
- ui.Input,
3758
- {
3759
- placeholder: "Order ID",
3760
- value: orderIdSearch,
3761
- onChange: (e) => setOrderIdSearch(e.target.value),
3762
- className: "md:max-w-[180px]",
3763
- "aria-label": "Filter by order ID"
3764
- }
3765
- ),
3766
- /* @__PURE__ */ jsxRuntime.jsx(
3767
- ui.Input,
3768
- {
3769
- placeholder: "Provider",
3770
- value: providerSearch,
3771
- onChange: (e) => setProviderSearch(e.target.value),
3772
- className: "md:max-w-[140px]",
3773
- "aria-label": "Filter by provider"
3774
- }
3775
- ),
3776
- /* @__PURE__ */ jsxRuntime.jsx(
3777
- ui.Input,
3778
- {
3779
- placeholder: "Currency",
3780
- value: currencySearch,
3781
- onChange: (e) => setCurrencySearch(e.target.value),
3782
- className: "md:max-w-[100px]",
3783
- "aria-label": "Filter by currency"
3784
- }
3785
- ),
3786
- /* @__PURE__ */ jsxRuntime.jsxs(
3787
- "select",
3788
- {
3789
- value: paymentStatusFilter,
3790
- onChange: (e) => setPaymentStatusFilter(e.target.value),
3791
- className: "h-9 rounded-md border border-ui-border-base bg-transparent px-3 text-sm text-ui-fg-base outline-none transition focus:ring-2 focus:ring-ui-fg-interactive md:max-w-[160px]",
3792
- "aria-label": "Filter by payment status",
3793
- children: [
3794
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All statuses" }),
3795
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "pending", children: "Pending" }),
3796
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "requires_more", children: "Requires more" }),
3797
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "error", children: "Error" }),
3798
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "canceled", children: "Canceled" }),
3799
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "authorized", children: "Authorized" }),
3800
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "captured", children: "Captured" })
3801
- ]
3802
- }
3803
- ),
3804
- /* @__PURE__ */ jsxRuntime.jsx(
3805
- ui.Input,
3806
- {
3807
- type: "date",
3808
- placeholder: "From",
3809
- value: dateFrom,
3810
- onChange: (e) => setDateFrom(e.target.value),
3811
- className: "md:max-w-[140px]",
3812
- "aria-label": "Date from"
3813
- }
3814
- ),
3815
- /* @__PURE__ */ jsxRuntime.jsx(
3816
- ui.Input,
3817
- {
3818
- type: "date",
3819
- placeholder: "To",
3820
- value: dateTo,
3821
- onChange: (e) => setDateTo(e.target.value),
3822
- className: "md:max-w-[140px]",
3823
- "aria-label": "Date to"
3824
- }
3825
- ),
3826
- /* @__PURE__ */ jsxRuntime.jsx(
3827
- ui.Input,
3828
- {
3829
- placeholder: "Amount min",
3830
- value: amountMin,
3831
- onChange: (e) => setAmountMin(e.target.value),
3832
- type: "number",
3833
- min: 0,
3834
- className: "md:max-w-[100px]",
3835
- "aria-label": "Refund amount minimum"
3836
- }
3837
- ),
3838
- /* @__PURE__ */ jsxRuntime.jsx(
3839
- ui.Input,
3840
- {
3841
- placeholder: "Amount max",
3842
- value: amountMax,
3843
- onChange: (e) => setAmountMax(e.target.value),
3844
- type: "number",
3845
- min: 0,
3846
- className: "md:max-w-[100px]",
3847
- "aria-label": "Refund amount maximum"
3848
- }
3849
- )
3884
+ actions
3885
+ ] }),
3886
+ children
3887
+ ] });
3888
+ const Field = ({ label, children }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-col gap-1", children: [
3889
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { className: "text-xs font-medium uppercase tracking-wide text-ui-fg-muted", children: label }),
3890
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { className: "min-w-0", children })
3891
+ ] });
3892
+ const DetailSkeleton = () => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", "aria-busy": "true", children: [
3893
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
3894
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-5 w-24 rounded-full" }),
3895
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-8 w-64" }),
3896
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-4 w-48" })
3897
+ ] }),
3898
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-14 w-full" }),
3899
+ Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4 rounded-lg border border-ui-border-base p-5", children: [
3900
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-5 w-40" }),
3901
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: Array.from({ length: 4 }).map((__, j) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
3902
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-3 w-20" }),
3903
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-4 w-36" })
3904
+ ] }, j)) })
3905
+ ] }, i))
3906
+ ] });
3907
+ const DetailError = ({
3908
+ notFound,
3909
+ message,
3910
+ onRetry,
3911
+ onBack
3912
+ }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-2 rounded-lg border border-ui-border-base px-6 py-12 text-center", children: [
3913
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ExclamationCircle, { className: ui.clx(notFound ? "text-ui-fg-muted" : "text-ui-fg-error") }),
3914
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", children: notFound ? "Audit entry not found" : "Unable to load this deleted record" }),
3915
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "max-w-md text-ui-fg-subtle", children: notFound ? "This audit entry doesn’t exist. The link may be incorrect." : "We couldn’t retrieve the audit entry right now. Check your connection and try again." }),
3916
+ !notFound ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "max-w-md font-mono text-ui-fg-muted", children: message }) : null,
3917
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 flex gap-2", children: [
3918
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", size: "small", onClick: onBack, children: "Back to Deleted Records" }),
3919
+ !notFound ? /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", size: "small", onClick: onRetry, children: "Try again" }) : null
3920
+ ] })
3921
+ ] });
3922
+ const config$4 = adminSdk.defineRouteConfig({});
3923
+ const getStatusBadgeClass$3 = (status) => {
3924
+ const s2 = status.toLowerCase();
3925
+ if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
3926
+ if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
3927
+ if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
3928
+ if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
3929
+ return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
3930
+ };
3931
+ const formatAmount = (value) => {
3932
+ return String(value);
3933
+ };
3934
+ const RefundDetailPage = () => {
3935
+ const navigate = reactRouterDom.useNavigate();
3936
+ const params = reactRouterDom.useParams();
3937
+ const id = params?.id?.trim();
3938
+ const [detail, setDetail] = react.useState(null);
3939
+ const [loading, setLoading] = react.useState(!!id);
3940
+ const [error, setError] = react.useState(null);
3941
+ const [gatewayExpanded, setGatewayExpanded] = react.useState(false);
3942
+ react.useEffect(() => {
3943
+ if (!id) {
3944
+ setLoading(false);
3945
+ return;
3946
+ }
3947
+ let cancelled = false;
3948
+ setLoading(true);
3949
+ setError(null);
3950
+ fetch(`/admin/refunds/${id}`, { credentials: "include" }).then((res) => {
3951
+ if (!res.ok) throw new Error(res.statusText || "Failed to load");
3952
+ return res.json();
3953
+ }).then((data) => {
3954
+ if (!cancelled) setDetail(data);
3955
+ }).catch((e) => {
3956
+ if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
3957
+ }).finally(() => {
3958
+ if (!cancelled) setLoading(false);
3959
+ });
3960
+ return () => {
3961
+ cancelled = true;
3962
+ };
3963
+ }, [id]);
3964
+ const paymentStatus = detail?.payment?.status ?? "—";
3965
+ const hasGatewayData = detail?.payment?.payment_data && typeof detail.payment.payment_data === "object" && Object.keys(detail.payment.payment_data).length > 0;
3966
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-4xl flex-col gap-6 p-6", children: [
3967
+ /* @__PURE__ */ jsxRuntime.jsx("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
3968
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => navigate("/refunds"), children: "← Refunds" }),
3969
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Refund details" }),
3970
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle font-mono", children: id ?? "—" })
3850
3971
  ] }) }),
3851
3972
  error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
3852
3973
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
3853
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => loadRefunds(0, true), children: "Try again" }) })
3854
- ] }) : null,
3855
- isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading refunds…" }) }) : items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
3856
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No refunds yet" }),
3857
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Refund records will appear here." })
3858
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full overflow-x-auto rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full table-fixed divide-y divide-ui-border-base", style: { minWidth: 0 }, children: [
3859
- /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
3860
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Refund ID" }),
3861
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
3862
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Payment ID" }),
3863
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[8%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Amount" }),
3864
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[6%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Currency" }),
3865
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[10%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Provider" }),
3866
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[10%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Payment Status" }),
3867
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[14%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Note" }),
3868
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
3869
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[8%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
3870
- ] }) }),
3871
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((r) => /* @__PURE__ */ jsxRuntime.jsxs(
3872
- "tr",
3873
- {
3874
- className: "cursor-pointer hover:bg-ui-bg-subtle/60",
3875
- onClick: () => navigate(`/refunds/${r.refund_id}`),
3876
- children: [
3877
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 font-mono text-sm text-ui-fg-base", title: r.refund_id, children: r.refund_id }),
3878
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 font-medium text-ui-fg-base", title: r.order_id ?? void 0, children: r.order_id ?? "—" }),
3879
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 font-mono text-sm text-ui-fg-subtle", title: r.payment_id, children: r.payment_id }),
3880
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle", children: displayAmount(r) }),
3881
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle uppercase", children: r.currency_code || "—" }),
3882
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle", title: r.provider_id || void 0, children: r.provider_id || "—" }),
3883
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 px-3 py-3", children: /* @__PURE__ */ jsxRuntime.jsx(
3974
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/refunds"), children: "Back to list" })
3975
+ ] }) : loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading…" }) }) : detail ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
3976
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
3977
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Refund summary" }),
3978
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
3979
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3980
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refund ID" }),
3981
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.id })
3982
+ ] }),
3983
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3984
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
3985
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.refund.amount) })
3986
+ ] }),
3987
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3988
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Note" }),
3989
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.refund.note ?? "—" })
3990
+ ] }),
3991
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3992
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created at" }),
3993
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: new Date(detail.refund.created_at).toLocaleDateString("en-US", {
3994
+ year: "numeric",
3995
+ month: "short",
3996
+ day: "numeric",
3997
+ hour: "numeric",
3998
+ minute: "2-digit",
3999
+ hour12: true
4000
+ }) })
4001
+ ] }),
4002
+ detail.refund.created_by ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4003
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created by" }),
4004
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.created_by })
4005
+ ] }) : null
4006
+ ] })
4007
+ ] }),
4008
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
4009
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Payment summary" }),
4010
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
4011
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4012
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Payment amount" }),
4013
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.payment_amount) })
4014
+ ] }),
4015
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4016
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Captured amount" }),
4017
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.captured_amount) })
4018
+ ] }),
4019
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4020
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refunded amount" }),
4021
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.refunded_amount) })
4022
+ ] }),
4023
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4024
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
4025
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.payment.provider_id || "—" })
4026
+ ] }),
4027
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4028
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
4029
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
3884
4030
  ui.Badge,
3885
4031
  {
3886
4032
  size: "2xsmall",
3887
- className: `uppercase ${getStatusBadgeClass$4(displayStatus(r))}`,
3888
- children: displayStatus(r) !== "—" ? displayStatus(r).replace(/_/g, " ") : "—"
4033
+ className: `uppercase ${getStatusBadgeClass$3(paymentStatus)}`,
4034
+ children: paymentStatus !== "—" ? paymentStatus.replace(/_/g, " ") : "—"
3889
4035
  }
3890
- ) }),
3891
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle", title: r.note ?? void 0, children: r.note ?? "—" }),
3892
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle text-xs", children: new Date(r.created_at).toLocaleDateString("en-US", {
3893
- month: "short",
3894
- day: "numeric",
3895
- hour: "numeric",
3896
- minute: "2-digit",
3897
- hour12: true
3898
- }) }),
3899
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 px-3 py-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-1", children: [
3900
- /* @__PURE__ */ jsxRuntime.jsx(
3901
- ui.Button,
3902
- {
3903
- variant: "transparent",
3904
- size: "small",
3905
- onClick: (e) => {
3906
- e.stopPropagation();
3907
- navigate(`/refunds/${r.refund_id}`);
3908
- },
3909
- children: "Details"
3910
- }
3911
- ),
3912
- r.order_id ? /* @__PURE__ */ jsxRuntime.jsx(
3913
- ui.Button,
3914
- {
3915
- variant: "transparent",
3916
- size: "small",
3917
- onClick: (e) => {
3918
- e.stopPropagation();
3919
- navigate(`/orders/${r.order_id}`);
3920
- },
3921
- children: "Order"
3922
- }
3923
- ) : null
3924
- ] }) })
3925
- ]
3926
- },
3927
- r.refund_id
3928
- )) })
3929
- ] }) }),
3930
- hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
3931
- ui.Button,
3932
- {
3933
- variant: "secondary",
3934
- isLoading: isFetchingMore,
3935
- onClick: () => loadRefunds(offset, false),
3936
- children: "Load more"
3937
- }
3938
- ) }) : null
4036
+ ) })
4037
+ ] }),
4038
+ detail.computed ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4039
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4040
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Full refund" }),
4041
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.computed.is_full_refund ? "Yes" : "No" })
4042
+ ] }),
4043
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4044
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Remaining refundable" }),
4045
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.computed.remaining_refundable_amount) })
4046
+ ] }),
4047
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4048
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refund %" }),
4049
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "mt-1 block", children: [
4050
+ detail.computed.refund_percentage.toFixed(1),
4051
+ "%"
4052
+ ] })
4053
+ ] })
4054
+ ] }) : null
4055
+ ] })
4056
+ ] }),
4057
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
4058
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Order summary" }),
4059
+ detail.order ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
4060
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4061
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Order" }),
4062
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
4063
+ ui.Button,
4064
+ {
4065
+ variant: "transparent",
4066
+ size: "small",
4067
+ onClick: () => navigate(`/orders/${detail.order.order_id}`),
4068
+ children: detail.order.order_number ?? detail.order.order_id
4069
+ }
4070
+ ) })
4071
+ ] }),
4072
+ detail.order.total != null ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4073
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Total" }),
4074
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.order.total) })
4075
+ ] }) : null,
4076
+ detail.order.customer_id ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4077
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Customer ID" }),
4078
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.order.customer_id })
4079
+ ] }) : null,
4080
+ detail.order.region ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4081
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Region" }),
4082
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.region })
4083
+ ] }) : null,
4084
+ detail.order.fulfillment_status ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4085
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Fulfillment status" }),
4086
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.fulfillment_status })
4087
+ ] }) : null
4088
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No order linked to this refund." })
4089
+ ] }),
4090
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
4091
+ /* @__PURE__ */ jsxRuntime.jsxs(
4092
+ "button",
4093
+ {
4094
+ type: "button",
4095
+ className: "flex w-full items-center justify-between text-left",
4096
+ onClick: () => setGatewayExpanded((prev) => !prev),
4097
+ "aria-expanded": gatewayExpanded,
4098
+ "aria-label": gatewayExpanded ? "Collapse gateway data" : "Expand gateway data",
4099
+ children: [
4100
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg", children: "Gateway data" }),
4101
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: gatewayExpanded ? "Collapse" : "Expand" })
4102
+ ]
4103
+ }
4104
+ ),
4105
+ gatewayExpanded && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4", children: hasGatewayData ? /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-xs bg-ui-bg-subtle p-4 rounded-lg overflow-auto max-h-96", children: JSON.stringify(detail.payment.payment_data, null, 2) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No gateway payload for this payment." }) })
4106
+ ] })
4107
+ ] }) : null
3939
4108
  ] }) });
3940
4109
  };
3941
- const config$4 = adminSdk.defineRouteConfig({
3942
- label: "Refunds",
4110
+ const config$3 = adminSdk.defineRouteConfig({
4111
+ label: "Refund details",
3943
4112
  icon: icons.Receipt
3944
4113
  });
3945
- const getStatusBadgeClass$3 = (status) => {
4114
+ const getStatusBadgeClass$2 = (status) => {
3946
4115
  const s2 = status.toLowerCase();
3947
4116
  if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
3948
4117
  if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
@@ -3951,10 +4120,9 @@ const getStatusBadgeClass$3 = (status) => {
3951
4120
  return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
3952
4121
  };
3953
4122
  const PaymentDetailPage = () => {
3954
- var _a;
3955
4123
  const navigate = reactRouterDom.useNavigate();
3956
4124
  const params = reactRouterDom.useParams();
3957
- const id = (_a = params == null ? void 0 : params.id) == null ? void 0 : _a.trim();
4125
+ const id = params?.id?.trim();
3958
4126
  const [detail, setDetail] = react.useState(null);
3959
4127
  const [loading, setLoading] = react.useState(!!id);
3960
4128
  const [error, setError] = react.useState(null);
@@ -3981,8 +4149,8 @@ const PaymentDetailPage = () => {
3981
4149
  };
3982
4150
  }, [id]);
3983
4151
  const displayStatus = detail ? (detail.payment_id != null && detail.payment_status != null && detail.payment_status !== "" ? detail.payment_status : detail.session_status ?? "") || "—" : "";
3984
- const sessionStatusRaw = (detail == null ? void 0 : detail.session_status) ?? "—";
3985
- const paymentStatusRaw = (detail == null ? void 0 : detail.payment_id) != null ? (detail == null ? void 0 : detail.payment_status) ?? "—" : "—";
4152
+ const sessionStatusRaw = detail?.session_status ?? "—";
4153
+ const paymentStatusRaw = detail?.payment_id != null ? detail?.payment_status ?? "—" : "—";
3986
4154
  const displayAmount = detail ? `${(detail.currency_code ?? "USD").toUpperCase()} ${Number(detail.amount)}` : "";
3987
4155
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-4xl flex-col gap-6 p-6", children: [
3988
4156
  /* @__PURE__ */ jsxRuntime.jsx("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
@@ -4021,7 +4189,7 @@ const PaymentDetailPage = () => {
4021
4189
  ui.Badge,
4022
4190
  {
4023
4191
  size: "2xsmall",
4024
- className: `uppercase ${getStatusBadgeClass$3(displayStatus)}`,
4192
+ className: `uppercase ${getStatusBadgeClass$2(displayStatus)}`,
4025
4193
  children: displayStatus !== "—" ? displayStatus.replace(/_/g, " ") : "—"
4026
4194
  }
4027
4195
  ) })
@@ -4057,11 +4225,11 @@ const PaymentDetailPage = () => {
4057
4225
  ] }) : null
4058
4226
  ] }) });
4059
4227
  };
4060
- const config$3 = adminSdk.defineRouteConfig({
4228
+ const config$2 = adminSdk.defineRouteConfig({
4061
4229
  label: "Payment details",
4062
4230
  icon: icons.CreditCard
4063
4231
  });
4064
- const getStatusBadgeClass$2 = (status) => {
4232
+ const getStatusBadgeClass$1 = (status) => {
4065
4233
  const statusLower = status.toLowerCase();
4066
4234
  if (statusLower === "requested") {
4067
4235
  return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
@@ -4072,109 +4240,104 @@ const getStatusBadgeClass$2 = (status) => {
4072
4240
  if (statusLower === "rejected") {
4073
4241
  return "bg-ui-tag-red-bg text-ui-tag-red-text";
4074
4242
  }
4243
+ if (statusLower === "received") {
4244
+ return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
4245
+ }
4246
+ if (statusLower === "refunded") {
4247
+ return "bg-ui-tag-green-bg text-ui-tag-green-text";
4248
+ }
4075
4249
  if (statusLower === "completed") {
4076
4250
  return "bg-ui-tag-green-bg text-ui-tag-green-text";
4077
4251
  }
4078
- if (statusLower === "cancelled" || statusLower === "canceled") {
4252
+ if (statusLower === "cancelled") {
4079
4253
  return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
4080
4254
  }
4081
- if (statusLower === "pending") {
4082
- return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
4083
- }
4084
4255
  return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
4085
4256
  };
4086
- const SwapDetailPage = () => {
4087
- var _a, _b, _c;
4257
+ const ReturnDetailPage = () => {
4088
4258
  const navigate = reactRouterDom.useNavigate();
4089
4259
  const { id } = reactRouterDom.useParams();
4090
- const [swap, setSwap] = react.useState(null);
4091
- const [order, setOrder] = react.useState(null);
4260
+ const [returnOrder, setReturnOrder] = react.useState(null);
4092
4261
  const [isLoading, setIsLoading] = react.useState(true);
4093
- react.useState(false);
4094
- const [isCancelling, setIsCancelling] = react.useState(false);
4262
+ const [isRejecting, setIsRejecting] = react.useState(false);
4095
4263
  const [error, setError] = react.useState(null);
4096
4264
  const [updateError, setUpdateError] = react.useState(null);
4097
4265
  const [updateSuccess, setUpdateSuccess] = react.useState(false);
4098
4266
  react.useEffect(() => {
4099
4267
  if (!id) {
4100
- navigate("/swaps");
4268
+ navigate("/returns");
4101
4269
  return;
4102
4270
  }
4103
- const loadSwap = async () => {
4271
+ const loadReturn = async () => {
4104
4272
  try {
4105
4273
  setIsLoading(true);
4106
4274
  setError(null);
4107
- const response = await fetch(`/admin/swaps/${id}`, {
4275
+ const response = await fetch(`/admin/return/${id}`, {
4108
4276
  credentials: "include"
4109
4277
  });
4110
4278
  if (!response.ok) {
4111
4279
  const message = await response.text();
4112
- throw new Error(message || "Unable to load swap");
4280
+ throw new Error(message || "Unable to load return order");
4113
4281
  }
4114
4282
  const payload = await response.json();
4115
- setSwap(payload.swap);
4116
- setOrder(payload.order || null);
4283
+ setReturnOrder(payload.return);
4117
4284
  } catch (loadError) {
4118
- const message = loadError instanceof Error ? loadError.message : "Unable to load swap";
4285
+ const message = loadError instanceof Error ? loadError.message : "Unable to load return order";
4119
4286
  setError(message);
4120
4287
  } finally {
4121
4288
  setIsLoading(false);
4122
4289
  }
4123
4290
  };
4124
- void loadSwap();
4291
+ void loadReturn();
4125
4292
  }, [id, navigate]);
4126
- const handleCancelExchange = async () => {
4293
+ const handleReject = async () => {
4127
4294
  if (!id) {
4128
4295
  return;
4129
4296
  }
4130
4297
  try {
4131
- setIsCancelling(true);
4298
+ setIsRejecting(true);
4132
4299
  setUpdateError(null);
4133
4300
  setUpdateSuccess(false);
4134
- const response = await fetch(`/admin/swaps/${id}/cancel`, {
4301
+ const response = await fetch(`/admin/return/${id}/reject`, {
4135
4302
  method: "POST",
4136
4303
  headers: {
4137
4304
  "Content-Type": "application/json"
4138
4305
  },
4139
- credentials: "include"
4306
+ credentials: "include",
4307
+ body: JSON.stringify({ reason: "Rejected by admin" })
4140
4308
  });
4141
4309
  if (!response.ok) {
4142
4310
  const message = await response.text();
4143
- throw new Error(message || "Unable to cancel exchange");
4311
+ throw new Error(message || "Unable to reject return");
4144
4312
  }
4145
4313
  const payload = await response.json();
4146
- setSwap(payload.swap);
4314
+ setReturnOrder(payload.return);
4147
4315
  setUpdateSuccess(true);
4148
4316
  setTimeout(() => setUpdateSuccess(false), 3e3);
4149
- const detailResponse = await fetch(`/admin/swaps/${id}`, {
4317
+ const detailResponse = await fetch(`/admin/return/${id}`, {
4150
4318
  credentials: "include"
4151
4319
  });
4152
4320
  if (detailResponse.ok) {
4153
4321
  const detailPayload = await detailResponse.json();
4154
- setSwap(detailPayload.swap);
4155
- setOrder(detailPayload.order || null);
4322
+ setReturnOrder(detailPayload.return);
4156
4323
  }
4157
- } catch (cancelErr) {
4158
- const message = cancelErr instanceof Error ? cancelErr.message : "Unable to cancel exchange";
4324
+ } catch (updateErr) {
4325
+ const message = updateErr instanceof Error ? updateErr.message : "Unable to reject return";
4159
4326
  setUpdateError(message);
4160
4327
  } finally {
4161
- setIsCancelling(false);
4328
+ setIsRejecting(false);
4162
4329
  }
4163
4330
  };
4164
- const isOrderExchange = Boolean(swap == null ? void 0 : swap.exchange_id);
4165
- const canCancelExchange = isOrderExchange && swap && !["cancelled", "canceled", "completed", "declined"].includes(
4166
- ((_a = swap.status) == null ? void 0 : _a.toLowerCase()) ?? ""
4167
- );
4168
4331
  if (isLoading) {
4169
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading swap..." }) }) }) });
4332
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading return order..." }) }) }) });
4170
4333
  }
4171
- if (error || !swap) {
4334
+ if (error || !returnOrder) {
4172
4335
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
4173
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "Swap not found" }),
4174
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/swaps"), children: "Back to list" }) })
4336
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "Return order not found" }),
4337
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/returns"), children: "Back to list" }) })
4175
4338
  ] }) }) });
4176
4339
  }
4177
- const statusHistory = ((_b = swap.metadata) == null ? void 0 : _b.status_history) || [];
4340
+ const statusHistory = returnOrder.metadata?.status_history || [];
4178
4341
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: [
4179
4342
  /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
4180
4343
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -4182,7 +4345,7 @@ const SwapDetailPage = () => {
4182
4345
  {
4183
4346
  variant: "transparent",
4184
4347
  size: "small",
4185
- onClick: () => navigate("/swaps"),
4348
+ onClick: () => navigate("/returns"),
4186
4349
  className: "w-fit",
4187
4350
  children: [
4188
4351
  /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, { className: "mr-2" }),
@@ -4192,67 +4355,82 @@ const SwapDetailPage = () => {
4192
4355
  ),
4193
4356
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 md:flex-row md:items-center md:justify-between", children: [
4194
4357
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
4195
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Exchange Details" }),
4196
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: swap.id })
4358
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Return Order Details" }),
4359
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: returnOrder.id })
4360
+ ] }),
4361
+ /* @__PURE__ */ jsxRuntime.jsx(
4362
+ ui.Badge,
4363
+ {
4364
+ size: "small",
4365
+ className: `uppercase ${getStatusBadgeClass$1(returnOrder.status)}`,
4366
+ children: returnOrder.status.replace(/_/g, " ")
4367
+ }
4368
+ )
4369
+ ] })
4370
+ ] }),
4371
+ returnOrder.status === "requested" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
4372
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxRuntime.jsx(
4373
+ ui.Button,
4374
+ {
4375
+ variant: "danger",
4376
+ onClick: handleReject,
4377
+ disabled: isRejecting,
4378
+ isLoading: isRejecting,
4379
+ children: "Reject (Cancel) Return"
4380
+ }
4381
+ ) }),
4382
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: 'Cancel this return request. Use "Mark as received" when items are received.' })
4383
+ ] }),
4384
+ returnOrder.refund ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: /* @__PURE__ */ jsxRuntime.jsx(RefundCalculationBlock, { refund: returnOrder.refund }) }) : null,
4385
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
4386
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Information" }),
4387
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
4388
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4389
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Return ID" }),
4390
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.id })
4197
4391
  ] }),
4198
- /* @__PURE__ */ jsxRuntime.jsx(
4199
- ui.Badge,
4392
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
4393
+ ui.Button,
4200
4394
  {
4201
- size: "small",
4202
- className: `uppercase ${getStatusBadgeClass$2(swap.status)}`,
4203
- children: swap.status.replace(/_/g, " ")
4395
+ variant: "secondary",
4396
+ onClick: () => {
4397
+ window.open(
4398
+ `/app/orders/${returnOrder.order_id}`,
4399
+ "_blank"
4400
+ );
4401
+ },
4402
+ children: "View order"
4204
4403
  }
4205
- )
4404
+ ) })
4206
4405
  ] })
4207
4406
  ] }),
4208
- canCancelExchange && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
4209
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxRuntime.jsx(
4210
- ui.Button,
4211
- {
4212
- variant: "danger",
4213
- onClick: handleCancelExchange,
4214
- disabled: isCancelling,
4215
- isLoading: isCancelling,
4216
- children: "Cancel Exchange"
4217
- }
4218
- ) }),
4219
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "This will cancel the exchange request. The order will remain unchanged." })
4220
- ] }),
4221
4407
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
4222
4408
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
4223
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Exchange Information" }),
4409
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Details" }),
4224
4410
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
4225
4411
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4226
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
4227
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.id })
4412
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Return ID" }),
4413
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.id })
4228
4414
  ] }),
4229
4415
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4230
4416
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Status" }),
4231
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.status })
4232
- ] }),
4233
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4234
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Difference Due" }),
4235
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.difference_due != null ? `${swap.currency_code || "$"}${(Number(swap.difference_due) / 100).toFixed(2)}` : "—" })
4417
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.status })
4236
4418
  ] }),
4237
- swap.reason && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4419
+ returnOrder.reason && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4238
4420
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Reason" }),
4239
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.reason })
4421
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.reason })
4240
4422
  ] }),
4241
- swap.note && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4423
+ returnOrder.note && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4242
4424
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Note" }),
4243
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.note })
4425
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.note })
4244
4426
  ] }),
4245
4427
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4246
4428
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Created" }),
4247
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(swap.created_at).toLocaleString() })
4429
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(returnOrder.created_at).toLocaleString() })
4248
4430
  ] }),
4249
4431
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4250
4432
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Last Updated" }),
4251
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(swap.updated_at).toLocaleString() })
4252
- ] }),
4253
- swap.exchange_id && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4254
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
4255
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.exchange_id })
4433
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(returnOrder.updated_at).toLocaleString() })
4256
4434
  ] })
4257
4435
  ] })
4258
4436
  ] }),
@@ -4267,7 +4445,7 @@ const SwapDetailPage = () => {
4267
4445
  ui.Badge,
4268
4446
  {
4269
4447
  size: "2xsmall",
4270
- className: `uppercase ${getStatusBadgeClass$2(entry.status)}`,
4448
+ className: `uppercase ${getStatusBadgeClass$1(entry.status)}`,
4271
4449
  children: entry.status.replace(/_/g, " ")
4272
4450
  }
4273
4451
  ) }),
@@ -4282,31 +4460,35 @@ const SwapDetailPage = () => {
4282
4460
  )) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No status history available" })
4283
4461
  ] })
4284
4462
  ] }),
4285
- order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
4463
+ returnOrder.order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
4286
4464
  /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Related Order Information" }),
4287
4465
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
4288
4466
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4289
4467
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order ID" }),
4290
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.id })
4468
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.id })
4291
4469
  ] }),
4292
4470
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4293
4471
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Status" }),
4294
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.status || "—" })
4472
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.status || "—" })
4295
4473
  ] }),
4296
4474
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4297
4475
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
4298
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_c = order.customer) == null ? void 0 : _c.email) || order.email || "—" })
4476
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.customer?.email || returnOrder.order.email || "—" })
4299
4477
  ] }),
4300
- order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4478
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4479
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Payment method" }),
4480
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.order_payment?.label || "—" })
4481
+ ] }),
4482
+ returnOrder.order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4301
4483
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
4302
4484
  /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "font-medium", children: [
4303
- order.currency_code || "$",
4304
- (Number(order.total) / 100).toFixed(2)
4485
+ returnOrder.order.currency_code || "$",
4486
+ (Number(returnOrder.order.total) / 100).toFixed(2)
4305
4487
  ] })
4306
4488
  ] })
4307
4489
  ] })
4308
4490
  ] }),
4309
- swap.return_items && swap.return_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
4491
+ returnOrder.return_items && returnOrder.return_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
4310
4492
  /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Items" }),
4311
4493
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
4312
4494
  /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
@@ -4314,33 +4496,22 @@ const SwapDetailPage = () => {
4314
4496
  /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" }),
4315
4497
  /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Reason" })
4316
4498
  ] }) }),
4317
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.return_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
4499
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: returnOrder.return_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
4318
4500
  /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.id }),
4319
4501
  /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity }),
4320
4502
  /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.reason || "—" })
4321
4503
  ] }, item.id || index)) })
4322
4504
  ] }) })
4323
4505
  ] }),
4324
- swap.new_items && swap.new_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
4325
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "New Items" }),
4326
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
4327
- /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
4328
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Variant ID" }),
4329
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" })
4330
- ] }) }),
4331
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.new_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
4332
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.variant_id }),
4333
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity })
4334
- ] }, item.variant_id || index)) })
4335
- ] }) })
4336
- ] })
4506
+ updateError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-ui-border-error bg-ui-bg-error-subtle p-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-error", children: updateError }) }),
4507
+ updateSuccess && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-ui-border-success bg-ui-bg-success-subtle p-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-success", children: "Action completed successfully" }) })
4337
4508
  ] }) });
4338
4509
  };
4339
- const config$2 = adminSdk.defineRouteConfig({
4340
- label: "Swap Details",
4341
- icon: icons.ArrowPath
4510
+ const config$1 = adminSdk.defineRouteConfig({
4511
+ label: "Return Order Details",
4512
+ icon: icons.CheckCircle
4342
4513
  });
4343
- const getStatusBadgeClass$1 = (status) => {
4514
+ const getStatusBadgeClass = (status) => {
4344
4515
  const statusLower = status.toLowerCase();
4345
4516
  if (statusLower === "requested") {
4346
4517
  return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
@@ -4351,105 +4522,108 @@ const getStatusBadgeClass$1 = (status) => {
4351
4522
  if (statusLower === "rejected") {
4352
4523
  return "bg-ui-tag-red-bg text-ui-tag-red-text";
4353
4524
  }
4354
- if (statusLower === "received") {
4355
- return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
4356
- }
4357
- if (statusLower === "refunded") {
4358
- return "bg-ui-tag-green-bg text-ui-tag-green-text";
4359
- }
4360
4525
  if (statusLower === "completed") {
4361
4526
  return "bg-ui-tag-green-bg text-ui-tag-green-text";
4362
4527
  }
4363
- if (statusLower === "cancelled") {
4528
+ if (statusLower === "cancelled" || statusLower === "canceled") {
4364
4529
  return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
4365
4530
  }
4531
+ if (statusLower === "pending") {
4532
+ return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
4533
+ }
4366
4534
  return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
4367
4535
  };
4368
- const ReturnDetailPage = () => {
4369
- var _a, _b, _c;
4536
+ const SwapDetailPage = () => {
4370
4537
  const navigate = reactRouterDom.useNavigate();
4371
4538
  const { id } = reactRouterDom.useParams();
4372
- const [returnOrder, setReturnOrder] = react.useState(null);
4539
+ const [swap, setSwap] = react.useState(null);
4540
+ const [order, setOrder] = react.useState(null);
4373
4541
  const [isLoading, setIsLoading] = react.useState(true);
4374
4542
  const [isRejecting, setIsRejecting] = react.useState(false);
4543
+ const [isCancelling, setIsCancelling] = react.useState(false);
4375
4544
  const [error, setError] = react.useState(null);
4376
4545
  const [updateError, setUpdateError] = react.useState(null);
4377
4546
  const [updateSuccess, setUpdateSuccess] = react.useState(false);
4378
4547
  react.useEffect(() => {
4379
4548
  if (!id) {
4380
- navigate("/returns");
4549
+ navigate("/swaps");
4381
4550
  return;
4382
4551
  }
4383
- const loadReturn = async () => {
4552
+ const loadSwap = async () => {
4384
4553
  try {
4385
4554
  setIsLoading(true);
4386
4555
  setError(null);
4387
- const response = await fetch(`/admin/return/${id}`, {
4556
+ const response = await fetch(`/admin/swaps/${id}`, {
4388
4557
  credentials: "include"
4389
4558
  });
4390
4559
  if (!response.ok) {
4391
4560
  const message = await response.text();
4392
- throw new Error(message || "Unable to load return order");
4561
+ throw new Error(message || "Unable to load swap");
4393
4562
  }
4394
4563
  const payload = await response.json();
4395
- setReturnOrder(payload.return);
4564
+ setSwap(payload.swap);
4565
+ setOrder(payload.order || null);
4396
4566
  } catch (loadError) {
4397
- const message = loadError instanceof Error ? loadError.message : "Unable to load return order";
4567
+ const message = loadError instanceof Error ? loadError.message : "Unable to load swap";
4398
4568
  setError(message);
4399
4569
  } finally {
4400
4570
  setIsLoading(false);
4401
4571
  }
4402
4572
  };
4403
- void loadReturn();
4573
+ void loadSwap();
4404
4574
  }, [id, navigate]);
4405
- const handleReject = async () => {
4575
+ const handleCancelExchange = async () => {
4406
4576
  if (!id) {
4407
4577
  return;
4408
4578
  }
4409
4579
  try {
4410
- setIsRejecting(true);
4580
+ setIsCancelling(true);
4411
4581
  setUpdateError(null);
4412
4582
  setUpdateSuccess(false);
4413
- const response = await fetch(`/admin/return/${id}/reject`, {
4583
+ const response = await fetch(`/admin/swaps/${id}/cancel`, {
4414
4584
  method: "POST",
4415
4585
  headers: {
4416
4586
  "Content-Type": "application/json"
4417
4587
  },
4418
- credentials: "include",
4419
- body: JSON.stringify({ reason: "Rejected by admin" })
4588
+ credentials: "include"
4420
4589
  });
4421
4590
  if (!response.ok) {
4422
4591
  const message = await response.text();
4423
- throw new Error(message || "Unable to reject return");
4592
+ throw new Error(message || "Unable to cancel exchange");
4424
4593
  }
4425
4594
  const payload = await response.json();
4426
- setReturnOrder(payload.return);
4595
+ setSwap(payload.swap);
4427
4596
  setUpdateSuccess(true);
4428
4597
  setTimeout(() => setUpdateSuccess(false), 3e3);
4429
- const detailResponse = await fetch(`/admin/return/${id}`, {
4598
+ const detailResponse = await fetch(`/admin/swaps/${id}`, {
4430
4599
  credentials: "include"
4431
4600
  });
4432
4601
  if (detailResponse.ok) {
4433
4602
  const detailPayload = await detailResponse.json();
4434
- setReturnOrder(detailPayload.return);
4603
+ setSwap(detailPayload.swap);
4604
+ setOrder(detailPayload.order || null);
4435
4605
  }
4436
- } catch (updateErr) {
4437
- const message = updateErr instanceof Error ? updateErr.message : "Unable to reject return";
4606
+ } catch (cancelErr) {
4607
+ const message = cancelErr instanceof Error ? cancelErr.message : "Unable to cancel exchange";
4438
4608
  setUpdateError(message);
4439
4609
  } finally {
4440
- setIsRejecting(false);
4610
+ setIsCancelling(false);
4441
4611
  }
4442
4612
  };
4613
+ const isOrderExchange = Boolean(swap?.exchange_id);
4614
+ const canCancelExchange = isOrderExchange && swap && !["cancelled", "canceled", "completed", "declined"].includes(
4615
+ swap.status?.toLowerCase() ?? ""
4616
+ );
4443
4617
  if (isLoading) {
4444
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading return order..." }) }) }) });
4618
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading swap..." }) }) }) });
4445
4619
  }
4446
- if (error || !returnOrder) {
4620
+ if (error || !swap) {
4447
4621
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
4448
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "Return order not found" }),
4449
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/returns"), children: "Back to list" }) })
4622
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "Swap not found" }),
4623
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/swaps"), children: "Back to list" }) })
4450
4624
  ] }) }) });
4451
4625
  }
4452
- const statusHistory = ((_a = returnOrder.metadata) == null ? void 0 : _a.status_history) || [];
4626
+ const statusHistory = swap.metadata?.status_history || [];
4453
4627
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: [
4454
4628
  /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
4455
4629
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -4457,7 +4631,7 @@ const ReturnDetailPage = () => {
4457
4631
  {
4458
4632
  variant: "transparent",
4459
4633
  size: "small",
4460
- onClick: () => navigate("/returns"),
4634
+ onClick: () => navigate("/swaps"),
4461
4635
  className: "w-fit",
4462
4636
  children: [
4463
4637
  /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, { className: "mr-2" }),
@@ -4467,82 +4641,67 @@ const ReturnDetailPage = () => {
4467
4641
  ),
4468
4642
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 md:flex-row md:items-center md:justify-between", children: [
4469
4643
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
4470
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Return Order Details" }),
4471
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: returnOrder.id })
4644
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Exchange Details" }),
4645
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: swap.id })
4472
4646
  ] }),
4473
4647
  /* @__PURE__ */ jsxRuntime.jsx(
4474
4648
  ui.Badge,
4475
4649
  {
4476
4650
  size: "small",
4477
- className: `uppercase ${getStatusBadgeClass$1(returnOrder.status)}`,
4478
- children: returnOrder.status.replace(/_/g, " ")
4651
+ className: `uppercase ${getStatusBadgeClass(swap.status)}`,
4652
+ children: swap.status.replace(/_/g, " ")
4479
4653
  }
4480
4654
  )
4481
4655
  ] })
4482
4656
  ] }),
4483
- returnOrder.status === "requested" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
4657
+ canCancelExchange && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
4484
4658
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxRuntime.jsx(
4485
4659
  ui.Button,
4486
4660
  {
4487
4661
  variant: "danger",
4488
- onClick: handleReject,
4489
- disabled: isRejecting,
4490
- isLoading: isRejecting,
4491
- children: "Reject (Cancel) Return"
4662
+ onClick: handleCancelExchange,
4663
+ disabled: isCancelling,
4664
+ isLoading: isCancelling,
4665
+ children: "Cancel Exchange"
4492
4666
  }
4493
4667
  ) }),
4494
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: 'Cancel this return request. Use "Mark as received" when items are received.' })
4495
- ] }),
4496
- returnOrder.refund ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: /* @__PURE__ */ jsxRuntime.jsx(RefundCalculationBlock, { refund: returnOrder.refund }) }) : null,
4497
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
4498
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Information" }),
4499
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
4500
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4501
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Return ID" }),
4502
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.id })
4503
- ] }),
4504
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
4505
- ui.Button,
4506
- {
4507
- variant: "secondary",
4508
- onClick: () => {
4509
- window.open(
4510
- `/app/orders/${returnOrder.order_id}`,
4511
- "_blank"
4512
- );
4513
- },
4514
- children: "View order"
4515
- }
4516
- ) })
4517
- ] })
4668
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "This will cancel the exchange request. The order will remain unchanged." })
4518
4669
  ] }),
4519
4670
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
4520
4671
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
4521
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Details" }),
4672
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Exchange Information" }),
4522
4673
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
4523
4674
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4524
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Return ID" }),
4525
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.id })
4675
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
4676
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.id })
4526
4677
  ] }),
4527
4678
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4528
4679
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Status" }),
4529
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.status })
4680
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.status })
4530
4681
  ] }),
4531
- returnOrder.reason && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4682
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4683
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Difference Due" }),
4684
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.difference_due != null ? `${swap.currency_code || "$"}${(Number(swap.difference_due) / 100).toFixed(2)}` : "—" })
4685
+ ] }),
4686
+ swap.reason && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4532
4687
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Reason" }),
4533
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.reason })
4688
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.reason })
4534
4689
  ] }),
4535
- returnOrder.note && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4690
+ swap.note && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4536
4691
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Note" }),
4537
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.note })
4692
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.note })
4538
4693
  ] }),
4539
4694
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4540
4695
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Created" }),
4541
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(returnOrder.created_at).toLocaleString() })
4696
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(swap.created_at).toLocaleString() })
4542
4697
  ] }),
4543
4698
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4544
4699
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Last Updated" }),
4545
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(returnOrder.updated_at).toLocaleString() })
4700
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(swap.updated_at).toLocaleString() })
4701
+ ] }),
4702
+ swap.exchange_id && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4703
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
4704
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.exchange_id })
4546
4705
  ] })
4547
4706
  ] })
4548
4707
  ] }),
@@ -4557,7 +4716,7 @@ const ReturnDetailPage = () => {
4557
4716
  ui.Badge,
4558
4717
  {
4559
4718
  size: "2xsmall",
4560
- className: `uppercase ${getStatusBadgeClass$1(entry.status)}`,
4719
+ className: `uppercase ${getStatusBadgeClass(entry.status)}`,
4561
4720
  children: entry.status.replace(/_/g, " ")
4562
4721
  }
4563
4722
  ) }),
@@ -4572,35 +4731,31 @@ const ReturnDetailPage = () => {
4572
4731
  )) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No status history available" })
4573
4732
  ] })
4574
4733
  ] }),
4575
- returnOrder.order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
4734
+ order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
4576
4735
  /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Related Order Information" }),
4577
4736
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
4578
4737
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4579
4738
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order ID" }),
4580
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.id })
4739
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.id })
4581
4740
  ] }),
4582
4741
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4583
4742
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Status" }),
4584
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.status || "—" })
4743
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.status || "—" })
4585
4744
  ] }),
4586
4745
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4587
4746
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
4588
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_b = returnOrder.order.customer) == null ? void 0 : _b.email) || returnOrder.order.email || "—" })
4747
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.customer?.email || order.email || "—" })
4589
4748
  ] }),
4590
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4591
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Payment method" }),
4592
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_c = returnOrder.order.order_payment) == null ? void 0 : _c.label) || "—" })
4593
- ] }),
4594
- returnOrder.order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4749
+ order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4595
4750
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
4596
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "font-medium", children: [
4597
- returnOrder.order.currency_code || "$",
4598
- (Number(returnOrder.order.total) / 100).toFixed(2)
4751
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "font-medium", children: [
4752
+ order.currency_code || "$",
4753
+ (Number(order.total) / 100).toFixed(2)
4599
4754
  ] })
4600
4755
  ] })
4601
4756
  ] })
4602
4757
  ] }),
4603
- returnOrder.return_items && returnOrder.return_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
4758
+ swap.return_items && swap.return_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
4604
4759
  /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Items" }),
4605
4760
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
4606
4761
  /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
@@ -4608,323 +4763,172 @@ const ReturnDetailPage = () => {
4608
4763
  /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" }),
4609
4764
  /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Reason" })
4610
4765
  ] }) }),
4611
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: returnOrder.return_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
4766
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.return_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
4612
4767
  /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.id }),
4613
4768
  /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity }),
4614
4769
  /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.reason || "—" })
4615
4770
  ] }, item.id || index)) })
4616
4771
  ] }) })
4617
4772
  ] }),
4618
- updateError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-ui-border-error bg-ui-bg-error-subtle p-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-error", children: updateError }) }),
4619
- updateSuccess && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-ui-border-success bg-ui-bg-success-subtle p-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-success", children: "Action completed successfully" }) })
4620
- ] }) });
4621
- };
4622
- const config$1 = adminSdk.defineRouteConfig({
4623
- label: "Return Order Details",
4624
- icon: icons.CheckCircle
4625
- });
4626
- const getStatusBadgeClass = (status) => {
4627
- const s2 = status.toLowerCase();
4628
- if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
4629
- if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
4630
- if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
4631
- if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
4632
- return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
4633
- };
4634
- const formatAmount = (value) => {
4635
- return String(value);
4636
- };
4637
- const RefundDetailPage = () => {
4638
- var _a, _b, _c;
4639
- const navigate = reactRouterDom.useNavigate();
4640
- const params = reactRouterDom.useParams();
4641
- const id = (_a = params == null ? void 0 : params.id) == null ? void 0 : _a.trim();
4642
- const [detail, setDetail] = react.useState(null);
4643
- const [loading, setLoading] = react.useState(!!id);
4644
- const [error, setError] = react.useState(null);
4645
- const [gatewayExpanded, setGatewayExpanded] = react.useState(false);
4646
- react.useEffect(() => {
4647
- if (!id) {
4648
- setLoading(false);
4649
- return;
4650
- }
4651
- let cancelled = false;
4652
- setLoading(true);
4653
- setError(null);
4654
- fetch(`/admin/refunds/${id}`, { credentials: "include" }).then((res) => {
4655
- if (!res.ok) throw new Error(res.statusText || "Failed to load");
4656
- return res.json();
4657
- }).then((data) => {
4658
- if (!cancelled) setDetail(data);
4659
- }).catch((e) => {
4660
- if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
4661
- }).finally(() => {
4662
- if (!cancelled) setLoading(false);
4663
- });
4664
- return () => {
4665
- cancelled = true;
4666
- };
4667
- }, [id]);
4668
- const paymentStatus = ((_b = detail == null ? void 0 : detail.payment) == null ? void 0 : _b.status) ?? "—";
4669
- const hasGatewayData = ((_c = detail == null ? void 0 : detail.payment) == null ? void 0 : _c.payment_data) && typeof detail.payment.payment_data === "object" && Object.keys(detail.payment.payment_data).length > 0;
4670
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-4xl flex-col gap-6 p-6", children: [
4671
- /* @__PURE__ */ jsxRuntime.jsx("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
4672
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => navigate("/refunds"), children: "← Refunds" }),
4673
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Refund details" }),
4674
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle font-mono", children: id ?? "—" })
4675
- ] }) }),
4676
- error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
4677
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
4678
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/refunds"), children: "Back to list" })
4679
- ] }) : loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading…" }) }) : detail ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
4680
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
4681
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Refund summary" }),
4682
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
4683
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4684
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refund ID" }),
4685
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.id })
4686
- ] }),
4687
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4688
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
4689
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.refund.amount) })
4690
- ] }),
4691
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4692
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Note" }),
4693
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.refund.note ?? "—" })
4694
- ] }),
4695
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4696
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created at" }),
4697
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: new Date(detail.refund.created_at).toLocaleDateString("en-US", {
4698
- year: "numeric",
4699
- month: "short",
4700
- day: "numeric",
4701
- hour: "numeric",
4702
- minute: "2-digit",
4703
- hour12: true
4704
- }) })
4705
- ] }),
4706
- detail.refund.created_by ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4707
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created by" }),
4708
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.created_by })
4709
- ] }) : null
4710
- ] })
4711
- ] }),
4712
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
4713
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Payment summary" }),
4714
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
4715
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4716
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Payment amount" }),
4717
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.payment_amount) })
4718
- ] }),
4719
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4720
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Captured amount" }),
4721
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.captured_amount) })
4722
- ] }),
4723
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4724
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refunded amount" }),
4725
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.refunded_amount) })
4726
- ] }),
4727
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4728
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
4729
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.payment.provider_id || "—" })
4730
- ] }),
4731
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4732
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
4733
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
4734
- ui.Badge,
4735
- {
4736
- size: "2xsmall",
4737
- className: `uppercase ${getStatusBadgeClass(paymentStatus)}`,
4738
- children: paymentStatus !== "—" ? paymentStatus.replace(/_/g, " ") : "—"
4739
- }
4740
- ) })
4741
- ] }),
4742
- detail.computed ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4743
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4744
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Full refund" }),
4745
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.computed.is_full_refund ? "Yes" : "No" })
4746
- ] }),
4747
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4748
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Remaining refundable" }),
4749
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.computed.remaining_refundable_amount) })
4750
- ] }),
4751
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4752
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refund %" }),
4753
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "mt-1 block", children: [
4754
- detail.computed.refund_percentage.toFixed(1),
4755
- "%"
4756
- ] })
4757
- ] })
4758
- ] }) : null
4759
- ] })
4760
- ] }),
4761
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
4762
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Order summary" }),
4763
- detail.order ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
4764
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4765
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Order" }),
4766
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
4767
- ui.Button,
4768
- {
4769
- variant: "transparent",
4770
- size: "small",
4771
- onClick: () => navigate(`/orders/${detail.order.order_id}`),
4772
- children: detail.order.order_number ?? detail.order.order_id
4773
- }
4774
- ) })
4775
- ] }),
4776
- detail.order.total != null ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4777
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Total" }),
4778
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.order.total) })
4779
- ] }) : null,
4780
- detail.order.customer_id ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4781
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Customer ID" }),
4782
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.order.customer_id })
4783
- ] }) : null,
4784
- detail.order.region ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4785
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Region" }),
4786
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.region })
4787
- ] }) : null,
4788
- detail.order.fulfillment_status ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4789
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Fulfillment status" }),
4790
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.fulfillment_status })
4791
- ] }) : null
4792
- ] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No order linked to this refund." })
4793
- ] }),
4794
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
4795
- /* @__PURE__ */ jsxRuntime.jsxs(
4796
- "button",
4797
- {
4798
- type: "button",
4799
- className: "flex w-full items-center justify-between text-left",
4800
- onClick: () => setGatewayExpanded((prev) => !prev),
4801
- "aria-expanded": gatewayExpanded,
4802
- "aria-label": gatewayExpanded ? "Collapse gateway data" : "Expand gateway data",
4803
- children: [
4804
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg", children: "Gateway data" }),
4805
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: gatewayExpanded ? "Collapse" : "Expand" })
4806
- ]
4807
- }
4808
- ),
4809
- gatewayExpanded && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4", children: hasGatewayData ? /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-xs bg-ui-bg-subtle p-4 rounded-lg overflow-auto max-h-96", children: JSON.stringify(detail.payment.payment_data, null, 2) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No gateway payload for this payment." }) })
4810
- ] })
4811
- ] }) : null
4773
+ swap.new_items && swap.new_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
4774
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "New Items" }),
4775
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
4776
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
4777
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Variant ID" }),
4778
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" })
4779
+ ] }) }),
4780
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.new_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
4781
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.variant_id }),
4782
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity })
4783
+ ] }, item.variant_id || index)) })
4784
+ ] }) })
4785
+ ] })
4812
4786
  ] }) });
4813
4787
  };
4814
4788
  const config = adminSdk.defineRouteConfig({
4815
- label: "Refund details",
4816
- icon: icons.Receipt
4789
+ label: "Swap Details",
4790
+ icon: icons.ArrowPath
4817
4791
  });
4818
4792
  const i18nTranslations0 = {};
4819
4793
  const widgetModule = { widgets: [
4820
4794
  {
4821
4795
  Component: OrderGiftItemsWidget,
4822
- zone: ["order.details.side.after"]
4796
+ zone: ["order.details.side.after"],
4797
+ widgetId: "Widget-b753"
4823
4798
  },
4824
4799
  {
4825
4800
  Component: OrderRefundContextWidget,
4826
- zone: ["order.details.after"]
4801
+ zone: ["order.details.after"],
4802
+ widgetId: "Widget-0606"
4827
4803
  }
4828
4804
  ] };
4829
4805
  const routeModule = {
4830
4806
  routes: [
4831
4807
  {
4832
4808
  Component: DeletedRecordsPage,
4833
- path: "/deleted-records-audit"
4809
+ path: "/deleted-records-audit",
4810
+ handle: { label: config$9.label, translationNs: config$9.translationNs }
4834
4811
  },
4835
4812
  {
4836
- Component: PaymentsPage,
4837
- path: "/payments"
4813
+ Component: RefundsPage,
4814
+ path: "/refunds",
4815
+ handle: { label: config$8.label, translationNs: config$8.translationNs }
4838
4816
  },
4839
4817
  {
4840
- Component: ReturnsPage,
4841
- path: "/returns"
4818
+ Component: PaymentsPage,
4819
+ path: "/payments",
4820
+ handle: { label: config$7.label, translationNs: config$7.translationNs }
4842
4821
  },
4843
4822
  {
4844
- Component: DeletedRecordDetailPage,
4845
- path: "/deleted-records-audit/:id"
4823
+ Component: ReturnsPage,
4824
+ path: "/returns",
4825
+ handle: { label: config$6.label, translationNs: config$6.translationNs }
4846
4826
  },
4847
4827
  {
4848
4828
  Component: SwapsPage,
4849
- path: "/swaps"
4829
+ path: "/swaps",
4830
+ handle: { label: config$5.label, translationNs: config$5.translationNs }
4850
4831
  },
4851
4832
  {
4852
- Component: RefundsPage,
4853
- path: "/refunds"
4833
+ Component: DeletedRecordDetailPage,
4834
+ path: "/deleted-records-audit/:id",
4835
+ handle: { label: config$4.label, translationNs: config$4.translationNs }
4854
4836
  },
4855
4837
  {
4856
- Component: PaymentDetailPage,
4857
- path: "/payments/:id"
4838
+ Component: RefundDetailPage,
4839
+ path: "/refunds/:id",
4840
+ handle: { label: config$3.label, translationNs: config$3.translationNs }
4858
4841
  },
4859
4842
  {
4860
- Component: SwapDetailPage,
4861
- path: "/swaps/:id"
4843
+ Component: PaymentDetailPage,
4844
+ path: "/payments/:id",
4845
+ handle: { label: config$2.label, translationNs: config$2.translationNs }
4862
4846
  },
4863
4847
  {
4864
4848
  Component: ReturnDetailPage,
4865
- path: "/returns/:id"
4849
+ path: "/returns/:id",
4850
+ handle: { label: config$1.label, translationNs: config$1.translationNs }
4866
4851
  },
4867
4852
  {
4868
- Component: RefundDetailPage,
4869
- path: "/refunds/:id"
4853
+ Component: SwapDetailPage,
4854
+ path: "/swaps/:id",
4855
+ handle: { label: config.label, translationNs: config.translationNs }
4870
4856
  }
4871
4857
  ]
4872
4858
  };
4873
4859
  const menuItemModule = {
4874
4860
  menuItems: [
4875
4861
  {
4876
- label: config$8.label,
4877
- icon: config$8.icon,
4862
+ label: config$9.label,
4863
+ icon: config$9.icon,
4878
4864
  path: "/deleted-records-audit",
4879
- nested: void 0
4865
+ nested: void 0,
4866
+ rank: void 0,
4867
+ translationNs: void 0
4880
4868
  },
4881
4869
  {
4882
4870
  label: config$7.label,
4883
4871
  icon: config$7.icon,
4884
4872
  path: "/payments",
4885
- nested: void 0
4873
+ nested: void 0,
4874
+ rank: void 0,
4875
+ translationNs: void 0
4876
+ },
4877
+ {
4878
+ label: config$8.label,
4879
+ icon: config$8.icon,
4880
+ path: "/refunds",
4881
+ nested: void 0,
4882
+ rank: void 0,
4883
+ translationNs: void 0
4886
4884
  },
4887
4885
  {
4888
4886
  label: config$6.label,
4889
4887
  icon: config$6.icon,
4890
4888
  path: "/returns",
4891
- nested: void 0
4889
+ nested: void 0,
4890
+ rank: void 0,
4891
+ translationNs: void 0
4892
4892
  },
4893
4893
  {
4894
4894
  label: config$5.label,
4895
4895
  icon: config$5.icon,
4896
4896
  path: "/swaps",
4897
- nested: void 0
4897
+ nested: void 0,
4898
+ rank: void 0,
4899
+ translationNs: void 0
4898
4900
  },
4899
4901
  {
4900
- label: config$4.label,
4901
- icon: config$4.icon,
4902
- path: "/refunds",
4903
- nested: void 0
4902
+ label: config$2.label,
4903
+ icon: config$2.icon,
4904
+ path: "/payments/:id",
4905
+ nested: void 0,
4906
+ rank: void 0,
4907
+ translationNs: void 0
4904
4908
  },
4905
4909
  {
4906
4910
  label: config$3.label,
4907
4911
  icon: config$3.icon,
4908
- path: "/payments/:id",
4909
- nested: void 0
4912
+ path: "/refunds/:id",
4913
+ nested: void 0,
4914
+ rank: void 0,
4915
+ translationNs: void 0
4910
4916
  },
4911
4917
  {
4912
4918
  label: config$1.label,
4913
4919
  icon: config$1.icon,
4914
4920
  path: "/returns/:id",
4915
- nested: void 0
4916
- },
4917
- {
4918
- label: config$2.label,
4919
- icon: config$2.icon,
4920
- path: "/swaps/:id",
4921
- nested: void 0
4921
+ nested: void 0,
4922
+ rank: void 0,
4923
+ translationNs: void 0
4922
4924
  },
4923
4925
  {
4924
4926
  label: config.label,
4925
4927
  icon: config.icon,
4926
- path: "/refunds/:id",
4927
- nested: void 0
4928
+ path: "/swaps/:id",
4929
+ nested: void 0,
4930
+ rank: void 0,
4931
+ translationNs: void 0
4928
4932
  }
4929
4933
  ]
4930
4934
  };
@@ -4933,12 +4937,18 @@ const displayModule = {
4933
4937
  displays: {}
4934
4938
  };
4935
4939
  const i18nModule = { resources: i18nTranslations0 };
4940
+ const cellRendererModule = {};
4941
+ const layoutModule = { layouts: [] };
4942
+ const searchEntityModule = {};
4936
4943
  const plugin = {
4937
4944
  widgetModule,
4938
4945
  routeModule,
4939
4946
  menuItemModule,
4940
4947
  formModule,
4941
4948
  displayModule,
4942
- i18nModule
4949
+ i18nModule,
4950
+ cellRendererModule,
4951
+ layoutModule,
4952
+ searchEntityModule
4943
4953
  };
4944
4954
  module.exports = plugin;