order-management 0.0.82 → 0.0.84

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.
Files changed (26) hide show
  1. package/.medusa/server/src/admin/index.js +668 -668
  2. package/.medusa/server/src/admin/index.mjs +669 -669
  3. package/.medusa/server/src/api/admin/return/[id]/reject/route.js +6 -2
  4. package/.medusa/server/src/api/admin/swaps/[id]/cancel/route.js +5 -1
  5. package/.medusa/server/src/api/admin/swaps/[id]/reject/route.js +5 -1
  6. package/.medusa/server/src/api/store/guest-orders/[id]/returns/route.js +56 -41
  7. package/.medusa/server/src/api/store/guest-orders/[id]/swaps/[swap_id]/cancel/route.js +3 -1
  8. package/.medusa/server/src/api/store/guest-orders/[id]/swaps/route.js +25 -15
  9. package/.medusa/server/src/api/store/returns/[id]/cancel/route.js +3 -1
  10. package/.medusa/server/src/api/store/returns/route.js +24 -19
  11. package/.medusa/server/src/api/store/swaps/[id]/cancel/route.js +5 -1
  12. package/.medusa/server/src/api/store/swaps/route.js +26 -15
  13. package/.medusa/server/src/helpers/index.js +2 -1
  14. package/.medusa/server/src/helpers/return-exchange-guard.js +129 -0
  15. package/.medusa/server/src/modules/order-rma-gate/constants.js +21 -0
  16. package/.medusa/server/src/modules/order-rma-gate/index.js +20 -0
  17. package/.medusa/server/src/modules/order-rma-gate/migrations/Migration20260724100000.js +34 -0
  18. package/.medusa/server/src/modules/order-rma-gate/models/order-rma-gate.js +11 -0
  19. package/.medusa/server/src/modules/order-rma-gate/service.js +202 -0
  20. package/.medusa/server/src/modules/order-rma-gate/stale-reclaim.js +18 -0
  21. package/.medusa/server/src/modules/order-rma-gate/types.js +3 -0
  22. package/.medusa/server/src/subscribers/order-return-received.js +45 -0
  23. package/.medusa/server/src/utils/notification-handler.js +13 -5
  24. package/.medusa/server/src/utils/phone-e164.js +66 -0
  25. package/README.md +13 -4
  26. package/package.json +4 -2
@@ -866,6 +866,238 @@ const useDebounce$3 = (value, delay) => {
866
866
  return debouncedValue;
867
867
  };
868
868
  const getStatusBadgeClass$7 = (status) => {
869
+ const statusLower = status.toLowerCase();
870
+ if (statusLower === "requested") {
871
+ return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
872
+ }
873
+ if (statusLower === "received") {
874
+ return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
875
+ }
876
+ if (statusLower === "requires_action") {
877
+ return "bg-ui-tag-red-bg text-ui-tag-red-text";
878
+ }
879
+ if (statusLower === "completed") {
880
+ return "bg-ui-tag-green-bg text-ui-tag-green-text";
881
+ }
882
+ if (statusLower === "canceled") {
883
+ return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
884
+ }
885
+ return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
886
+ };
887
+ const ReturnsPage = () => {
888
+ const navigate = reactRouterDom.useNavigate();
889
+ const [items, setItems] = react.useState([]);
890
+ const [statusFilter, setStatusFilter] = react.useState("all");
891
+ const [createdByFilter, setCreatedByFilter] = react.useState("all");
892
+ const [searchQuery, setSearchQuery] = react.useState("");
893
+ const debouncedSearchQuery = useDebounce$3(searchQuery, 300);
894
+ const [isLoading, setIsLoading] = react.useState(true);
895
+ const [isFetchingMore, setIsFetchingMore] = react.useState(false);
896
+ const [error, setError] = react.useState(null);
897
+ const [offset, setOffset] = react.useState(0);
898
+ const [count, setCount] = react.useState(0);
899
+ const limit = 50;
900
+ const loadReturns = react.useCallback(
901
+ async (nextOffset, replace = false) => {
902
+ var _a;
903
+ try {
904
+ if (replace) {
905
+ setIsLoading(true);
906
+ } else {
907
+ setIsFetchingMore(true);
908
+ }
909
+ setError(null);
910
+ const params = new URLSearchParams();
911
+ params.set("limit", String(limit));
912
+ params.set("offset", String(nextOffset));
913
+ if (statusFilter !== "all") {
914
+ params.set("status", statusFilter);
915
+ }
916
+ if (debouncedSearchQuery.trim()) {
917
+ params.set("q", debouncedSearchQuery.trim());
918
+ }
919
+ if (createdByFilter !== "all") {
920
+ params.set("created_by", createdByFilter);
921
+ }
922
+ params.set("order", "created_at");
923
+ const response = await fetch(
924
+ `/admin/return?${params.toString()}`,
925
+ { credentials: "include" }
926
+ );
927
+ if (!response.ok) {
928
+ const message = await response.text();
929
+ throw new Error(message || "Unable to load return orders");
930
+ }
931
+ const payload = await response.json();
932
+ setCount(payload.count ?? 0);
933
+ setOffset(nextOffset + (((_a = payload.returns) == null ? void 0 : _a.length) ?? 0));
934
+ setItems(
935
+ (prev) => replace ? payload.returns ?? [] : [...prev, ...payload.returns ?? []]
936
+ );
937
+ } catch (loadError) {
938
+ const message = loadError instanceof Error ? loadError.message : "Unable to load return orders";
939
+ setError(message);
940
+ } finally {
941
+ setIsLoading(false);
942
+ setIsFetchingMore(false);
943
+ }
944
+ },
945
+ [statusFilter, createdByFilter, debouncedSearchQuery]
946
+ );
947
+ react.useEffect(() => {
948
+ void loadReturns(0, true);
949
+ }, [statusFilter, createdByFilter, debouncedSearchQuery, loadReturns]);
950
+ const hasMore = react.useMemo(() => offset < count, [offset, count]);
951
+ const availableStatuses = react.useMemo(() => {
952
+ const statuses = /* @__PURE__ */ new Set();
953
+ items.forEach((item) => statuses.add(item.status));
954
+ return Array.from(statuses).sort();
955
+ }, [items]);
956
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-7xl flex-col gap-6 p-6", children: [
957
+ /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
958
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
959
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Return Orders" }),
960
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer return orders" })
961
+ ] }),
962
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadReturns(0, true), children: "Refresh" })
963
+ ] }),
964
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
965
+ /* @__PURE__ */ jsxRuntime.jsx(
966
+ ui.Input,
967
+ {
968
+ placeholder: "Search by return ID, order ID, or customer email",
969
+ value: searchQuery,
970
+ onChange: (event) => setSearchQuery(event.target.value),
971
+ className: "md:max-w-sm"
972
+ }
973
+ ),
974
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
975
+ /* @__PURE__ */ jsxRuntime.jsxs(
976
+ "select",
977
+ {
978
+ value: createdByFilter,
979
+ onChange: (event) => setCreatedByFilter(event.target.value),
980
+ 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",
981
+ children: [
982
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All (Created by)" }),
983
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "customer", children: "Customer" }),
984
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "admin", children: "Admin" })
985
+ ]
986
+ }
987
+ ),
988
+ /* @__PURE__ */ jsxRuntime.jsxs(
989
+ "select",
990
+ {
991
+ value: statusFilter,
992
+ onChange: (event) => setStatusFilter(event.target.value),
993
+ 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",
994
+ children: [
995
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All Statuses" }),
996
+ availableStatuses.map((status) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
997
+ ]
998
+ }
999
+ )
1000
+ ] })
1001
+ ] }),
1002
+ error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
1003
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
1004
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
1005
+ ui.Button,
1006
+ {
1007
+ variant: "secondary",
1008
+ onClick: () => loadReturns(0, true),
1009
+ children: "Try again"
1010
+ }
1011
+ ) })
1012
+ ] }) : null,
1013
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading return orders..." }) }) : items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
1014
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No return orders yet" }),
1015
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Return orders created by customers will appear here." })
1016
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
1017
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
1018
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Return ID" }),
1019
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
1020
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Customer" }),
1021
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
1022
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Refund Amount" }),
1023
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
1024
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
1025
+ ] }) }),
1026
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((returnOrder) => /* @__PURE__ */ jsxRuntime.jsxs(
1027
+ "tr",
1028
+ {
1029
+ className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
1030
+ onClick: () => navigate(`/returns/${returnOrder.id}`),
1031
+ children: [
1032
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-0.5", children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: returnOrder.id }) }) }),
1033
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.order_id }),
1034
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.customer_email || returnOrder.order_email || "—" }),
1035
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
1036
+ ui.Badge,
1037
+ {
1038
+ size: "2xsmall",
1039
+ className: `uppercase ${getStatusBadgeClass$7(returnOrder.status)}`,
1040
+ children: returnOrder.status.replace(/_/g, " ")
1041
+ }
1042
+ ) }),
1043
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
1044
+ const amount = returnOrder.refund_amount;
1045
+ if (amount == null || amount === void 0) {
1046
+ return "—";
1047
+ }
1048
+ const displayAmount = Number(amount) / 100;
1049
+ const currency = returnOrder.currency_code || "$";
1050
+ return `${currency}${displayAmount.toFixed(2)}`;
1051
+ })() }),
1052
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(returnOrder.created_at).toLocaleDateString("en-US", {
1053
+ year: "numeric",
1054
+ month: "short",
1055
+ day: "numeric",
1056
+ hour: "numeric",
1057
+ minute: "2-digit",
1058
+ hour12: true
1059
+ }) }),
1060
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
1061
+ ui.Button,
1062
+ {
1063
+ variant: "transparent",
1064
+ size: "small",
1065
+ onClick: (e) => {
1066
+ e.stopPropagation();
1067
+ navigate(`/app/orders/${returnOrder.order_id}`);
1068
+ },
1069
+ children: "Go to order"
1070
+ }
1071
+ ) })
1072
+ ]
1073
+ },
1074
+ returnOrder.id
1075
+ )) })
1076
+ ] }) }),
1077
+ hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
1078
+ ui.Button,
1079
+ {
1080
+ variant: "secondary",
1081
+ isLoading: isFetchingMore,
1082
+ onClick: () => loadReturns(offset, false),
1083
+ children: "Load more"
1084
+ }
1085
+ ) }) : null
1086
+ ] }) });
1087
+ };
1088
+ const config$7 = adminSdk.defineRouteConfig({
1089
+ label: "Return Orders",
1090
+ icon: icons.ArrowPath
1091
+ });
1092
+ const useDebounce$2 = (value, delay) => {
1093
+ const [debouncedValue, setDebouncedValue] = react.useState(value);
1094
+ react.useEffect(() => {
1095
+ const handler = setTimeout(() => setDebouncedValue(value), delay);
1096
+ return () => clearTimeout(handler);
1097
+ }, [value, delay]);
1098
+ return debouncedValue;
1099
+ };
1100
+ const getStatusBadgeClass$6 = (status) => {
869
1101
  const s2 = status.toLowerCase();
870
1102
  if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
871
1103
  if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
@@ -878,7 +1110,7 @@ const PaymentsPage = () => {
878
1110
  const [items, setItems] = react.useState([]);
879
1111
  const [statusFilter, setStatusFilter] = react.useState("all");
880
1112
  const [orderIdSearch, setOrderIdSearch] = react.useState("");
881
- const debouncedOrderId = useDebounce$3(orderIdSearch, 300);
1113
+ const debouncedOrderId = useDebounce$2(orderIdSearch, 300);
882
1114
  const [isLoading, setIsLoading] = react.useState(true);
883
1115
  const [isFetchingMore, setIsFetchingMore] = react.useState(false);
884
1116
  const [error, setError] = react.useState(null);
@@ -998,7 +1230,7 @@ const PaymentsPage = () => {
998
1230
  ui.Badge,
999
1231
  {
1000
1232
  size: "2xsmall",
1001
- className: `uppercase ${getStatusBadgeClass$7(displayStatus(t))}`,
1233
+ className: `uppercase ${getStatusBadgeClass$6(displayStatus(t))}`,
1002
1234
  children: displayStatus(t) !== "—" ? displayStatus(t).replace(/_/g, " ") : "—"
1003
1235
  }
1004
1236
  ) }),
