order-management 0.0.100 → 0.0.102

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: [
@@ -936,501 +924,6 @@ const OrderRefundContextWidget = (props) => {
936
924
  adminSdk.defineWidgetConfig({
937
925
  zone: "order.details.after"
938
926
  });
939
- const useDebounce$3 = (value, delay) => {
940
- const [debouncedValue, setDebouncedValue] = react.useState(value);
941
- react.useEffect(() => {
942
- const handler = setTimeout(() => setDebouncedValue(value), delay);
943
- return () => clearTimeout(handler);
944
- }, [value, delay]);
945
- return debouncedValue;
946
- };
947
- const getStatusBadgeClass$7 = (status) => {
948
- const s2 = status.toLowerCase();
949
- if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
950
- if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
951
- if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
952
- if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
953
- return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
954
- };
955
- const PaymentsPage = () => {
956
- const navigate = reactRouterDom.useNavigate();
957
- const [items, setItems] = react.useState([]);
958
- const [statusFilter, setStatusFilter] = react.useState("all");
959
- const [orderIdSearch, setOrderIdSearch] = react.useState("");
960
- const debouncedOrderId = useDebounce$3(orderIdSearch, 300);
961
- const [isLoading, setIsLoading] = react.useState(true);
962
- const [isFetchingMore, setIsFetchingMore] = react.useState(false);
963
- const [error, setError] = react.useState(null);
964
- const [offset, setOffset] = react.useState(0);
965
- const [count, setCount] = react.useState(0);
966
- const limit = 50;
967
- const loadTransactions = react.useCallback(
968
- async (nextOffset, replace) => {
969
- try {
970
- if (replace) setIsLoading(true);
971
- else setIsFetchingMore(true);
972
- setError(null);
973
- const params = new URLSearchParams();
974
- params.set("limit", String(limit));
975
- params.set("offset", String(nextOffset));
976
- if (statusFilter !== "all") params.set("status", statusFilter);
977
- if (debouncedOrderId.trim()) params.set("order_id", debouncedOrderId.trim());
978
- const response = await fetch(
979
- `/admin/payment-transactions?${params.toString()}`,
980
- { credentials: "include" }
981
- );
982
- if (!response.ok) {
983
- const text = await response.text();
984
- throw new Error(text || "Failed to load payment transactions");
985
- }
986
- const payload = await response.json();
987
- const list = payload.transactions ?? [];
988
- setCount(payload.count ?? 0);
989
- setOffset(nextOffset + list.length);
990
- setItems((prev) => replace ? list : [...prev, ...list]);
991
- } catch (e) {
992
- setError(e instanceof Error ? e.message : "Failed to load");
993
- } finally {
994
- setIsLoading(false);
995
- setIsFetchingMore(false);
996
- }
997
- },
998
- [statusFilter, debouncedOrderId]
999
- );
1000
- react.useEffect(() => {
1001
- void loadTransactions(0, true);
1002
- }, [loadTransactions]);
1003
- const hasMore = react.useMemo(() => offset < count, [offset, count]);
1004
- const displayStatus = (t) => {
1005
- const s2 = t.payment_id != null && t.payment_status != null && t.payment_status !== "" ? t.payment_status : t.session_status ?? "";
1006
- return s2 !== "" ? s2 : "—";
1007
- };
1008
- const displayAmount = (t) => {
1009
- const code = (t.currency_code ?? "USD").toUpperCase();
1010
- return `${code} ${Number(t.amount)}`;
1011
- };
1012
- 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: [
1013
- /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
1014
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
1015
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Payments" }),
1016
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "All payment attempts — completed, pending, failed, requires action" })
1017
- ] }),
1018
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadTransactions(0, true), children: "Refresh" })
1019
- ] }),
1020
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
1021
- /* @__PURE__ */ jsxRuntime.jsx(
1022
- ui.Input,
1023
- {
1024
- placeholder: "Search by Order ID",
1025
- value: orderIdSearch,
1026
- onChange: (e) => setOrderIdSearch(e.target.value),
1027
- className: "md:max-w-sm",
1028
- "aria-label": "Search by order ID"
1029
- }
1030
- ),
1031
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxRuntime.jsxs(
1032
- "select",
1033
- {
1034
- value: statusFilter,
1035
- onChange: (e) => setStatusFilter(e.target.value),
1036
- 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",
1037
- "aria-label": "Filter by status",
1038
- children: [
1039
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All statuses" }),
1040
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "pending", children: "Pending" }),
1041
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "requires_more", children: "Requires more" }),
1042
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "error", children: "Error" }),
1043
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "canceled", children: "Canceled" }),
1044
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "authorized", children: "Authorized" }),
1045
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "captured", children: "Captured" })
1046
- ]
1047
- }
1048
- ) })
1049
- ] }),
1050
- error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
1051
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
1052
- /* @__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" }) })
1053
- ] }) : null,
1054
- 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: [
1055
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No payment transactions yet" }),
1056
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Payment attempts will appear here." })
1057
- ] }) : /* @__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: [
1058
- /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
1059
- /* @__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" }),
1060
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Amount" }),
1061
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Provider" }),
1062
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
1063
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Finalized" }),
1064
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
1065
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
1066
- ] }) }),
1067
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((t) => /* @__PURE__ */ jsxRuntime.jsxs(
1068
- "tr",
1069
- {
1070
- className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
1071
- onClick: () => navigate(`/payments/${t.payment_session_id}`),
1072
- children: [
1073
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: t.order_id ?? "—" }),
1074
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: displayAmount(t) }),
1075
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: t.provider_id }),
1076
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
1077
- ui.Badge,
1078
- {
1079
- size: "2xsmall",
1080
- className: `uppercase ${getStatusBadgeClass$7(displayStatus(t))}`,
1081
- children: displayStatus(t) !== "—" ? displayStatus(t).replace(/_/g, " ") : "—"
1082
- }
1083
- ) }),
1084
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: t.payment_id != null ? "Yes" : "No" }),
1085
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(t.created_at).toLocaleDateString("en-US", {
1086
- year: "numeric",
1087
- month: "short",
1088
- day: "numeric",
1089
- hour: "numeric",
1090
- minute: "2-digit",
1091
- hour12: true
1092
- }) }),
1093
- /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "px-4 py-4", children: [
1094
- /* @__PURE__ */ jsxRuntime.jsx(
1095
- ui.Button,
1096
- {
1097
- variant: "transparent",
1098
- size: "small",
1099
- onClick: (e) => {
1100
- e.stopPropagation();
1101
- navigate(`/payments/${t.payment_session_id}`);
1102
- },
1103
- children: "View details"
1104
- }
1105
- ),
1106
- t.order_id ? /* @__PURE__ */ jsxRuntime.jsx(
1107
- ui.Button,
1108
- {
1109
- variant: "transparent",
1110
- size: "small",
1111
- onClick: (e) => {
1112
- e.stopPropagation();
1113
- navigate(`/orders/${t.order_id}`);
1114
- },
1115
- children: "Order"
1116
- }
1117
- ) : null
1118
- ] })
1119
- ]
1120
- },
1121
- t.payment_session_id
1122
- )) })
1123
- ] }) }),
1124
- hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
1125
- ui.Button,
1126
- {
1127
- variant: "secondary",
1128
- isLoading: isFetchingMore,
1129
- onClick: () => loadTransactions(offset, false),
1130
- children: "Load more"
1131
- }
1132
- ) }) : null
1133
- ] }) });
1134
- };
1135
- const config$8 = adminSdk.defineRouteConfig({
1136
- label: "Payments",
1137
- icon: icons.CreditCard
1138
- });
1139
- const useDebounce$2 = (value, delay) => {
1140
- const [debouncedValue, setDebouncedValue] = react.useState(value);
1141
- react.useEffect(() => {
1142
- const handler = setTimeout(() => setDebouncedValue(value), delay);
1143
- return () => clearTimeout(handler);
1144
- }, [value, delay]);
1145
- return debouncedValue;
1146
- };
1147
- const getStatusBadgeClass$6 = (status) => {
1148
- const s2 = status.toLowerCase();
1149
- if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
1150
- if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
1151
- if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
1152
- if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
1153
- return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
1154
- };
1155
- const RefundsPage = () => {
1156
- const navigate = reactRouterDom.useNavigate();
1157
- const [items, setItems] = react.useState([]);
1158
- const [orderIdSearch, setOrderIdSearch] = react.useState("");
1159
- const debouncedOrderId = useDebounce$2(orderIdSearch, 300);
1160
- const [paymentStatusFilter, setPaymentStatusFilter] = react.useState("all");
1161
- const [providerSearch, setProviderSearch] = react.useState("");
1162
- const debouncedProvider = useDebounce$2(providerSearch, 300);
1163
- const [currencySearch, setCurrencySearch] = react.useState("");
1164
- const debouncedCurrency = useDebounce$2(currencySearch, 300);
1165
- const [dateFrom, setDateFrom] = react.useState("");
1166
- const [dateTo, setDateTo] = react.useState("");
1167
- const [amountMin, setAmountMin] = react.useState("");
1168
- const [amountMax, setAmountMax] = react.useState("");
1169
- const [isLoading, setIsLoading] = react.useState(true);
1170
- const [isFetchingMore, setIsFetchingMore] = react.useState(false);
1171
- const [error, setError] = react.useState(null);
1172
- const [offset, setOffset] = react.useState(0);
1173
- const [count, setCount] = react.useState(0);
1174
- const limit = 50;
1175
- const loadRefunds = react.useCallback(
1176
- async (nextOffset, replace) => {
1177
- try {
1178
- if (replace) setIsLoading(true);
1179
- else setIsFetchingMore(true);
1180
- setError(null);
1181
- const params = new URLSearchParams();
1182
- params.set("limit", String(limit));
1183
- params.set("offset", String(nextOffset));
1184
- if (debouncedOrderId.trim()) params.set("order_id", debouncedOrderId.trim());
1185
- if (paymentStatusFilter !== "all") params.set("payment_status", paymentStatusFilter);
1186
- if (debouncedProvider.trim()) params.set("provider_id", debouncedProvider.trim());
1187
- if (debouncedCurrency.trim()) params.set("currency_code", debouncedCurrency.trim());
1188
- if (dateFrom.trim()) params.set("date_from", dateFrom.trim());
1189
- if (dateTo.trim()) params.set("date_to", dateTo.trim());
1190
- const min = amountMin.trim() ? Number(amountMin) : void 0;
1191
- const max = amountMax.trim() ? Number(amountMax) : void 0;
1192
- if (min != null && !Number.isNaN(min)) params.set("amount_min", String(min));
1193
- if (max != null && !Number.isNaN(max)) params.set("amount_max", String(max));
1194
- const response = await fetch(`/admin/refunds?${params.toString()}`, {
1195
- credentials: "include"
1196
- });
1197
- if (!response.ok) {
1198
- const text = await response.text();
1199
- throw new Error(text || "Failed to load refunds");
1200
- }
1201
- const payload = await response.json();
1202
- const list = payload.refunds ?? [];
1203
- setCount(payload.count ?? 0);
1204
- setOffset(nextOffset + list.length);
1205
- setItems((prev) => replace ? list : [...prev, ...list]);
1206
- } catch (e) {
1207
- setError(e instanceof Error ? e.message : "Failed to load");
1208
- } finally {
1209
- setIsLoading(false);
1210
- setIsFetchingMore(false);
1211
- }
1212
- },
1213
- [
1214
- debouncedOrderId,
1215
- paymentStatusFilter,
1216
- debouncedProvider,
1217
- debouncedCurrency,
1218
- dateFrom,
1219
- dateTo,
1220
- amountMin,
1221
- amountMax
1222
- ]
1223
- );
1224
- react.useEffect(() => {
1225
- void loadRefunds(0, true);
1226
- }, [loadRefunds]);
1227
- const hasMore = react.useMemo(() => offset < count, [offset, count]);
1228
- const displayAmount = (r) => {
1229
- const code = (r.currency_code ?? "USD").toUpperCase();
1230
- return `${code} ${Number(r.amount)}`;
1231
- };
1232
- const displayStatus = (r) => {
1233
- const s2 = r.payment_status ?? "";
1234
- return s2 !== "" ? s2 : "—";
1235
- };
1236
- 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: [
1237
- /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
1238
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
1239
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Refunds" }),
1240
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Refund records — amount, order, payment status" })
1241
- ] }),
1242
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadRefunds(0, true), children: "Refresh" })
1243
- ] }),
1244
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
1245
- /* @__PURE__ */ jsxRuntime.jsx(
1246
- ui.Input,
1247
- {
1248
- placeholder: "Order ID",
1249
- value: orderIdSearch,
1250
- onChange: (e) => setOrderIdSearch(e.target.value),
1251
- className: "md:max-w-[180px]",
1252
- "aria-label": "Filter by order ID"
1253
- }
1254
- ),
1255
- /* @__PURE__ */ jsxRuntime.jsx(
1256
- ui.Input,
1257
- {
1258
- placeholder: "Provider",
1259
- value: providerSearch,
1260
- onChange: (e) => setProviderSearch(e.target.value),
1261
- className: "md:max-w-[140px]",
1262
- "aria-label": "Filter by provider"
1263
- }
1264
- ),
1265
- /* @__PURE__ */ jsxRuntime.jsx(
1266
- ui.Input,
1267
- {
1268
- placeholder: "Currency",
1269
- value: currencySearch,
1270
- onChange: (e) => setCurrencySearch(e.target.value),
1271
- className: "md:max-w-[100px]",
1272
- "aria-label": "Filter by currency"
1273
- }
1274
- ),
1275
- /* @__PURE__ */ jsxRuntime.jsxs(
1276
- "select",
1277
- {
1278
- value: paymentStatusFilter,
1279
- onChange: (e) => setPaymentStatusFilter(e.target.value),
1280
- 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]",
1281
- "aria-label": "Filter by payment status",
1282
- children: [
1283
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All statuses" }),
1284
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "pending", children: "Pending" }),
1285
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "requires_more", children: "Requires more" }),
1286
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "error", children: "Error" }),
1287
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "canceled", children: "Canceled" }),
1288
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "authorized", children: "Authorized" }),
1289
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "captured", children: "Captured" })
1290
- ]
1291
- }
1292
- ),
1293
- /* @__PURE__ */ jsxRuntime.jsx(
1294
- ui.Input,
1295
- {
1296
- type: "date",
1297
- placeholder: "From",
1298
- value: dateFrom,
1299
- onChange: (e) => setDateFrom(e.target.value),
1300
- className: "md:max-w-[140px]",
1301
- "aria-label": "Date from"
1302
- }
1303
- ),
1304
- /* @__PURE__ */ jsxRuntime.jsx(
1305
- ui.Input,
1306
- {
1307
- type: "date",
1308
- placeholder: "To",
1309
- value: dateTo,
1310
- onChange: (e) => setDateTo(e.target.value),
1311
- className: "md:max-w-[140px]",
1312
- "aria-label": "Date to"
1313
- }
1314
- ),
1315
- /* @__PURE__ */ jsxRuntime.jsx(
1316
- ui.Input,
1317
- {
1318
- placeholder: "Amount min",
1319
- value: amountMin,
1320
- onChange: (e) => setAmountMin(e.target.value),
1321
- type: "number",
1322
- min: 0,
1323
- className: "md:max-w-[100px]",
1324
- "aria-label": "Refund amount minimum"
1325
- }
1326
- ),
1327
- /* @__PURE__ */ jsxRuntime.jsx(
1328
- ui.Input,
1329
- {
1330
- placeholder: "Amount max",
1331
- value: amountMax,
1332
- onChange: (e) => setAmountMax(e.target.value),
1333
- type: "number",
1334
- min: 0,
1335
- className: "md:max-w-[100px]",
1336
- "aria-label": "Refund amount maximum"
1337
- }
1338
- )
1339
- ] }) }),
1340
- error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
1341
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
1342
- /* @__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" }) })
1343
- ] }) : null,
1344
- 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: [
1345
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No refunds yet" }),
1346
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Refund records will appear here." })
1347
- ] }) : /* @__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: [
1348
- /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
1349
- /* @__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" }),
1350
- /* @__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" }),
1351
- /* @__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" }),
1352
- /* @__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" }),
1353
- /* @__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" }),
1354
- /* @__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" }),
1355
- /* @__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" }),
1356
- /* @__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" }),
1357
- /* @__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" }),
1358
- /* @__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" })
1359
- ] }) }),
1360
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((r) => /* @__PURE__ */ jsxRuntime.jsxs(
1361
- "tr",
1362
- {
1363
- className: "cursor-pointer hover:bg-ui-bg-subtle/60",
1364
- onClick: () => navigate(`/refunds/${r.refund_id}`),
1365
- children: [
1366
- /* @__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 }),
1367
- /* @__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 ?? "—" }),
1368
- /* @__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 }),
1369
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle", children: displayAmount(r) }),
1370
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle uppercase", children: r.currency_code || "—" }),
1371
- /* @__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 || "—" }),
1372
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 px-3 py-3", children: /* @__PURE__ */ jsxRuntime.jsx(
1373
- ui.Badge,
1374
- {
1375
- size: "2xsmall",
1376
- className: `uppercase ${getStatusBadgeClass$6(displayStatus(r))}`,
1377
- children: displayStatus(r) !== "—" ? displayStatus(r).replace(/_/g, " ") : "—"
1378
- }
1379
- ) }),
1380
- /* @__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 ?? "—" }),
1381
- /* @__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", {
1382
- month: "short",
1383
- day: "numeric",
1384
- hour: "numeric",
1385
- minute: "2-digit",
1386
- hour12: true
1387
- }) }),
1388
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 px-3 py-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-1", children: [
1389
- /* @__PURE__ */ jsxRuntime.jsx(
1390
- ui.Button,
1391
- {
1392
- variant: "transparent",
1393
- size: "small",
1394
- onClick: (e) => {
1395
- e.stopPropagation();
1396
- navigate(`/refunds/${r.refund_id}`);
1397
- },
1398
- children: "Details"
1399
- }
1400
- ),
1401
- r.order_id ? /* @__PURE__ */ jsxRuntime.jsx(
1402
- ui.Button,
1403
- {
1404
- variant: "transparent",
1405
- size: "small",
1406
- onClick: (e) => {
1407
- e.stopPropagation();
1408
- navigate(`/orders/${r.order_id}`);
1409
- },
1410
- children: "Order"
1411
- }
1412
- ) : null
1413
- ] }) })
1414
- ]
1415
- },
1416
- r.refund_id
1417
- )) })
1418
- ] }) }),
1419
- hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
1420
- ui.Button,
1421
- {
1422
- variant: "secondary",
1423
- isLoading: isFetchingMore,
1424
- onClick: () => loadRefunds(offset, false),
1425
- children: "Load more"
1426
- }
1427
- ) }) : null
1428
- ] }) });
1429
- };
1430
- const config$7 = adminSdk.defineRouteConfig({
1431
- label: "Refunds",
1432
- icon: icons.Receipt
1433
- });
1434
927
  const AUDITED_TABLE_NAMES = [
1435
928
  "account_deletion_request",
1436
929
  "account_holder",
@@ -1854,7 +1347,7 @@ function getEntityInfo(tableName) {
1854
1347
  const def = ENTITY_DEFINITIONS[tableName];
1855
1348
  return {
1856
1349
  tableName,
1857
- label: (def == null ? void 0 : def.label) ?? humanizeTableName(tableName),
1350
+ label: def?.label ?? humanizeTableName(tableName),
1858
1351
  category: def && CATEGORY_BY_ID.get(def.category) || SYSTEM_CATEGORY
1859
1352
  };
1860
1353
  }
@@ -1879,13 +1372,11 @@ function getTablesForCategory(id) {
1879
1372
  }
1880
1373
  const GROUPS = getEntitiesByCategory();
1881
1374
  function triggerLabel(entity, category) {
1882
- var _a;
1883
1375
  if (entity) return getEntityInfo(entity).label;
1884
- if (category) return `All ${((_a = getCategory(category)) == null ? void 0 : _a.label) ?? category}`;
1376
+ if (category) return `All ${getCategory(category)?.label ?? category}`;
1885
1377
  return "All entities";
1886
1378
  }
1887
1379
  const EntityPicker = ({ entity, category, onChange }) => {
1888
- var _a;
1889
1380
  const [open, setOpen] = react.useState(false);
1890
1381
  const [search, setSearch] = react.useState("");
1891
1382
  const searchRef = react.useRef(null);
@@ -1905,7 +1396,7 @@ const EntityPicker = ({ entity, category, onChange }) => {
1905
1396
  setOpen(false);
1906
1397
  setSearch("");
1907
1398
  };
1908
- const firstMatch = (_a = filteredGroups[0]) == null ? void 0 : _a.entities[0];
1399
+ const firstMatch = filteredGroups[0]?.entities[0];
1909
1400
  const isAll = !entity && !category;
1910
1401
  return /* @__PURE__ */ jsxRuntime.jsxs(
1911
1402
  ui.Popover,
@@ -1938,9 +1429,8 @@ const EntityPicker = ({ entity, category, onChange }) => {
1938
1429
  align: "start",
1939
1430
  className: "w-[min(360px,calc(100vw-2rem))] p-0",
1940
1431
  onOpenAutoFocus: (event) => {
1941
- var _a2;
1942
1432
  event.preventDefault();
1943
- (_a2 = searchRef.current) == null ? void 0 : _a2.focus();
1433
+ searchRef.current?.focus();
1944
1434
  },
1945
1435
  children: [
1946
1436
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b border-ui-border-base p-2", children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -2080,7 +1570,7 @@ function formatNumber(value) {
2080
1570
  return new Intl.NumberFormat().format(value);
2081
1571
  }
2082
1572
  function formatMoney(amount, currencyCode) {
2083
- const code = currencyCode == null ? void 0 : currencyCode.trim().toUpperCase();
1573
+ const code = currencyCode?.trim().toUpperCase();
2084
1574
  if (code && /^[A-Z]{3}$/.test(code)) {
2085
1575
  try {
2086
1576
  return new Intl.NumberFormat(void 0, { style: "currency", currency: code }).format(amount);
@@ -2147,9 +1637,9 @@ const SummaryCards = ({ stats, loading, failed }) => {
2147
1637
  };
2148
1638
  const BASE = "/admin/deleted-records-audit";
2149
1639
  class AuditApiError extends Error {
1640
+ status;
2150
1641
  constructor(message, status) {
2151
1642
  super(message);
2152
- __publicField(this, "status");
2153
1643
  this.status = status;
2154
1644
  }
2155
1645
  }
@@ -2214,10 +1704,7 @@ const URL_KEYS = {
2214
1704
  const DATE_PRESET_VALUES = new Set(DATE_PRESETS.map((p) => p.value));
2215
1705
  const DAY_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
2216
1706
  function filtersFromSearchParams(params) {
2217
- const read = (key) => {
2218
- var _a;
2219
- return ((_a = params.get(URL_KEYS[key])) == null ? void 0 : _a.trim()) ?? "";
2220
- };
1707
+ const read = (key) => params.get(URL_KEYS[key])?.trim() ?? "";
2221
1708
  const date = read("date");
2222
1709
  const from = read("from");
2223
1710
  const to = read("to");
@@ -2371,9 +1858,9 @@ const DeletedRecordsPage = () => {
2371
1858
  try {
2372
1859
  setStats(await fetchAuditStats(signal));
2373
1860
  } catch (e) {
2374
- if (!(signal == null ? void 0 : signal.aborted)) setStatsFailed(true);
1861
+ if (!signal?.aborted) setStatsFailed(true);
2375
1862
  } finally {
2376
- if (!(signal == null ? void 0 : signal.aborted)) setStatsLoading(false);
1863
+ if (!signal?.aborted) setStatsLoading(false);
2377
1864
  }
2378
1865
  }, []);
2379
1866
  react.useEffect(() => {
@@ -2430,7 +1917,7 @@ const DeletedRecordsPage = () => {
2430
1917
  const visible = Array.from(document.querySelectorAll(`[data-audit-row="${lastViewed}"]`)).find(
2431
1918
  (el) => el.offsetParent !== null
2432
1919
  );
2433
- visible == null ? void 0 : visible.scrollIntoView({ block: "center" });
1920
+ visible?.scrollIntoView({ block: "center" });
2434
1921
  });
2435
1922
  const handle = setTimeout(() => setHighlightId(null), 2500);
2436
1923
  return () => clearTimeout(handle);
@@ -2457,8 +1944,8 @@ const DeletedRecordsPage = () => {
2457
1944
  };
2458
1945
  const refresh = () => setReloadToken((t) => t + 1);
2459
1946
  const hasMore = items.length < count;
2460
- const knownSources = (stats == null ? void 0 : stats.sources) ?? [];
2461
- const knownDeletedBy = (stats == null ? void 0 : stats.deleted_by) ?? [];
1947
+ const knownSources = stats?.sources ?? [];
1948
+ const knownDeletedBy = stats?.deleted_by ?? [];
2462
1949
  const attributionMissing = !!stats && stats.total > 0 && knownSources.length === 0 && knownDeletedBy.length === 0;
2463
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: [
2464
1951
  /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-start md:justify-between", children: [
@@ -2722,11 +2209,11 @@ const ErrorState = ({ onRetry, detail }) => /* @__PURE__ */ jsxRuntime.jsxs("div
2722
2209
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "max-w-md font-mono text-ui-fg-muted", children: detail }),
2723
2210
  /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", size: "small", className: "mt-2", onClick: onRetry, children: "Try again" })
2724
2211
  ] });
2725
- const config$6 = adminSdk.defineRouteConfig({
2212
+ const config$9 = adminSdk.defineRouteConfig({
2726
2213
  label: "Deleted Records",
2727
2214
  icon: icons.Trash
2728
2215
  });
2729
- const useDebounce$1 = (value, delay) => {
2216
+ const useDebounce$3 = (value, delay) => {
2730
2217
  const [debouncedValue, setDebouncedValue] = react.useState(value);
2731
2218
  react.useEffect(() => {
2732
2219
  const handler = setTimeout(() => setDebouncedValue(value), delay);
@@ -2734,201 +2221,145 @@ const useDebounce$1 = (value, delay) => {
2734
2221
  }, [value, delay]);
2735
2222
  return debouncedValue;
2736
2223
  };
2737
- const getStatusBadgeClass$5 = (status) => {
2738
- const statusLower = status.toLowerCase();
2739
- if (statusLower === "requested") {
2740
- return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
2741
- }
2742
- if (statusLower === "received") {
2743
- return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
2744
- }
2745
- if (statusLower === "requires_action") {
2746
- return "bg-ui-tag-red-bg text-ui-tag-red-text";
2747
- }
2748
- if (statusLower === "completed") {
2749
- return "bg-ui-tag-green-bg text-ui-tag-green-text";
2750
- }
2751
- if (statusLower === "canceled") {
2752
- return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
2753
- }
2224
+ const getStatusBadgeClass$7 = (status) => {
2225
+ const s2 = status.toLowerCase();
2226
+ if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
2227
+ if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
2228
+ if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
2229
+ if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
2754
2230
  return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
2755
2231
  };
2756
- const ReturnsPage = () => {
2232
+ const PaymentsPage = () => {
2757
2233
  const navigate = reactRouterDom.useNavigate();
2758
2234
  const [items, setItems] = react.useState([]);
2759
2235
  const [statusFilter, setStatusFilter] = react.useState("all");
2760
- const [createdByFilter, setCreatedByFilter] = react.useState("all");
2761
- const [searchQuery, setSearchQuery] = react.useState("");
2762
- const debouncedSearchQuery = useDebounce$1(searchQuery, 300);
2236
+ const [orderIdSearch, setOrderIdSearch] = react.useState("");
2237
+ const debouncedOrderId = useDebounce$3(orderIdSearch, 300);
2763
2238
  const [isLoading, setIsLoading] = react.useState(true);
2764
2239
  const [isFetchingMore, setIsFetchingMore] = react.useState(false);
2765
2240
  const [error, setError] = react.useState(null);
2766
2241
  const [offset, setOffset] = react.useState(0);
2767
2242
  const [count, setCount] = react.useState(0);
2768
2243
  const limit = 50;
2769
- const loadReturns = react.useCallback(
2770
- async (nextOffset, replace = false) => {
2771
- var _a;
2244
+ const loadTransactions = react.useCallback(
2245
+ async (nextOffset, replace) => {
2772
2246
  try {
2773
- if (replace) {
2774
- setIsLoading(true);
2775
- } else {
2776
- setIsFetchingMore(true);
2777
- }
2247
+ if (replace) setIsLoading(true);
2248
+ else setIsFetchingMore(true);
2778
2249
  setError(null);
2779
2250
  const params = new URLSearchParams();
2780
2251
  params.set("limit", String(limit));
2781
2252
  params.set("offset", String(nextOffset));
2782
- if (statusFilter !== "all") {
2783
- params.set("status", statusFilter);
2784
- }
2785
- if (debouncedSearchQuery.trim()) {
2786
- params.set("q", debouncedSearchQuery.trim());
2787
- }
2788
- if (createdByFilter !== "all") {
2789
- params.set("created_by", createdByFilter);
2790
- }
2791
- params.set("order", "created_at");
2253
+ if (statusFilter !== "all") params.set("status", statusFilter);
2254
+ if (debouncedOrderId.trim()) params.set("order_id", debouncedOrderId.trim());
2792
2255
  const response = await fetch(
2793
- `/admin/return?${params.toString()}`,
2256
+ `/admin/payment-transactions?${params.toString()}`,
2794
2257
  { credentials: "include" }
2795
2258
  );
2796
2259
  if (!response.ok) {
2797
- const message = await response.text();
2798
- throw new Error(message || "Unable to load return orders");
2260
+ const text = await response.text();
2261
+ throw new Error(text || "Failed to load payment transactions");
2799
2262
  }
2800
2263
  const payload = await response.json();
2264
+ const list = payload.transactions ?? [];
2801
2265
  setCount(payload.count ?? 0);
2802
- setOffset(nextOffset + (((_a = payload.returns) == null ? void 0 : _a.length) ?? 0));
2803
- setItems(
2804
- (prev) => replace ? payload.returns ?? [] : [...prev, ...payload.returns ?? []]
2805
- );
2806
- } catch (loadError) {
2807
- const message = loadError instanceof Error ? loadError.message : "Unable to load return orders";
2808
- setError(message);
2266
+ setOffset(nextOffset + list.length);
2267
+ setItems((prev) => replace ? list : [...prev, ...list]);
2268
+ } catch (e) {
2269
+ setError(e instanceof Error ? e.message : "Failed to load");
2809
2270
  } finally {
2810
2271
  setIsLoading(false);
2811
2272
  setIsFetchingMore(false);
2812
2273
  }
2813
2274
  },
2814
- [statusFilter, createdByFilter, debouncedSearchQuery]
2275
+ [statusFilter, debouncedOrderId]
2815
2276
  );
2816
2277
  react.useEffect(() => {
2817
- void loadReturns(0, true);
2818
- }, [statusFilter, createdByFilter, debouncedSearchQuery, loadReturns]);
2278
+ void loadTransactions(0, true);
2279
+ }, [loadTransactions]);
2819
2280
  const hasMore = react.useMemo(() => offset < count, [offset, count]);
2820
- const availableStatuses = react.useMemo(() => {
2821
- const statuses = /* @__PURE__ */ new Set();
2822
- items.forEach((item) => statuses.add(item.status));
2823
- return Array.from(statuses).sort();
2824
- }, [items]);
2281
+ const displayStatus = (t) => {
2282
+ const s2 = t.payment_id != null && t.payment_status != null && t.payment_status !== "" ? t.payment_status : t.session_status ?? "";
2283
+ return s2 !== "" ? s2 : "—";
2284
+ };
2285
+ const displayAmount = (t) => {
2286
+ const code = (t.currency_code ?? "USD").toUpperCase();
2287
+ return `${code} ${Number(t.amount)}`;
2288
+ };
2825
2289
  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: [
2826
2290
  /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
2827
2291
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
2828
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Return Orders" }),
2829
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer return orders" })
2292
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Payments" }),
2293
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "All payment attempts — completed, pending, failed, requires action" })
2830
2294
  ] }),
2831
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadReturns(0, true), children: "Refresh" })
2295
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadTransactions(0, true), children: "Refresh" })
2832
2296
  ] }),
2833
2297
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
2834
2298
  /* @__PURE__ */ jsxRuntime.jsx(
2835
2299
  ui.Input,
2836
2300
  {
2837
- placeholder: "Search by return ID, order ID, or customer email",
2838
- value: searchQuery,
2839
- onChange: (event) => setSearchQuery(event.target.value),
2840
- className: "md:max-w-sm"
2301
+ placeholder: "Search by Order ID",
2302
+ value: orderIdSearch,
2303
+ onChange: (e) => setOrderIdSearch(e.target.value),
2304
+ className: "md:max-w-sm",
2305
+ "aria-label": "Search by order ID"
2841
2306
  }
2842
2307
  ),
2843
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
2844
- /* @__PURE__ */ jsxRuntime.jsxs(
2845
- "select",
2846
- {
2847
- value: createdByFilter,
2848
- onChange: (event) => setCreatedByFilter(event.target.value),
2849
- 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",
2850
- children: [
2851
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All (Created by)" }),
2852
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "customer", children: "Customer" }),
2853
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "admin", children: "Admin" })
2854
- ]
2855
- }
2856
- ),
2857
- /* @__PURE__ */ jsxRuntime.jsxs(
2858
- "select",
2859
- {
2860
- value: statusFilter,
2861
- onChange: (event) => setStatusFilter(event.target.value),
2862
- 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",
2863
- children: [
2864
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All Statuses" }),
2865
- availableStatuses.map((status) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
2866
- ]
2867
- }
2868
- )
2869
- ] })
2870
- ] }),
2871
- error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
2872
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
2873
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
2874
- ui.Button,
2308
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxRuntime.jsxs(
2309
+ "select",
2875
2310
  {
2876
- variant: "secondary",
2877
- onClick: () => loadReturns(0, true),
2878
- children: "Try again"
2311
+ value: statusFilter,
2312
+ onChange: (e) => setStatusFilter(e.target.value),
2313
+ 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",
2314
+ "aria-label": "Filter by status",
2315
+ children: [
2316
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All statuses" }),
2317
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "pending", children: "Pending" }),
2318
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "requires_more", children: "Requires more" }),
2319
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "error", children: "Error" }),
2320
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "canceled", children: "Canceled" }),
2321
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "authorized", children: "Authorized" }),
2322
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "captured", children: "Captured" })
2323
+ ]
2879
2324
  }
