order-management 0.0.72 → 0.0.74

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.
@@ -2,7 +2,7 @@ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
2
  import { defineWidgetConfig, defineRouteConfig } from "@medusajs/admin-sdk";
3
3
  import { useState, useEffect, useRef, useCallback, useMemo } from "react";
4
4
  import { Container, Text, Heading, Badge, Button, Label, Select, Textarea, Input } from "@medusajs/ui";
5
- import { CashSolid, PencilSquareSolid, Trash, CreditCard, Receipt, ArrowPath, CheckCircle, ArrowLeft } from "@medusajs/icons";
5
+ import { CashSolid, PencilSquareSolid, Trash, CreditCard, ArrowPath, Receipt, CheckCircle, ArrowLeft } from "@medusajs/icons";
6
6
  import { useNavigate, useParams } from "react-router-dom";
7
7
  function roundRectPath(ctx, x, y, w, h, r) {
8
8
  ctx.beginPath();
@@ -1065,6 +1065,238 @@ const useDebounce$2 = (value, delay) => {
1065
1065
  return debouncedValue;
1066
1066
  };
1067
1067
  const getStatusBadgeClass$6 = (status) => {
1068
+ const statusLower = status.toLowerCase();
1069
+ if (statusLower === "requested") {
1070
+ return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
1071
+ }
1072
+ if (statusLower === "received") {
1073
+ return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
1074
+ }
1075
+ if (statusLower === "requires_action") {
1076
+ return "bg-ui-tag-red-bg text-ui-tag-red-text";
1077
+ }
1078
+ if (statusLower === "completed") {
1079
+ return "bg-ui-tag-green-bg text-ui-tag-green-text";
1080
+ }
1081
+ if (statusLower === "canceled") {
1082
+ return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
1083
+ }
1084
+ return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
1085
+ };
1086
+ const ReturnsPage = () => {
1087
+ const navigate = useNavigate();
1088
+ const [items, setItems] = useState([]);
1089
+ const [statusFilter, setStatusFilter] = useState("all");
1090
+ const [createdByFilter, setCreatedByFilter] = useState("all");
1091
+ const [searchQuery, setSearchQuery] = useState("");
1092
+ const debouncedSearchQuery = useDebounce$2(searchQuery, 300);
1093
+ const [isLoading, setIsLoading] = useState(true);
1094
+ const [isFetchingMore, setIsFetchingMore] = useState(false);
1095
+ const [error, setError] = useState(null);
1096
+ const [offset, setOffset] = useState(0);
1097
+ const [count, setCount] = useState(0);
1098
+ const limit = 50;
1099
+ const loadReturns = useCallback(
1100
+ async (nextOffset, replace = false) => {
1101
+ var _a;
1102
+ try {
1103
+ if (replace) {
1104
+ setIsLoading(true);
1105
+ } else {
1106
+ setIsFetchingMore(true);
1107
+ }
1108
+ setError(null);
1109
+ const params = new URLSearchParams();
1110
+ params.set("limit", String(limit));
1111
+ params.set("offset", String(nextOffset));
1112
+ if (statusFilter !== "all") {
1113
+ params.set("status", statusFilter);
1114
+ }
1115
+ if (debouncedSearchQuery.trim()) {
1116
+ params.set("q", debouncedSearchQuery.trim());
1117
+ }
1118
+ if (createdByFilter !== "all") {
1119
+ params.set("created_by", createdByFilter);
1120
+ }
1121
+ params.set("order", "created_at");
1122
+ const response = await fetch(
1123
+ `/admin/return?${params.toString()}`,
1124
+ { credentials: "include" }
1125
+ );
1126
+ if (!response.ok) {
1127
+ const message = await response.text();
1128
+ throw new Error(message || "Unable to load return orders");
1129
+ }
1130
+ const payload = await response.json();
1131
+ setCount(payload.count ?? 0);
1132
+ setOffset(nextOffset + (((_a = payload.returns) == null ? void 0 : _a.length) ?? 0));
1133
+ setItems(
1134
+ (prev) => replace ? payload.returns ?? [] : [...prev, ...payload.returns ?? []]
1135
+ );
1136
+ } catch (loadError) {
1137
+ const message = loadError instanceof Error ? loadError.message : "Unable to load return orders";
1138
+ setError(message);
1139
+ } finally {
1140
+ setIsLoading(false);
1141
+ setIsFetchingMore(false);
1142
+ }
1143
+ },
1144
+ [statusFilter, createdByFilter, debouncedSearchQuery]
1145
+ );
1146
+ useEffect(() => {
1147
+ void loadReturns(0, true);
1148
+ }, [statusFilter, createdByFilter, debouncedSearchQuery, loadReturns]);
1149
+ const hasMore = useMemo(() => offset < count, [offset, count]);
1150
+ const availableStatuses = 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__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxs(Container, { className: "mx-auto flex w-full max-w-7xl flex-col gap-6 p-6", children: [
1156
+ /* @__PURE__ */ jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
1157
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
1158
+ /* @__PURE__ */ jsx(Heading, { level: "h1", children: "Return Orders" }),
1159
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer return orders" })
1160
+ ] }),
1161
+ /* @__PURE__ */ jsx(Button, { variant: "primary", onClick: () => loadReturns(0, true), children: "Refresh" })
1162
+ ] }),
1163
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
1164
+ /* @__PURE__ */ jsx(
1165
+ Input,
1166
+ {
1167
+ placeholder: "Search by return ID, order ID, or customer email",
1168
+ value: searchQuery,
1169
+ onChange: (event) => setSearchQuery(event.target.value),
1170
+ className: "md:max-w-sm"
1171
+ }
1172
+ ),
1173
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-3", children: [
1174
+ /* @__PURE__ */ 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__ */ jsx("option", { value: "all", children: "All (Created by)" }),
1182
+ /* @__PURE__ */ jsx("option", { value: "customer", children: "Customer" }),
1183
+ /* @__PURE__ */ jsx("option", { value: "admin", children: "Admin" })
1184
+ ]
1185
+ }
1186
+ ),
1187
+ /* @__PURE__ */ 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__ */ jsx("option", { value: "all", children: "All Statuses" }),
1195
+ availableStatuses.map((status) => /* @__PURE__ */ jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
1196
+ ]
1197
+ }
1198
+ )
1199
+ ] })
1200
+ ] }),
1201
+ error ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
1202
+ /* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
1203
+ /* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx(
1204
+ Button,
1205
+ {
1206
+ variant: "secondary",
1207
+ onClick: () => loadReturns(0, true),
1208
+ children: "Try again"
1209
+ }
1210
+ ) })
1211
+ ] }) : null,
1212
+ isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading return orders..." }) }) : items.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
1213
+ /* @__PURE__ */ jsx(Heading, { level: "h3", className: "text-xl", children: "No return orders yet" }),
1214
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Return orders created by customers will appear here." })
1215
+ ] }) : /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
1216
+ /* @__PURE__ */ jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
1217
+ /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Return ID" }),
1218
+ /* @__PURE__ */ 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__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Customer" }),
1220
+ /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
1221
+ /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Refund Amount" }),
1222
+ /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
1223
+ /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
1224
+ ] }) }),
1225
+ /* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((returnOrder) => /* @__PURE__ */ jsxs(
1226
+ "tr",
1227
+ {
1228
+ className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
1229
+ onClick: () => navigate(`/returns/${returnOrder.id}`),
1230
+ children: [
1231
+ /* @__PURE__ */ jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-0.5", children: /* @__PURE__ */ jsx("span", { children: returnOrder.id }) }) }),
1232
+ /* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.order_id }),
1233
+ /* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.customer_email || returnOrder.order_email || "—" }),
1234
+ /* @__PURE__ */ jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsx(
1235
+ Badge,
1236
+ {
1237
+ size: "2xsmall",
1238
+ className: `uppercase ${getStatusBadgeClass$6(returnOrder.status)}`,
1239
+ children: returnOrder.status.replace(/_/g, " ")
1240
+ }
1241
+ ) }),
1242
+ /* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
1243
+ const amount = returnOrder.refund_amount;
1244
+ if (amount == null || amount === void 0) {
1245
+ return "—";
1246
+ }
1247
+ const displayAmount = Number(amount) / 100;
1248
+ const currency = returnOrder.currency_code || "$";
1249
+ return `${currency}${displayAmount.toFixed(2)}`;
1250
+ })() }),
1251
+ /* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(returnOrder.created_at).toLocaleDateString("en-US", {
1252
+ year: "numeric",
1253
+ month: "short",
1254
+ day: "numeric",
1255
+ hour: "numeric",
1256
+ minute: "2-digit",
1257
+ hour12: true
1258
+ }) }),
1259
+ /* @__PURE__ */ jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsx(
1260
+ Button,
1261
+ {
1262
+ variant: "transparent",
1263
+ size: "small",
1264
+ onClick: (e) => {
1265
+ e.stopPropagation();
1266
+ navigate(`/app/orders/${returnOrder.order_id}`);
1267
+ },
1268
+ children: "Go to order"
1269
+ }
1270
+ ) })
1271
+ ]
1272
+ },
1273
+ returnOrder.id
1274
+ )) })
1275
+ ] }) }),
1276
+ hasMore ? /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(
1277
+ Button,
1278
+ {
1279
+ variant: "secondary",
1280
+ isLoading: isFetchingMore,
1281
+ onClick: () => loadReturns(offset, false),
1282
+ children: "Load more"
1283
+ }
1284
+ ) }) : null
1285
+ ] }) });
1286
+ };
1287
+ const config$6 = defineRouteConfig({
1288
+ label: "Return Orders",
1289
+ icon: ArrowPath
1290
+ });
1291
+ const useDebounce$1 = (value, delay) => {
1292
+ const [debouncedValue, setDebouncedValue] = useState(value);
1293
+ useEffect(() => {
1294
+ const handler = setTimeout(() => setDebouncedValue(value), delay);
1295
+ return () => clearTimeout(handler);
1296
+ }, [value, delay]);
1297
+ return debouncedValue;
1298
+ };
1299
+ const getStatusBadgeClass$5 = (status) => {
1068
1300
  const s2 = status.toLowerCase();
1069
1301
  if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
1070
1302
  if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
@@ -1076,12 +1308,12 @@ const RefundsPage = () => {
1076
1308
  const navigate = useNavigate();
1077
1309
  const [items, setItems] = useState([]);
1078
1310
  const [orderIdSearch, setOrderIdSearch] = useState("");
1079
- const debouncedOrderId = useDebounce$2(orderIdSearch, 300);
1311
+ const debouncedOrderId = useDebounce$1(orderIdSearch, 300);
1080
1312
  const [paymentStatusFilter, setPaymentStatusFilter] = useState("all");
1081
1313
  const [providerSearch, setProviderSearch] = useState("");
1082
- const debouncedProvider = useDebounce$2(providerSearch, 300);
1314
+ const debouncedProvider = useDebounce$1(providerSearch, 300);
1083
1315
  const [currencySearch, setCurrencySearch] = useState("");
1084
- const debouncedCurrency = useDebounce$2(currencySearch, 300);
1316
+ const debouncedCurrency = useDebounce$1(currencySearch, 300);
1085
1317
  const [dateFrom, setDateFrom] = useState("");
1086
1318
  const [dateTo, setDateTo] = useState("");
1087
1319
  const [amountMin, setAmountMin] = useState("");
@@ -1293,7 +1525,7 @@ const RefundsPage = () => {
1293
1525
  Badge,
1294
1526
  {
1295
1527
  size: "2xsmall",
1296
- className: `uppercase ${getStatusBadgeClass$6(displayStatus(r))}`,
1528
+ className: `uppercase ${getStatusBadgeClass$5(displayStatus(r))}`,
1297
1529
  children: displayStatus(r) !== "—" ? displayStatus(r).replace(/_/g, " ") : "—"
1298
1530
  }
1299
1531
  ) }),