@@ -1053,11 +1285,11 @@ const PaymentsPage = () => {
1053
1285
  ) }) : null
1054
1286
  ] }) });
1055
1287
  };
1056
- const config$7 = adminSdk.defineRouteConfig({
1288
+ const config$6 = adminSdk.defineRouteConfig({
1057
1289
  label: "Payments",
1058
1290
  icon: icons.CreditCard
1059
1291
  });
1060
- const useDebounce$2 = (value, delay) => {
1292
+ const useDebounce$1 = (value, delay) => {
1061
1293
  const [debouncedValue, setDebouncedValue] = react.useState(value);
1062
1294
  react.useEffect(() => {
1063
1295
  const handler = setTimeout(() => setDebouncedValue(value), delay);
@@ -1065,7 +1297,7 @@ const useDebounce$2 = (value, delay) => {
1065
1297
  }, [value, delay]);
1066
1298
  return debouncedValue;
1067
1299
  };
1068
- const getStatusBadgeClass$6 = (status) => {
1300
+ const getStatusBadgeClass$5 = (status) => {
1069
1301
  const s2 = status.toLowerCase();
1070
1302
  if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
1071
1303
  if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
@@ -1077,12 +1309,12 @@ const RefundsPage = () => {
1077
1309
  const navigate = reactRouterDom.useNavigate();
1078
1310
  const [items, setItems] = react.useState([]);
1079
1311
  const [orderIdSearch, setOrderIdSearch] = react.useState("");
1080
- const debouncedOrderId = useDebounce$2(orderIdSearch, 300);
1312
+ const debouncedOrderId = useDebounce$1(orderIdSearch, 300);
1081
1313
  const [paymentStatusFilter, setPaymentStatusFilter] = react.useState("all");
1082
1314
  const [providerSearch, setProviderSearch] = react.useState("");
1083
- const debouncedProvider = useDebounce$2(providerSearch, 300);
1315
+ const debouncedProvider = useDebounce$1(providerSearch, 300);
1084
1316
  const [currencySearch, setCurrencySearch] = react.useState("");
1085
- const debouncedCurrency = useDebounce$2(currencySearch, 300);
1317
+ const debouncedCurrency = useDebounce$1(currencySearch, 300);
1086
1318
  const [dateFrom, setDateFrom] = react.useState("");
1087
1319
  const [dateTo, setDateTo] = react.useState("");
1088
1320
  const [amountMin, setAmountMin] = react.useState("");
@@ -1294,7 +1526,7 @@ const RefundsPage = () => {
1294
1526
  ui.Badge,
1295
1527
  {
1296
1528
  size: "2xsmall",
1297
- className: `uppercase ${getStatusBadgeClass$6(displayStatus(r))}`,
1529
+ className: `uppercase ${getStatusBadgeClass$5(displayStatus(r))}`,
1298
1530
  children: displayStatus(r) !== "—" ? displayStatus(r).replace(/_/g, " ") : "—"
1299
1531
  }
1300
1532
  ) }),
@@ -1348,11 +1580,11 @@ const RefundsPage = () => {
1348
1580
  ) }) : null
1349
1581
  ] }) });
1350
1582
  };