2880
2325
  ) })
2326
+ ] }),
2327
+ error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
2328
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
2329
+ /* @__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" }) })
2881
2330
  ] }) : null,
2882
- isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading return orders..." }) }) : items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
2883
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No return orders yet" }),
2884
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Return orders created by customers will appear here." })
2331
+ 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: [
2332
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No payment transactions yet" }),
2333
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Payment attempts will appear here." })
2885
2334
  ] }) : /* @__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: [
2886
2335
  /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2887
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Return ID" }),
2888
2336
  /* @__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" }),
2889
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Customer" }),
2337
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Amount" }),
2338
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Provider" }),
2890
2339
  /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
2891
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Refund Amount" }),
2340
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Finalized" }),
2892
2341
  /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
2893
2342
  /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
2894
2343
  ] }) }),
2895
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((returnOrder) => /* @__PURE__ */ jsxRuntime.jsxs(
2344
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((t) => /* @__PURE__ */ jsxRuntime.jsxs(
2896
2345
  "tr",
2897
2346
  {
2898
2347
  className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
2899
- onClick: () => navigate(`/returns/${returnOrder.id}`),
2348
+ onClick: () => navigate(`/payments/${t.payment_session_id}`),
2900
2349
  children: [
2901
- /* @__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: returnOrder.id }) }) }),
2902
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.order_id }),
2903
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.customer_email || returnOrder.order_email || "—" }),
2350
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: t.order_id ?? "—" }),
2351
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: displayAmount(t) }),
2352
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: t.provider_id }),
2904
2353
  /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
2905
2354
  ui.Badge,
2906
2355
  {
2907
2356
  size: "2xsmall",
2908
- className: `uppercase ${getStatusBadgeClass$5(returnOrder.status)}`,
2909
- children: returnOrder.status.replace(/_/g, " ")
2357
+ className: `uppercase ${getStatusBadgeClass$7(displayStatus(t))}`,
2358
+ children: displayStatus(t) !== "—" ? displayStatus(t).replace(/_/g, " ") : "—"
2910
2359
  }
2911
2360
  ) }),
2912
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
2913
- const calc = returnOrder.refund;
2914
- if ((calc == null ? void 0 : calc.is_processed) && calc.final_refund_amount != null) {
2915
- return formatRefundCurrency(
2916
- calc.final_refund_amount,
2917
- calc.currency_code || returnOrder.currency_code
2918
- );
2919
- }
2920
- if (calc) {
2921
- return "Pending";
2922
- }
2923
- if (returnOrder.refund_amount == null) {
2924
- return "—";
2925
- }
2926
- return formatRefundCurrency(
2927
- Number(returnOrder.refund_amount),
2928
- returnOrder.currency_code
2929
- );
2930
- })() }),
2931
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(returnOrder.created_at).toLocaleDateString("en-US", {
2361
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: t.payment_id != null ? "Yes" : "No" }),
2362
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(t.created_at).toLocaleDateString("en-US", {
2932
2363
  year: "numeric",
2933
2364
  month: "short",
2934
2365
  day: "numeric",
@@ -2936,21 +2367,35 @@ const ReturnsPage = () => {
2936
2367
  minute: "2-digit",
2937
2368
  hour12: true
2938
2369
  }) }),
2939
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
2940
- ui.Button,
2941
- {
2942
- variant: "transparent",
2943
- size: "small",
2944
- onClick: (e) => {
2945
- e.stopPropagation();
2946
- navigate(`/app/orders/${returnOrder.order_id}`);
2947
- },
2948
- children: "Go to order"
2949
- }
2950
- ) })
2370
+ /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "px-4 py-4", children: [
2371
+ /* @__PURE__ */ jsxRuntime.jsx(
2372
+ ui.Button,
2373
+ {
2374
+ variant: "transparent",
2375
+ size: "small",
2376
+ onClick: (e) => {
2377
+ e.stopPropagation();
2378
+ navigate(`/payments/${t.payment_session_id}`);
2379
+ },
2380
+ children: "View details"
2381
+ }
2382
+ ),
2383
+ t.order_id ? /* @__PURE__ */ jsxRuntime.jsx(
2384
+ ui.Button,
2385
+ {
2386
+ variant: "transparent",
2387
+ size: "small",
2388
+ onClick: (e) => {
2389
+ e.stopPropagation();
2390
+ navigate(`/orders/${t.order_id}`);
2391
+ },
2392
+ children: "Order"
2393
+ }
2394
+ ) : null
2395
+ ] })
2951
2396
  ]
2952
2397
  },
