order-management 0.0.83 → 0.0.85

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.
@@ -1066,6 +1066,236 @@ const useDebounce$2 = (value, delay) => {
1066
1066
  return debouncedValue;
1067
1067
  };
1068
1068
  const getStatusBadgeClass$6 = (status) => {
1069
+ const statusLower = status.toLowerCase();
1070
+ if (statusLower === "requested") {
1071
+ return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
1072
+ }
1073
+ if (statusLower === "approved") {
1074
+ return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
1075
+ }
1076
+ if (statusLower === "rejected") {
1077
+ return "bg-ui-tag-red-bg text-ui-tag-red-text";
1078
+ }
1079
+ if (statusLower === "completed") {
1080
+ return "bg-ui-tag-green-bg text-ui-tag-green-text";
1081
+ }
1082
+ if (statusLower === "cancelled") {
1083
+ return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
1084
+ }
1085
+ return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
1086
+ };
1087
+ const SwapsPage = () => {
1088
+ const navigate = reactRouterDom.useNavigate();
1089
+ const [items, setItems] = react.useState([]);
1090
+ const [statusFilter, setStatusFilter] = react.useState("all");
1091
+ const [createdByFilter, setCreatedByFilter] = react.useState("all");
1092
+ const [searchQuery, setSearchQuery] = react.useState("");
1093
+ const debouncedSearchQuery = useDebounce$2(searchQuery, 300);
1094
+ const [isLoading, setIsLoading] = react.useState(true);
1095
+ const [isFetchingMore, setIsFetchingMore] = react.useState(false);
1096
+ const [error, setError] = react.useState(null);
1097
+ const [offset, setOffset] = react.useState(0);
1098
+ const [count, setCount] = react.useState(0);
1099
+ const limit = 50;
1100
+ const loadSwaps = react.useCallback(
1101
+ async (nextOffset, replace = false) => {
1102
+ var _a;
1103
+ try {
1104
+ if (replace) {
1105
+ setIsLoading(true);
1106
+ } else {
1107
+ setIsFetchingMore(true);
1108
+ }
1109
+ setError(null);
1110
+ const params = new URLSearchParams();
1111
+ params.set("limit", String(limit));
1112
+ params.set("offset", String(nextOffset));
1113
+ if (statusFilter !== "all") {
1114
+ params.set("status", statusFilter);
1115
+ }
1116
+ if (debouncedSearchQuery.trim()) {
1117
+ params.set("order_id", debouncedSearchQuery.trim());
1118
+ }
1119
+ if (createdByFilter !== "all") {
1120
+ params.set("created_by", createdByFilter);
1121
+ }
1122
+ const response = await fetch(
1123
+ `/admin/swaps?${params.toString()}`,
1124
+ { credentials: "include" }
1125
+ );
1126
+ if (!response.ok) {
1127
+ const message = await response.text();
1128
+ throw new Error(message || "Unable to load swaps");
1129
+ }
1130
+ const payload = await response.json();
1131
+ setCount(payload.count ?? 0);
1132
+ setOffset(nextOffset + (((_a = payload.swaps) == null ? void 0 : _a.length) ?? 0));
1133
+ setItems(
1134
+ (prev) => replace ? payload.swaps ?? [] : [...prev, ...payload.swaps ?? []]
1135
+ );
1136
+ } catch (loadError) {
1137
+ const message = loadError instanceof Error ? loadError.message : "Unable to load swaps";
1138
+ setError(message);
1139
+ } finally {
1140
+ setIsLoading(false);
1141
+ setIsFetchingMore(false);
1142
+ }
1143
+ },
1144
+ [statusFilter, createdByFilter, debouncedSearchQuery]
1145
+ );
1146
+ react.useEffect(() => {
1147
+ void loadSwaps(0, true);
1148
+ }, [statusFilter, createdByFilter, debouncedSearchQuery, loadSwaps]);
1149
+ const hasMore = react.useMemo(() => offset < count, [offset, count]);
1150
+ const availableStatuses = react.useMemo(() => {
1151
+ const statuses = /* @__PURE__ */ new Set();
1152
+ items.forEach((item) => statuses.add(item.status));
1153
+ return Array.from(statuses).sort();
1154
+ }, [items]);
1155
+ 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: [
1156
+ /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
1157
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
1158
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Exchanges" }),
1159
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer exchange requests" })
1160
+ ] }),
1161
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadSwaps(0, true), children: "Refresh" })
1162
+ ] }),
1163
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
1164
+ /* @__PURE__ */ jsxRuntime.jsx(
1165
+ ui.Input,
1166
+ {
1167
+ placeholder: "Search by swap ID or order ID",
1168
+ value: searchQuery,
1169
+ onChange: (event) => setSearchQuery(event.target.value),
1170
+ className: "md:max-w-sm"
1171
+ }
1172
+ ),
1173
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
1174
+ /* @__PURE__ */ jsxRuntime.jsxs(
1175
+ "select",
1176
+ {
1177
+ value: createdByFilter,
1178
+ onChange: (event) => setCreatedByFilter(event.target.value),
1179
+ 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",
1180
+ children: [
1181
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All (Created by)" }),
1182
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "customer", children: "Customer" }),
1183
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "admin", children: "Admin" })
1184
+ ]
1185
+ }
1186
+ ),
1187
+ /* @__PURE__ */ jsxRuntime.jsxs(
1188
+ "select",
1189
+ {
1190
+ value: statusFilter,
1191
+ onChange: (event) => setStatusFilter(event.target.value),
1192
+ 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",
1193
+ children: [
1194
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All Statuses" }),
1195
+ availableStatuses.map((status) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
1196
+ ]
1197
+ }
1198
+ )
1199
+ ] })
1200
+ ] }),
1201
+ error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
1202
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
1203
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
1204
+ ui.Button,
1205
+ {
1206
+ variant: "secondary",
1207
+ onClick: () => loadSwaps(0, true),
1208
+ children: "Try again"
1209
+ }
1210
+ ) })
1211
+ ] }) : null,
1212
+ 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: [
1213
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No exchanges yet" }),
1214
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Exchange requests created by customers will appear here." })
1215
+ ] }) : /* @__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: [
1216
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
1217
+ /* @__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" }),
1218
+ /* @__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" }),
1219
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
1220
+ /* @__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" }),
1221
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
1222
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
1223
+ ] }) }),
1224
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((swap) => /* @__PURE__ */ jsxRuntime.jsxs(
1225
+ "tr",
1226
+ {
1227
+ className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
1228
+ onClick: () => navigate(`/swaps/${swap.id}`),
1229
+ children: [
1230
+ /* @__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 }) }) }),
1231
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: swap.order_id }),
1232
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
1233
+ ui.Badge,
1234
+ {
1235
+ size: "2xsmall",
1236
+ className: `uppercase ${getStatusBadgeClass$6(swap.status)}`,
1237
+ children: swap.status.replace(/_/g, " ")
1238
+ }
1239
+ ) }),
1240
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
1241
+ const amount = swap.difference_due;
1242
+ if (amount == null || amount === void 0) {
1243
+ return "—";
1244
+ }
1245
+ const displayAmount = Number(amount) / 100;
1246
+ const currency = swap.currency_code || "$";
1247
+ const sign = displayAmount >= 0 ? "+" : "";
1248
+ return `${sign}${currency}${displayAmount.toFixed(2)}`;
1249
+ })() }),
1250
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(swap.created_at).toLocaleDateString("en-US", {
1251
+ year: "numeric",
1252
+ month: "short",
1253
+ day: "numeric",
1254
+ hour: "numeric",
1255
+ minute: "2-digit",
1256
+ hour12: true
1257
+ }) }),
1258
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
1259
+ ui.Button,
1260
+ {
1261
+ variant: "transparent",
1262
+ size: "small",
1263
+ onClick: (e) => {
1264
+ e.stopPropagation();
1265
+ navigate(`/app/orders/${swap.order_id}`);
1266
+ },
1267
+ children: "Go to order"
1268
+ }
1269
+ ) })
1270
+ ]
1271
+ },
1272
+ swap.id
1273
+ )) })
1274
+ ] }) }),
1275
+ hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
1276
+ ui.Button,
1277
+ {
1278
+ variant: "secondary",
1279
+ isLoading: isFetchingMore,
1280
+ onClick: () => loadSwaps(offset, false),
1281
+ children: "Load more"
1282
+ }
1283
+ ) }) : null
1284
+ ] }) });
1285
+ };
1286
+ const config$6 = adminSdk.defineRouteConfig({
1287
+ label: "Exchanges",
1288
+ icon: icons.ArrowPath
1289
+ });
1290
+ const useDebounce$1 = (value, delay) => {
1291
+ const [debouncedValue, setDebouncedValue] = react.useState(value);
1292
+ react.useEffect(() => {
1293
+ const handler = setTimeout(() => setDebouncedValue(value), delay);
1294
+ return () => clearTimeout(handler);
1295
+ }, [value, delay]);
1296
+ return debouncedValue;
1297
+ };
1298
+ const getStatusBadgeClass$5 = (status) => {
1069
1299
  const s2 = status.toLowerCase();
1070
1300
  if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
1071
1301
  if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
@@ -1077,12 +1307,12 @@ const RefundsPage = () => {
1077
1307
  const navigate = reactRouterDom.useNavigate();
1078
1308
  const [items, setItems] = react.useState([]);
1079
1309
  const [orderIdSearch, setOrderIdSearch] = react.useState("");
1080
- const debouncedOrderId = useDebounce$2(orderIdSearch, 300);
1310
+ const debouncedOrderId = useDebounce$1(orderIdSearch, 300);
1081
1311
  const [paymentStatusFilter, setPaymentStatusFilter] = react.useState("all");
1082
1312
  const [providerSearch, setProviderSearch] = react.useState("");
1083
- const debouncedProvider = useDebounce$2(providerSearch, 300);
1313
+ const debouncedProvider = useDebounce$1(providerSearch, 300);
1084
1314
  const [currencySearch, setCurrencySearch] = react.useState("");
1085
- const debouncedCurrency = useDebounce$2(currencySearch, 300);
1315
+ const debouncedCurrency = useDebounce$1(currencySearch, 300);
1086
1316
  const [dateFrom, setDateFrom] = react.useState("");
1087
1317
  const [dateTo, setDateTo] = react.useState("");
1088
1318
  const [amountMin, setAmountMin] = react.useState("");
@@ -1294,7 +1524,7 @@ const RefundsPage = () => {
1294
1524
  ui.Badge,
1295
1525
  {
1296
1526
  size: "2xsmall",
1297
- className: `uppercase ${getStatusBadgeClass$6(displayStatus(r))}`,
1527
+ className: `uppercase ${getStatusBadgeClass$5(displayStatus(r))}`,
1298
1528
  children: displayStatus(r) !== "—" ? displayStatus(r).replace(/_/g, " ") : "—"
1299
1529
  }
1300
1530
  ) }),
@@ -1348,11 +1578,11 @@ const RefundsPage = () => {
1348
1578
  ) }) : null
1349
1579
  ] }) });
1350
1580
  };
1351
- const config$6 = adminSdk.defineRouteConfig({
1581
+ const config$5 = adminSdk.defineRouteConfig({
1352
1582
  label: "Refunds",
1353
1583
  icon: icons.Receipt
1354
1584
  });
1355
- const useDebounce$1 = (value, delay) => {
1585
+ const useDebounce = (value, delay) => {
1356
1586
  const [debouncedValue, setDebouncedValue] = react.useState(value);
1357
1587
  react.useEffect(() => {
1358
1588
  const handler = setTimeout(() => setDebouncedValue(value), delay);
@@ -1360,7 +1590,7 @@ const useDebounce$1 = (value, delay) => {
1360
1590
  }, [value, delay]);
1361
1591
  return debouncedValue;
1362
1592
  };
1363
- const getStatusBadgeClass$5 = (status) => {
1593
+ const getStatusBadgeClass$4 = (status) => {
1364
1594
  const statusLower = status.toLowerCase();
1365
1595
  if (statusLower === "requested") {
1366
1596
  return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
@@ -1385,7 +1615,7 @@ const ReturnsPage = () => {
1385
1615
  const [statusFilter, setStatusFilter] = react.useState("all");
1386
1616
  const [createdByFilter, setCreatedByFilter] = react.useState("all");
1387
1617
  const [searchQuery, setSearchQuery] = react.useState("");
1388
- const debouncedSearchQuery = useDebounce$1(searchQuery, 300);
1618
+ const debouncedSearchQuery = useDebounce(searchQuery, 300);
1389
1619
  const [isLoading, setIsLoading] = react.useState(true);
1390
1620
  const [isFetchingMore, setIsFetchingMore] = react.useState(false);
1391
1621
  const [error, setError] = react.useState(null);
@@ -1531,7 +1761,7 @@ const ReturnsPage = () => {
1531
1761
  ui.Badge,
1532
1762
  {
1533
1763
  size: "2xsmall",
1534
- className: `uppercase ${getStatusBadgeClass$5(returnOrder.status)}`,
1764
+ className: `uppercase ${getStatusBadgeClass$4(returnOrder.status)}`,
1535
1765
  children: returnOrder.status.replace(/_/g, " ")
1536
1766
  }
1537
1767
  ) }),
@@ -1580,247 +1810,17 @@ const ReturnsPage = () => {
1580
1810
  ) }) : null
1581
1811
  ] }) });
1582
1812
  };
1583
- const config$5 = adminSdk.defineRouteConfig({
1813
+ const config$4 = adminSdk.defineRouteConfig({
1584
1814
  label: "Return Orders",
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) => {
1596
- const statusLower = status.toLowerCase();
1597
- if (statusLower === "requested") {
1598
- return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
1599
- }
1600
- if (statusLower === "approved") {
1601
- return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
1602
- }
1603
- if (statusLower === "rejected") {
1604
- return "bg-ui-tag-red-bg text-ui-tag-red-text";
1605
- }
1606
- if (statusLower === "completed") {
1607
- return "bg-ui-tag-green-bg text-ui-tag-green-text";
1608
- }
1609
- if (statusLower === "cancelled") {
1610
- return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
1611
- }
1612
- return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
1613
- };
1614
- const SwapsPage = () => {
1615
- 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);
1621
- const [isLoading, setIsLoading] = react.useState(true);
1622
- const [isFetchingMore, setIsFetchingMore] = react.useState(false);
1623
- 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;
1630
- try {
1631
- if (replace) {
1632
- setIsLoading(true);
1633
- } else {
1634
- setIsFetchingMore(true);
1635
- }
1636
- 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
- );
1653
- if (!response.ok) {
1654
- const message = await response.text();
1655
- throw new Error(message || "Unable to load swaps");
1656
- }
1657
- 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
- );
1663
- } catch (loadError) {
1664
- const message = loadError instanceof Error ? loadError.message : "Unable to load swaps";
1665
- setError(message);
1666
- } finally {
1667
- setIsLoading(false);
1668
- setIsFetchingMore(false);
1669
- }
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,
1693
- {
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"
1698
- }
1699
- ),
1700
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
1701
- /* @__PURE__ */ jsxRuntime.jsxs(
1702
- "select",
1703
- {
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
- ]
1724
- }
1725
- )
1726
- ] })
1727
- ] }),
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(
1731
- ui.Button,
1732
- {
1733
- variant: "secondary",
1734
- onClick: () => loadSwaps(0, true),
1735
- children: "Try again"
1736
- }
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
1811
- ] }) });
1812
- };
1813
- const config$4 = adminSdk.defineRouteConfig({
1814
- label: "Exchanges",
1815
- icon: icons.ArrowPath
1816
- });
1817
- const getStatusBadgeClass$3 = (status) => {
1818
- const s2 = status.toLowerCase();
1819
- if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
1820
- if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
1821
- if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
1822
- if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
1823
- return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
1817
+ const getStatusBadgeClass$3 = (status) => {
1818
+ const s2 = status.toLowerCase();
1819
+ if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
1820
+ if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
1821
+ if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
1822
+ if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
1823
+ return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
1824
1824
  };
1825
1825
  const PaymentDetailPage = () => {
1826
1826
  var _a;
@@ -1934,196 +1934,283 @@ const config$3 = adminSdk.defineRouteConfig({
1934
1934
  icon: icons.CreditCard
1935
1935
  });
1936
1936
  const getStatusBadgeClass$2 = (status) => {
1937
- const s2 = status.toLowerCase();
1938
- if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
1939
- if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
1940
- if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
1941
- if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
1937
+ const statusLower = status.toLowerCase();
1938
+ if (statusLower === "requested") {
1939
+ return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
1940
+ }
1941
+ if (statusLower === "approved") {
1942
+ return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
1943
+ }
1944
+ if (statusLower === "rejected") {
1945
+ return "bg-ui-tag-red-bg text-ui-tag-red-text";
1946
+ }
1947
+ if (statusLower === "completed") {
1948
+ return "bg-ui-tag-green-bg text-ui-tag-green-text";
1949
+ }
1950
+ if (statusLower === "cancelled" || statusLower === "canceled") {
1951
+ return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
1952
+ }
1953
+ if (statusLower === "pending") {
1954
+ return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
1955
+ }
1942
1956
  return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
1943
1957
  };
1944
- const formatAmount = (value) => {
1945
- return String(value);
1946
- };
1947
- const RefundDetailPage = () => {
1958
+ const SwapDetailPage = () => {
1948
1959
  var _a, _b, _c;
1949
1960
  const navigate = reactRouterDom.useNavigate();
1950
- const params = reactRouterDom.useParams();
1951
- const id = (_a = params == null ? void 0 : params.id) == null ? void 0 : _a.trim();
1952
- const [detail, setDetail] = react.useState(null);
1953
- const [loading, setLoading] = react.useState(!!id);
1961
+ const { id } = reactRouterDom.useParams();
1962
+ const [swap, setSwap] = react.useState(null);
1963
+ const [order, setOrder] = react.useState(null);
1964
+ const [isLoading, setIsLoading] = react.useState(true);
1965
+ react.useState(false);
1966
+ const [isCancelling, setIsCancelling] = react.useState(false);
1954
1967
  const [error, setError] = react.useState(null);
1955
- const [gatewayExpanded, setGatewayExpanded] = react.useState(false);
1968
+ const [updateError, setUpdateError] = react.useState(null);
1969
+ const [updateSuccess, setUpdateSuccess] = react.useState(false);
1956
1970
  react.useEffect(() => {
1957
1971
  if (!id) {
1958
- setLoading(false);
1972
+ navigate("/swaps");
1959
1973
  return;
1960
1974
  }
1961
- let cancelled = false;
1962
- setLoading(true);
1963
- setError(null);
1964
- fetch(`/admin/refunds/${id}`, { credentials: "include" }).then((res) => {
1965
- if (!res.ok) throw new Error(res.statusText || "Failed to load");
1966
- return res.json();
1967
- }).then((data) => {
1968
- if (!cancelled) setDetail(data);
1969
- }).catch((e) => {
1970
- if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
1971
- }).finally(() => {
1972
- if (!cancelled) setLoading(false);
1973
- });
1974
- return () => {
1975
- cancelled = true;
1975
+ const loadSwap = async () => {
1976
+ try {
1977
+ setIsLoading(true);
1978
+ setError(null);
1979
+ const response = await fetch(`/admin/swaps/${id}`, {
1980
+ credentials: "include"
1981
+ });
1982
+ if (!response.ok) {
1983
+ const message = await response.text();
1984
+ throw new Error(message || "Unable to load swap");
1985
+ }
1986
+ const payload = await response.json();
1987
+ setSwap(payload.swap);
1988
+ setOrder(payload.order || null);
1989
+ } catch (loadError) {
1990
+ const message = loadError instanceof Error ? loadError.message : "Unable to load swap";
1991
+ setError(message);
1992
+ } finally {
1993
+ setIsLoading(false);
1994
+ }
1976
1995
  };
1977
- }, [id]);
1978
- const paymentStatus = ((_b = detail == null ? void 0 : detail.payment) == null ? void 0 : _b.status) ?? "—";
1979
- const hasGatewayData = ((_c = detail == null ? void 0 : detail.payment) == null ? void 0 : _c.payment_data) && typeof detail.payment.payment_data === "object" && Object.keys(detail.payment.payment_data).length > 0;
1980
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-4xl flex-col gap-6 p-6", children: [
1981
- /* @__PURE__ */ jsxRuntime.jsx("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
1982
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => navigate("/refunds"), children: "← Refunds" }),
1983
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Refund details" }),
1984
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle font-mono", children: id ?? "—" })
1985
- ] }) }),
1986
- error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
1987
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
1988
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/refunds"), children: "Back to list" })
1989
- ] }) : 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
- /* @__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
- ] }),
1996
+ void loadSwap();
1997
+ }, [id, navigate]);
1998
+ const handleCancelExchange = async () => {
1999
+ if (!id) {
2000
+ return;
2001
+ }
2002
+ try {
2003
+ setIsCancelling(true);
2004
+ setUpdateError(null);
2005
+ setUpdateSuccess(false);
2006
+ const response = await fetch(`/admin/swaps/${id}/cancel`, {
2007
+ method: "POST",
2008
+ headers: {
2009
+ "Content-Type": "application/json"
2010
+ },
2011
+ credentials: "include"
2012
+ });
2013
+ if (!response.ok) {
2014
+ const message = await response.text();
2015
+ throw new Error(message || "Unable to cancel exchange");
2016
+ }
2017
+ const payload = await response.json();
2018
+ setSwap(payload.swap);
2019
+ setUpdateSuccess(true);
2020
+ setTimeout(() => setUpdateSuccess(false), 3e3);
2021
+ const detailResponse = await fetch(`/admin/swaps/${id}`, {
2022
+ credentials: "include"
2023
+ });
2024
+ if (detailResponse.ok) {
2025
+ const detailPayload = await detailResponse.json();
2026
+ setSwap(detailPayload.swap);
2027
+ setOrder(detailPayload.order || null);
2028
+ }
2029
+ } catch (cancelErr) {
2030
+ const message = cancelErr instanceof Error ? cancelErr.message : "Unable to cancel exchange";
2031
+ setUpdateError(message);
2032
+ } finally {
2033
+ setIsCancelling(false);
2034
+ }
2035
+ };
2036
+ const isOrderExchange = Boolean(swap == null ? void 0 : swap.exchange_id);
2037
+ const canCancelExchange = isOrderExchange && swap && !["cancelled", "canceled", "completed", "declined"].includes(
2038
+ ((_a = swap.status) == null ? void 0 : _a.toLowerCase()) ?? ""
2039
+ );
2040
+ if (isLoading) {
2041
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading swap..." }) }) }) });
2042
+ }
2043
+ if (error || !swap) {
2044
+ 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: [
2045
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "Swap not found" }),
2046
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/swaps"), children: "Back to list" }) })
2047
+ ] }) }) });
2048
+ }
2049
+ const statusHistory = ((_b = swap.metadata) == null ? void 0 : _b.status_history) || [];
2050
+ 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: [
2051
+ /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
2052
+ /* @__PURE__ */ jsxRuntime.jsxs(
2053
+ ui.Button,
2054
+ {
2055
+ variant: "transparent",
2056
+ size: "small",
2057
+ onClick: () => navigate("/swaps"),
2058
+ className: "w-fit",
2059
+ children: [
2060
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, { className: "mr-2" }),
2061
+ "Back to list"
2062
+ ]
2063
+ }
2064
+ ),
2065
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 md:flex-row md:items-center md:justify-between", children: [
2066
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
2067
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Exchange Details" }),
2068
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: swap.id })
2069
+ ] }),
2070
+ /* @__PURE__ */ jsxRuntime.jsx(
2071
+ ui.Badge,
2072
+ {
2073
+ size: "small",
2074
+ className: `uppercase ${getStatusBadgeClass$2(swap.status)}`,
2075
+ children: swap.status.replace(/_/g, " ")
2076
+ }
2077
+ )
2078
+ ] })
2079
+ ] }),
2080
+ canCancelExchange && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
2081
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxRuntime.jsx(
2082
+ ui.Button,
2083
+ {
2084
+ variant: "danger",
2085
+ onClick: handleCancelExchange,
2086
+ disabled: isCancelling,
2087
+ isLoading: isCancelling,
2088
+ children: "Cancel Exchange"
2089
+ }
2090
+ ) }),
2091
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "This will cancel the exchange request. The order will remain unchanged." })
2092
+ ] }),
2093
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
2094
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
2095
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Exchange Information" }),
2096
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
2001
2097
  /* @__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 ?? "—" })
2098
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
2099
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.id })
2004
2100
  ] }),
2005
2101
  /* @__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
- }) })
2102
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Status" }),
2103
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.status })
2015
2104
  ] }),
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
2105
  /* @__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) })
2106
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Difference Due" }),
2107
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.difference_due != null ? `${swap.currency_code || "$"}${(Number(swap.difference_due) / 100).toFixed(2)}` : "—" })
2028
2108
  ] }),
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) })
2109
+ swap.reason && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2110
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Reason" }),
2111
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.reason })
2032
2112
  ] }),
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) })
2113
+ swap.note && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2114
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Note" }),
2115
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.note })
2036
2116
  ] }),
2037
2117
  /* @__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 || "—" })
2118
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Created" }),
2119
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(swap.created_at).toLocaleString() })
2040
2120
  ] }),
2041
2121
  /* @__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
- ) })
2122
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Last Updated" }),
2123
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(swap.updated_at).toLocaleString() })
2051
2124
  ] }),
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
2125
+ swap.exchange_id && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2126
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
2127
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.exchange_id })
2128
+ ] })
2069
2129
  ] })
2070
2130
  ] }),
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",
2131
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
2132
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Status History" }),
2133
+ statusHistory.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: statusHistory.map((entry, index) => /* @__PURE__ */ jsxRuntime.jsx(
2134
+ "div",
2107
2135
  {
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." }) })
2136
+ className: "flex items-center justify-between border-b border-ui-border-subtle pb-2 last:border-0",
2137
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
2138
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
2139
+ ui.Badge,
2140
+ {
2141
+ size: "2xsmall",
2142
+ className: `uppercase ${getStatusBadgeClass$2(entry.status)}`,
2143
+ children: entry.status.replace(/_/g, " ")
2144
+ }
2145
+ ) }),
2146
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
2147
+ new Date(entry.timestamp).toLocaleString(),
2148
+ entry.admin_id && ` by ${entry.admin_id}`,
2149
+ entry.reason && ` - ${entry.reason}`
2150
+ ] })
2151
+ ] })
2152
+ },
2153
+ index
2154
+ )) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No status history available" })
2120
2155
  ] })