1351
- const config$6 = adminSdk.defineRouteConfig({
1583
+ const config$5 = adminSdk.defineRouteConfig({
1352
1584
  label: "Refunds",
1353
1585
  icon: icons.Receipt
1354
1586
  });
1355
- const useDebounce$1 = (value, delay) => {
1587
+ const useDebounce = (value, delay) => {
1356
1588
  const [debouncedValue, setDebouncedValue] = react.useState(value);
1357
1589
  react.useEffect(() => {
1358
1590
  const handler = setTimeout(() => setDebouncedValue(value), delay);
@@ -1360,39 +1592,39 @@ const useDebounce$1 = (value, delay) => {
1360
1592
  }, [value, delay]);
1361
1593
  return debouncedValue;
1362
1594
  };
1363
- const getStatusBadgeClass$5 = (status) => {
1595
+ const getStatusBadgeClass$4 = (status) => {
1364
1596
  const statusLower = status.toLowerCase();
1365
1597
  if (statusLower === "requested") {
1366
1598
  return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
1367
1599
  }
1368
- if (statusLower === "received") {
1600
+ if (statusLower === "approved") {
1369
1601
  return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
1370
1602
  }
1371
- if (statusLower === "requires_action") {
1603
+ if (statusLower === "rejected") {
1372
1604
  return "bg-ui-tag-red-bg text-ui-tag-red-text";
1373
1605
  }
1374
1606
  if (statusLower === "completed") {
1375
1607
  return "bg-ui-tag-green-bg text-ui-tag-green-text";
1376
1608
  }
1377
- if (statusLower === "canceled") {
1609
+ if (statusLower === "cancelled") {
1378
1610
  return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
1379
1611
  }
1380
1612
  return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
1381
1613
  };
1382
- const ReturnsPage = () => {
1614
+ const SwapsPage = () => {
1383
1615
  const navigate = reactRouterDom.useNavigate();
1384
1616
  const [items, setItems] = react.useState([]);
1385
1617
  const [statusFilter, setStatusFilter] = react.useState("all");
1386
1618
  const [createdByFilter, setCreatedByFilter] = react.useState("all");
1387
1619
  const [searchQuery, setSearchQuery] = react.useState("");
1388
- const debouncedSearchQuery = useDebounce$1(searchQuery, 300);
1620
+ const debouncedSearchQuery = useDebounce(searchQuery, 300);
1389
1621
  const [isLoading, setIsLoading] = react.useState(true);
1390
1622
  const [isFetchingMore, setIsFetchingMore] = react.useState(false);
1391
1623
  const [error, setError] = react.useState(null);
1392
1624
  const [offset, setOffset] = react.useState(0);
1393
1625
  const [count, setCount] = react.useState(0);
1394
1626
  const limit = 50;
1395
- const loadReturns = react.useCallback(
1627
+ const loadSwaps = react.useCallback(
1396
1628
  async (nextOffset, replace = false) => {
1397
1629
  var _a;
1398
1630
  try {
@@ -1409,28 +1641,27 @@ const ReturnsPage = () => {
1409
1641
  params.set("status", statusFilter);
1410
1642
  }
1411
1643
  if (debouncedSearchQuery.trim()) {
1412
- params.set("q", debouncedSearchQuery.trim());
1644
+ params.set("order_id", debouncedSearchQuery.trim());
1413
1645
  }
1414
1646
  if (createdByFilter !== "all") {
1415
1647
  params.set("created_by", createdByFilter);
1416
1648
  }
1417
- params.set("order", "created_at");
1418
1649
  const response = await fetch(
1419
- `/admin/return?${params.toString()}`,
1650
+ `/admin/swaps?${params.toString()}`,
1420
1651
  { credentials: "include" }
1421
1652
  );
1422
1653
  if (!response.ok) {
1423
1654
  const message = await response.text();
1424
- throw new Error(message || "Unable to load return orders");
1655
+ throw new Error(message || "Unable to load swaps");
1425
1656
  }
1426
1657
  const payload = await response.json();
1427
1658
  setCount(payload.count ?? 0);
1428
- setOffset(nextOffset + (((_a = payload.returns) == null ? void 0 : _a.length) ?? 0));
1659
+ setOffset(nextOffset + (((_a = payload.swaps) == null ? void 0 : _a.length) ?? 0));
1429
1660
  setItems(
1430
- (prev) => replace ? payload.returns ?? [] : [...prev, ...payload.returns ?? []]
1661
+ (prev) => replace ? payload.swaps ?? [] : [...prev, ...payload.swaps ?? []]
1431
1662
  );
1432
1663
  } catch (loadError) {
1433
- const message = loadError instanceof Error ? loadError.message : "Unable to load return orders";
1664
+ const message = loadError instanceof Error ? loadError.message : "Unable to load swaps";
1434
1665
  setError(message);
1435
1666
  } finally {
1436
1667
  setIsLoading(false);
@@ -1440,8 +1671,8 @@ const ReturnsPage = () => {
1440
1671
  [statusFilter, createdByFilter, debouncedSearchQuery]
1441
1672
  );
1442
1673
  react.useEffect(() => {
1443
- void loadReturns(0, true);
1444
- }, [statusFilter, createdByFilter, debouncedSearchQuery, loadReturns]);
1674
+ void loadSwaps(0, true);
1675
+ }, [statusFilter, createdByFilter, debouncedSearchQuery, loadSwaps]);
1445
1676
  const hasMore = react.useMemo(() => offset < count, [offset, count]);
1446
1677
  const availableStatuses = react.useMemo(() => {
1447
1678
  const statuses = /* @__PURE__ */ new Set();
@@ -1451,16 +1682,16 @@ const ReturnsPage = () => {
1451
1682
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-7xl flex-col gap-6 p-6", children: [
1452
1683
  /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
1453
1684
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
1454
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Return Orders" }),
1455
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer return orders" })
1685
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Exchanges" }),
1686
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer exchange requests" })
1456
1687
  ] }),
1457
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadReturns(0, true), children: "Refresh" })
1688
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadSwaps(0, true), children: "Refresh" })
1458
1689
  ] }),
1459
1690
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
1460
1691
  /* @__PURE__ */ jsxRuntime.jsx(
1461
1692
  ui.Input,
1462
1693
  {
1463
- placeholder: "Search by return ID, order ID, or customer email",
1694
+ placeholder: "Search by swap ID or order ID",
1464
1695
  value: searchQuery,
1465
1696
  onChange: (event) => setSearchQuery(event.target.value),
1466
1697
  className: "md:max-w-sm"
@@ -1500,51 +1731,50 @@ const ReturnsPage = () => {
1500
1731
  ui.Button,
1501
1732
  {
1502
1733
  variant: "secondary",
1503
- onClick: () => loadReturns(0, true),
1734
+ onClick: () => loadSwaps(0, true),
1504
1735
  children: "Try again"
1505
1736
  }
1506
1737
  ) })
1507
1738
  ] }) : null,
1508
- isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading return orders..." }) }) : items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
1509
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No return orders yet" }),
1510
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Return orders created by customers will appear here." })
1739
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading swaps..." }) }) : items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
1740
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No exchanges yet" }),
1741
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Exchange requests created by customers will appear here." })
1511
1742
  ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
1512
1743
  /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
1513
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Return ID" }),
1744
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Exchange ID" }),
1514
1745
  /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
1515
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Customer" }),
1516
1746
  /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
1517
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Refund Amount" }),
1747
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Difference Due" }),
1518
1748
  /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
1519
1749
  /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
1520
1750
  ] }) }),
1521
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((returnOrder) => /* @__PURE__ */ jsxRuntime.jsxs(
1751
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((swap) => /* @__PURE__ */ jsxRuntime.jsxs(
1522
1752
  "tr",
1523
1753
  {
1524
1754
  className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
1525
- onClick: () => navigate(`/returns/${returnOrder.id}`),
1755
+ onClick: () => navigate(`/swaps/${swap.id}`),
1526
1756
  children: [
1527
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-0.5", children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: returnOrder.id }) }) }),
1528
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.order_id }),
1529
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.customer_email || returnOrder.order_email || "—" }),
1757
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-0.5", children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: swap.id }) }) }),
1758
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: swap.order_id }),
1530
1759
  /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
1531
1760
  ui.Badge,
1532
1761
  {
1533
1762
  size: "2xsmall",
1534
- className: `uppercase ${getStatusBadgeClass$5(returnOrder.status)}`,
1535
- children: returnOrder.status.replace(/_/g, " ")
1763
+ className: `uppercase ${getStatusBadgeClass$4(swap.status)}`,
1764
+ children: swap.status.replace(/_/g, " ")
1536
1765
  }
1537
1766
  ) }),
1538
1767
  /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
1539
- const amount = returnOrder.refund_amount;
1768
+ const amount = swap.difference_due;
1540
1769
  if (amount == null || amount === void 0) {
1541
1770
  return "—";
1542
1771
  }
1543
1772
  const displayAmount = Number(amount) / 100;
1544
- const currency = returnOrder.currency_code || "$";
1545
- return `${currency}${displayAmount.toFixed(2)}`;
1773
+ const currency = swap.currency_code || "$";
1774
+ const sign = displayAmount >= 0 ? "+" : "";
1775
+ return `${sign}${currency}${displayAmount.toFixed(2)}`;
1546
1776
  })() }),