2953
- returnOrder.id
2398
+ t.payment_session_id
2954
2399
  )) })
2955
2400
  ] }) }),
2956
2401
  hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -2958,17 +2403,17 @@ const ReturnsPage = () => {
2958
2403
  {
2959
2404
  variant: "secondary",
2960
2405
  isLoading: isFetchingMore,
2961
- onClick: () => loadReturns(offset, false),
2406
+ onClick: () => loadTransactions(offset, false),
2962
2407
  children: "Load more"
2963
2408
  }
2964
2409
  ) }) : null
2965
2410
  ] }) });
2966
2411
  };
2967
- const config$5 = adminSdk.defineRouteConfig({
2968
- label: "Return Orders",
2969
- icon: icons.ArrowPath
2412
+ const config$8 = adminSdk.defineRouteConfig({
2413
+ label: "Payments",
2414
+ icon: icons.CreditCard
2970
2415
  });
2971
- const useDebounce = (value, delay) => {
2416
+ const useDebounce$2 = (value, delay) => {
2972
2417
  const [debouncedValue, setDebouncedValue] = react.useState(value);
2973
2418
  react.useEffect(() => {
2974
2419
  const handler = setTimeout(() => setDebouncedValue(value), delay);
@@ -2976,547 +2421,771 @@ const useDebounce = (value, delay) => {
2976
2421
  }, [value, delay]);
2977
2422
  return debouncedValue;
2978
2423
  };
2979
- const getStatusBadgeClass$4 = (status) => {
2980
- const statusLower = status.toLowerCase();
2981
- if (statusLower === "requested") {
2982
- return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
2983
- }
2984
- if (statusLower === "approved") {
2985
- return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
2986
- }
2987
- if (statusLower === "rejected") {
2988
- return "bg-ui-tag-red-bg text-ui-tag-red-text";
2989
- }
2990
- if (statusLower === "completed") {
2991
- return "bg-ui-tag-green-bg text-ui-tag-green-text";
2992
- }
2993
- if (statusLower === "cancelled") {
2994
- return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
2995
- }
2424
+ const getStatusBadgeClass$6 = (status) => {
2425
+ const s2 = status.toLowerCase();
2426
+ if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
2427
+ if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
2428
+ if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
2429
+ if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
2996
2430
  return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
2997
2431
  };
2998
- const SwapsPage = () => {
2432
+ const RefundsPage = () => {
2999
2433
  const navigate = reactRouterDom.useNavigate();
3000
2434
  const [items, setItems] = react.useState([]);
3001
- const [statusFilter, setStatusFilter] = react.useState("all");
3002
- const [createdByFilter, setCreatedByFilter] = react.useState("all");
3003
- const [searchQuery, setSearchQuery] = react.useState("");
3004
- const debouncedSearchQuery = useDebounce(searchQuery, 300);
2435
+ const [orderIdSearch, setOrderIdSearch] = react.useState("");
2436
+ const debouncedOrderId = useDebounce$2(orderIdSearch, 300);
2437
+ const [paymentStatusFilter, setPaymentStatusFilter] = react.useState("all");
2438
+ const [providerSearch, setProviderSearch] = react.useState("");
2439
+ const debouncedProvider = useDebounce$2(providerSearch, 300);
2440
+ const [currencySearch, setCurrencySearch] = react.useState("");
2441
+ const debouncedCurrency = useDebounce$2(currencySearch, 300);
2442
+ const [dateFrom, setDateFrom] = react.useState("");
2443
+ const [dateTo, setDateTo] = react.useState("");
2444
+ const [amountMin, setAmountMin] = react.useState("");
2445
+ const [amountMax, setAmountMax] = react.useState("");
3005
2446
  const [isLoading, setIsLoading] = react.useState(true);
3006
2447
  const [isFetchingMore, setIsFetchingMore] = react.useState(false);
3007
2448
  const [error, setError] = react.useState(null);
3008
2449
  const [offset, setOffset] = react.useState(0);
3009
2450
  const [count, setCount] = react.useState(0);
3010
2451
  const limit = 50;
3011
- const loadSwaps = react.useCallback(
3012
- async (nextOffset, replace = false) => {
3013
- var _a;
2452
+ const loadRefunds = react.useCallback(
2453
+ async (nextOffset, replace) => {
3014
2454
  try {
3015
- if (replace) {
3016
- setIsLoading(true);
3017
- } else {
3018
- setIsFetchingMore(true);
3019
- }
2455
+ if (replace) setIsLoading(true);
2456
+ else setIsFetchingMore(true);
3020
2457
  setError(null);
3021
2458
  const params = new URLSearchParams();
3022
2459
  params.set("limit", String(limit));
3023
2460
  params.set("offset", String(nextOffset));
3024
- if (statusFilter !== "all") {
3025
- params.set("status", statusFilter);
3026
- }
3027
- if (debouncedSearchQuery.trim()) {
3028
- params.set("order_id", debouncedSearchQuery.trim());
3029
- }
3030
- if (createdByFilter !== "all") {
3031
- params.set("created_by", createdByFilter);
3032
- }
3033
- const response = await fetch(
3034
- `/admin/swaps?${params.toString()}`,
3035
- { credentials: "include" }
3036
- );
2461
+ if (debouncedOrderId.trim()) params.set("order_id", debouncedOrderId.trim());
2462
+ if (paymentStatusFilter !== "all") params.set("payment_status", paymentStatusFilter);
2463
+ if (debouncedProvider.trim()) params.set("provider_id", debouncedProvider.trim());
2464
+ if (debouncedCurrency.trim()) params.set("currency_code", debouncedCurrency.trim());
2465
+ if (dateFrom.trim()) params.set("date_from", dateFrom.trim());
2466
+ if (dateTo.trim()) params.set("date_to", dateTo.trim());
2467
+ const min = amountMin.trim() ? Number(amountMin) : void 0;
2468
+ const max = amountMax.trim() ? Number(amountMax) : void 0;
2469
+ if (min != null && !Number.isNaN(min)) params.set("amount_min", String(min));
2470
+ if (max != null && !Number.isNaN(max)) params.set("amount_max", String(max));
2471
+ const response = await fetch(`/admin/refunds?${params.toString()}`, {
2472
+ credentials: "include"
2473
+ });
3037
2474
  if (!response.ok) {
3038
- const message = await response.text();
3039
- throw new Error(message || "Unable to load swaps");
2475
+ const text = await response.text();
2476
+ throw new Error(text || "Failed to load refunds");
3040
2477
  }
3041
2478
  const payload = await response.json();
2479
+ const list = payload.refunds ?? [];
3042
2480
  setCount(payload.count ?? 0);
3043
- setOffset(nextOffset + (((_a = payload.swaps) == null ? void 0 : _a.length) ?? 0));
3044
- setItems(
3045
- (prev) => replace ? payload.swaps ?? [] : [...prev, ...payload.swaps ?? []]
3046
- );
3047
- } catch (loadError) {
3048
- const message = loadError instanceof Error ? loadError.message : "Unable to load swaps";
3049
- setError(message);
2481
+ setOffset(nextOffset + list.length);
2482
+ setItems((prev) => replace ? list : [...prev, ...list]);
2483
+ } catch (e) {
2484
+ setError(e instanceof Error ? e.message : "Failed to load");
3050
2485
  } finally {
3051
2486
  setIsLoading(false);
3052
2487
  setIsFetchingMore(false);
3053
2488
  }
3054
2489
  },
3055
- [statusFilter, createdByFilter, debouncedSearchQuery]
2490
+ [
2491
+ debouncedOrderId,
2492
+ paymentStatusFilter,
2493
+ debouncedProvider,
2494
+ debouncedCurrency,
2495
+ dateFrom,
2496
+ dateTo,
2497
+ amountMin,
2498
+ amountMax
2499
+ ]
3056
2500
  );
3057
2501
  react.useEffect(() => {
3058
- void loadSwaps(0, true);
3059
- }, [statusFilter, createdByFilter, debouncedSearchQuery, loadSwaps]);
2502
+ void loadRefunds(0, true);
2503
+ }, [loadRefunds]);
3060
2504
  const hasMore = react.useMemo(() => offset < count, [offset, count]);
3061
- const availableStatuses = react.useMemo(() => {
3062
- const statuses = /* @__PURE__ */ new Set();
3063
- items.forEach((item) => statuses.add(item.status));
3064
- return Array.from(statuses).sort();
3065
- }, [items]);
2505
+ const displayAmount = (r) => {
2506
+ const code = (r.currency_code ?? "USD").toUpperCase();
2507
+ return `${code} ${Number(r.amount)}`;
2508
+ };
2509
+ const displayStatus = (r) => {
2510
+ const s2 = r.payment_status ?? "";
2511
+ return s2 !== "" ? s2 : "—";
2512
+ };
3066
2513
  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: [
3067
2514
  /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
3068
2515
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
3069
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Exchanges" }),
3070
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer exchange requests" })
2516
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Refunds" }),
2517
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Refund records — amount, order, payment status" })
3071
2518
  ] }),
3072
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadSwaps(0, true), children: "Refresh" })
2519
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadRefunds(0, true), children: "Refresh" })
3073
2520
  ] }),