@@ -1347,11 +1579,11 @@ const RefundsPage = () => {
1347
1579
  ) }) : null
1348
1580
  ] }) });
1349
1581
  };
1350
- const config$6 = defineRouteConfig({
1582
+ const config$5 = defineRouteConfig({
1351
1583
  label: "Refunds",
1352
1584
  icon: Receipt
1353
1585
  });
1354
- const useDebounce$1 = (value, delay) => {
1586
+ const useDebounce = (value, delay) => {
1355
1587
  const [debouncedValue, setDebouncedValue] = useState(value);
1356
1588
  useEffect(() => {
1357
1589
  const handler = setTimeout(() => setDebouncedValue(value), delay);
@@ -1359,39 +1591,39 @@ const useDebounce$1 = (value, delay) => {
1359
1591
  }, [value, delay]);
1360
1592
  return debouncedValue;
1361
1593
  };
1362
- const getStatusBadgeClass$5 = (status) => {
1594
+ const getStatusBadgeClass$4 = (status) => {
1363
1595
  const statusLower = status.toLowerCase();
1364
1596
  if (statusLower === "requested") {
1365
1597
  return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
1366
1598
  }
1367
- if (statusLower === "received") {
1599
+ if (statusLower === "approved") {
1368
1600
  return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
1369
1601
  }
1370
- if (statusLower === "requires_action") {
1602
+ if (statusLower === "rejected") {
1371
1603
  return "bg-ui-tag-red-bg text-ui-tag-red-text";
1372
1604
  }
1373
1605
  if (statusLower === "completed") {
1374
1606
  return "bg-ui-tag-green-bg text-ui-tag-green-text";
1375
1607
  }
1376
- if (statusLower === "canceled") {
1608
+ if (statusLower === "cancelled") {
1377
1609
  return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
1378
1610
  }
1379
1611
  return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
1380
1612
  };
1381
- const ReturnsPage = () => {
1613
+ const SwapsPage = () => {
1382
1614
  const navigate = useNavigate();
1383
1615
  const [items, setItems] = useState([]);
1384
1616
  const [statusFilter, setStatusFilter] = useState("all");
1385
1617
  const [createdByFilter, setCreatedByFilter] = useState("all");
1386
1618
  const [searchQuery, setSearchQuery] = useState("");
1387
- const debouncedSearchQuery = useDebounce$1(searchQuery, 300);
1619
+ const debouncedSearchQuery = useDebounce(searchQuery, 300);
1388
1620
  const [isLoading, setIsLoading] = useState(true);
1389
1621
  const [isFetchingMore, setIsFetchingMore] = useState(false);
1390
1622
  const [error, setError] = useState(null);
1391
1623
  const [offset, setOffset] = useState(0);
1392
1624
  const [count, setCount] = useState(0);
1393
1625
  const limit = 50;
1394
- const loadReturns = useCallback(
1626
+ const loadSwaps = useCallback(
1395
1627
  async (nextOffset, replace = false) => {
1396
1628
  var _a;
1397
1629
  try {
@@ -1408,254 +1640,22 @@ const ReturnsPage = () => {
1408
1640
  params.set("status", statusFilter);
1409
1641
  }
1410
1642
  if (debouncedSearchQuery.trim()) {
1411
- params.set("q", debouncedSearchQuery.trim());
1643
+ params.set("order_id", debouncedSearchQuery.trim());
1412
1644
  }
1413
1645
  if (createdByFilter !== "all") {
1414
1646
  params.set("created_by", createdByFilter);
1415
1647
  }
1416
- params.set("order", "created_at");
1417
1648
  const response = await fetch(
1418
- `/admin/return?${params.toString()}`,
1649
+ `/admin/swaps?${params.toString()}`,
1419
1650
  { credentials: "include" }
1420
1651
  );
1421
1652
  if (!response.ok) {
1422
1653
  const message = await response.text();
1423
- throw new Error(message || "Unable to load return orders");
1654
+ throw new Error(message || "Unable to load swaps");
1424
1655
  }
1425
1656
  const payload = await response.json();
1426
1657
  setCount(payload.count ?? 0);
1427
- setOffset(nextOffset + (((_a = payload.returns) == null ? void 0 : _a.length) ?? 0));
1428
- setItems(
1429
- (prev) => replace ? payload.returns ?? [] : [...prev, ...payload.returns ?? []]
1430
- );
1431
- } catch (loadError) {
1432
- const message = loadError instanceof Error ? loadError.message : "Unable to load return orders";
1433
- setError(message);
1434
- } finally {
1435
- setIsLoading(false);
1436
- setIsFetchingMore(false);
1437
- }
1438
- },
1439
- [statusFilter, createdByFilter, debouncedSearchQuery]
1440
- );
1441
- useEffect(() => {
1442
- void loadReturns(0, true);
1443
- }, [statusFilter, createdByFilter, debouncedSearchQuery, loadReturns]);
1444
- const hasMore = useMemo(() => offset < count, [offset, count]);
1445
- const availableStatuses = useMemo(() => {
1446
- const statuses = /* @__PURE__ */ new Set();
1447
- items.forEach((item) => statuses.add(item.status));
1448
- return Array.from(statuses).sort();
1449
- }, [items]);
1450
- return /* @__PURE__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxs(Container, { className: "mx-auto flex w-full max-w-7xl flex-col gap-6 p-6", children: [
1451
- /* @__PURE__ */ jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
1452
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
1453
- /* @__PURE__ */ jsx(Heading, { level: "h1", children: "Return Orders" }),
1454
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer return orders" })
1455
- ] }),
1456
- /* @__PURE__ */ jsx(Button, { variant: "primary", onClick: () => loadReturns(0, true), children: "Refresh" })
1457
- ] }),
1458
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
1459
- /* @__PURE__ */ jsx(
1460
- Input,
1461
- {
1462
- placeholder: "Search by return ID, order ID, or customer email",
1463
- value: searchQuery,
1464
- onChange: (event) => setSearchQuery(event.target.value),
1465
- className: "md:max-w-sm"
1466
- }
1467
- ),
1468
- /* @__PURE__ */ jsxs("div", { className: "flex gap-3", children: [
1469
- /* @__PURE__ */ jsxs(
1470
- "select",
1471
- {
1472
- value: createdByFilter,
1473
- onChange: (event) => setCreatedByFilter(event.target.value),
1474
- 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",
1475
- children: [
1476
- /* @__PURE__ */ jsx("option", { value: "all", children: "All (Created by)" }),
1477
- /* @__PURE__ */ jsx("option", { value: "customer", children: "Customer" }),
1478
- /* @__PURE__ */ jsx("option", { value: "admin", children: "Admin" })
1479
- ]
1480
- }
1481
- ),
1482
- /* @__PURE__ */ jsxs(
1483
- "select",
1484
- {
1485
- value: statusFilter,
1486
- onChange: (event) => setStatusFilter(event.target.value),
1487
- 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",
1488
- children: [
1489
- /* @__PURE__ */ jsx("option", { value: "all", children: "All Statuses" }),
1490
- availableStatuses.map((status) => /* @__PURE__ */ jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
1491
- ]
1492
- }
1493
- )
1494
- ] })
1495
- ] }),
1496
- error ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
1497
- /* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
1498
- /* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx(
1499
- Button,
1500
- {
1501
- variant: "secondary",
1502
- onClick: () => loadReturns(0, true),
1503
- children: "Try again"
1504
- }
1505
- ) })
1506
- ] }) : null,
1507
- isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading return orders..." }) }) : items.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
1508
- /* @__PURE__ */ jsx(Heading, { level: "h3", className: "text-xl", children: "No return orders yet" }),
1509
- /* @__PURE__ */ jsx(Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Return orders created by customers will appear here." })
1510
- ] }) : /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
1511
- /* @__PURE__ */ jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
1512
- /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Return ID" }),
1513
- /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
1514
- /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Customer" }),
1515
- /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
1516
- /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Refund Amount" }),
1517
- /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
1518
- /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
1519
- ] }) }),
1520
- /* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((returnOrder) => /* @__PURE__ */ jsxs(
1521
- "tr",
1522
- {
1523
- className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
1524
- onClick: () => navigate(`/returns/${returnOrder.id}`),
1525
- children: [
1526
- /* @__PURE__ */ jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-0.5", children: /* @__PURE__ */ jsx("span", { children: returnOrder.id }) }) }),
1527
- /* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.order_id }),
1528
- /* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.customer_email || returnOrder.order_email || "—" }),
1529
- /* @__PURE__ */ jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsx(
1530
- Badge,
1531
- {
1532
- size: "2xsmall",
1533
- className: `uppercase ${getStatusBadgeClass$5(returnOrder.status)}`,
1534
- children: returnOrder.status.replace(/_/g, " ")
1535
- }
1536
- ) }),
1537
- /* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
1538
- const amount = returnOrder.refund_amount;
1539
- if (amount == null || amount === void 0) {
1540
- return "—";
1541
- }
1542
- const displayAmount = Number(amount) / 100;
1543
- const currency = returnOrder.currency_code || "$";
1544
- return `${currency}${displayAmount.toFixed(2)}`;
1545
- })() }),
1546
- /* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(returnOrder.created_at).toLocaleDateString("en-US", {
1547
- year: "numeric",
1548
- month: "short",
1549
- day: "numeric",
1550
- hour: "numeric",
1551
- minute: "2-digit",
1552
- hour12: true
1553
- }) }),
1554
- /* @__PURE__ */ jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsx(
1555
- Button,
1556
- {
1557
- variant: "transparent",
1558
- size: "small",
1559
- onClick: (e) => {
1560
- e.stopPropagation();
1561
- navigate(`/app/orders/${returnOrder.order_id}`);
1562
- },
1563
- children: "Go to order"
1564
- }
1565
- ) })
1566
- ]
1567
- },
1568
- returnOrder.id
1569
- )) })
1570
- ] }) }),
1571
- hasMore ? /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(
1572
- Button,
1573
- {
1574
- variant: "secondary",
1575
- isLoading: isFetchingMore,
1576
- onClick: () => loadReturns(offset, false),
1577
- children: "Load more"
1578
- }
1579
- ) }) : null
1580
- ] }) });
1581
- };
1582
- const config$5 = defineRouteConfig({
1583
- label: "Return Orders",
1584
- icon: ArrowPath
1585
- });
1586
- const useDebounce = (value, delay) => {
1587
- const [debouncedValue, setDebouncedValue] = useState(value);
1588
- useEffect(() => {
1589
- const handler = setTimeout(() => setDebouncedValue(value), delay);
1590
- return () => clearTimeout(handler);
1591
- }, [value, delay]);
1592
- return debouncedValue;
1593
- };
1594
- const getStatusBadgeClass$4 = (status) => {
1595
- const statusLower = status.toLowerCase();
1596
- if (statusLower === "requested") {
1597
- return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
1598
- }
1599
- if (statusLower === "approved") {
1600
- return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
1601
- }
1602
- if (statusLower === "rejected") {
1603
- return "bg-ui-tag-red-bg text-ui-tag-red-text";
1604
- }
1605
- if (statusLower === "completed") {
1606
- return "bg-ui-tag-green-bg text-ui-tag-green-text";
1607
- }
1608
- if (statusLower === "cancelled") {
1609
- return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
1610
- }
1611
- return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
1612
- };
1613
- const SwapsPage = () => {
1614
- const navigate = useNavigate();
1615
- const [items, setItems] = useState([]);
1616
- const [statusFilter, setStatusFilter] = useState("all");
1617
- const [createdByFilter, setCreatedByFilter] = useState("all");
1618
- const [searchQuery, setSearchQuery] = useState("");
1619
- const debouncedSearchQuery = useDebounce(searchQuery, 300);
1620
- const [isLoading, setIsLoading] = useState(true);
1621
- const [isFetchingMore, setIsFetchingMore] = useState(false);
1622
- const [error, setError] = useState(null);
1623
- const [offset, setOffset] = useState(0);
1624
- const [count, setCount] = useState(0);
1625
- const limit = 50;
1626
- const loadSwaps = useCallback(
1627
- async (nextOffset, replace = false) => {
1628
- var _a;
1629
- try {
1630
- if (replace) {
1631
- setIsLoading(true);
1632
- } else {
1633
- setIsFetchingMore(true);
1634
- }
1635
- setError(null);
1636
- const params = new URLSearchParams();
1637
- params.set("limit", String(limit));
1638
- params.set("offset", String(nextOffset));
1639
- if (statusFilter !== "all") {
1640
- params.set("status", statusFilter);
1641
- }
1642
- if (debouncedSearchQuery.trim()) {
1643
- params.set("order_id", debouncedSearchQuery.trim());
1644
- }
1645
- if (createdByFilter !== "all") {
1646
- params.set("created_by", createdByFilter);
1647
- }
1648
- const response = await fetch(
1649
- `/admin/swaps?${params.toString()}`,
1650
- { credentials: "include" }
1651
- );
1652
- if (!response.ok) {
1653
- const message = await response.text();
1654
- throw new Error(message || "Unable to load swaps");
1655
- }
1656
- const payload = await response.json();
1657
- setCount(payload.count ?? 0);
1658
- setOffset(nextOffset + (((_a = payload.swaps) == null ? void 0 : _a.length) ?? 0));
1658
+ setOffset(nextOffset + (((_a = payload.swaps) == null ? void 0 : _a.length) ?? 0));
1659
1659
  setItems(
1660
1660
  (prev) => replace ? payload.swaps ?? [] : [...prev, ...payload.swaps ?? []]
1661
1661
  );
@@ -1902,229 +1902,37 @@ const PaymentDetailPage = () => {
1902
1902
  /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: sessionStatusRaw })
1903
1903
  ] }),