1547
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(returnOrder.created_at).toLocaleDateString("en-US", {
1777
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(swap.created_at).toLocaleDateString("en-US", {
1548
1778
  year: "numeric",
1549
1779
  month: "short",
1550
1780
  day: "numeric",
@@ -1559,14 +1789,14 @@ const ReturnsPage = () => {
1559
1789
  size: "small",
1560
1790
  onClick: (e) => {
1561
1791
  e.stopPropagation();
1562
- navigate(`/app/orders/${returnOrder.order_id}`);
1792
+ navigate(`/app/orders/${swap.order_id}`);
1563
1793
  },
1564
1794
  children: "Go to order"
1565
1795
  }
1566
1796
  ) })
1567
1797
  ]
1568
1798
  },
1569
- returnOrder.id
1799
+ swap.id
1570
1800
  )) })
1571
1801
  ] }) }),
1572
1802
  hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -1574,25 +1804,17 @@ const ReturnsPage = () => {
1574
1804
  {
1575
1805
  variant: "secondary",
1576
1806
  isLoading: isFetchingMore,
1577
- onClick: () => loadReturns(offset, false),
1807
+ onClick: () => loadSwaps(offset, false),
1578
1808
  children: "Load more"
1579
1809
  }
1580
1810
  ) }) : null
1581
1811
  ] }) });
1582
1812
  };
1583
- const config$5 = adminSdk.defineRouteConfig({
1584
- label: "Return Orders",
1813
+ const config$4 = adminSdk.defineRouteConfig({
1814
+ label: "Exchanges",
1585
1815
  icon: icons.ArrowPath
1586
1816
  });
1587
- const useDebounce = (value, delay) => {
1588
- const [debouncedValue, setDebouncedValue] = react.useState(value);
1589
- react.useEffect(() => {
1590
- const handler = setTimeout(() => setDebouncedValue(value), delay);
1591
- return () => clearTimeout(handler);
1592
- }, [value, delay]);
1593
- return debouncedValue;
1594
- };
1595
- const getStatusBadgeClass$4 = (status) => {
1817
+ const getStatusBadgeClass$3 = (status) => {
1596
1818
  const statusLower = status.toLowerCase();
1597
1819
  if (statusLower === "requested") {
1598
1820
  return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
@@ -1603,6 +1825,12 @@ const getStatusBadgeClass$4 = (status) => {
1603
1825
  if (statusLower === "rejected") {
1604
1826
  return "bg-ui-tag-red-bg text-ui-tag-red-text";
1605
1827
  }
1828
+ if (statusLower === "received") {
1829
+ return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
1830
+ }
1831
+ if (statusLower === "refunded") {
1832
+ return "bg-ui-tag-green-bg text-ui-tag-green-text";
1833
+ }
1606
1834
  if (statusLower === "completed") {
1607
1835
  return "bg-ui-tag-green-bg text-ui-tag-green-text";
1608
1836
  }
@@ -1611,210 +1839,260 @@ const getStatusBadgeClass$4 = (status) => {
1611
1839
  }
1612
1840
  return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
1613
1841
  };
1614
- const SwapsPage = () => {
1842
+ const ReturnDetailPage = () => {
1843
+ var _a, _b;
1615
1844
  const navigate = reactRouterDom.useNavigate();
1616
- const [items, setItems] = react.useState([]);
1617
- const [statusFilter, setStatusFilter] = react.useState("all");
1618
- const [createdByFilter, setCreatedByFilter] = react.useState("all");
1619
- const [searchQuery, setSearchQuery] = react.useState("");
1620
- const debouncedSearchQuery = useDebounce(searchQuery, 300);
1845
+ const { id } = reactRouterDom.useParams();
1846
+ const [returnOrder, setReturnOrder] = react.useState(null);
1621
1847
  const [isLoading, setIsLoading] = react.useState(true);
1622
- const [isFetchingMore, setIsFetchingMore] = react.useState(false);
1848
+ const [isRejecting, setIsRejecting] = react.useState(false);
1623
1849
  const [error, setError] = react.useState(null);
1624
- const [offset, setOffset] = react.useState(0);
1625
- const [count, setCount] = react.useState(0);
1626
- const limit = 50;
1627
- const loadSwaps = react.useCallback(
1628
- async (nextOffset, replace = false) => {
1629
- var _a;
1850
+ const [updateError, setUpdateError] = react.useState(null);
1851
+ const [updateSuccess, setUpdateSuccess] = react.useState(false);
1852
+ react.useEffect(() => {
1853
+ if (!id) {
1854
+ navigate("/returns");
1855
+ return;
1856
+ }
1857
+ const loadReturn = async () => {
1630
1858
  try {
1631
- if (replace) {
1632
- setIsLoading(true);
1633
- } else {
1634
- setIsFetchingMore(true);
1635
- }
1859
+ setIsLoading(true);
1636
1860
  setError(null);
1637
- const params = new URLSearchParams();
1638
- params.set("limit", String(limit));
1639
- params.set("offset", String(nextOffset));
1640
- if (statusFilter !== "all") {
1641
- params.set("status", statusFilter);
1642
- }
1643
- if (debouncedSearchQuery.trim()) {
1644
- params.set("order_id", debouncedSearchQuery.trim());
1645
- }
1646
- if (createdByFilter !== "all") {
1647
- params.set("created_by", createdByFilter);
1648
- }
1649
- const response = await fetch(
1650
- `/admin/swaps?${params.toString()}`,
1651
- { credentials: "include" }
1652
- );
1861
+ const response = await fetch(`/admin/returns/${id}`, {
1862
+ credentials: "include"
1863
+ });
1653
1864
  if (!response.ok) {
1654
1865
  const message = await response.text();
1655
- throw new Error(message || "Unable to load swaps");
1866
+ throw new Error(message || "Unable to load return order");
1656
1867
  }
1657
1868
  const payload = await response.json();
1658
- setCount(payload.count ?? 0);
1659
- setOffset(nextOffset + (((_a = payload.swaps) == null ? void 0 : _a.length) ?? 0));
1660
- setItems(
1661
- (prev) => replace ? payload.swaps ?? [] : [...prev, ...payload.swaps ?? []]
1662
- );
1869
+ setReturnOrder(payload.return);
1663
1870
  } catch (loadError) {
1664
- const message = loadError instanceof Error ? loadError.message : "Unable to load swaps";
1871
+ const message = loadError instanceof Error ? loadError.message : "Unable to load return order";
1665
1872
  setError(message);
1666
1873
  } finally {
1667
1874
  setIsLoading(false);
1668
- setIsFetchingMore(false);
1669
1875
  }
1670
- },
1671
- [statusFilter, createdByFilter, debouncedSearchQuery]
1672
- );
1673
- react.useEffect(() => {
1674
- void loadSwaps(0, true);
1675
- }, [statusFilter, createdByFilter, debouncedSearchQuery, loadSwaps]);
1676
- const hasMore = react.useMemo(() => offset < count, [offset, count]);
1677
- const availableStatuses = react.useMemo(() => {
1678
- const statuses = /* @__PURE__ */ new Set();
1679
- items.forEach((item) => statuses.add(item.status));
1680
- return Array.from(statuses).sort();
1681
- }, [items]);
1682
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-7xl flex-col gap-6 p-6", children: [
1683
- /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
1684
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
1685
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Exchanges" }),
1686
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer exchange requests" })
1687
- ] }),
1688
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadSwaps(0, true), children: "Refresh" })
1689
- ] }),
1690
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
1691
- /* @__PURE__ */ jsxRuntime.jsx(
1692
- ui.Input,
1876
+ };
1877
+ void loadReturn();
1878
+ }, [id, navigate]);
1879
+ const handleReject = async () => {
1880
+ if (!id) {
1881
+ return;
1882
+ }
1883
+ try {
1884
+ setIsRejecting(true);
1885
+ setUpdateError(null);
1886
+ setUpdateSuccess(false);
1887
+ const response = await fetch(`/admin/returns/${id}/reject`, {
1888
+ method: "POST",
1889
+ headers: {
1890
+ "Content-Type": "application/json"
1891
+ },
1892
+ credentials: "include",
1893
+ body: JSON.stringify({ reason: "Rejected by admin" })
1894
+ });
1895
+ if (!response.ok) {
1896
+ const message = await response.text();
1897
+ throw new Error(message || "Unable to reject return");
1898
+ }
1899
+ const payload = await response.json();
1900
+ setReturnOrder(payload.return);
1901
+ setUpdateSuccess(true);
1902
+ setTimeout(() => setUpdateSuccess(false), 3e3);
1903
+ const detailResponse = await fetch(`/admin/returns/${id}`, {
1904
+ credentials: "include"
1905
+ });
1906
+ if (detailResponse.ok) {
1907
+ const detailPayload = await detailResponse.json();
1908
+ setReturnOrder(detailPayload.return);
1909
+ }
1910
+ } catch (updateErr) {
1911
+ const message = updateErr instanceof Error ? updateErr.message : "Unable to reject return";
1912
+ setUpdateError(message);
1913
+ } finally {
1914
+ setIsRejecting(false);
1915
+ }
1916
+ };
1917
+ if (isLoading) {
1918
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading return order..." }) }) }) });
1919
+ }
1920
+ if (error || !returnOrder) {
1921
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
1922
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "Return order not found" }),
1923
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/returns"), children: "Back to list" }) })
1924
+ ] }) }) });
1925
+ }
1926
+ const statusHistory = ((_a = returnOrder.metadata) == null ? void 0 : _a.status_history) || [];
1927
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: [
1928
+ /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
1929
+ /* @__PURE__ */ jsxRuntime.jsxs(
1930
+ ui.Button,
1693
1931
  {
1694
- placeholder: "Search by swap ID or order ID",
1695
- value: searchQuery,
1696
- onChange: (event) => setSearchQuery(event.target.value),
1697
- className: "md:max-w-sm"
1932
+ variant: "transparent",
1933
+ size: "small",
1934
+ onClick: () => navigate("/returns"),
1935
+ className: "w-fit",
1936
+ children: [
1937
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, { className: "mr-2" }),
1938
+ "Back to list"
1939
+ ]
1698
1940
  }
1699
1941
  ),