3074
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
2521
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
3075
2522
  /* @__PURE__ */ jsxRuntime.jsx(
3076
2523
  ui.Input,
3077
2524
  {
3078
- placeholder: "Search by swap ID or order ID",
3079
- value: searchQuery,
3080
- onChange: (event) => setSearchQuery(event.target.value),
3081
- className: "md:max-w-sm"
2525
+ placeholder: "Order ID",
2526
+ value: orderIdSearch,
2527
+ onChange: (e) => setOrderIdSearch(e.target.value),
2528
+ className: "md:max-w-[180px]",
2529
+ "aria-label": "Filter by order ID"
3082
2530
  }
3083
2531
  ),
3084
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
3085
- /* @__PURE__ */ jsxRuntime.jsxs(
3086
- "select",
3087
- {
3088
- value: createdByFilter,
3089
- onChange: (event) => setCreatedByFilter(event.target.value),
3090
- 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",
3091
- children: [
3092
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All (Created by)" }),
3093
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "customer", children: "Customer" }),
3094
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "admin", children: "Admin" })
3095
- ]
3096
- }
3097
- ),
3098
- /* @__PURE__ */ jsxRuntime.jsxs(
3099
- "select",
3100
- {
3101
- value: statusFilter,
3102
- onChange: (event) => setStatusFilter(event.target.value),
3103
- 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",
3104
- children: [
3105
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All Statuses" }),
3106
- availableStatuses.map((status) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
3107
- ]
3108
- }
3109
- )
3110
- ] })
3111
- ] }),
3112
- error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
3113
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
3114
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
3115
- ui.Button,
2532
+ /* @__PURE__ */ jsxRuntime.jsx(
2533
+ ui.Input,
3116
2534
  {
3117
- variant: "secondary",
3118
- onClick: () => loadSwaps(0, true),
3119
- children: "Try again"
2535
+ placeholder: "Provider",
2536
+ value: providerSearch,
2537
+ onChange: (e) => setProviderSearch(e.target.value),
2538
+ className: "md:max-w-[140px]",
2539
+ "aria-label": "Filter by provider"
3120
2540
  }
3121
- ) })
3122
- ] }) : null,
3123
- 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: [
3124
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No exchanges yet" }),
3125
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Exchange requests created by customers will appear here." })
3126
- ] }) : /* @__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: [
3127
- /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
3128
- /* @__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" }),
3129
- /* @__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" }),
3130
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
3131
- /* @__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" }),
3132
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
3133
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
3134
- ] }) }),
3135
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((swap) => /* @__PURE__ */ jsxRuntime.jsxs(
3136
- "tr",
2541
+ ),
2542
+ /* @__PURE__ */ jsxRuntime.jsx(
2543
+ ui.Input,
3137
2544
  {
3138
- className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
3139
- onClick: () => navigate(`/swaps/${swap.id}`),
2545
+ placeholder: "Currency",
2546
+ value: currencySearch,
2547
+ onChange: (e) => setCurrencySearch(e.target.value),
2548
+ className: "md:max-w-[100px]",
2549
+ "aria-label": "Filter by currency"
2550
+ }
2551
+ ),
2552
+ /* @__PURE__ */ jsxRuntime.jsxs(
2553
+ "select",
2554
+ {
2555
+ value: paymentStatusFilter,
2556
+ onChange: (e) => setPaymentStatusFilter(e.target.value),
2557
+ 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]",
2558
+ "aria-label": "Filter by payment status",
3140
2559
  children: [
3141
- /* @__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 }) }) }),
3142
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: swap.order_id }),
3143
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
3144
- ui.Badge,
3145
- {
3146
- size: "2xsmall",
3147
- className: `uppercase ${getStatusBadgeClass$4(swap.status)}`,
3148
- children: swap.status.replace(/_/g, " ")
3149
- }
3150
- ) }),
3151
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
3152
- const amount = swap.difference_due;
3153
- if (amount == null || amount === void 0) {
3154
- return "—";
3155
- }
3156
- const displayAmount = Number(amount) / 100;
3157
- const currency = swap.currency_code || "$";
3158
- const sign = displayAmount >= 0 ? "+" : "";
3159
- return `${sign}${currency}${displayAmount.toFixed(2)}`;
3160
- })() }),
3161
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(swap.created_at).toLocaleDateString("en-US", {
3162
- year: "numeric",
3163
- month: "short",
3164
- day: "numeric",
3165
- hour: "numeric",
3166
- minute: "2-digit",
3167
- hour12: true
3168
- }) }),
3169
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
3170
- ui.Button,
3171
- {
3172
- variant: "transparent",
3173
- size: "small",
3174
- onClick: (e) => {
3175
- e.stopPropagation();
3176
- navigate(`/app/orders/${swap.order_id}`);
3177
- },
3178
- children: "Go to order"
3179
- }
3180
- ) })
2560
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All statuses" }),
2561
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "pending", children: "Pending" }),
2562
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "requires_more", children: "Requires more" }),
2563
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "error", children: "Error" }),
2564
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "canceled", children: "Canceled" }),
2565
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "authorized", children: "Authorized" }),
2566
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "captured", children: "Captured" })
3181
2567
  ]
3182
- },
3183
- swap.id
3184
- )) })
3185
- ] }) }),
3186
- hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
2568
+ }
2569
+ ),
2570
+ /* @__PURE__ */ jsxRuntime.jsx(
2571
+ ui.Input,
2572
+ {
2573
+ type: "date",
2574
+ placeholder: "From",
2575
+ value: dateFrom,
2576
+ onChange: (e) => setDateFrom(e.target.value),
2577
+ className: "md:max-w-[140px]",
2578
+ "aria-label": "Date from"
2579
+ }
2580
+ ),
2581
+ /* @__PURE__ */ jsxRuntime.jsx(
2582
+ ui.Input,
2583
+ {
2584
+ type: "date",
2585
+ placeholder: "To",
2586
+ value: dateTo,
2587
+ onChange: (e) => setDateTo(e.target.value),
2588
+ className: "md:max-w-[140px]",
2589
+ "aria-label": "Date to"
2590
+ }
2591
+ ),
2592
+ /* @__PURE__ */ jsxRuntime.jsx(
2593
+ ui.Input,
2594
+ {
2595
+ placeholder: "Amount min",
2596
+ value: amountMin,
2597
+ onChange: (e) => setAmountMin(e.target.value),
2598
+ type: "number",
2599
+ min: 0,
2600
+ className: "md:max-w-[100px]",
2601
+ "aria-label": "Refund amount minimum"
2602
+ }
2603
+ ),
2604
+ /* @__PURE__ */ jsxRuntime.jsx(
2605
+ ui.Input,
2606
+ {
2607
+ placeholder: "Amount max",
2608
+ value: amountMax,
2609
+ onChange: (e) => setAmountMax(e.target.value),
2610
+ type: "number",
2611
+ min: 0,
2612
+ className: "md:max-w-[100px]",
2613
+ "aria-label": "Refund amount maximum"
2614
+ }
2615
+ )
2616
+ ] }) }),
2617
+ error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
2618
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
2619
+ /* @__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" }) })
2620
+ ] }) : null,
2621
+ 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: [
2622
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No refunds yet" }),
2623
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Refund records will appear here." })
2624
+ ] }) : /* @__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: [
2625
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2626
+ /* @__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" }),
2627
+ /* @__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" }),
2628
+ /* @__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" }),
2629
+ /* @__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" }),
2630
+ /* @__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" }),
2631
+ /* @__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" }),
2632
+ /* @__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" }),
2633
+ /* @__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" }),
2634
+ /* @__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" }),
2635
+ /* @__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" })
2636
+ ] }) }),
2637
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((r) => /* @__PURE__ */ jsxRuntime.jsxs(
2638
+ "tr",
2639
+ {
2640
+ className: "cursor-pointer hover:bg-ui-bg-subtle/60",
2641
+ onClick: () => navigate(`/refunds/${r.refund_id}`),
2642
+ children: [
2643
+ /* @__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 }),
2644
+ /* @__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 ?? "—" }),
2645
+ /* @__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 }),
2646
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle", children: displayAmount(r) }),
2647
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle uppercase", children: r.currency_code || "—" }),
2648
+ /* @__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 || "—" }),
2649
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 px-3 py-3", children: /* @__PURE__ */ jsxRuntime.jsx(
2650
+ ui.Badge,
2651
+ {
2652
+ size: "2xsmall",
2653
+ className: `uppercase ${getStatusBadgeClass$6(displayStatus(r))}`,
2654
+ children: displayStatus(r) !== "—" ? displayStatus(r).replace(/_/g, " ") : "—"
2655
+ }
2656
+ ) }),
2657
+ /* @__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 ?? "—" }),
2658
+ /* @__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", {
2659
+ month: "short",
2660
+ day: "numeric",
2661
+ hour: "numeric",
2662
+ minute: "2-digit",
2663
+ hour12: true
2664
+ }) }),
2665
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 px-3 py-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-1", children: [
2666
+ /* @__PURE__ */ jsxRuntime.jsx(
2667
+ ui.Button,
2668
+ {
2669
+ variant: "transparent",
2670
+ size: "small",
2671
+ onClick: (e) => {
2672
+ e.stopPropagation();
2673
+ navigate(`/refunds/${r.refund_id}`);
2674
+ },
2675
+ children: "Details"
2676
+ }
2677
+ ),
2678
+ r.order_id ? /* @__PURE__ */ jsxRuntime.jsx(
2679
+ ui.Button,
2680
+ {
2681
+ variant: "transparent",
2682
+ size: "small",
2683
+ onClick: (e) => {
2684
+ e.stopPropagation();
2685
+ navigate(`/orders/${r.order_id}`);
2686
+ },
2687
+ children: "Order"
2688
+ }
2689
+ ) : null
2690
+ ] }) })
2691
+ ]
2692
+ },
2693
+ r.refund_id
2694
+ )) })
2695
+ ] }) }),
2696
+ hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
3187
2697
  ui.Button,