1904
1904
  /* @__PURE__ */ jsxs("div", { children: [
1905
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Payment status (DB)" }),
1906
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: paymentStatusRaw })
1907
- ] }),
1908
- /* @__PURE__ */ jsxs("div", { children: [
1909
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Finalized" }),
1910
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.payment_id != null ? "Yes" : "No" })
1911
- ] }),
1912
- /* @__PURE__ */ jsxs("div", { children: [
1913
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Created" }),
1914
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: new Date(detail.created_at).toLocaleDateString("en-US", {
1915
- year: "numeric",
1916
- month: "short",
1917
- day: "numeric",
1918
- hour: "numeric",
1919
- minute: "2-digit",
1920
- hour12: true
1921
- }) })
1922
- ] })
1923
- ] }) }),
1924
- Object.keys(detail.data ?? {}).length > 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
1925
- /* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg mb-4", children: "Provider data" }),
1926
- /* @__PURE__ */ jsx("pre", { className: "text-xs bg-ui-bg-subtle p-4 rounded-lg overflow-auto max-h-96", children: JSON.stringify(detail.data, null, 2) })
1927
- ] }) : /* @__PURE__ */ jsx("div", { className: "rounded-xl border border-ui-border-base p-6", children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "No provider data for this session." }) })
1928
- ] }) : null
1929
- ] }) });
1930
- };
1931
- const config$3 = defineRouteConfig({
1932
- label: "Payment details",
1933
- icon: CreditCard
1934
- });
1935
- const getStatusBadgeClass$2 = (status) => {
1936
- const s2 = status.toLowerCase();
1937
- if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
1938
- if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
1939
- if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
1940
- if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
1941
- return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
1942
- };
1943
- const formatAmount = (value) => {
1944
- return String(value);
1945
- };
1946
- const RefundDetailPage = () => {
1947
- var _a, _b, _c;
1948
- const navigate = useNavigate();
1949
- const params = useParams();
1950
- const id = (_a = params == null ? void 0 : params.id) == null ? void 0 : _a.trim();
1951
- const [detail, setDetail] = useState(null);
1952
- const [loading, setLoading] = useState(!!id);
1953
- const [error, setError] = useState(null);
1954
- const [gatewayExpanded, setGatewayExpanded] = useState(false);
1955
- useEffect(() => {
1956
- if (!id) {
1957
- setLoading(false);
1958
- return;
1959
- }
1960
- let cancelled = false;
1961
- setLoading(true);
1962
- setError(null);
1963
- fetch(`/admin/refunds/${id}`, { credentials: "include" }).then((res) => {
1964
- if (!res.ok) throw new Error(res.statusText || "Failed to load");
1965
- return res.json();
1966
- }).then((data) => {
1967
- if (!cancelled) setDetail(data);
1968
- }).catch((e) => {
1969
- if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
1970
- }).finally(() => {
1971
- if (!cancelled) setLoading(false);
1972
- });
1973
- return () => {
1974
- cancelled = true;
1975
- };
1976
- }, [id]);
1977
- const paymentStatus = ((_b = detail == null ? void 0 : detail.payment) == null ? void 0 : _b.status) ?? "—";
1978
- 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;
1979
- return /* @__PURE__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxs(Container, { className: "mx-auto flex w-full max-w-4xl flex-col gap-6 p-6", children: [
1980
- /* @__PURE__ */ jsx("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
1981
- /* @__PURE__ */ jsx(Button, { variant: "transparent", size: "small", onClick: () => navigate("/refunds"), children: "← Refunds" }),
1982
- /* @__PURE__ */ jsx(Heading, { level: "h1", children: "Refund details" }),
1983
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle font-mono", children: id ?? "—" })
1984
- ] }) }),
1985
- error ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
1986
- /* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
1987
- /* @__PURE__ */ jsx(Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/refunds"), children: "Back to list" })
1988
- ] }) : loading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading…" }) }) : detail ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", children: [
1989
- /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
1990
- /* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg mb-4", children: "Refund summary" }),
1991
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
1992
- /* @__PURE__ */ jsxs("div", { children: [
1993
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Refund ID" }),
1994
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.id })
1995
- ] }),
1996
- /* @__PURE__ */ jsxs("div", { children: [
1997
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
1998
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.refund.amount) })
1999
- ] }),
2000
- /* @__PURE__ */ jsxs("div", { children: [
2001
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Note" }),
2002
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.refund.note ?? "—" })
2003
- ] }),
2004
- /* @__PURE__ */ jsxs("div", { children: [
2005
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Created at" }),
2006
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: new Date(detail.refund.created_at).toLocaleDateString("en-US", {
2007
- year: "numeric",
2008
- month: "short",
2009
- day: "numeric",
2010
- hour: "numeric",
2011
- minute: "2-digit",
2012
- hour12: true
2013
- }) })
2014
- ] }),
2015
- detail.refund.created_by ? /* @__PURE__ */ jsxs("div", { children: [
2016
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Created by" }),
2017
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.created_by })
2018
- ] }) : null
2019
- ] })
2020
- ] }),
2021
- /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
2022
- /* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg mb-4", children: "Payment summary" }),
2023
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
2024
- /* @__PURE__ */ jsxs("div", { children: [
2025
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Payment amount" }),
2026
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.payment.payment_amount) })
2027
- ] }),
2028
- /* @__PURE__ */ jsxs("div", { children: [
2029
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Captured amount" }),
2030
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.payment.captured_amount) })
2031
- ] }),
2032
- /* @__PURE__ */ jsxs("div", { children: [
2033
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Refunded amount" }),
2034
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.payment.refunded_amount) })
2035
- ] }),
2036
- /* @__PURE__ */ jsxs("div", { children: [
2037
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
2038
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.payment.provider_id || "—" })
2039
- ] }),
2040
- /* @__PURE__ */ jsxs("div", { children: [
2041
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
2042
- /* @__PURE__ */ jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsx(
2043
- Badge,
2044
- {
2045
- size: "2xsmall",
2046
- className: `uppercase ${getStatusBadgeClass$2(paymentStatus)}`,
2047
- children: paymentStatus !== "—" ? paymentStatus.replace(/_/g, " ") : "—"
2048
- }
2049
- ) })
2050
- ] }),
2051
- detail.computed ? /* @__PURE__ */ jsxs(Fragment, { children: [
2052
- /* @__PURE__ */ jsxs("div", { children: [
2053
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Full refund" }),
2054
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.computed.is_full_refund ? "Yes" : "No" })
2055
- ] }),
2056
- /* @__PURE__ */ jsxs("div", { children: [
2057
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Remaining refundable" }),
2058
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.computed.remaining_refundable_amount) })
2059
- ] }),
2060
- /* @__PURE__ */ jsxs("div", { children: [
2061
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Refund %" }),
2062
- /* @__PURE__ */ jsxs(Text, { className: "mt-1 block", children: [
2063
- detail.computed.refund_percentage.toFixed(1),
2064
- "%"
2065
- ] })
2066
- ] })
2067
- ] }) : null
2068
- ] })
2069
- ] }),
2070
- /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
2071
- /* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg mb-4", children: "Order summary" }),
2072
- detail.order ? /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
2073
- /* @__PURE__ */ jsxs("div", { children: [
2074
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Order" }),
2075
- /* @__PURE__ */ jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsx(
2076
- Button,
2077
- {
2078
- variant: "transparent",
2079
- size: "small",
2080
- onClick: () => navigate(`/orders/${detail.order.order_id}`),
2081
- children: detail.order.order_number ?? detail.order.order_id
2082
- }
2083
- ) })
2084
- ] }),
2085
- detail.order.total != null ? /* @__PURE__ */ jsxs("div", { children: [
2086
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Total" }),
2087
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.order.total) })
2088
- ] }) : null,
2089
- detail.order.customer_id ? /* @__PURE__ */ jsxs("div", { children: [
2090
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Customer ID" }),
2091
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block font-mono text-sm", children: detail.order.customer_id })
2092
- ] }) : null,
2093
- detail.order.region ? /* @__PURE__ */ jsxs("div", { children: [
2094
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Region" }),
2095
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.order.region })
2096
- ] }) : null,
2097
- detail.order.fulfillment_status ? /* @__PURE__ */ jsxs("div", { children: [
2098
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Fulfillment status" }),
2099
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.order.fulfillment_status })
2100
- ] }) : null
2101
- ] }) : /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "No order linked to this refund." })
2102
- ] }),
2103
- /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
2104
- /* @__PURE__ */ jsxs(
2105
- "button",
2106
- {
2107
- type: "button",
2108
- className: "flex w-full items-center justify-between text-left",
2109
- onClick: () => setGatewayExpanded((prev) => !prev),
2110
- "aria-expanded": gatewayExpanded,
2111
- "aria-label": gatewayExpanded ? "Collapse gateway data" : "Expand gateway data",
2112
- children: [
2113
- /* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg", children: "Gateway data" }),
2114
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: gatewayExpanded ? "Collapse" : "Expand" })
2115
- ]
2116
- }
2117
- ),
2118
- gatewayExpanded && /* @__PURE__ */ jsx("div", { className: "mt-4", children: hasGatewayData ? /* @__PURE__ */ jsx("pre", { className: "text-xs bg-ui-bg-subtle p-4 rounded-lg overflow-auto max-h-96", children: JSON.stringify(detail.payment.payment_data, null, 2) }) : /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "No gateway payload for this payment." }) })
2119
- ] })
1905
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Payment status (DB)" }),
1906
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: paymentStatusRaw })
1907
+ ] }),
1908
+ /* @__PURE__ */ jsxs("div", { children: [
1909
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Finalized" }),
1910
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.payment_id != null ? "Yes" : "No" })
1911
+ ] }),
1912
+ /* @__PURE__ */ jsxs("div", { children: [
1913
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Created" }),
1914
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: new Date(detail.created_at).toLocaleDateString("en-US", {
1915
+ year: "numeric",
1916
+ month: "short",
1917
+ day: "numeric",
1918
+ hour: "numeric",
1919
+ minute: "2-digit",
1920
+ hour12: true
1921
+ }) })
1922
+ ] })
1923
+ ] }) }),
1924
+ Object.keys(detail.data ?? {}).length > 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
1925
+ /* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg mb-4", children: "Provider data" }),
1926
+ /* @__PURE__ */ jsx("pre", { className: "text-xs bg-ui-bg-subtle p-4 rounded-lg overflow-auto max-h-96", children: JSON.stringify(detail.data, null, 2) })
1927
+ ] }) : /* @__PURE__ */ jsx("div", { className: "rounded-xl border border-ui-border-base p-6", children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "No provider data for this session." }) })
2120
1928
  ] }) : null