2121
- ] }) : null
2156
+ ] }),
2157
+ order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
2158
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Related Order Information" }),
2159
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
2160
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2161
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order ID" }),
2162
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.id })
2163
+ ] }),
2164
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2165
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Status" }),
2166
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.status || "—" })
2167
+ ] }),
2168
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2169
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
2170
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_c = order.customer) == null ? void 0 : _c.email) || order.email || "—" })
2171
+ ] }),
2172
+ order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2173
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
2174
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "font-medium", children: [
2175
+ order.currency_code || "$",
2176
+ (Number(order.total) / 100).toFixed(2)
2177
+ ] })
2178
+ ] })
2179
+ ] })
2180
+ ] }),
2181
+ swap.return_items && swap.return_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
2182
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Items" }),
2183
+ /* @__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: [
2184
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2185
+ /* @__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" }),
2186
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" }),
2187
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Reason" })
2188
+ ] }) }),
2189
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.return_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2190
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.id }),
2191
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity }),
2192
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.reason || "—" })
2193
+ ] }, item.id || index)) })
2194
+ ] }) })
2195
+ ] }),
2196
+ swap.new_items && swap.new_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
2197
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "New Items" }),
2198
+ /* @__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: [
2199
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2200
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Variant ID" }),
2201
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" })
2202
+ ] }) }),
2203
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.new_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2204
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.variant_id }),
2205
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity })
2206
+ ] }, item.variant_id || index)) })
2207
+ ] }) })
2208
+ ] })
2122
2209
  ] }) });
2123
2210
  };
2124
2211
  const config$2 = adminSdk.defineRouteConfig({
2125
- label: "Refund details",
2126
- icon: icons.Receipt
2212
+ label: "Swap Details",
2213
+ icon: icons.ArrowPath
2127
2214
  });
2128
2215
  const getStatusBadgeClass$1 = (status) => {
2129
2216
  const statusLower = status.toLowerCase();
@@ -2404,283 +2491,196 @@ const config$1 = adminSdk.defineRouteConfig({
2404
2491
  icon: icons.CheckCircle
2405
2492
  });
2406
2493
  const getStatusBadgeClass = (status) => {
2407
- const statusLower = status.toLowerCase();
2408
- if (statusLower === "requested") {
2409
- return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
2410
- }
2411
- if (statusLower === "approved") {
2412
- return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
2413
- }
2414
- if (statusLower === "rejected") {
2415
- return "bg-ui-tag-red-bg text-ui-tag-red-text";
2416
- }
2417
- if (statusLower === "completed") {
2418
- return "bg-ui-tag-green-bg text-ui-tag-green-text";
2419
- }
2420
- if (statusLower === "cancelled" || statusLower === "canceled") {
2421
- return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
2422
- }
2423
- if (statusLower === "pending") {
2424
- return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
2425
- }
2494
+ const s2 = status.toLowerCase();
2495
+ if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
2496
+ if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
2497
+ if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
2498
+ if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
2426
2499
  return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
2427
2500
  };
2428
- const SwapDetailPage = () => {
2501
+ const formatAmount = (value) => {
2502
+ return String(value);
2503
+ };
2504
+ const RefundDetailPage = () => {
2429
2505
  var _a, _b, _c;
2430
2506
  const navigate = reactRouterDom.useNavigate();
2431
- const { id } = reactRouterDom.useParams();
2432
- const [swap, setSwap] = react.useState(null);
2433
- const [order, setOrder] = react.useState(null);
2434
- const [isLoading, setIsLoading] = react.useState(true);
2435
- react.useState(false);
2436
- const [isCancelling, setIsCancelling] = react.useState(false);
2507
+ const params = reactRouterDom.useParams();
2508
+ const id = (_a = params == null ? void 0 : params.id) == null ? void 0 : _a.trim();
2509
+ const [detail, setDetail] = react.useState(null);
2510
+ const [loading, setLoading] = react.useState(!!id);
2437
2511
  const [error, setError] = react.useState(null);
2438
- const [updateError, setUpdateError] = react.useState(null);
2439
- const [updateSuccess, setUpdateSuccess] = react.useState(false);
2512
+ const [gatewayExpanded, setGatewayExpanded] = react.useState(false);
2440
2513
  react.useEffect(() => {
2441
2514
  if (!id) {
2442
- navigate("/swaps");
2515
+ setLoading(false);
2443
2516
  return;
2444
2517
  }
2445
- const loadSwap = async () => {
2446
- try {
2447
- setIsLoading(true);
2448
- setError(null);
2449
- const response = await fetch(`/admin/swaps/${id}`, {
2450
- credentials: "include"
2451
- });
2452
- if (!response.ok) {
2453
- const message = await response.text();
2454
- throw new Error(message || "Unable to load swap");
2455
- }
2456
- const payload = await response.json();
2457
- setSwap(payload.swap);
2458
- setOrder(payload.order || null);
2459
- } catch (loadError) {
2460
- const message = loadError instanceof Error ? loadError.message : "Unable to load swap";
2461
- setError(message);
2462
- } finally {
2463
- setIsLoading(false);
2464
- }
2518
+ let cancelled = false;
2519
+ setLoading(true);
2520
+ setError(null);
2521
+ fetch(`/admin/refunds/${id}`, { credentials: "include" }).then((res) => {
2522
+ if (!res.ok) throw new Error(res.statusText || "Failed to load");
2523
+ return res.json();
2524
+ }).then((data) => {
2525
+ if (!cancelled) setDetail(data);
2526
+ }).catch((e) => {
2527
+ if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
2528
+ }).finally(() => {
2529
+ if (!cancelled) setLoading(false);
2530
+ });
2531
+ return () => {
2532
+ cancelled = true;
2465
2533
  };
2466
- void loadSwap();
2467
- }, [id, navigate]);
2468
- const handleCancelExchange = async () => {
2469
- if (!id) {
2470
- return;
2471
- }
2472
- try {
2473
- setIsCancelling(true);
2474
- setUpdateError(null);
2475
- setUpdateSuccess(false);
2476
- const response = await fetch(`/admin/swaps/${id}/cancel`, {
2477
- method: "POST",
2478
- headers: {
2479
- "Content-Type": "application/json"
2480
- },
2481
- credentials: "include"
2482
- });
2483
- if (!response.ok) {
2484
- const message = await response.text();
2485
- throw new Error(message || "Unable to cancel exchange");
2486
- }
2487
- const payload = await response.json();
2488
- setSwap(payload.swap);
2489
- setUpdateSuccess(true);
2490
- setTimeout(() => setUpdateSuccess(false), 3e3);
2491
- const detailResponse = await fetch(`/admin/swaps/${id}`, {
2492
- credentials: "include"
2493
- });
2494
- if (detailResponse.ok) {
2495
- const detailPayload = await detailResponse.json();
2496
- setSwap(detailPayload.swap);
2497
- setOrder(detailPayload.order || null);
2498
- }
2499
- } catch (cancelErr) {
2500
- const message = cancelErr instanceof Error ? cancelErr.message : "Unable to cancel exchange";
2501
- setUpdateError(message);
2502
- } finally {
2503
- setIsCancelling(false);
2504
- }
2505
- };
2506
- const isOrderExchange = Boolean(swap == null ? void 0 : swap.exchange_id);
2507
- const canCancelExchange = isOrderExchange && swap && !["cancelled", "canceled", "completed", "declined"].includes(
2508
- ((_a = swap.status) == null ? void 0 : _a.toLowerCase()) ?? ""
2509
- );
2510
- if (isLoading) {
2511
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading swap..." }) }) }) });
2512
- }
2513
- if (error || !swap) {
2514
- 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: [
2515
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "Swap not found" }),
2516
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/swaps"), children: "Back to list" }) })
2517
- ] }) }) });
2518
- }
2519
- const statusHistory = ((_b = swap.metadata) == null ? void 0 : _b.status_history) || [];
2520
- 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: [
2521
- /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
2522
- /* @__PURE__ */ jsxRuntime.jsxs(
2523
- ui.Button,
2524
- {
2525
- variant: "transparent",
2526
- size: "small",
2527
- onClick: () => navigate("/swaps"),
2528
- className: "w-fit",
2529
- children: [
2530
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, { className: "mr-2" }),
2531
- "Back to list"
2532
- ]
2533
- }
2534
- ),
2535
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 md:flex-row md:items-center md:justify-between", children: [
2536
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
2537
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Exchange Details" }),
2538
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: swap.id })
2539
- ] }),
2540
- /* @__PURE__ */ jsxRuntime.jsx(
2541
- ui.Badge,
2542
- {
2543
- size: "small",
2544
- className: `uppercase ${getStatusBadgeClass(swap.status)}`,
2545
- children: swap.status.replace(/_/g, " ")
2546
- }
2547
- )
2548
- ] })
2549
- ] }),
2550
- canCancelExchange && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
2551
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxRuntime.jsx(
2552
- ui.Button,
2553
- {
2554
- variant: "danger",
2555
- onClick: handleCancelExchange,
2556
- disabled: isCancelling,
2557
- isLoading: isCancelling,
2558
- children: "Cancel Exchange"
2559
- }
2560
- ) }),
2561
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "This will cancel the exchange request. The order will remain unchanged." })
2562
- ] }),
2563
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
2564
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
2565
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Exchange Information" }),
2566
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
2534
+ }, [id]);
2535
+ const paymentStatus = ((_b = detail == null ? void 0 : detail.payment) == null ? void 0 : _b.status) ?? "—";
2536
+ const hasGatewayData = ((_c = detail == null ? void 0 : detail.payment) == null ? void 0 : _c.payment_data) && typeof detail.payment.payment_data === "object" && Object.keys(detail.payment.payment_data).length > 0;
2537
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-4xl flex-col gap-6 p-6", children: [
2538
+ /* @__PURE__ */ jsxRuntime.jsx("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
2539
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => navigate("/refunds"), children: "← Refunds" }),
2540
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Refund details" }),
2541
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle font-mono", children: id ?? "—" })
2542
+ ] }) }),
2543
+ error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
2544
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
2545
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/refunds"), children: "Back to list" })
2546
+ ] }) : 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: [
2547
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
2548
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Refund summary" }),
2549
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
2567
2550
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2568
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
2569
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.id })
2551
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refund ID" }),
2552
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.id })
2570
2553
  ] }),