3188
2698
  {
3189
2699
  variant: "secondary",
3190
2700
  isLoading: isFetchingMore,
3191
- onClick: () => loadSwaps(offset, false),
2701
+ onClick: () => loadRefunds(offset, false),
3192
2702
  children: "Load more"
3193
2703
  }
3194
2704
  ) }) : null
3195
2705
  ] }) });
3196
2706
  };
3197
- const config$4 = adminSdk.defineRouteConfig({
3198
- label: "Exchanges",
3199
- icon: icons.ArrowPath
2707
+ const config$7 = adminSdk.defineRouteConfig({
2708
+ label: "Refunds",
2709
+ icon: icons.Receipt
3200
2710
  });
3201
- const getStatusBadgeClass$3 = (status) => {
3202
- const s2 = status.toLowerCase();
3203
- if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
3204
- if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
3205
- if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
3206
- if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
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
+ }
3207
2736
  return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
3208
2737
  };
3209
- const PaymentDetailPage = () => {
3210
- var _a;
2738
+ const ReturnsPage = () => {
3211
2739
  const navigate = reactRouterDom.useNavigate();
3212
- const params = reactRouterDom.useParams();
3213
- const id = (_a = params == null ? void 0 : params.id) == null ? void 0 : _a.trim();
3214
- const [detail, setDetail] = react.useState(null);
3215
- const [loading, setLoading] = react.useState(!!id);
2740
+ const [items, setItems] = react.useState([]);
2741
+ const [statusFilter, setStatusFilter] = react.useState("all");
2742
+ const [createdByFilter, setCreatedByFilter] = react.useState("all");
2743
+ const [searchQuery, setSearchQuery] = react.useState("");
2744
+ const debouncedSearchQuery = useDebounce$1(searchQuery, 300);
2745
+ const [isLoading, setIsLoading] = react.useState(true);
2746
+ const [isFetchingMore, setIsFetchingMore] = react.useState(false);
3216
2747
  const [error, setError] = react.useState(null);
2748
+ const [offset, setOffset] = react.useState(0);
2749
+ const [count, setCount] = react.useState(0);
2750
+ const limit = 50;
2751
+ const loadReturns = react.useCallback(
2752
+ async (nextOffset, replace = false) => {
2753
+ try {
2754
+ if (replace) {
2755
+ setIsLoading(true);
2756
+ } else {
2757
+ setIsFetchingMore(true);
2758
+ }
2759
+ setError(null);
2760
+ const params = new URLSearchParams();
2761
+ params.set("limit", String(limit));
2762
+ params.set("offset", String(nextOffset));
2763
+ if (statusFilter !== "all") {
2764
+ params.set("status", statusFilter);
2765
+ }
2766
+ if (debouncedSearchQuery.trim()) {
2767
+ params.set("q", debouncedSearchQuery.trim());
2768
+ }
2769
+ if (createdByFilter !== "all") {
2770
+ params.set("created_by", createdByFilter);
2771
+ }
2772
+ params.set("order", "created_at");
2773
+ const response = await fetch(
2774
+ `/admin/return?${params.toString()}`,
2775
+ { credentials: "include" }
2776
+ );
2777
+ if (!response.ok) {
2778
+ const message = await response.text();
2779
+ throw new Error(message || "Unable to load return orders");
2780
+ }
2781
+ const payload = await response.json();
2782
+ setCount(payload.count ?? 0);
2783
+ setOffset(nextOffset + (payload.returns?.length ?? 0));
2784
+ setItems(
2785
+ (prev) => replace ? payload.returns ?? [] : [...prev, ...payload.returns ?? []]
2786
+ );
2787
+ } catch (loadError) {
2788
+ const message = loadError instanceof Error ? loadError.message : "Unable to load return orders";
2789
+ setError(message);
2790
+ } finally {
2791
+ setIsLoading(false);
2792
+ setIsFetchingMore(false);
2793
+ }
2794
+ },
2795
+ [statusFilter, createdByFilter, debouncedSearchQuery]
2796
+ );
3217
2797
  react.useEffect(() => {
3218
- if (!id) {
3219
- setLoading(false);
3220
- return;
3221
- }
3222
- let cancelled = false;
3223
- setLoading(true);
3224
- setError(null);
3225
- fetch(`/admin/payment-transactions/${id}`, { credentials: "include" }).then((res) => {
3226
- if (!res.ok) throw new Error(res.statusText || "Failed to load");
3227
- return res.json();
3228
- }).then((data) => {
3229
- if (!cancelled) setDetail(data);
3230
- }).catch((e) => {
3231
- if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
3232
- }).finally(() => {
3233
- if (!cancelled) setLoading(false);
3234
- });
3235
- return () => {
3236
- cancelled = true;
3237
- };
3238
- }, [id]);
3239
- const displayStatus = detail ? (detail.payment_id != null && detail.payment_status != null && detail.payment_status !== "" ? detail.payment_status : detail.session_status ?? "") || "—" : "";
3240
- const sessionStatusRaw = (detail == null ? void 0 : detail.session_status) ?? "—";
3241
- const paymentStatusRaw = (detail == null ? void 0 : detail.payment_id) != null ? (detail == null ? void 0 : detail.payment_status) ?? "—" : "—";
3242
- const displayAmount = detail ? `${(detail.currency_code ?? "USD").toUpperCase()} ${Number(detail.amount)}` : "";
3243
- 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: [
3244
- /* @__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: [
3245
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => navigate("/payments"), children: "← Payments" }),
3246
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Payment session" }),
3247
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: id ?? "—" })
3248
- ] }) }),
2798
+ void loadReturns(0, true);
2799
+ }, [statusFilter, createdByFilter, debouncedSearchQuery, loadReturns]);
2800
+ const hasMore = react.useMemo(() => offset < count, [offset, count]);
2801
+ const availableStatuses = react.useMemo(() => {
2802
+ const statuses = /* @__PURE__ */ new Set();
2803
+ items.forEach((item) => statuses.add(item.status));
2804
+ return Array.from(statuses).sort();
2805
+ }, [items]);
2806
+ 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: [
2807
+ /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
2808
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
2809
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Return Orders" }),
2810
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer return orders" })
2811
+ ] }),
2812
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadReturns(0, true), children: "Refresh" })
2813
+ ] }),
2814
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
2815
+ /* @__PURE__ */ jsxRuntime.jsx(
2816
+ ui.Input,
2817
+ {
2818
+ placeholder: "Search by return ID, order ID, or customer email",
2819
+ value: searchQuery,
2820
+ onChange: (event) => setSearchQuery(event.target.value),
2821
+ className: "md:max-w-sm"
2822
+ }
2823
+ ),
2824
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
2825
+ /* @__PURE__ */ jsxRuntime.jsxs(
2826
+ "select",
2827
+ {
2828
+ value: createdByFilter,
2829
+ onChange: (event) => setCreatedByFilter(event.target.value),
2830
+ 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",
2831
+ children: [
2832
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All (Created by)" }),
2833
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "customer", children: "Customer" }),
2834
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "admin", children: "Admin" })
2835
+ ]
2836
+ }
2837
+ ),
2838
+ /* @__PURE__ */ jsxRuntime.jsxs(
2839
+ "select",
2840
+ {
2841
+ value: statusFilter,
2842
+ onChange: (event) => setStatusFilter(event.target.value),
2843
+ 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",
2844
+ children: [
2845
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All Statuses" }),
2846
+ availableStatuses.map((status) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
2847
+ ]
2848
+ }
2849
+ )
2850
+ ] })
2851
+ ] }),
3249
2852
  error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