2121
1929
  ] }) });
2122
1930
  };
2123
- const config$2 = defineRouteConfig({
2124
- label: "Refund details",
2125
- icon: Receipt
1931
+ const config$3 = defineRouteConfig({
1932
+ label: "Payment details",
1933
+ icon: CreditCard
2126
1934
  });
2127
- const getStatusBadgeClass$1 = (status) => {
1935
+ const getStatusBadgeClass$2 = (status) => {
2128
1936
  const statusLower = status.toLowerCase();
2129
1937
  if (statusLower === "requested") {
2130
1938
  return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
@@ -2258,7 +2066,7 @@ const ReturnDetailPage = () => {
2258
2066
  Badge,
2259
2067
  {
2260
2068
  size: "small",
2261
- className: `uppercase ${getStatusBadgeClass$1(returnOrder.status)}`,
2069
+ className: `uppercase ${getStatusBadgeClass$2(returnOrder.status)}`,
2262
2070
  children: returnOrder.status.replace(/_/g, " ")
2263
2071
  }
2264
2072
  )
@@ -2340,7 +2148,7 @@ const ReturnDetailPage = () => {
2340
2148
  Badge,
2341
2149
  {
2342
2150
  size: "2xsmall",
2343
- className: `uppercase ${getStatusBadgeClass$1(entry.status)}`,
2151
+ className: `uppercase ${getStatusBadgeClass$2(entry.status)}`,
2344
2152
  children: entry.status.replace(/_/g, " ")
2345
2153
  }
2346
2154
  ) }),
@@ -2398,10 +2206,202 @@ const ReturnDetailPage = () => {
2398
2206
  updateSuccess && /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-ui-border-success bg-ui-bg-success-subtle p-4", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-success", children: "Action completed successfully" }) })