2571
2554
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2572
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Status" }),
2573
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.status })
2555
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
2556
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.refund.amount) })
2574
2557
  ] }),
2575
2558
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2576
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Difference Due" }),
2577
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.difference_due != null ? `${swap.currency_code || "$"}${(Number(swap.difference_due) / 100).toFixed(2)}` : "—" })
2559
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Note" }),
2560
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.refund.note ?? "—" })
2578
2561
  ] }),
2579
- swap.reason && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2580
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Reason" }),
2581
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.reason })
2562
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2563
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created at" }),
2564
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: new Date(detail.refund.created_at).toLocaleDateString("en-US", {
2565
+ year: "numeric",
2566
+ month: "short",
2567
+ day: "numeric",
2568
+ hour: "numeric",
2569
+ minute: "2-digit",
2570
+ hour12: true
2571
+ }) })
2582
2572
  ] }),
2583
- swap.note && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2584
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Note" }),
2585
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.note })
2573
+ detail.refund.created_by ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2574
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created by" }),
2575
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.created_by })
2576
+ ] }) : null
2577
+ ] })
2578
+ ] }),
2579
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
2580
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Payment summary" }),
2581
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
2582
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2583
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Payment amount" }),
2584
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.payment_amount) })
2586
2585
  ] }),