3250
2853
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
3251
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/payments"), children: "Back to list" })
3252
- ] }) : 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: [
3253
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl border border-ui-border-base p-6 flex flex-col gap-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
3254
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3255
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Order ID" }),
3256
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: detail.order_id ? /* @__PURE__ */ jsxRuntime.jsx(
3257
- ui.Button,
3258
- {
3259
- variant: "transparent",
3260
- size: "small",
3261
- onClick: () => navigate(`/orders/${detail.order_id}`),
3262
- children: detail.order_id
3263
- }
3264
- ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "—" }) })
3265
- ] }),
3266
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3267
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
3268
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: displayAmount })
3269
- ] }),
3270
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3271
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
3272
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.provider_id })
3273
- ] }),
3274
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3275
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
3276
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
3277
- ui.Badge,
3278
- {
3279
- size: "2xsmall",
3280
- className: `uppercase ${getStatusBadgeClass$3(displayStatus)}`,
3281
- children: displayStatus !== "—" ? displayStatus.replace(/_/g, " ") : "—"
3282
- }
3283
- ) })
3284
- ] }),
3285
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3286
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Session status (DB)" }),
3287
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: sessionStatusRaw })
3288
- ] }),
3289
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3290
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Payment status (DB)" }),
3291
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: paymentStatusRaw })
3292
- ] }),
3293
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3294
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Finalized" }),
3295
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.payment_id != null ? "Yes" : "No" })
3296
- ] }),
3297
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3298
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created" }),
3299
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: new Date(detail.created_at).toLocaleDateString("en-US", {
3300
- year: "numeric",
3301
- month: "short",
3302
- day: "numeric",
3303
- hour: "numeric",
3304
- minute: "2-digit",
3305
- hour12: true
3306
- }) })
3307
- ] })
2854
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
2855
+ ui.Button,
2856
+ {
2857
+ variant: "secondary",
2858
+ onClick: () => loadReturns(0, true),
2859
+ children: "Try again"
2860
+ }
2861
+ ) })
2862
+ ] }) : null,
2863
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading return orders..." }) }) : items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
2864
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No return orders yet" }),
2865
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Return orders created by customers will appear here." })
2866
+ ] }) : /* @__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: [
2867
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2868
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Return ID" }),
2869
+ /* @__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" }),
2870
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Customer" }),
2871
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
2872
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Refund Amount" }),
2873
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
2874
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
3308
2875
  ] }) }),
3309
- Object.keys(detail.data ?? {}).length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
3310
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Provider data" }),
3311
- /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-xs bg-ui-bg-subtle p-4 rounded-lg overflow-auto max-h-96", children: JSON.stringify(detail.data, null, 2) })
3312
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl border border-ui-border-base p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No provider data for this session." }) })
3313
- ] }) : null
3314
- ] }) });
3315
- };
3316
- const config$3 = adminSdk.defineRouteConfig({
3317
- label: "Payment details",
3318
- icon: icons.CreditCard
3319
- });
3320
- const getStatusBadgeClass$2 = (status) => {
3321
- const s2 = status.toLowerCase();
3322
- if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
3323
- if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
3324
- if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
3325
- if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
3326
- return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
3327
- };
3328
- const formatAmount = (value) => {
3329
- return String(value);
3330
- };
3331
- const RefundDetailPage = () => {
3332
- var _a, _b, _c;
3333
- const navigate = reactRouterDom.useNavigate();
3334
- const params = reactRouterDom.useParams();
3335
- const id = (_a = params == null ? void 0 : params.id) == null ? void 0 : _a.trim();
3336
- const [detail, setDetail] = react.useState(null);
3337
- const [loading, setLoading] = react.useState(!!id);
3338
- const [error, setError] = react.useState(null);
3339
- const [gatewayExpanded, setGatewayExpanded] = react.useState(false);
3340
- react.useEffect(() => {
3341
- if (!id) {
3342
- setLoading(false);
3343
- return;
3344
- }
3345
- let cancelled = false;
3346
- setLoading(true);
3347
- setError(null);
3348
- fetch(`/admin/refunds/${id}`, { credentials: "include" }).then((res) => {
3349
- if (!res.ok) throw new Error(res.statusText || "Failed to load");
3350
- return res.json();
3351
- }).then((data) => {
3352
- if (!cancelled) setDetail(data);
3353
- }).catch((e) => {
3354
- if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
3355
- }).finally(() => {
3356
- if (!cancelled) setLoading(false);
3357
- });
3358
- return () => {
3359
- cancelled = true;
3360
- };
3361
- }, [id]);
3362
- const paymentStatus = ((_b = detail == null ? void 0 : detail.payment) == null ? void 0 : _b.status) ?? "—";
3363
- 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;
3364
- 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: [
3365
- /* @__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: [
3366
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => navigate("/refunds"), children: "← Refunds" }),
3367
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Refund details" }),
3368
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle font-mono", children: id ?? "—" })
3369
- ] }) }),
3370
- error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
3371
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
3372
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/refunds"), children: "Back to list" })
3373
- ] }) : 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: [
3374
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
3375
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Refund summary" }),
3376
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
3377
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3378
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refund ID" }),
3379
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.id })
3380
- ] }),
3381
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3382
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
3383
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.refund.amount) })
3384
- ] }),
3385
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3386
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Note" }),
3387
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.refund.note ?? "—" })
3388
- ] }),
3389
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3390
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created at" }),
3391
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: new Date(detail.refund.created_at).toLocaleDateString("en-US", {
2876
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((returnOrder) => /* @__PURE__ */ jsxRuntime.jsxs(
2877
+ "tr",
2878
+ {
2879
+ className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
2880
+ onClick: () => navigate(`/returns/${returnOrder.id}`),
2881
+ children: [
2882
+ /* @__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: returnOrder.id }) }) }),
2883
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.order_id }),
2884
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.customer_email || returnOrder.order_email || "—" }),
2885
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
2886
+ ui.Badge,
2887
+ {
2888
+ size: "2xsmall",
2889
+ className: `uppercase ${getStatusBadgeClass$5(returnOrder.status)}`,
2890
+ children: returnOrder.status.replace(/_/g, " ")
2891
+ }
2892
+ ) }),
2893
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
2894
+ const calc = returnOrder.refund;
2895
+ if (calc?.is_processed && calc.final_refund_amount != null) {
2896
+ return formatRefundCurrency(
2897
+ calc.final_refund_amount,
2898
+ calc.currency_code || returnOrder.currency_code
2899
+ );
2900
+ }
2901
+ if (calc) {
2902
+ return "Pending";
2903
+ }
2904
+ if (returnOrder.refund_amount == null) {
2905
+ return "—";
2906
+ }
2907
+ return formatRefundCurrency(
2908
+ Number(returnOrder.refund_amount),
2909
+ returnOrder.currency_code
2910
+ );
2911
+ })() }),
2912
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(returnOrder.created_at).toLocaleDateString("en-US", {
3392
2913
  year: "numeric",
3393
2914
  month: "short",
3394
2915
  day: "numeric",
3395
2916
  hour: "numeric",
3396
2917
  minute: "2-digit",
3397
2918
  hour12: true
3398
- }) })
3399
- ] }),
3400
- detail.refund.created_by ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3401
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created by" }),
3402
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.created_by })
3403
- ] }) : null
3404
- ] })
3405
- ] }),
3406
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
3407
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Payment summary" }),
3408
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
3409
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3410
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Payment amount" }),
3411
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.payment_amount) })
3412
- ] }),
3413
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3414
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Captured amount" }),
3415
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.captured_amount) })
3416
- ] }),
3417
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3418
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refunded amount" }),
3419
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.refunded_amount) })
3420
- ] }),
3421
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3422
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
3423
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.payment.provider_id || "—" })
3424
- ] }),
3425
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3426
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
3427
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
3428
- ui.Badge,
3429
- {
3430
- size: "2xsmall",
3431
- className: `uppercase ${getStatusBadgeClass$2(paymentStatus)}`,
3432
- children: paymentStatus !== "—" ? paymentStatus.replace(/_/g, " ") : "—"
3433
- }
3434
- ) })
3435
- ] }),
3436
- detail.computed ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3437
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3438
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Full refund" }),
3439
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.computed.is_full_refund ? "Yes" : "No" })
3440
- ] }),
3441
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3442
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Remaining refundable" }),
3443
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.computed.remaining_refundable_amount) })
3444
- ] }),
3445
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3446
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refund %" }),
3447
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "mt-1 block", children: [
3448
- detail.computed.refund_percentage.toFixed(1),
3449
- "%"
3450
- ] })
3451
- ] })
3452
- ] }) : null
3453
- ] })
3454
- ] }),
3455
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
3456
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Order summary" }),
3457
- detail.order ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
3458
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3459
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Order" }),
3460
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
2919
+ }) }),
2920
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
3461
2921
  ui.Button,
3462
2922
  {
3463
2923
  variant: "transparent",
3464
2924
  size: "small",
3465
- onClick: () => navigate(`/orders/${detail.order.order_id}`),
3466
- children: detail.order.order_number ?? detail.order.order_id
2925
+ onClick: (e) => {
2926
+ e.stopPropagation();
2927
+ navigate(`/app/orders/${returnOrder.order_id}`);
2928
+ },
2929
+ children: "Go to order"
3467
2930
  }
3468
2931
  ) })
3469
- ] }),
3470
- detail.order.total != null ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3471
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Total" }),
3472
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.order.total) })
3473
- ] }) : null,
3474
- detail.order.customer_id ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3475
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Customer ID" }),
3476
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.order.customer_id })
3477
- ] }) : null,
3478
- detail.order.region ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3479
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Region" }),
3480
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.region })
3481
- ] }) : null,
3482
- detail.order.fulfillment_status ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3483
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Fulfillment status" }),
3484
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.fulfillment_status })
3485
- ] }) : null
3486
- ] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No order linked to this refund." })
2932
+ ]
2933
+ },
2934
+ returnOrder.id
2935
+ )) })
2936
+ ] }) }),
2937
+ hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
2938
+ ui.Button,
2939
+ {
2940
+ variant: "secondary",
2941
+ isLoading: isFetchingMore,
2942
+ onClick: () => loadReturns(offset, false),
2943
+ children: "Load more"
2944
+ }
2945
+ ) }) : null
2946
+ ] }) });
2947
+ };
2948
+ const config$6 = adminSdk.defineRouteConfig({
2949
+ label: "Return Orders",
2950
+ icon: icons.ArrowPath
2951
+ });
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;
2959
+ };
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";
2964
+ }
2965
+ if (statusLower === "approved") {
2966
+ return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
2967
+ }
2968
+ if (statusLower === "rejected") {
2969
+ return "bg-ui-tag-red-bg text-ui-tag-red-text";
2970
+ }
2971
+ if (statusLower === "completed") {
2972
+ return "bg-ui-tag-green-bg text-ui-tag-green-text";
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";
2978
+ };
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" })
3487
3051
  ] }),
3488
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
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: [
3489
3065
  /* @__PURE__ */ jsxRuntime.jsxs(
3490
- "button",
3066
+ "select",
3491
3067
  {
3492
- type: "button",
3493
- className: "flex w-full items-center justify-between text-left",
3494
- onClick: () => setGatewayExpanded((prev) => !prev),
3495
- "aria-expanded": gatewayExpanded,
3496
- "aria-label": gatewayExpanded ? "Collapse gateway data" : "Expand gateway data",
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",
3497
3071
  children: [
3498
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg", children: "Gateway data" }),
3499
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: gatewayExpanded ? "Collapse" : "Expand" })
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" })
3500
3075
  ]
3501
3076
  }
3502
3077
  ),
3503
- 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." }) })
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
+ )
3504
3090
  ] })