1700
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
1701
- /* @__PURE__ */ jsxRuntime.jsxs(
1702
- "select",
1942
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 md:flex-row md:items-center md:justify-between", children: [
1943
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
1944
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Return Order Details" }),
1945
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: returnOrder.id })
1946
+ ] }),
1947
+ /* @__PURE__ */ jsxRuntime.jsx(
1948
+ ui.Badge,
1703
1949
  {
1704
- value: createdByFilter,
1705
- onChange: (event) => setCreatedByFilter(event.target.value),
1706
- 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",
1707
- children: [
1708
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All (Created by)" }),
1709
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "customer", children: "Customer" }),
1710
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "admin", children: "Admin" })
1711
- ]
1712
- }
1713
- ),
1714
- /* @__PURE__ */ jsxRuntime.jsxs(
1715
- "select",
1716
- {
1717
- value: statusFilter,
1718
- onChange: (event) => setStatusFilter(event.target.value),
1719
- 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",
1720
- children: [
1721
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All Statuses" }),
1722
- availableStatuses.map((status) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
1723
- ]
1950
+ size: "small",
1951
+ className: `uppercase ${getStatusBadgeClass$3(returnOrder.status)}`,
1952
+ children: returnOrder.status.replace(/_/g, " ")
1724
1953
  }
1725
1954
  )
1726
1955
  ] })
1727
1956
  ] }),
1728
- error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
1729
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
1730
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
1957
+ returnOrder.status === "requested" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
1958
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxRuntime.jsx(
1731
1959
  ui.Button,
1732
1960
  {
1733
- variant: "secondary",
1734
- onClick: () => loadSwaps(0, true),
1735
- children: "Try again"
1961
+ variant: "danger",
1962
+ onClick: handleReject,
1963
+ disabled: isRejecting,
1964
+ isLoading: isRejecting,
1965
+ children: "Reject (Cancel) Return"
1736
1966
  }
1737
- ) })
1738
- ] }) : null,
1739
- isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading swaps..." }) }) : items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
1740
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No exchanges yet" }),
1741
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Exchange requests created by customers will appear here." })
1742
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
1743
- /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
1744
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Exchange ID" }),
1745
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
1746
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
1747
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Difference Due" }),
1748
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
1749
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
1750
- ] }) }),
1751
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((swap) => /* @__PURE__ */ jsxRuntime.jsxs(
1752
- "tr",
1753
- {
1754
- className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
1755
- onClick: () => navigate(`/swaps/${swap.id}`),
1756
- children: [
1757
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-0.5", children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: swap.id }) }) }),
1758
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: swap.order_id }),
1759
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
1760
- ui.Badge,
1761
- {
1762
- size: "2xsmall",
1763
- className: `uppercase ${getStatusBadgeClass$4(swap.status)}`,
1764
- children: swap.status.replace(/_/g, " ")
1765
- }
1766
- ) }),
1767
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
1768
- const amount = swap.difference_due;
1769
- if (amount == null || amount === void 0) {
1770
- return "—";
1771
- }
1772
- const displayAmount = Number(amount) / 100;
1773
- const currency = swap.currency_code || "$";
1774
- const sign = displayAmount >= 0 ? "+" : "";
1775
- return `${sign}${currency}${displayAmount.toFixed(2)}`;
1776
- })() }),
1777
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(swap.created_at).toLocaleDateString("en-US", {
1778
- year: "numeric",
1779
- month: "short",
1780
- day: "numeric",
1781
- hour: "numeric",
1782
- minute: "2-digit",
1783
- hour12: true
1784
- }) }),
1785
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
1786
- ui.Button,
1787
- {
1788
- variant: "transparent",
1789
- size: "small",
1790
- onClick: (e) => {
1791
- e.stopPropagation();
1792
- navigate(`/app/orders/${swap.order_id}`);
1793
- },
1794
- children: "Go to order"
1795
- }
1796
- ) })
1797
- ]
1798
- },
1799
- swap.id
1800
- )) })
1801
- ] }) }),
1802
- hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
1803
- ui.Button,
1804
- {
1805
- variant: "secondary",
1806
- isLoading: isFetchingMore,
1807
- onClick: () => loadSwaps(offset, false),
1808
- children: "Load more"
1809
- }
1810
- ) }) : null
1967
+ ) }),
1968
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: 'Cancel this return request. Use "Mark as received" when items are received.' })
1969
+ ] }),
1970
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
1971
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Information" }),
1972
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
1973
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1974
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Return ID" }),
1975
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.id })
1976
+ ] }),
1977
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
1978
+ ui.Button,
1979
+ {
1980
+ variant: "secondary",
1981
+ onClick: () => {
1982
+ window.open(
1983
+ `/app/orders/${returnOrder.order_id}`,
1984
+ "_blank"
1985
+ );
1986
+ },
1987
+ children: "View order"
1988
+ }
1989
+ ) })
1990
+ ] })
1991
+ ] }),
1992
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
1993
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
1994
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Details" }),
1995
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
1996
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1997
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Return ID" }),
1998
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.id })
1999
+ ] }),
2000
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2001
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Status" }),
2002
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.status })
2003
+ ] }),
2004
+ returnOrder.reason && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2005
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Reason" }),
2006
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.reason })
2007
+ ] }),
2008
+ returnOrder.note && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2009
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Note" }),
2010
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.note })
2011
+ ] }),
2012
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2013
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Created" }),
2014
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(returnOrder.created_at).toLocaleString() })
2015
+ ] }),
2016
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2017
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Last Updated" }),
2018
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(returnOrder.updated_at).toLocaleString() })
2019
+ ] })
2020
+ ] })
2021
+ ] }),
2022
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
2023
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Status History" }),
2024
+ statusHistory.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: statusHistory.map((entry, index) => /* @__PURE__ */ jsxRuntime.jsx(
2025
+ "div",
2026
+ {
2027
+ className: "flex items-center justify-between border-b border-ui-border-subtle pb-2 last:border-0",
2028
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
2029
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
2030
+ ui.Badge,
2031
+ {
2032
+ size: "2xsmall",
2033
+ className: `uppercase ${getStatusBadgeClass$3(entry.status)}`,
2034
+ children: entry.status.replace(/_/g, " ")
2035
+ }
2036
+ ) }),
2037
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
2038
+ new Date(entry.timestamp).toLocaleString(),
2039
+ entry.admin_id && ` by ${entry.admin_id}`,
2040
+ entry.reason && ` - ${entry.reason}`
2041
+ ] })
2042
+ ] })
2043
+ },
2044
+ index
2045
+ )) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No status history available" })
2046
+ ] })
2047
+ ] }),
2048
+ returnOrder.order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
2049
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Related Order Information" }),
2050
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
2051
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2052
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order ID" }),
2053
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.id })
2054
+ ] }),
2055
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2056
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Status" }),
2057
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.status || "—" })
2058
+ ] }),
2059
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2060
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
2061
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_b = returnOrder.order.customer) == null ? void 0 : _b.email) || returnOrder.order.email || "—" })
2062
+ ] }),
2063
+ returnOrder.order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2064
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
2065
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "font-medium", children: [
2066
+ returnOrder.order.currency_code || "$",
2067
+ (Number(returnOrder.order.total) / 100).toFixed(2)
2068
+ ] })
2069
+ ] })
2070
+ ] })
2071
+ ] }),
2072
+ returnOrder.return_items && returnOrder.return_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
2073
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Items" }),
2074
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
2075
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2076
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Item ID" }),
2077
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" }),
2078
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Reason" })
2079
+ ] }) }),
2080
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: returnOrder.return_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2081
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.id }),
2082
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity }),
2083
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.reason || "—" })
2084
+ ] }, item.id || index)) })
2085
+ ] }) })
2086
+ ] }),
2087
+ updateError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-ui-border-error bg-ui-bg-error-subtle p-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-error", children: updateError }) }),
2088
+ updateSuccess && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-ui-border-success bg-ui-bg-success-subtle p-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-success", children: "Action completed successfully" }) })
1811
2089
  ] }) });