2587
2586
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2588
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Created" }),
2589
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(swap.created_at).toLocaleString() })
2587
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Captured amount" }),
2588
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.captured_amount) })
2590
2589
  ] }),
2591
2590
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2592
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Last Updated" }),
2593
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(swap.updated_at).toLocaleString() })
2591
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refunded amount" }),
2592
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.refunded_amount) })
2594
2593
  ] }),
2595
- swap.exchange_id && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2596
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
2597
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.exchange_id })
2598
- ] })
2599
- ] })
2600
- ] }),
2601
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
2602
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Status History" }),
2603
- statusHistory.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: statusHistory.map((entry, index) => /* @__PURE__ */ jsxRuntime.jsx(
2604
- "div",
2605
- {
2606
- className: "flex items-center justify-between border-b border-ui-border-subtle pb-2 last:border-0",
2607
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
2608
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
2609
- ui.Badge,
2610
- {
2611
- size: "2xsmall",
2612
- className: `uppercase ${getStatusBadgeClass(entry.status)}`,
2613
- children: entry.status.replace(/_/g, " ")
2614
- }
2615
- ) }),
2616
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
2617
- new Date(entry.timestamp).toLocaleString(),
2618
- entry.admin_id && ` by ${entry.admin_id}`,
2619
- entry.reason && ` - ${entry.reason}`
2594
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2595
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
2596
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.payment.provider_id || "—" })
2597
+ ] }),
2598
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2599
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
2600
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
2601
+ ui.Badge,
2602
+ {
2603
+ size: "2xsmall",
2604
+ className: `uppercase ${getStatusBadgeClass(paymentStatus)}`,
2605
+ children: paymentStatus !== "—" ? paymentStatus.replace(/_/g, " ") : "—"
2606
+ }
2607
+ ) })
2608
+ ] }),
2609
+ detail.computed ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2610
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2611
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Full refund" }),
2612
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.computed.is_full_refund ? "Yes" : "No" })
2613
+ ] }),
2614
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2615
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Remaining refundable" }),
2616
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.computed.remaining_refundable_amount) })
2617
+ ] }),
2618
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2619
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refund %" }),
2620
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "mt-1 block", children: [
2621
+ detail.computed.refund_percentage.toFixed(1),
2622
+ "%"
2620
2623
  ] })