3505
- ] }) : null
3506
- ] }) });
3507
- };
3508
- const config$2 = adminSdk.defineRouteConfig({
3509
- label: "Refund details",
3510
- icon: icons.Receipt
3511
- });
3512
- const MASKED_VALUE = "••••••••••••";
3513
- const SENSITIVE_KEY_PATTERNS = [
3514
- /password|passwd|passphrase/i,
3515
- /secret/i,
3516
- /token/i,
3517
- /api_?key$/i,
3518
- /private_?key/i,
3519
- /access_?key/i,
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
+ ] }) });
3176
+ };
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,
3520
3189
  /(^|_)hash(ed)?($|_)/i,
3521
3190
  /(^|_)salt$/i,
3522
3191
  /^cvv$|^cvc$|security_code/i,
@@ -3550,13 +3219,12 @@ function isSensitiveKey(key) {
3550
3219
  const FULLY_SECRET_TABLES = /* @__PURE__ */ new Set(["auth_mfa_recovery_code", "auth_password_reset_token"]);
3551
3220
  const ALWAYS_VISIBLE_KEYS = /* @__PURE__ */ new Set(["id", "created_at", "updated_at", "deleted_at", "expires_at", "used_at"]);
3552
3221
  function maskValue(value, ctx, depth) {
3553
- var _a;
3554
3222
  if (Array.isArray(value)) return value.map((item) => maskValue(item, ctx, depth + 1));
3555
3223
  if (value !== null && typeof value === "object") {
3556
3224
  const out = {};
3557
3225
  for (const [key, inner] of Object.entries(value)) {
3558
3226
  const topLevel = depth === 0;
3559
- 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"));
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"));
3560
3228
  if (secret) {
3561
3229
  ctx.count += 1;
3562
3230
  out[key] = MASKED_VALUE;
@@ -4022,13 +3690,12 @@ function readLastListSearch() {
4022
3690
  }
4023
3691
  }
4024
3692
  const DeletedRecordDetailPage = () => {
4025
- var _a;
4026
3693
  const navigate = reactRouterDom.useNavigate();
4027
3694
  const location = reactRouterDom.useLocation();
4028
3695
  const { id = "" } = reactRouterDom.useParams();
4029
3696
  const [state, setState] = react.useState({ status: "loading" });
4030
3697
  const [reloadToken, setReloadToken] = react.useState(0);
4031
- const cameFromList = ((_a = location.state) == null ? void 0 : _a.fromList) === true;
3698
+ const cameFromList = location.state?.fromList === true;
4032
3699
  const goBack = () => {
4033
3700
  if (cameFromList) navigate(-1);
4034
3701
  else navigate(`/deleted-records-audit${readLastListSearch()}`);
@@ -4163,96 +3830,405 @@ const DetailContent = ({ audit }) => {
4163
3830
  " ",
4164
3831
  "from this screen."
4165
3832
  ] }),
4166
- /* @__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: [
4167
- /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
4168
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-ui-fg-base", children: "Check whether this was expected." }),
4169
- " ",
4170
- 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)}.`,
4171
- " ",
4172
- guidance.headline
4173
- ] }),
4174
- /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
4175
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-ui-fg-base", children: "If it needs to come back:" }),
4176
- " ",
4177
- guidance.recreate
4178
- ] }),
4179
- /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
4180
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-ui-fg-base", children: "Need the details?" }),
4181
- " Use “View full record” above to see or copy everything that was stored. Sensitive values stay hidden."
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
3883
+ ] }),
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 PaymentDetailPage = () => {
3932
+ const navigate = reactRouterDom.useNavigate();
3933
+ const params = reactRouterDom.useParams();
3934
+ const id = params?.id?.trim();
3935
+ const [detail, setDetail] = react.useState(null);
3936
+ const [loading, setLoading] = react.useState(!!id);
3937
+ const [error, setError] = react.useState(null);
3938
+ react.useEffect(() => {
3939
+ if (!id) {
3940
+ setLoading(false);
3941
+ return;
3942
+ }
3943
+ let cancelled = false;
3944
+ setLoading(true);
3945
+ setError(null);
3946
+ fetch(`/admin/payment-transactions/${id}`, { credentials: "include" }).then((res) => {
3947
+ if (!res.ok) throw new Error(res.statusText || "Failed to load");
3948
+ return res.json();
3949
+ }).then((data) => {
3950
+ if (!cancelled) setDetail(data);
3951
+ }).catch((e) => {
3952
+ if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
3953
+ }).finally(() => {
3954
+ if (!cancelled) setLoading(false);
3955
+ });
3956
+ return () => {
3957
+ cancelled = true;
3958
+ };
3959
+ }, [id]);
3960
+ const displayStatus = detail ? (detail.payment_id != null && detail.payment_status != null && detail.payment_status !== "" ? detail.payment_status : detail.session_status ?? "") || "—" : "";
3961
+ const sessionStatusRaw = detail?.session_status ?? "—";
3962
+ const paymentStatusRaw = detail?.payment_id != null ? detail?.payment_status ?? "—" : "—";
3963
+ const displayAmount = detail ? `${(detail.currency_code ?? "USD").toUpperCase()} ${Number(detail.amount)}` : "";
3964
+ 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: [
3965
+ /* @__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: [
3966
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => navigate("/payments"), children: "← Payments" }),
3967
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Payment session" }),
3968
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: id ?? "—" })
3969
+ ] }) }),
3970
+ error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
3971
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
3972
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/payments"), children: "Back to list" })
3973
+ ] }) : 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: [
3974
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl border border-ui-border-base p-6 flex flex-col gap-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
3975
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3976
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Order ID" }),
3977
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: detail.order_id ? /* @__PURE__ */ jsxRuntime.jsx(
3978
+ ui.Button,
3979
+ {
3980
+ variant: "transparent",
3981
+ size: "small",
3982
+ onClick: () => navigate(`/orders/${detail.order_id}`),
3983
+ children: detail.order_id
3984
+ }
3985
+ ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "—" }) })
3986
+ ] }),
3987
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3988
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
3989
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: displayAmount })
3990
+ ] }),
3991
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3992
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
3993
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.provider_id })
3994
+ ] }),
3995
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3996
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
3997
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
3998
+ ui.Badge,
3999
+ {
4000
+ size: "2xsmall",
4001
+ className: `uppercase ${getStatusBadgeClass$3(displayStatus)}`,
4002
+ children: displayStatus !== "—" ? displayStatus.replace(/_/g, " ") : "—"
4003
+ }
4004
+ ) })
4005
+ ] }),
4006
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4007
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Session status (DB)" }),
4008
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: sessionStatusRaw })
4009
+ ] }),
4010
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4011
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Payment status (DB)" }),
4012
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: paymentStatusRaw })
4013
+ ] }),
4014
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4015
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Finalized" }),
4016
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.payment_id != null ? "Yes" : "No" })
4017
+ ] }),
4018
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4019
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created" }),
4020
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: new Date(detail.created_at).toLocaleDateString("en-US", {
4021
+ year: "numeric",
4022
+ month: "short",
4023
+ day: "numeric",
4024
+ hour: "numeric",
4025
+ minute: "2-digit",
4026
+ hour12: true
4027
+ }) })
4028
+ ] })
4029
+ ] }) }),
4030
+ Object.keys(detail.data ?? {}).length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
4031
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Provider data" }),
4032
+ /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-xs bg-ui-bg-subtle p-4 rounded-lg overflow-auto max-h-96", children: JSON.stringify(detail.data, null, 2) })
4033
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl border border-ui-border-base p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No provider data for this session." }) })
4034
+ ] }) : null
4035
+ ] }) });
4036
+ };
4037
+ const config$3 = adminSdk.defineRouteConfig({
4038
+ label: "Payment details",
4039
+ icon: icons.CreditCard
4040
+ });
4041
+ const getStatusBadgeClass$2 = (status) => {
4042
+ const s2 = status.toLowerCase();
4043
+ if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
4044
+ if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
4045
+ if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
4046
+ if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
4047
+ return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
4048
+ };
4049
+ const formatAmount = (value) => {
4050
+ return String(value);
4051
+ };
4052
+ const RefundDetailPage = () => {
4053
+ const navigate = reactRouterDom.useNavigate();
4054
+ const params = reactRouterDom.useParams();
4055
+ const id = params?.id?.trim();
4056
+ const [detail, setDetail] = react.useState(null);
4057
+ const [loading, setLoading] = react.useState(!!id);
4058
+ const [error, setError] = react.useState(null);
4059
+ const [gatewayExpanded, setGatewayExpanded] = react.useState(false);
4060
+ react.useEffect(() => {
4061
+ if (!id) {
4062
+ setLoading(false);
4063
+ return;
4064
+ }
4065
+ let cancelled = false;
4066
+ setLoading(true);
4067
+ setError(null);
4068
+ fetch(`/admin/refunds/${id}`, { credentials: "include" }).then((res) => {
4069
+ if (!res.ok) throw new Error(res.statusText || "Failed to load");
4070
+ return res.json();
4071
+ }).then((data) => {
4072
+ if (!cancelled) setDetail(data);
4073
+ }).catch((e) => {
4074
+ if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
4075
+ }).finally(() => {
4076
+ if (!cancelled) setLoading(false);
4077
+ });
4078
+ return () => {
4079
+ cancelled = true;
4080
+ };
4081
+ }, [id]);
4082
+ const paymentStatus = detail?.payment?.status ?? "—";
4083
+ const hasGatewayData = detail?.payment?.payment_data && typeof detail.payment.payment_data === "object" && Object.keys(detail.payment.payment_data).length > 0;
4084
+ 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: [
4085
+ /* @__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: [
4086
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => navigate("/refunds"), children: "← Refunds" }),
4087
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Refund details" }),
4088
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle font-mono", children: id ?? "—" })
4089
+ ] }) }),
4090
+ error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
4091
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
4092
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/refunds"), children: "Back to list" })
4093
+ ] }) : 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: [
4094
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
4095
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Refund summary" }),
4096
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
4097
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4098
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refund ID" }),
4099
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.id })
4100
+ ] }),
4101
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4102
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
4103
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.refund.amount) })
4104
+ ] }),
4105
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4106
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Note" }),
4107
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.refund.note ?? "—" })
4108
+ ] }),
4109
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4110
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created at" }),
4111
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: new Date(detail.refund.created_at).toLocaleDateString("en-US", {
4112
+ year: "numeric",
4113
+ month: "short",
4114
+ day: "numeric",
4115
+ hour: "numeric",
4116
+ minute: "2-digit",
4117
+ hour12: true
4118
+ }) })
4119
+ ] }),
4120
+ detail.refund.created_by ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4121
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created by" }),
4122
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.created_by })
4123
+ ] }) : null
4124
+ ] })
4125
+ ] }),
4126
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
4127
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Payment summary" }),
4128
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
4129
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4130
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Payment amount" }),
4131
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.payment_amount) })
4132
+ ] }),
4133
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4134
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Captured amount" }),
4135
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.captured_amount) })
4136
+ ] }),
4137
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4138
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refunded amount" }),
4139
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.refunded_amount) })
4140
+ ] }),
4141
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4142
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
4143
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.payment.provider_id || "—" })
4144
+ ] }),
4145
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4146
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
4147
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
4148
+ ui.Badge,
4149
+ {
4150
+ size: "2xsmall",
4151
+ className: `uppercase ${getStatusBadgeClass$2(paymentStatus)}`,
4152
+ children: paymentStatus !== "—" ? paymentStatus.replace(/_/g, " ") : "—"
4153
+ }
4154
+ ) })
4155
+ ] }),
4156
+ detail.computed ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4157
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4158
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Full refund" }),
4159
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.computed.is_full_refund ? "Yes" : "No" })
4160
+ ] }),
4161
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4162
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Remaining refundable" }),
4163
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.computed.remaining_refundable_amount) })
4164
+ ] }),
4165
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4166
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refund %" }),
4167
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "mt-1 block", children: [
4168
+ detail.computed.refund_percentage.toFixed(1),
4169
+ "%"
4170
+ ] })
4171
+ ] })
4172
+ ] }) : null
4182
4173
  ] })
4183
4174
  ] }),
4184
- guidance.adminSection || related.length ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
4185
- guidance.adminSection ? /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", size: "small", onClick: () => navigate(guidance.adminSection.path), children: guidance.adminSection.label }) : null,
4186
- related.map((link) => /* @__PURE__ */ jsxRuntime.jsxs(
4187
- ui.Button,
4175
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
4176
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Order summary" }),
4177
+ detail.order ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
4178
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4179
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Order" }),
4180
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
4181
+ ui.Button,
4182
+ {
4183
+ variant: "transparent",
4184
+ size: "small",
4185
+ onClick: () => navigate(`/orders/${detail.order.order_id}`),
4186
+ children: detail.order.order_number ?? detail.order.order_id
4187
+ }
4188
+ ) })
4189
+ ] }),
4190
+ detail.order.total != null ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4191
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Total" }),
4192
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.order.total) })
4193
+ ] }) : null,
4194
+ detail.order.customer_id ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4195
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Customer ID" }),
4196
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.order.customer_id })
4197
+ ] }) : null,
4198
+ detail.order.region ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4199
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Region" }),
4200
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.region })
4201
+ ] }) : null,
4202
+ detail.order.fulfillment_status ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4203
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Fulfillment status" }),
4204
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.fulfillment_status })
4205
+ ] }) : null
4206
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No order linked to this refund." })
4207
+ ] }),
4208
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
4209
+ /* @__PURE__ */ jsxRuntime.jsxs(
4210
+ "button",
4188
4211
  {
4189
- variant: "transparent",
4190
- size: "small",
4191
- onClick: () => navigate(link.path),
4192
- title: `Opens ${link.label.toLowerCase()} ${link.id} if it still exists`,
4212
+ type: "button",
4213
+ className: "flex w-full items-center justify-between text-left",
4214
+ onClick: () => setGatewayExpanded((prev) => !prev),
4215
+ "aria-expanded": gatewayExpanded,
4216
+ "aria-label": gatewayExpanded ? "Collapse gateway data" : "Expand gateway data",
4193
4217
  children: [
4194
- "Open related ",
4195
- link.label.toLowerCase(),
4196
- /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronRightMini, {})
4218
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg", children: "Gateway data" }),
4219
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: gatewayExpanded ? "Collapse" : "Expand" })
4197
4220
  ]
