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