1812
2090
  };
1813
- const config$4 = adminSdk.defineRouteConfig({
1814
- label: "Exchanges",
1815
- icon: icons.ArrowPath
2091
+ const config$3 = adminSdk.defineRouteConfig({
2092
+ label: "Return Order Details",
2093
+ icon: icons.CheckCircle
1816
2094
  });
1817
- const getStatusBadgeClass$3 = (status) => {
2095
+ const getStatusBadgeClass$2 = (status) => {
1818
2096
  const s2 = status.toLowerCase();
1819
2097
  if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
1820
2098
  if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
@@ -1893,7 +2171,7 @@ const PaymentDetailPage = () => {
1893
2171
  ui.Badge,
1894
2172
  {
1895
2173
  size: "2xsmall",
1896
- className: `uppercase ${getStatusBadgeClass$3(displayStatus)}`,
2174
+ className: `uppercase ${getStatusBadgeClass$2(displayStatus)}`,
1897
2175
  children: displayStatus !== "—" ? displayStatus.replace(/_/g, " ") : "—"
1898
2176
  }
1899
2177
  ) })
@@ -1929,11 +2207,11 @@ const PaymentDetailPage = () => {
1929
2207
  ] }) : null
1930
2208
  ] }) });
1931
2209
  };
1932
- const config$3 = adminSdk.defineRouteConfig({
2210
+ const config$2 = adminSdk.defineRouteConfig({
1933
2211
  label: "Payment details",
1934
2212
  icon: icons.CreditCard
1935
2213
  });
1936
- const getStatusBadgeClass$2 = (status) => {
2214
+ const getStatusBadgeClass$1 = (status) => {
1937
2215
  const s2 = status.toLowerCase();
1938
2216
  if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
1939
2217
  if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
@@ -1988,420 +2266,142 @@ const RefundDetailPage = () => {
1988
2266
  /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/refunds"), children: "Back to list" })
1989
2267
  ] }) : loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading…" }) }) : detail ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
1990
2268
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
1991
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Refund summary" }),
1992
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
1993
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1994
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refund ID" }),
1995
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.id })
1996
- ] }),
1997
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1998
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
1999
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.refund.amount) })
2000
- ] }),
2001
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2002
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Note" }),
2003
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.refund.note ?? "—" })
2004
- ] }),
2005
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2006
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created at" }),
2007
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: new Date(detail.refund.created_at).toLocaleDateString("en-US", {
2008
- year: "numeric",
2009
- month: "short",
2010
- day: "numeric",
2011
- hour: "numeric",
2012
- minute: "2-digit",
2013
- hour12: true
2014
- }) })
2015
- ] }),
2016
- detail.refund.created_by ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2017
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created by" }),
2018
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.created_by })
2019
- ] }) : null
2020
- ] })
2021
- ] }),
2022
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
2023
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Payment summary" }),
2024
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
2025
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2026
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Payment amount" }),
2027
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.payment_amount) })
2028
- ] }),
2029
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2030
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Captured amount" }),
2031
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.captured_amount) })
2032
- ] }),
2033
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2034
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refunded amount" }),
2035
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.refunded_amount) })
2036
- ] }),
2037
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2038
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
2039
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.payment.provider_id || "—" })
2040
- ] }),
2041
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2042
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
2043
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
2044
- ui.Badge,
2045
- {
2046
- size: "2xsmall",
2047
- className: `uppercase ${getStatusBadgeClass$2(paymentStatus)}`,
2048
- children: paymentStatus !== "—" ? paymentStatus.replace(/_/g, " ") : "—"
2049
- }
2050
- ) })
2051
- ] }),
2052
- detail.computed ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2053
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2054
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Full refund" }),
2055
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.computed.is_full_refund ? "Yes" : "No" })
2056
- ] }),
2057
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2058
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Remaining refundable" }),
2059
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.computed.remaining_refundable_amount) })
2060
- ] }),
2061
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2062
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refund %" }),
2063
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "mt-1 block", children: [
2064
- detail.computed.refund_percentage.toFixed(1),
2065
- "%"
2066
- ] })
2067
- ] })
2068
- ] }) : null
2069
- ] })
2070
- ] }),
2071
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
2072
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Order summary" }),
2073
- detail.order ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
2074
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2075
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Order" }),
2076
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
2077
- ui.Button,
2078
- {
2079
- variant: "transparent",
2080
- size: "small",
2081
- onClick: () => navigate(`/orders/${detail.order.order_id}`),
2082
- children: detail.order.order_number ?? detail.order.order_id
2083
- }
2084
- ) })
2085
- ] }),
2086
- detail.order.total != null ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2087
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Total" }),
2088
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.order.total) })
2089
- ] }) : null,
2090
- detail.order.customer_id ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2091
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Customer ID" }),
2092
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.order.customer_id })
2093
- ] }) : null,
2094
- detail.order.region ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2095
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Region" }),
2096
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.region })
2097
- ] }) : null,
2098
- detail.order.fulfillment_status ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2099
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Fulfillment status" }),
2100
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.fulfillment_status })
2101
- ] }) : null
2102
- ] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No order linked to this refund." })
2103
- ] }),
2104
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
2105
- /* @__PURE__ */ jsxRuntime.jsxs(
2106
- "button",
2107
- {
2108
- type: "button",
2109
- className: "flex w-full items-center justify-between text-left",
2110
- onClick: () => setGatewayExpanded((prev) => !prev),
2111
- "aria-expanded": gatewayExpanded,
2112
- "aria-label": gatewayExpanded ? "Collapse gateway data" : "Expand gateway data",
2113
- children: [
2114
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg", children: "Gateway data" }),
2115
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: gatewayExpanded ? "Collapse" : "Expand" })
2116
- ]
2117
- }
2118
- ),
2119
- gatewayExpanded && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4", children: hasGatewayData ? /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-xs bg-ui-bg-subtle p-4 rounded-lg overflow-auto max-h-96", children: JSON.stringify(detail.payment.payment_data, null, 2) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No gateway payload for this payment." }) })
2120
- ] })
2121
- ] }) : null
2122
- ] }) });
2123
- };
2124
- const config$2 = adminSdk.defineRouteConfig({
2125
- label: "Refund details",
2126
- icon: icons.Receipt
2127
- });
2128
- const getStatusBadgeClass$1 = (status) => {
2129
- const statusLower = status.toLowerCase();
2130
- if (statusLower === "requested") {
2131
- return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
2132
- }
2133
- if (statusLower === "approved") {
2134
- return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
2135
- }
2136
- if (statusLower === "rejected") {
2137
- return "bg-ui-tag-red-bg text-ui-tag-red-text";
2138
- }
2139
- if (statusLower === "received") {
2140
- return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
2141
- }
2142
- if (statusLower === "refunded") {
2143
- return "bg-ui-tag-green-bg text-ui-tag-green-text";
2144
- }
2145
- if (statusLower === "completed") {
2146
- return "bg-ui-tag-green-bg text-ui-tag-green-text";
2147
- }
2148
- if (statusLower === "cancelled") {
2149
- return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
2150
- }
2151
- return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
2152
- };
2153
- const ReturnDetailPage = () => {
2154
- var _a, _b;
2155
- const navigate = reactRouterDom.useNavigate();
2156
- const { id } = reactRouterDom.useParams();
2157
- const [returnOrder, setReturnOrder] = react.useState(null);
2158
- const [isLoading, setIsLoading] = react.useState(true);
2159
- const [isRejecting, setIsRejecting] = react.useState(false);
2160
- const [error, setError] = react.useState(null);
2161
- const [updateError, setUpdateError] = react.useState(null);
2162
- const [updateSuccess, setUpdateSuccess] = react.useState(false);
2163
- react.useEffect(() => {
2164
- if (!id) {
2165
- navigate("/returns");
2166
- return;
2167
- }
2168
- const loadReturn = async () => {
2169
- try {
2170
- setIsLoading(true);
2171
- setError(null);
2172
- const response = await fetch(`/admin/returns/${id}`, {
2173
- credentials: "include"
2174
- });
2175
- if (!response.ok) {
2176
- const message = await response.text();
2177
- throw new Error(message || "Unable to load return order");
2178
- }
2179
- const payload = await response.json();
2180
- setReturnOrder(payload.return);
2181
- } catch (loadError) {
2182
- const message = loadError instanceof Error ? loadError.message : "Unable to load return order";
2183
- setError(message);
2184
- } finally {
2185
- setIsLoading(false);
2186
- }
2187
- };
2188
- void loadReturn();
2189
- }, [id, navigate]);
2190
- const handleReject = async () => {
2191
- if (!id) {
2192
- return;
2193
- }
2194
- try {
2195
- setIsRejecting(true);
2196
- setUpdateError(null);
2197
- setUpdateSuccess(false);
2198
- const response = await fetch(`/admin/returns/${id}/reject`, {
2199
- method: "POST",
2200
- headers: {
2201
- "Content-Type": "application/json"
2202
- },
2203
- credentials: "include",
2204
- body: JSON.stringify({ reason: "Rejected by admin" })
2205
- });
2206
- if (!response.ok) {
2207
- const message = await response.text();
2208
- throw new Error(message || "Unable to reject return");
2209
- }
2210
- const payload = await response.json();
2211
- setReturnOrder(payload.return);
2212
- setUpdateSuccess(true);
2213
- setTimeout(() => setUpdateSuccess(false), 3e3);
2214
- const detailResponse = await fetch(`/admin/returns/${id}`, {
2215
- credentials: "include"
2216
- });
2217
- if (detailResponse.ok) {
2218
- const detailPayload = await detailResponse.json();
2219
- setReturnOrder(detailPayload.return);
2220
- }
2221
- } catch (updateErr) {
2222
- const message = updateErr instanceof Error ? updateErr.message : "Unable to reject return";
2223
- setUpdateError(message);
2224
- } finally {
2225
- setIsRejecting(false);
2226
- }
2227
- };
2228
- if (isLoading) {
2229
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading return order..." }) }) }) });
2230
- }
2231
- if (error || !returnOrder) {
2232
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
2233
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "Return order not found" }),
2234
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/returns"), children: "Back to list" }) })
2235
- ] }) }) });
2236
- }
2237
- const statusHistory = ((_a = returnOrder.metadata) == null ? void 0 : _a.status_history) || [];
2238
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: [
2239
- /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
2240
- /* @__PURE__ */ jsxRuntime.jsxs(
2241
- ui.Button,
2242
- {
2243
- variant: "transparent",
2244
- size: "small",
2245
- onClick: () => navigate("/returns"),
2246
- className: "w-fit",
2247
- children: [
2248
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, { className: "mr-2" }),
2249
- "Back to list"
2250
- ]
2251
- }
2252
- ),
2253
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 md:flex-row md:items-center md:justify-between", children: [
2254
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
2255
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Return Order Details" }),
2256
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: returnOrder.id })
2257
- ] }),
2258
- /* @__PURE__ */ jsxRuntime.jsx(
2259
- ui.Badge,
2260
- {
2261
- size: "small",
2262
- className: `uppercase ${getStatusBadgeClass$1(returnOrder.status)}`,
2263
- children: returnOrder.status.replace(/_/g, " ")
2264
- }
2265
- )
2266
- ] })
2267
- ] }),
2268
- returnOrder.status === "requested" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
2269
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxRuntime.jsx(
2270
- ui.Button,
2271
- {
2272
- variant: "danger",
2273
- onClick: handleReject,
2274
- disabled: isRejecting,
2275
- isLoading: isRejecting,
2276
- children: "Reject (Cancel) Return"
2277
- }
2278
- ) }),
2279
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: 'Cancel this return request. Use "Mark as received" when items are received.' })
2280
- ] }),
2281
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
2282
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Information" }),
2283
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
2284
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2285
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Return ID" }),
2286
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.id })
2287
- ] }),
2288
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
2289
- ui.Button,
2290
- {
2291
- variant: "secondary",
2292
- onClick: () => {
2293
- window.open(
2294
- `/app/orders/${returnOrder.order_id}`,
2295
- "_blank"
2296
- );
2297
- },
2298
- children: "View order"
2299
- }
2300
- ) })
2301
- ] })
2302
- ] }),
2303
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
2304
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
2305
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Details" }),
2306
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
2269
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Refund summary" }),
2270
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
2307
2271
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2308
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Return ID" }),
2309
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.id })
2272
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refund ID" }),
2273
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.id })
2310
2274
  ] }),