2621
2624
  ] })
2622
- },
2623
- index
2624
- )) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No status history available" })
2625
- ] })
2626
- ] }),
2627
- order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
2628
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Related Order Information" }),
2629
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
2630
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2631
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order ID" }),
2632
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.id })
2633
- ] }),
2634
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2635
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Status" }),
2636
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.status || "—" })
2637
- ] }),
2638
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2639
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
2640
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_c = order.customer) == null ? void 0 : _c.email) || order.email || "—" })
2641
- ] }),
2642
- order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2643
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
2644
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "font-medium", children: [
2645
- order.currency_code || "$",
2646
- (Number(order.total) / 100).toFixed(2)
2647
- ] })
2625
+ ] }) : null
2648
2626
  ] })
2627
+ ] }),
2628
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
2629
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Order summary" }),
2630
+ detail.order ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
2631
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2632
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Order" }),
2633
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
2634
+ ui.Button,
2635
+ {
2636
+ variant: "transparent",
2637
+ size: "small",
2638
+ onClick: () => navigate(`/orders/${detail.order.order_id}`),
2639
+ children: detail.order.order_number ?? detail.order.order_id
2640
+ }
2641
+ ) })
2642
+ ] }),
2643
+ detail.order.total != null ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2644
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Total" }),
2645
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.order.total) })
2646
+ ] }) : null,
2647
+ detail.order.customer_id ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2648
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Customer ID" }),
2649
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.order.customer_id })
2650
+ ] }) : null,
2651
+ detail.order.region ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2652
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Region" }),
2653
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.region })
2654
+ ] }) : null,
2655
+ detail.order.fulfillment_status ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2656
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Fulfillment status" }),
2657
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.fulfillment_status })
2658
+ ] }) : null
2659
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No order linked to this refund." })
2660
+ ] }),
2661
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
2662
+ /* @__PURE__ */ jsxRuntime.jsxs(
2663
+ "button",
2664
+ {
2665
+ type: "button",
2666
+ className: "flex w-full items-center justify-between text-left",
2667
+ onClick: () => setGatewayExpanded((prev) => !prev),
2668
+ "aria-expanded": gatewayExpanded,
2669
+ "aria-label": gatewayExpanded ? "Collapse gateway data" : "Expand gateway data",
2670
+ children: [
2671
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg", children: "Gateway data" }),
2672
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: gatewayExpanded ? "Collapse" : "Expand" })
2673
+ ]
2674
+ }
2675
+ ),
2676
+ 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." }) })
2649
2677
  ] })