4198
- },
4199
- link.path
4200
- ))
4201
- ] }) : null,
4202
- 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
4203
- ] }) })
4204
- ] });
4221
+ }
4222
+ ),
4223
+ 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." }) })
4224
+ ] })
4225
+ ] }) : null
4226
+ ] }) });
4205
4227
  };
4206
- const Section = ({
4207
- title,
4208
- description,
4209
- actions,
4210
- children
4211
- }) => /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "flex flex-col gap-4 rounded-lg border border-ui-border-base p-5", children: [
4212
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-start justify-between gap-2", children: [
4213
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [
4214
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: title }),
4215
- description ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: description }) : null
4216
- ] }),
4217
- actions
4218
- ] }),
4219
- children
4220
- ] });
4221
- const Field = ({ label, children }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-col gap-1", children: [
4222
- /* @__PURE__ */ jsxRuntime.jsx("dt", { className: "text-xs font-medium uppercase tracking-wide text-ui-fg-muted", children: label }),
4223
- /* @__PURE__ */ jsxRuntime.jsx("dd", { className: "min-w-0", children })
4224
- ] });
4225
- const DetailSkeleton = () => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", "aria-busy": "true", children: [
4226
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
4227
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-5 w-24 rounded-full" }),
4228
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-8 w-64" }),
4229
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-4 w-48" })
4230
- ] }),
4231
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-14 w-full" }),
4232
- 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: [
4233
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-5 w-40" }),
4234
- /* @__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: [
4235
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-3 w-20" }),
4236
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-4 w-36" })
4237
- ] }, j)) })
4238
- ] }, i))
4239
- ] });
4240
- const DetailError = ({
4241
- notFound,
4242
- message,
4243
- onRetry,
4244
- onBack
4245
- }) => /* @__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: [
4246
- /* @__PURE__ */ jsxRuntime.jsx(icons.ExclamationCircle, { className: ui.clx(notFound ? "text-ui-fg-muted" : "text-ui-fg-error") }),
4247
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", children: notFound ? "Audit entry not found" : "Unable to load this deleted record" }),
4248
- /* @__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." }),
4249
- !notFound ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "max-w-md font-mono text-ui-fg-muted", children: message }) : null,
4250
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 flex gap-2", children: [
4251
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", size: "small", onClick: onBack, children: "Back to Deleted Records" }),
4252
- !notFound ? /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", size: "small", onClick: onRetry, children: "Try again" }) : null
4253
- ] })
4254
- ] });
4255
- adminSdk.defineRouteConfig({});
4228
+ const config$2 = adminSdk.defineRouteConfig({
4229
+ label: "Refund details",
4230
+ icon: icons.Receipt
4231
+ });
4256
4232
  const getStatusBadgeClass$1 = (status) => {
4257
4233
  const statusLower = status.toLowerCase();
4258
4234
  if (statusLower === "requested") {
@@ -4279,7 +4255,6 @@ const getStatusBadgeClass$1 = (status) => {
4279
4255
  return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
4280
4256
  };
4281
4257
  const ReturnDetailPage = () => {
4282
- var _a, _b, _c;
4283
4258
  const navigate = reactRouterDom.useNavigate();
4284
4259
  const { id } = reactRouterDom.useParams();
4285
4260
  const [returnOrder, setReturnOrder] = react.useState(null);
@@ -4362,7 +4337,7 @@ const ReturnDetailPage = () => {
4362
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" }) })
4363
4338
  ] }) }) });
4364
4339
  }
4365
- const statusHistory = ((_a = returnOrder.metadata) == null ? void 0 : _a.status_history) || [];
4340
+ const statusHistory = returnOrder.metadata?.status_history || [];
4366
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: [
4367
4342
  /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
4368
4343
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -4498,11 +4473,11 @@ const ReturnDetailPage = () => {
4498
4473
  ] }),
4499
4474
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4500
4475
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
4501
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_b = returnOrder.order.customer) == null ? void 0 : _b.email) || returnOrder.order.email || "—" })
4476
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.customer?.email || returnOrder.order.email || "—" })
4502
4477
  ] }),
4503
4478
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4504
4479
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Payment method" }),
4505
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_c = returnOrder.order.order_payment) == null ? void 0 : _c.label) || "—" })
4480
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.order_payment?.label || "—" })
4506
4481
  ] }),
4507
4482
  returnOrder.order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4508
4483
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
@@ -4559,13 +4534,12 @@ const getStatusBadgeClass = (status) => {
4559
4534
  return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
4560
4535
  };
4561
4536
  const SwapDetailPage = () => {
4562
- var _a, _b, _c;
4563
4537
  const navigate = reactRouterDom.useNavigate();
4564
4538
  const { id } = reactRouterDom.useParams();
4565
4539
  const [swap, setSwap] = react.useState(null);
4566
4540
  const [order, setOrder] = react.useState(null);
4567
4541
  const [isLoading, setIsLoading] = react.useState(true);
4568
- react.useState(false);
4542
+ const [isRejecting, setIsRejecting] = react.useState(false);
4569
4543
  const [isCancelling, setIsCancelling] = react.useState(false);
4570
4544
  const [error, setError] = react.useState(null);
4571
4545
  const [updateError, setUpdateError] = react.useState(null);
@@ -4636,9 +4610,9 @@ const SwapDetailPage = () => {
4636
4610
  setIsCancelling(false);
4637
4611
  }
4638
4612
  };
4639
- const isOrderExchange = Boolean(swap == null ? void 0 : swap.exchange_id);
4613
+ const isOrderExchange = Boolean(swap?.exchange_id);
4640
4614
  const canCancelExchange = isOrderExchange && swap && !["cancelled", "canceled", "completed", "declined"].includes(
4641
- ((_a = swap.status) == null ? void 0 : _a.toLowerCase()) ?? ""
4615
+ swap.status?.toLowerCase() ?? ""
4642
4616
  );
4643
4617
  if (isLoading) {
4644
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..." }) }) }) });
@@ -4649,7 +4623,7 @@ const SwapDetailPage = () => {
4649
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" }) })
4650
4624
  ] }) }) });
4651
4625
  }
4652
- const statusHistory = ((_b = swap.metadata) == null ? void 0 : _b.status_history) || [];
4626
+ const statusHistory = swap.metadata?.status_history || [];
4653
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: [
4654
4628
  /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
4655
4629
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -4770,7 +4744,7 @@ const SwapDetailPage = () => {
4770
4744
  ] }),
4771
4745
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4772
4746
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
4773
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_c = order.customer) == null ? void 0 : _c.email) || order.email || "—" })
4747
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.customer?.email || order.email || "—" })
4774
4748
  ] }),
4775
4749
  order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4776
4750
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
@@ -4819,112 +4793,142 @@ 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
- Component: PaymentsPage,
4833
- path: "/payments"
4808
+ Component: DeletedRecordsPage,
4809
+ path: "/deleted-records-audit",
4810
+ handle: { label: config$9.label, translationNs: config$9.translationNs }
4834
4811
  },
4835
4812
  {
4836
- Component: RefundsPage,
4837
- path: "/refunds"
4813
+ Component: PaymentsPage,
4814
+ path: "/payments",
4815
+ handle: { label: config$8.label, translationNs: config$8.translationNs }
4838
4816
  },
4839
4817
  {
4840
- Component: DeletedRecordsPage,
4841
- path: "/deleted-records-audit"
4818
+ Component: RefundsPage,
4819
+ path: "/refunds",
4820
+ handle: { label: config$7.label, translationNs: config$7.translationNs }
4842
4821
  },
4843
4822
  {
4844
4823
  Component: ReturnsPage,
4845
- path: "/returns"
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: PaymentDetailPage,
4853
- path: "/payments/:id"
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: RefundDetailPage,
4857
- path: "/refunds/:id"
4838
+ Component: PaymentDetailPage,
4839
+ path: "/payments/:id",
4840
+ handle: { label: config$3.label, translationNs: config$3.translationNs }
4858
4841
  },
4859
4842
  {
4860
- Component: DeletedRecordDetailPage,
4861
- path: "/deleted-records-audit/:id"
4843
+ Component: RefundDetailPage,
4844
+ path: "/refunds/: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
4853
  Component: SwapDetailPage,
4869
- path: "/swaps/:id"
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$5.label,
4877
- icon: config$5.icon,
4878
- path: "/returns",
4879
- nested: void 0
4862
+ label: config$9.label,
4863
+ icon: config$9.icon,
4864
+ path: "/deleted-records-audit",
4865
+ nested: void 0,
4866
+ rank: void 0,
4867
+ translationNs: void 0
4868
+ },
4869
+ {
4870
+ label: config$8.label,
4871
+ icon: config$8.icon,
4872
+ path: "/payments",
4873
+ nested: void 0,
4874
+ rank: void 0,
4875
+ translationNs: void 0
4880
4876
  },
4881
4877
  {
4882
4878
  label: config$7.label,
4883
4879
  icon: config$7.icon,
4884
4880
  path: "/refunds",
4885
- nested: void 0
4886
- },
4887
- {
4888
- label: config$4.label,
4889
- icon: config$4.icon,
4890
- path: "/swaps",
4891
- nested: void 0
4881
+ nested: void 0,
4882
+ rank: void 0,
4883
+ translationNs: void 0
4892
4884
  },
4893
4885
  {
4894
4886
  label: config$6.label,
4895
4887
  icon: config$6.icon,
4896
- path: "/deleted-records-audit",
4897
- nested: void 0
4888
+ path: "/returns",
4889
+ nested: void 0,
4890
+ rank: void 0,
4891
+ translationNs: void 0
4898
4892
  },
4899
4893
  {
4900
- label: config$1.label,
4901
- icon: config$1.icon,
4902
- path: "/returns/:id",
4903
- nested: void 0
4894
+ label: config$5.label,
4895
+ icon: config$5.icon,
4896
+ path: "/swaps",
4897
+ nested: void 0,
4898
+ rank: void 0,
4899
+ translationNs: void 0
4904
4900
  },
4905
4901
  {
4906
- label: config$8.label,
4907
- icon: config$8.icon,
4908
- path: "/payments",
4909
- nested: void 0
4902
+ label: config$3.label,
4903
+ icon: config$3.icon,
4904
+ path: "/payments/:id",
4905
+ nested: void 0,
4906
+ rank: void 0,
4907
+ translationNs: void 0
4910
4908
  },
4911
4909
  {
4912
4910
  label: config$2.label,
4913
4911
  icon: config$2.icon,
4914
4912
  path: "/refunds/:id",
4915
- nested: void 0
4913
+ nested: void 0,
4914
+ rank: void 0,
4915
+ translationNs: void 0
4916
+ },
4917
+ {
4918
+ label: config$1.label,
4919
+ icon: config$1.icon,
4920
+ path: "/returns/:id",
4921
+ nested: void 0,
4922
+ rank: void 0,
4923
+ translationNs: void 0
4916
4924
  },
4917
4925
  {
4918
4926
  label: config.label,
4919
4927
  icon: config.icon,
4920
4928
  path: "/swaps/:id",
4921
- nested: void 0
4922
- },
4923
- {
4924
- label: config$3.label,
4925
- icon: config$3.icon,
4926
- path: "/payments/:id",
4927
- nested: void 0
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;