2311
2275
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2312
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Status" }),
2313
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.status })
2314
- ] }),
2315
- returnOrder.reason && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2316
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Reason" }),
2317
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.reason })
2318
- ] }),
2319
- returnOrder.note && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2320
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Note" }),
2321
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.note })
2276
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
2277
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.refund.amount) })
2322
2278
  ] }),
2323
2279
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2324
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Created" }),
2325
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(returnOrder.created_at).toLocaleString() })
2280
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Note" }),
2281
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.refund.note ?? "—" })
2326
2282
  ] }),
2327
2283
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2328
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Last Updated" }),
2329
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(returnOrder.updated_at).toLocaleString() })
2330
- ] })
2284
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created at" }),
2285
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: new Date(detail.refund.created_at).toLocaleDateString("en-US", {
2286
+ year: "numeric",
2287
+ month: "short",
2288
+ day: "numeric",
2289
+ hour: "numeric",
2290
+ minute: "2-digit",
2291
+ hour12: true
2292
+ }) })
2293
+ ] }),
2294
+ detail.refund.created_by ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2295
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created by" }),
2296
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.created_by })
2297
+ ] }) : null
2331
2298
  ] })
2332
2299
  ] }),
2333
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
2334
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Status History" }),
2335
- statusHistory.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: statusHistory.map((entry, index) => /* @__PURE__ */ jsxRuntime.jsx(
2336
- "div",
2337
- {
2338
- className: "flex items-center justify-between border-b border-ui-border-subtle pb-2 last:border-0",
2339
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
2340
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
2341
- ui.Badge,
2342
- {
2343
- size: "2xsmall",
2344
- className: `uppercase ${getStatusBadgeClass$1(entry.status)}`,
2345
- children: entry.status.replace(/_/g, " ")
2346
- }
2347
- ) }),
2348
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
2349
- new Date(entry.timestamp).toLocaleString(),
2350
- entry.admin_id && ` by ${entry.admin_id}`,
2351
- entry.reason && ` - ${entry.reason}`
2300
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
2301
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Payment summary" }),
2302
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
2303
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2304
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Payment amount" }),
2305
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.payment_amount) })
2306
+ ] }),
2307
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2308
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Captured amount" }),
2309
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.captured_amount) })
2310
+ ] }),
2311
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2312
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refunded amount" }),
2313
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.refunded_amount) })
2314
+ ] }),
2315
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2316
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
2317
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.payment.provider_id || "—" })
2318
+ ] }),
2319
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2320
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
2321
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
2322
+ ui.Badge,
2323
+ {
2324
+ size: "2xsmall",
2325
+ className: `uppercase ${getStatusBadgeClass$1(paymentStatus)}`,
2326
+ children: paymentStatus !== "—" ? paymentStatus.replace(/_/g, " ") : "—"
2327
+ }
2328
+ ) })
2329
+ ] }),
2330
+ detail.computed ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2331
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2332
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Full refund" }),
2333
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.computed.is_full_refund ? "Yes" : "No" })
2334
+ ] }),
2335
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2336
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Remaining refundable" }),
2337
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.computed.remaining_refundable_amount) })
2338
+ ] }),
2339
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2340
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refund %" }),
2341
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "mt-1 block", children: [
2342
+ detail.computed.refund_percentage.toFixed(1),
2343
+ "%"
2352
2344
  ] })