2650
- ] }),
2651
- swap.return_items && swap.return_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
2652
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Items" }),
2653
- /* @__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: [
2654
- /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2655
- /* @__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" }),
2656
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" }),
2657
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Reason" })
2658
- ] }) }),
2659
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.return_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2660
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.id }),
2661
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity }),
2662
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.reason || "—" })
2663
- ] }, item.id || index)) })
2664
- ] }) })
2665
- ] }),
2666
- swap.new_items && swap.new_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
2667
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "New Items" }),
2668
- /* @__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: [
2669
- /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2670
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Variant ID" }),
2671
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" })
2672
- ] }) }),
2673
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.new_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2674
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.variant_id }),
2675
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity })
2676
- ] }, item.variant_id || index)) })
2677
- ] }) })
2678
- ] })
2678
+ ] }) : null
2679
2679
  ] }) });
2680
2680
  };
2681
2681
  const config = adminSdk.defineRouteConfig({
2682
- label: "Swap Details",
2683
- icon: icons.ArrowPath
2682
+ label: "Refund details",
2683
+ icon: icons.Receipt
2684
2684
  });
2685
2685
  const i18nTranslations0 = {};
2686
2686
  const widgetModule = { widgets: [
@@ -2699,6 +2699,10 @@ const routeModule = {
2699
2699
  Component: PaymentsPage,
2700
2700
  path: "/payments"
2701
2701
  },
2702
+ {
2703
+ Component: SwapsPage,
2704
+ path: "/swaps"
2705
+ },
2702
2706
  {
2703
2707
  Component: RefundsPage,
2704
2708
  path: "/refunds"
@@ -2707,46 +2711,36 @@ const routeModule = {
2707
2711
  Component: ReturnsPage,
2708
2712
  path: "/returns"
2709
2713
  },
2710
- {
2711
- Component: SwapsPage,
2712
- path: "/swaps"
2713
- },
2714
2714
  {
2715
2715
  Component: PaymentDetailPage,
2716
2716
  path: "/payments/:id"
2717
2717
  },
2718
2718
  {
2719
- Component: RefundDetailPage,
2720
- path: "/refunds/:id"
2719
+ Component: SwapDetailPage,
2720
+ path: "/swaps/:id"
2721
2721
  },
2722
2722
  {
2723
2723
  Component: ReturnDetailPage,
2724
2724
  path: "/returns/:id"
2725
2725
  },
2726
2726
  {
2727
- Component: SwapDetailPage,
2728
- path: "/swaps/:id"
2727
+ Component: RefundDetailPage,
2728
+ path: "/refunds/:id"
2729
2729
  }
2730
2730
  ]
2731
2731
  };
2732
2732
  const menuItemModule = {
2733
2733
  menuItems: [
2734
2734
  {
2735
- label: config$6.label,
2736
- icon: config$6.icon,
2737
- path: "/refunds",
2735
+ label: config$4.label,
2736
+ icon: config$4.icon,
2737
+ path: "/returns",
2738
2738
  nested: void 0
2739
2739
  },
2740
2740
  {
2741
2741
  label: config$5.label,
2742
2742
  icon: config$5.icon,
2743
- path: "/returns",
2744
- nested: void 0
2745
- },
2746
- {
2747
- label: config$4.label,
2748
- icon: config$4.icon,
2749
- path: "/swaps",
2743
+ path: "/refunds",
2750
2744
  nested: void 0
2751
2745
  },
2752
2746
  {
@@ -2756,9 +2750,9 @@ const menuItemModule = {
2756
2750
  nested: void 0
2757
2751
  },
2758
2752
  {
2759
- label: config$2.label,
2760
- icon: config$2.icon,
2761
- path: "/refunds/:id",
2753
+ label: config$6.label,
2754
+ icon: config$6.icon,
2755
+ path: "/swaps",
2762
2756
  nested: void 0
2763
2757
  },
2764
2758
  {
@@ -2770,7 +2764,7 @@ const menuItemModule = {
2770
2764
  {
2771
2765
  label: config.label,
2772
2766
  icon: config.icon,
2773
- path: "/swaps/:id",
2767
+ path: "/refunds/:id",
2774
2768
  nested: void 0
2775
2769
  },
2776
2770
  {
@@ -2778,6 +2772,12 @@ const menuItemModule = {
2778
2772
  icon: config$3.icon,
2779
2773
  path: "/payments/:id",
2780
2774
  nested: void 0
2775
+ },
2776
+ {
2777
+ label: config$2.label,
2778
+ icon: config$2.icon,
2779
+ path: "/swaps/:id",
2780
+ nested: void 0
2781
2781
  }
2782
2782
  ]
2783
2783
  };