2399
2207
  ] }) });
2400
2208
  };
2401
- const config$1 = defineRouteConfig({
2209
+ const config$2 = defineRouteConfig({
2402
2210
  label: "Return Order Details",
2403
2211
  icon: CheckCircle
2404
2212
  });
2213
+ const getStatusBadgeClass$1 = (status) => {
2214
+ const s2 = status.toLowerCase();
2215
+ if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
2216
+ if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
2217
+ if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
2218
+ if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
2219
+ return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
2220
+ };
2221
+ const formatAmount = (value) => {
2222
+ return String(value);
2223
+ };
2224
+ const RefundDetailPage = () => {
2225
+ var _a, _b, _c;
2226
+ const navigate = useNavigate();
2227
+ const params = useParams();
2228
+ const id = (_a = params == null ? void 0 : params.id) == null ? void 0 : _a.trim();
2229
+ const [detail, setDetail] = useState(null);
2230
+ const [loading, setLoading] = useState(!!id);
2231
+ const [error, setError] = useState(null);
2232
+ const [gatewayExpanded, setGatewayExpanded] = useState(false);
2233
+ useEffect(() => {
2234
+ if (!id) {
2235
+ setLoading(false);
2236
+ return;
2237
+ }
2238
+ let cancelled = false;
2239
+ setLoading(true);
2240
+ setError(null);
2241
+ fetch(`/admin/refunds/${id}`, { credentials: "include" }).then((res) => {
2242
+ if (!res.ok) throw new Error(res.statusText || "Failed to load");
2243
+ return res.json();
2244
+ }).then((data) => {
2245
+ if (!cancelled) setDetail(data);
2246
+ }).catch((e) => {
2247
+ if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
2248
+ }).finally(() => {
2249
+ if (!cancelled) setLoading(false);
2250
+ });
2251
+ return () => {
2252
+ cancelled = true;
2253
+ };
2254
+ }, [id]);
2255
+ const paymentStatus = ((_b = detail == null ? void 0 : detail.payment) == null ? void 0 : _b.status) ?? "—";
2256
+ 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;
2257
+ return /* @__PURE__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxs(Container, { className: "mx-auto flex w-full max-w-4xl flex-col gap-6 p-6", children: [
2258
+ /* @__PURE__ */ jsx("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
2259
+ /* @__PURE__ */ jsx(Button, { variant: "transparent", size: "small", onClick: () => navigate("/refunds"), children: "← Refunds" }),
2260
+ /* @__PURE__ */ jsx(Heading, { level: "h1", children: "Refund details" }),
2261
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle font-mono", children: id ?? "—" })
2262
+ ] }) }),
2263
+ error ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
2264
+ /* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
2265
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/refunds"), children: "Back to list" })
2266
+ ] }) : loading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading…" }) }) : detail ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", children: [
2267
+ /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
2268
+ /* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg mb-4", children: "Refund summary" }),
2269
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
2270
+ /* @__PURE__ */ jsxs("div", { children: [
2271
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Refund ID" }),
2272
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.id })
2273
+ ] }),
2274
+ /* @__PURE__ */ jsxs("div", { children: [
2275
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
2276
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.refund.amount) })
2277
+ ] }),
2278
+ /* @__PURE__ */ jsxs("div", { children: [
2279
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Note" }),
2280
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.refund.note ?? "—" })
2281
+ ] }),
2282
+ /* @__PURE__ */ jsxs("div", { children: [
2283
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Created at" }),
2284
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: new Date(detail.refund.created_at).toLocaleDateString("en-US", {
2285
+ year: "numeric",
2286
+ month: "short",
2287
+ day: "numeric",
2288
+ hour: "numeric",
2289
+ minute: "2-digit",
2290
+ hour12: true
2291
+ }) })
2292
+ ] }),
2293
+ detail.refund.created_by ? /* @__PURE__ */ jsxs("div", { children: [
2294
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Created by" }),
2295
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.created_by })
2296
+ ] }) : null
2297
+ ] })
2298
+ ] }),
2299
+ /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
2300
+ /* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg mb-4", children: "Payment summary" }),
2301
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
2302
+ /* @__PURE__ */ jsxs("div", { children: [
2303
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Payment amount" }),
2304
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.payment.payment_amount) })
2305
+ ] }),
2306
+ /* @__PURE__ */ jsxs("div", { children: [
2307
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Captured amount" }),
2308
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.payment.captured_amount) })
2309
+ ] }),
2310
+ /* @__PURE__ */ jsxs("div", { children: [
2311
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Refunded amount" }),
2312
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.payment.refunded_amount) })
2313
+ ] }),
2314
+ /* @__PURE__ */ jsxs("div", { children: [
2315
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
2316
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.payment.provider_id || "—" })
2317
+ ] }),
2318
+ /* @__PURE__ */ jsxs("div", { children: [
2319
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
2320
+ /* @__PURE__ */ jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsx(
2321
+ Badge,
2322
+ {
2323
+ size: "2xsmall",
2324
+ className: `uppercase ${getStatusBadgeClass$1(paymentStatus)}`,
2325
+ children: paymentStatus !== "—" ? paymentStatus.replace(/_/g, " ") : "—"
2326
+ }
2327
+ ) })
2328
+ ] }),
2329
+ detail.computed ? /* @__PURE__ */ jsxs(Fragment, { children: [
2330
+ /* @__PURE__ */ jsxs("div", { children: [
2331
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Full refund" }),
2332
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.computed.is_full_refund ? "Yes" : "No" })
2333
+ ] }),
2334
+ /* @__PURE__ */ jsxs("div", { children: [
2335
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Remaining refundable" }),
2336
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.computed.remaining_refundable_amount) })
2337
+ ] }),
2338
+ /* @__PURE__ */ jsxs("div", { children: [
2339
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Refund %" }),
2340
+ /* @__PURE__ */ jsxs(Text, { className: "mt-1 block", children: [
2341
+ detail.computed.refund_percentage.toFixed(1),
2342
+ "%"
2343
+ ] })
2344
+ ] })
2345
+ ] }) : null
2346
+ ] })
2347
+ ] }),
2348
+ /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
2349
+ /* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg mb-4", children: "Order summary" }),
2350
+ detail.order ? /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
2351
+ /* @__PURE__ */ jsxs("div", { children: [
2352
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Order" }),
2353
+ /* @__PURE__ */ jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsx(
2354
+ Button,
2355
+ {
2356
+ variant: "transparent",
2357
+ size: "small",
2358
+ onClick: () => navigate(`/orders/${detail.order.order_id}`),
2359
+ children: detail.order.order_number ?? detail.order.order_id
2360
+ }
2361
+ ) })
2362
+ ] }),
2363
+ detail.order.total != null ? /* @__PURE__ */ jsxs("div", { children: [
2364
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Total" }),
2365
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.order.total) })
2366
+ ] }) : null,
2367
+ detail.order.customer_id ? /* @__PURE__ */ jsxs("div", { children: [
2368
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Customer ID" }),
2369
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block font-mono text-sm", children: detail.order.customer_id })
2370
+ ] }) : null,
2371
+ detail.order.region ? /* @__PURE__ */ jsxs("div", { children: [
2372
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Region" }),
2373
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.order.region })
2374
+ ] }) : null,
2375
+ detail.order.fulfillment_status ? /* @__PURE__ */ jsxs("div", { children: [
2376
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Fulfillment status" }),
2377
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.order.fulfillment_status })
2378
+ ] }) : null
2379
+ ] }) : /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "No order linked to this refund." })
2380
+ ] }),
2381
+ /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
2382
+ /* @__PURE__ */ jsxs(
2383
+ "button",
2384
+ {
2385
+ type: "button",
2386
+ className: "flex w-full items-center justify-between text-left",
2387
+ onClick: () => setGatewayExpanded((prev) => !prev),
2388
+ "aria-expanded": gatewayExpanded,
2389
+ "aria-label": gatewayExpanded ? "Collapse gateway data" : "Expand gateway data",
2390
+ children: [
2391
+ /* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg", children: "Gateway data" }),
2392
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: gatewayExpanded ? "Collapse" : "Expand" })
2393
+ ]
2394
+ }
2395
+ ),
2396
+ gatewayExpanded && /* @__PURE__ */ jsx("div", { className: "mt-4", children: hasGatewayData ? /* @__PURE__ */ jsx("pre", { className: "text-xs bg-ui-bg-subtle p-4 rounded-lg overflow-auto max-h-96", children: JSON.stringify(detail.payment.payment_data, null, 2) }) : /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "No gateway payload for this payment." }) })
2397
+ ] })
2398
+ ] }) : null
2399
+ ] }) });
2400
+ };
2401
+ const config$1 = defineRouteConfig({
2402
+ label: "Refund details",
2403
+ icon: Receipt
2404
+ });
2405
2405
  const getStatusBadgeClass = (status) => {
2406
2406
  const statusLower = status.toLowerCase();
2407
2407
  if (statusLower === "requested") {
@@ -2698,14 +2698,14 @@ const routeModule = {
2698
2698
  Component: PaymentsPage,
2699
2699
  path: "/payments"
2700
2700
  },
2701
- {
2702
- Component: RefundsPage,
2703
- path: "/refunds"
2704
- },
2705
2701
  {
2706
2702
  Component: ReturnsPage,
2707
2703
  path: "/returns"
2708
2704
  },
2705
+ {
2706
+ Component: RefundsPage,
2707
+ path: "/refunds"
2708
+ },
2709
2709
  {
2710
2710
  Component: SwapsPage,
2711
2711
  path: "/swaps"
@@ -2714,14 +2714,14 @@ const routeModule = {
2714
2714
  Component: PaymentDetailPage,
2715
2715
  path: "/payments/:id"
2716
2716
  },
2717
- {
2718
- Component: RefundDetailPage,
2719
- path: "/refunds/:id"
2720
- },
2721
2717
  {
2722
2718
  Component: ReturnDetailPage,
2723
2719
  path: "/returns/:id"
2724
2720
  },
2721
+ {
2722
+ Component: RefundDetailPage,
2723
+ path: "/refunds/:id"
2724
+ },
2725
2725
  {
2726
2726
  Component: SwapDetailPage,
2727
2727
  path: "/swaps/:id"
@@ -2737,14 +2737,14 @@ const menuItemModule = {
2737
2737
  nested: void 0
2738
2738
  },
2739
2739
  {
2740
- label: config$6.label,
2741
- icon: config$6.icon,
2740
+ label: config$5.label,
2741
+ icon: config$5.icon,
2742
2742
  path: "/refunds",
2743
2743
  nested: void 0
2744
2744
  },
2745
2745
  {
2746
- label: config$5.label,
2747
- icon: config$5.icon,
2746
+ label: config$6.label,
2747
+ icon: config$6.icon,
2748
2748
  path: "/returns",
2749
2749
  nested: void 0
2750
2750
  },
@@ -2761,14 +2761,14 @@ const menuItemModule = {
2761
2761
  nested: void 0
2762
2762
  },
2763
2763
  {
2764
- label: config$2.label,
2765
- icon: config$2.icon,
2764
+ label: config$1.label,
2765
+ icon: config$1.icon,
2766
2766
  path: "/refunds/:id",
2767
2767
  nested: void 0
2768
2768
  },
2769
2769
  {
2770
- label: config$1.label,
2771
- icon: config$1.icon,
2770
+ label: config$2.label,
2771
+ icon: config$2.icon,
2772
2772
  path: "/returns/:id",
2773
2773
  nested: void 0
2774
2774
  },