2353
2345
  ] })
2354
- },
2355
- index
2356
- )) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No status history available" })
2357
- ] })
2358
- ] }),
2359
- returnOrder.order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
2360
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Related Order Information" }),
2361
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
2362
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2363
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order ID" }),
2364
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.id })
2365
- ] }),
2366
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2367
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Status" }),
2368
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.status || "—" })
2369
- ] }),
2370
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2371
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
2372
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_b = returnOrder.order.customer) == null ? void 0 : _b.email) || returnOrder.order.email || "—" })
2373
- ] }),
2374
- returnOrder.order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2375
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
2376
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "font-medium", children: [
2377
- returnOrder.order.currency_code || "$",
2378
- (Number(returnOrder.order.total) / 100).toFixed(2)
2379
- ] })
2346
+ ] }) : null
2380
2347
  ] })
2348
+ ] }),
2349
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
2350
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Order summary" }),
2351
+ detail.order ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
2352
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2353
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Order" }),
2354
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
2355
+ ui.Button,
2356
+ {
2357
+ variant: "transparent",
2358
+ size: "small",
2359
+ onClick: () => navigate(`/orders/${detail.order.order_id}`),
2360
+ children: detail.order.order_number ?? detail.order.order_id
2361
+ }
2362
+ ) })
2363
+ ] }),
2364
+ detail.order.total != null ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2365
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Total" }),
2366
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.order.total) })
2367
+ ] }) : null,
2368
+ detail.order.customer_id ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2369
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Customer ID" }),
2370
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.order.customer_id })
2371
+ ] }) : null,
2372
+ detail.order.region ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2373
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Region" }),
2374
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.region })
2375
+ ] }) : null,
2376
+ detail.order.fulfillment_status ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2377
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Fulfillment status" }),
2378
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.fulfillment_status })
2379
+ ] }) : null
2380
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No order linked to this refund." })
2381
+ ] }),
2382
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
2383
+ /* @__PURE__ */ jsxRuntime.jsxs(
2384
+ "button",
2385
+ {
2386
+ type: "button",
2387
+ className: "flex w-full items-center justify-between text-left",
2388
+ onClick: () => setGatewayExpanded((prev) => !prev),
2389
+ "aria-expanded": gatewayExpanded,
2390
+ "aria-label": gatewayExpanded ? "Collapse gateway data" : "Expand gateway data",
2391
+ children: [
2392
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg", children: "Gateway data" }),
2393
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: gatewayExpanded ? "Collapse" : "Expand" })
2394
+ ]
2395
+ }
2396
+ ),
2397
+ gatewayExpanded && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4", children: hasGatewayData ? /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-xs bg-ui-bg-subtle p-4 rounded-lg overflow-auto max-h-96", children: JSON.stringify(detail.payment.payment_data, null, 2) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No gateway payload for this payment." }) })
2381
2398
  ] })
2382
- ] }),
2383
- returnOrder.return_items && returnOrder.return_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
2384
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Items" }),
2385
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
2386
- /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2387
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Item ID" }),
2388
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" }),
2389
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Reason" })
2390
- ] }) }),
2391
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: returnOrder.return_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2392
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.id }),
2393
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity }),
2394
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.reason || "—" })
2395
- ] }, item.id || index)) })
2396
- ] }) })
2397
- ] }),
2398
- updateError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-ui-border-error bg-ui-bg-error-subtle p-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-error", children: updateError }) }),
2399
- updateSuccess && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-ui-border-success bg-ui-bg-success-subtle p-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-success", children: "Action completed successfully" }) })
2399
+ ] }) : null
2400
2400
  ] }) });
2401
2401
  };
2402
2402
  const config$1 = adminSdk.defineRouteConfig({
2403
- label: "Return Order Details",
2404
- icon: icons.CheckCircle
2403
+ label: "Refund details",
2404
+ icon: icons.Receipt
2405
2405
  });
2406
2406
  const getStatusBadgeClass = (status) => {
2407
2407
  const statusLower = status.toLowerCase();
@@ -2695,6 +2695,10 @@ const widgetModule = { widgets: [
2695
2695
  ] };
2696
2696
  const routeModule = {
2697
2697
  routes: [
2698
+ {
2699
+ Component: ReturnsPage,
2700
+ path: "/returns"
2701
+ },
2698
2702
  {
2699
2703
  Component: PaymentsPage,
2700
2704
  path: "/payments"
@@ -2703,14 +2707,14 @@ const routeModule = {
2703
2707
  Component: RefundsPage,
2704
2708
  path: "/refunds"
2705
2709
  },
2706
- {
2707
- Component: ReturnsPage,
2708
- path: "/returns"
2709
- },
2710
2710
  {
2711
2711
  Component: SwapsPage,
2712
2712
  path: "/swaps"
2713
2713
  },
2714
+ {
2715
+ Component: ReturnDetailPage,
2716
+ path: "/returns/:id"
2717
+ },
2714
2718
  {
2715
2719
  Component: PaymentDetailPage,
2716
2720
  path: "/payments/:id"
@@ -2719,10 +2723,6 @@ const routeModule = {
2719
2723
  Component: RefundDetailPage,
2720
2724
  path: "/refunds/:id"
2721
2725
  },
2722
- {
2723
- Component: ReturnDetailPage,
2724
- path: "/returns/:id"
2725
- },
2726
2726
  {
2727
2727
  Component: SwapDetailPage,
2728
2728
  path: "/swaps/:id"
@@ -2732,51 +2732,51 @@ const routeModule = {
2732
2732
  const menuItemModule = {
2733
2733
  menuItems: [
2734
2734
  {
2735
- label: config$7.label,
2736
- icon: config$7.icon,
2737
- path: "/payments",
2735
+ label: config$4.label,
2736
+ icon: config$4.icon,
2737
+ path: "/swaps",
2738
2738
  nested: void 0
2739
2739
  },
2740
2740
  {
2741
- label: config$6.label,
2742
- icon: config$6.icon,
2741
+ label: config$5.label,
2742
+ icon: config$5.icon,
2743
2743
  path: "/refunds",
2744
2744
  nested: void 0
2745
2745
  },
2746
2746
  {
2747
- label: config$5.label,
2748
- icon: config$5.icon,
2747
+ label: config$7.label,
2748
+ icon: config$7.icon,
2749
2749
  path: "/returns",
2750
2750
  nested: void 0
2751
2751
  },
2752
2752
  {
2753
- label: config$4.label,
2754
- icon: config$4.icon,
2755
- path: "/swaps",
2753
+ label: config$6.label,
2754
+ icon: config$6.icon,
2755
+ path: "/payments",
2756
2756
  nested: void 0
2757
2757
  },
2758
2758
  {
2759
- label: config$3.label,
2760
- icon: config$3.icon,
2761
- path: "/payments/:id",
2759
+ label: config.label,
2760
+ icon: config.icon,
2761
+ path: "/swaps/:id",
2762
2762
  nested: void 0
2763
2763
  },
2764
2764
  {
2765
- label: config$2.label,
2766
- icon: config$2.icon,
2765
+ label: config$1.label,
2766
+ icon: config$1.icon,
2767
2767
  path: "/refunds/:id",
2768
2768
  nested: void 0
2769
2769
  },
2770
2770
  {
2771
- label: config$1.label,
2772
- icon: config$1.icon,
2771
+ label: config$3.label,
2772
+ icon: config$3.icon,
2773
2773
  path: "/returns/:id",
2774
2774
  nested: void 0
2775
2775
  },
2776
2776
  {
2777
- label: config.label,
2778
- icon: config.icon,
2779
- path: "/swaps/:id",
2777
+ label: config$2.label,
2778
+ icon: config$2.icon,
2779
+ path: "/payments/:id",
2780
2780
  nested: void 0
2781
2781
  }
2782
2782
  ]