order-management 0.0.76 → 0.0.78
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.
- package/.medusa/server/src/admin/index.js +600 -600
- package/.medusa/server/src/admin/index.mjs +601 -601
- package/.medusa/server/src/config.js +2 -1
- package/.medusa/server/src/subscribers/order-fulfilled.js +260 -1
- package/.medusa/server/src/workflows/steps/send-notification-step.js +1 -35
- package/README.md +7 -0
- package/package.json +1 -1
|
@@ -1161,144 +1161,188 @@ const useDebounce$2 = (value, delay) => {
|
|
|
1161
1161
|
return debouncedValue;
|
|
1162
1162
|
};
|
|
1163
1163
|
const getStatusBadgeClass$6 = (status) => {
|
|
1164
|
-
const
|
|
1165
|
-
if (
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
if (
|
|
1164
|
+
const statusLower = status.toLowerCase();
|
|
1165
|
+
if (statusLower === "requested") {
|
|
1166
|
+
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
1167
|
+
}
|
|
1168
|
+
if (statusLower === "approved") {
|
|
1169
|
+
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
1170
|
+
}
|
|
1171
|
+
if (statusLower === "rejected") {
|
|
1172
|
+
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
1173
|
+
}
|
|
1174
|
+
if (statusLower === "completed") {
|
|
1175
|
+
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1176
|
+
}
|
|
1177
|
+
if (statusLower === "cancelled") {
|
|
1178
|
+
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
1179
|
+
}
|
|
1169
1180
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
1170
1181
|
};
|
|
1171
|
-
const
|
|
1182
|
+
const SwapsPage = () => {
|
|
1172
1183
|
const navigate = reactRouterDom.useNavigate();
|
|
1173
1184
|
const [items, setItems] = react.useState([]);
|
|
1174
1185
|
const [statusFilter, setStatusFilter] = react.useState("all");
|
|
1175
|
-
const [
|
|
1176
|
-
const
|
|
1186
|
+
const [createdByFilter, setCreatedByFilter] = react.useState("all");
|
|
1187
|
+
const [searchQuery, setSearchQuery] = react.useState("");
|
|
1188
|
+
const debouncedSearchQuery = useDebounce$2(searchQuery, 300);
|
|
1177
1189
|
const [isLoading, setIsLoading] = react.useState(true);
|
|
1178
1190
|
const [isFetchingMore, setIsFetchingMore] = react.useState(false);
|
|
1179
1191
|
const [error, setError] = react.useState(null);
|
|
1180
1192
|
const [offset, setOffset] = react.useState(0);
|
|
1181
1193
|
const [count, setCount] = react.useState(0);
|
|
1182
1194
|
const limit = 50;
|
|
1183
|
-
const
|
|
1184
|
-
async (nextOffset, replace) => {
|
|
1195
|
+
const loadSwaps = react.useCallback(
|
|
1196
|
+
async (nextOffset, replace = false) => {
|
|
1197
|
+
var _a;
|
|
1185
1198
|
try {
|
|
1186
|
-
if (replace)
|
|
1187
|
-
|
|
1199
|
+
if (replace) {
|
|
1200
|
+
setIsLoading(true);
|
|
1201
|
+
} else {
|
|
1202
|
+
setIsFetchingMore(true);
|
|
1203
|
+
}
|
|
1188
1204
|
setError(null);
|
|
1189
1205
|
const params = new URLSearchParams();
|
|
1190
1206
|
params.set("limit", String(limit));
|
|
1191
1207
|
params.set("offset", String(nextOffset));
|
|
1192
|
-
if (statusFilter !== "all")
|
|
1193
|
-
|
|
1208
|
+
if (statusFilter !== "all") {
|
|
1209
|
+
params.set("status", statusFilter);
|
|
1210
|
+
}
|
|
1211
|
+
if (debouncedSearchQuery.trim()) {
|
|
1212
|
+
params.set("order_id", debouncedSearchQuery.trim());
|
|
1213
|
+
}
|
|
1214
|
+
if (createdByFilter !== "all") {
|
|
1215
|
+
params.set("created_by", createdByFilter);
|
|
1216
|
+
}
|
|
1194
1217
|
const response = await fetch(
|
|
1195
|
-
`/admin/
|
|
1218
|
+
`/admin/swaps?${params.toString()}`,
|
|
1196
1219
|
{ credentials: "include" }
|
|
1197
1220
|
);
|
|
1198
1221
|
if (!response.ok) {
|
|
1199
|
-
const
|
|
1200
|
-
throw new Error(
|
|
1222
|
+
const message = await response.text();
|
|
1223
|
+
throw new Error(message || "Unable to load swaps");
|
|
1201
1224
|
}
|
|
1202
1225
|
const payload = await response.json();
|
|
1203
|
-
const list = payload.transactions ?? [];
|
|
1204
1226
|
setCount(payload.count ?? 0);
|
|
1205
|
-
setOffset(nextOffset +
|
|
1206
|
-
setItems(
|
|
1207
|
-
|
|
1208
|
-
|
|
1227
|
+
setOffset(nextOffset + (((_a = payload.swaps) == null ? void 0 : _a.length) ?? 0));
|
|
1228
|
+
setItems(
|
|
1229
|
+
(prev) => replace ? payload.swaps ?? [] : [...prev, ...payload.swaps ?? []]
|
|
1230
|
+
);
|
|
1231
|
+
} catch (loadError) {
|
|
1232
|
+
const message = loadError instanceof Error ? loadError.message : "Unable to load swaps";
|
|
1233
|
+
setError(message);
|
|
1209
1234
|
} finally {
|
|
1210
1235
|
setIsLoading(false);
|
|
1211
1236
|
setIsFetchingMore(false);
|
|
1212
1237
|
}
|
|
1213
1238
|
},
|
|
1214
|
-
[statusFilter,
|
|
1239
|
+
[statusFilter, createdByFilter, debouncedSearchQuery]
|
|
1215
1240
|
);
|
|
1216
1241
|
react.useEffect(() => {
|
|
1217
|
-
void
|
|
1218
|
-
}, [
|
|
1242
|
+
void loadSwaps(0, true);
|
|
1243
|
+
}, [statusFilter, createdByFilter, debouncedSearchQuery, loadSwaps]);
|
|
1219
1244
|
const hasMore = react.useMemo(() => offset < count, [offset, count]);
|
|
1220
|
-
const
|
|
1221
|
-
const
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
const code = (t.currency_code ?? "USD").toUpperCase();
|
|
1226
|
-
return `${code} ${Number(t.amount)}`;
|
|
1227
|
-
};
|
|
1245
|
+
const availableStatuses = react.useMemo(() => {
|
|
1246
|
+
const statuses = /* @__PURE__ */ new Set();
|
|
1247
|
+
items.forEach((item) => statuses.add(item.status));
|
|
1248
|
+
return Array.from(statuses).sort();
|
|
1249
|
+
}, [items]);
|
|
1228
1250
|
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: [
|
|
1229
1251
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1230
1252
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1231
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "
|
|
1232
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
1253
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Exchanges" }),
|
|
1254
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer exchange requests" })
|
|
1233
1255
|
] }),
|
|
1234
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () =>
|
|
1256
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadSwaps(0, true), children: "Refresh" })
|
|
1235
1257
|
] }),
|
|
1236
1258
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1237
1259
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1238
1260
|
ui.Input,
|
|
1239
1261
|
{
|
|
1240
|
-
placeholder: "Search by
|
|
1241
|
-
value:
|
|
1242
|
-
onChange: (
|
|
1243
|
-
className: "md:max-w-sm"
|
|
1244
|
-
"aria-label": "Search by order ID"
|
|
1262
|
+
placeholder: "Search by swap ID or order ID",
|
|
1263
|
+
value: searchQuery,
|
|
1264
|
+
onChange: (event) => setSearchQuery(event.target.value),
|
|
1265
|
+
className: "md:max-w-sm"
|
|
1245
1266
|
}
|
|
1246
1267
|
),
|
|
1247
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1268
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
|
|
1269
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1270
|
+
"select",
|
|
1271
|
+
{
|
|
1272
|
+
value: createdByFilter,
|
|
1273
|
+
onChange: (event) => setCreatedByFilter(event.target.value),
|
|
1274
|
+
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",
|
|
1275
|
+
children: [
|
|
1276
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All (Created by)" }),
|
|
1277
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "customer", children: "Customer" }),
|
|
1278
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "admin", children: "Admin" })
|
|
1279
|
+
]
|
|
1280
|
+
}
|
|
1281
|
+
),
|
|
1282
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1283
|
+
"select",
|
|
1284
|
+
{
|
|
1285
|
+
value: statusFilter,
|
|
1286
|
+
onChange: (event) => setStatusFilter(event.target.value),
|
|
1287
|
+
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",
|
|
1288
|
+
children: [
|
|
1289
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All Statuses" }),
|
|
1290
|
+
availableStatuses.map((status) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
|
|
1291
|
+
]
|
|
1292
|
+
}
|
|
1293
|
+
)
|
|
1294
|
+
] })
|
|
1265
1295
|
] }),
|
|
1266
1296
|
error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
1267
1297
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
1268
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1298
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1299
|
+
ui.Button,
|
|
1300
|
+
{
|
|
1301
|
+
variant: "secondary",
|
|
1302
|
+
onClick: () => loadSwaps(0, true),
|
|
1303
|
+
children: "Try again"
|
|
1304
|
+
}
|
|
1305
|
+
) })
|
|
1269
1306
|
] }) : null,
|
|
1270
|
-
isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading
|
|
1271
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No
|
|
1272
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "
|
|
1307
|
+
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: [
|
|
1308
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No exchanges yet" }),
|
|
1309
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Exchange requests created by customers will appear here." })
|
|
1273
1310
|
] }) : /* @__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: [
|
|
1274
1311
|
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1312
|
+
/* @__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" }),
|
|
1275
1313
|
/* @__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" }),
|
|
1276
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Amount" }),
|
|
1277
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Provider" }),
|
|
1278
1314
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
|
|
1279
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "
|
|
1315
|
+
/* @__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" }),
|
|
1280
1316
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
1281
1317
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
1282
1318
|
] }) }),
|
|
1283
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((
|
|
1319
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((swap) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1284
1320
|
"tr",
|
|
1285
1321
|
{
|
|
1286
1322
|
className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
|
|
1287
|
-
onClick: () => navigate(`/
|
|
1323
|
+
onClick: () => navigate(`/swaps/${swap.id}`),
|
|
1288
1324
|
children: [
|
|
1289
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children:
|
|
1290
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children:
|
|
1291
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: t.provider_id }),
|
|
1325
|
+
/* @__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 }) }) }),
|
|
1326
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: swap.order_id }),
|
|
1292
1327
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1293
1328
|
ui.Badge,
|
|
1294
1329
|
{
|
|
1295
1330
|
size: "2xsmall",
|
|
1296
|
-
className: `uppercase ${getStatusBadgeClass$6(
|
|
1297
|
-
children:
|
|
1331
|
+
className: `uppercase ${getStatusBadgeClass$6(swap.status)}`,
|
|
1332
|
+
children: swap.status.replace(/_/g, " ")
|
|
1298
1333
|
}
|
|
1299
1334
|
) }),
|
|
1300
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children:
|
|
1301
|
-
|
|
1335
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
|
|
1336
|
+
const amount = swap.difference_due;
|
|
1337
|
+
if (amount == null || amount === void 0) {
|
|
1338
|
+
return "—";
|
|
1339
|
+
}
|
|
1340
|
+
const displayAmount = Number(amount) / 100;
|
|
1341
|
+
const currency = swap.currency_code || "$";
|
|
1342
|
+
const sign = displayAmount >= 0 ? "+" : "";
|
|
1343
|
+
return `${sign}${currency}${displayAmount.toFixed(2)}`;
|
|
1344
|
+
})() }),
|
|
1345
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(swap.created_at).toLocaleDateString("en-US", {
|
|
1302
1346
|
year: "numeric",
|
|
1303
1347
|
month: "short",
|
|
1304
1348
|
day: "numeric",
|
|
@@ -1306,35 +1350,21 @@ const PaymentsPage = () => {
|
|
|
1306
1350
|
minute: "2-digit",
|
|
1307
1351
|
hour12: true
|
|
1308
1352
|
}) }),
|
|
1309
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
),
|
|
1322
|
-
t.order_id ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1323
|
-
ui.Button,
|
|
1324
|
-
{
|
|
1325
|
-
variant: "transparent",
|
|
1326
|
-
size: "small",
|
|
1327
|
-
onClick: (e) => {
|
|
1328
|
-
e.stopPropagation();
|
|
1329
|
-
navigate(`/orders/${t.order_id}`);
|
|
1330
|
-
},
|
|
1331
|
-
children: "Order"
|
|
1332
|
-
}
|
|
1333
|
-
) : null
|
|
1334
|
-
] })
|
|
1353
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1354
|
+
ui.Button,
|
|
1355
|
+
{
|
|
1356
|
+
variant: "transparent",
|
|
1357
|
+
size: "small",
|
|
1358
|
+
onClick: (e) => {
|
|
1359
|
+
e.stopPropagation();
|
|
1360
|
+
navigate(`/app/orders/${swap.order_id}`);
|
|
1361
|
+
},
|
|
1362
|
+
children: "Go to order"
|
|
1363
|
+
}
|
|
1364
|
+
) })
|
|
1335
1365
|
]
|
|
1336
1366
|
},
|
|
1337
|
-
|
|
1367
|
+
swap.id
|
|
1338
1368
|
)) })
|
|
1339
1369
|
] }) }),
|
|
1340
1370
|
hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1342,15 +1372,15 @@ const PaymentsPage = () => {
|
|
|
1342
1372
|
{
|
|
1343
1373
|
variant: "secondary",
|
|
1344
1374
|
isLoading: isFetchingMore,
|
|
1345
|
-
onClick: () =>
|
|
1375
|
+
onClick: () => loadSwaps(offset, false),
|
|
1346
1376
|
children: "Load more"
|
|
1347
1377
|
}
|
|
1348
1378
|
) }) : null
|
|
1349
1379
|
] }) });
|
|
1350
1380
|
};
|
|
1351
1381
|
const config$6 = adminSdk.defineRouteConfig({
|
|
1352
|
-
label: "
|
|
1353
|
-
icon: icons.
|
|
1382
|
+
label: "Exchanges",
|
|
1383
|
+
icon: icons.ArrowPath
|
|
1354
1384
|
});
|
|
1355
1385
|
const useDebounce$1 = (value, delay) => {
|
|
1356
1386
|
const [debouncedValue, setDebouncedValue] = react.useState(value);
|
|
@@ -1593,188 +1623,144 @@ const useDebounce = (value, delay) => {
|
|
|
1593
1623
|
return debouncedValue;
|
|
1594
1624
|
};
|
|
1595
1625
|
const getStatusBadgeClass$4 = (status) => {
|
|
1596
|
-
const
|
|
1597
|
-
if (
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
if (
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
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();
|
|
1626
|
+
const s2 = status.toLowerCase();
|
|
1627
|
+
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1628
|
+
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
1629
|
+
if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
1630
|
+
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
1631
|
+
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
1632
|
+
};
|
|
1633
|
+
const PaymentsPage = () => {
|
|
1634
|
+
const navigate = reactRouterDom.useNavigate();
|
|
1616
1635
|
const [items, setItems] = react.useState([]);
|
|
1617
1636
|
const [statusFilter, setStatusFilter] = react.useState("all");
|
|
1618
|
-
const [
|
|
1619
|
-
const
|
|
1620
|
-
const debouncedSearchQuery = useDebounce(searchQuery, 300);
|
|
1637
|
+
const [orderIdSearch, setOrderIdSearch] = react.useState("");
|
|
1638
|
+
const debouncedOrderId = useDebounce(orderIdSearch, 300);
|
|
1621
1639
|
const [isLoading, setIsLoading] = react.useState(true);
|
|
1622
1640
|
const [isFetchingMore, setIsFetchingMore] = react.useState(false);
|
|
1623
1641
|
const [error, setError] = react.useState(null);
|
|
1624
1642
|
const [offset, setOffset] = react.useState(0);
|
|
1625
1643
|
const [count, setCount] = react.useState(0);
|
|
1626
1644
|
const limit = 50;
|
|
1627
|
-
const
|
|
1628
|
-
async (nextOffset, replace
|
|
1629
|
-
var _a;
|
|
1645
|
+
const loadTransactions = react.useCallback(
|
|
1646
|
+
async (nextOffset, replace) => {
|
|
1630
1647
|
try {
|
|
1631
|
-
if (replace)
|
|
1632
|
-
|
|
1633
|
-
} else {
|
|
1634
|
-
setIsFetchingMore(true);
|
|
1635
|
-
}
|
|
1648
|
+
if (replace) setIsLoading(true);
|
|
1649
|
+
else setIsFetchingMore(true);
|
|
1636
1650
|
setError(null);
|
|
1637
1651
|
const params = new URLSearchParams();
|
|
1638
1652
|
params.set("limit", String(limit));
|
|
1639
1653
|
params.set("offset", String(nextOffset));
|
|
1640
|
-
if (statusFilter !== "all")
|
|
1641
|
-
|
|
1642
|
-
}
|
|
1643
|
-
if (debouncedSearchQuery.trim()) {
|
|
1644
|
-
params.set("order_id", debouncedSearchQuery.trim());
|
|
1645
|
-
}
|
|
1646
|
-
if (createdByFilter !== "all") {
|
|
1647
|
-
params.set("created_by", createdByFilter);
|
|
1648
|
-
}
|
|
1654
|
+
if (statusFilter !== "all") params.set("status", statusFilter);
|
|
1655
|
+
if (debouncedOrderId.trim()) params.set("order_id", debouncedOrderId.trim());
|
|
1649
1656
|
const response = await fetch(
|
|
1650
|
-
`/admin/
|
|
1657
|
+
`/admin/payment-transactions?${params.toString()}`,
|
|
1651
1658
|
{ credentials: "include" }
|
|
1652
1659
|
);
|
|
1653
1660
|
if (!response.ok) {
|
|
1654
|
-
const
|
|
1655
|
-
throw new Error(
|
|
1661
|
+
const text = await response.text();
|
|
1662
|
+
throw new Error(text || "Failed to load payment transactions");
|
|
1656
1663
|
}
|
|
1657
1664
|
const payload = await response.json();
|
|
1665
|
+
const list = payload.transactions ?? [];
|
|
1658
1666
|
setCount(payload.count ?? 0);
|
|
1659
|
-
setOffset(nextOffset +
|
|
1660
|
-
setItems(
|
|
1661
|
-
|
|
1662
|
-
);
|
|
1663
|
-
} catch (loadError) {
|
|
1664
|
-
const message = loadError instanceof Error ? loadError.message : "Unable to load swaps";
|
|
1665
|
-
setError(message);
|
|
1667
|
+
setOffset(nextOffset + list.length);
|
|
1668
|
+
setItems((prev) => replace ? list : [...prev, ...list]);
|
|
1669
|
+
} catch (e) {
|
|
1670
|
+
setError(e instanceof Error ? e.message : "Failed to load");
|
|
1666
1671
|
} finally {
|
|
1667
1672
|
setIsLoading(false);
|
|
1668
1673
|
setIsFetchingMore(false);
|
|
1669
1674
|
}
|
|
1670
1675
|
},
|
|
1671
|
-
[statusFilter,
|
|
1676
|
+
[statusFilter, debouncedOrderId]
|
|
1672
1677
|
);
|
|
1673
1678
|
react.useEffect(() => {
|
|
1674
|
-
void
|
|
1675
|
-
}, [
|
|
1679
|
+
void loadTransactions(0, true);
|
|
1680
|
+
}, [loadTransactions]);
|
|
1676
1681
|
const hasMore = react.useMemo(() => offset < count, [offset, count]);
|
|
1677
|
-
const
|
|
1678
|
-
const
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
+
const displayStatus = (t) => {
|
|
1683
|
+
const s2 = t.payment_id != null && t.payment_status != null && t.payment_status !== "" ? t.payment_status : t.session_status ?? "";
|
|
1684
|
+
return s2 !== "" ? s2 : "—";
|
|
1685
|
+
};
|
|
1686
|
+
const displayAmount = (t) => {
|
|
1687
|
+
const code = (t.currency_code ?? "USD").toUpperCase();
|
|
1688
|
+
return `${code} ${Number(t.amount)}`;
|
|
1689
|
+
};
|
|
1682
1690
|
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
1691
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1684
1692
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1685
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "
|
|
1686
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
1693
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Payments" }),
|
|
1694
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "All payment attempts — completed, pending, failed, requires action" })
|
|
1687
1695
|
] }),
|
|
1688
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () =>
|
|
1696
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadTransactions(0, true), children: "Refresh" })
|
|
1689
1697
|
] }),
|
|
1690
1698
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1691
1699
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1692
1700
|
ui.Input,
|
|
1693
1701
|
{
|
|
1694
|
-
placeholder: "Search by
|
|
1695
|
-
value:
|
|
1696
|
-
onChange: (
|
|
1697
|
-
className: "md:max-w-sm"
|
|
1702
|
+
placeholder: "Search by Order ID",
|
|
1703
|
+
value: orderIdSearch,
|
|
1704
|
+
onChange: (e) => setOrderIdSearch(e.target.value),
|
|
1705
|
+
className: "md:max-w-sm",
|
|
1706
|
+
"aria-label": "Search by order ID"
|
|
1698
1707
|
}
|
|
1699
1708
|
),
|
|
1700
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1701
|
-
|
|
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,
|
|
1709
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1710
|
+
"select",
|
|
1732
1711
|
{
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1712
|
+
value: statusFilter,
|
|
1713
|
+
onChange: (e) => setStatusFilter(e.target.value),
|
|
1714
|
+
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",
|
|
1715
|
+
"aria-label": "Filter by status",
|
|
1716
|
+
children: [
|
|
1717
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All statuses" }),
|
|
1718
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "pending", children: "Pending" }),
|
|
1719
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "requires_more", children: "Requires more" }),
|
|
1720
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "error", children: "Error" }),
|
|
1721
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "canceled", children: "Canceled" }),
|
|
1722
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "authorized", children: "Authorized" }),
|
|
1723
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "captured", children: "Captured" })
|
|
1724
|
+
]
|
|
1736
1725
|
}
|
|
1737
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(ui.Button, { variant: "secondary", onClick: () => loadTransactions(0, true), children: "Try again" }) })
|
|
1738
1731
|
] }) : null,
|
|
1739
|
-
isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading
|
|
1740
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No
|
|
1741
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "
|
|
1732
|
+
isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading payments…" }) }) : items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
|
|
1733
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No payment transactions yet" }),
|
|
1734
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Payment attempts will appear here." })
|
|
1742
1735
|
] }) : /* @__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
1736
|
/* @__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
1737
|
/* @__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" }),
|
|
1738
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Amount" }),
|
|
1739
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Provider" }),
|
|
1746
1740
|
/* @__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: "
|
|
1741
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Finalized" }),
|
|
1748
1742
|
/* @__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
1743
|
/* @__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
1744
|
] }) }),
|
|
1751
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((
|
|
1745
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((t) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1752
1746
|
"tr",
|
|
1753
1747
|
{
|
|
1754
1748
|
className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
|
|
1755
|
-
onClick: () => navigate(`/
|
|
1749
|
+
onClick: () => navigate(`/payments/${t.payment_session_id}`),
|
|
1756
1750
|
children: [
|
|
1757
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children:
|
|
1758
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children:
|
|
1751
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: t.order_id ?? "—" }),
|
|
1752
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: displayAmount(t) }),
|
|
1753
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: t.provider_id }),
|
|
1759
1754
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1760
1755
|
ui.Badge,
|
|
1761
1756
|
{
|
|
1762
1757
|
size: "2xsmall",
|
|
1763
|
-
className: `uppercase ${getStatusBadgeClass$4(
|
|
1764
|
-
children:
|
|
1758
|
+
className: `uppercase ${getStatusBadgeClass$4(displayStatus(t))}`,
|
|
1759
|
+
children: displayStatus(t) !== "—" ? displayStatus(t).replace(/_/g, " ") : "—"
|
|
1765
1760
|
}
|
|
1766
1761
|
) }),
|
|
1767
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children:
|
|
1768
|
-
|
|
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", {
|
|
1762
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: t.payment_id != null ? "Yes" : "No" }),
|
|
1763
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(t.created_at).toLocaleDateString("en-US", {
|
|
1778
1764
|
year: "numeric",
|
|
1779
1765
|
month: "short",
|
|
1780
1766
|
day: "numeric",
|
|
@@ -1782,21 +1768,35 @@ const SwapsPage = () => {
|
|
|
1782
1768
|
minute: "2-digit",
|
|
1783
1769
|
hour12: true
|
|
1784
1770
|
}) }),
|
|
1785
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
e
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1771
|
+
/* @__PURE__ */ jsxRuntime.jsxs("td", { className: "px-4 py-4", children: [
|
|
1772
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1773
|
+
ui.Button,
|
|
1774
|
+
{
|
|
1775
|
+
variant: "transparent",
|
|
1776
|
+
size: "small",
|
|
1777
|
+
onClick: (e) => {
|
|
1778
|
+
e.stopPropagation();
|
|
1779
|
+
navigate(`/payments/${t.payment_session_id}`);
|
|
1780
|
+
},
|
|
1781
|
+
children: "View details"
|
|
1782
|
+
}
|
|
1783
|
+
),
|
|
1784
|
+
t.order_id ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1785
|
+
ui.Button,
|
|
1786
|
+
{
|
|
1787
|
+
variant: "transparent",
|
|
1788
|
+
size: "small",
|
|
1789
|
+
onClick: (e) => {
|
|
1790
|
+
e.stopPropagation();
|
|
1791
|
+
navigate(`/orders/${t.order_id}`);
|
|
1792
|
+
},
|
|
1793
|
+
children: "Order"
|
|
1794
|
+
}
|
|
1795
|
+
) : null
|
|
1796
|
+
] })
|
|
1797
1797
|
]
|
|
1798
1798
|
},
|
|
1799
|
-
|
|
1799
|
+
t.payment_session_id
|
|
1800
1800
|
)) })
|
|
1801
1801
|
] }) }),
|
|
1802
1802
|
hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1804,15 +1804,15 @@ const SwapsPage = () => {
|
|
|
1804
1804
|
{
|
|
1805
1805
|
variant: "secondary",
|
|
1806
1806
|
isLoading: isFetchingMore,
|
|
1807
|
-
onClick: () =>
|
|
1807
|
+
onClick: () => loadTransactions(offset, false),
|
|
1808
1808
|
children: "Load more"
|
|
1809
1809
|
}
|
|
1810
1810
|
) }) : null
|
|
1811
1811
|
] }) });
|
|
1812
1812
|
};
|
|
1813
1813
|
const config$4 = adminSdk.defineRouteConfig({
|
|
1814
|
-
label: "
|
|
1815
|
-
icon: icons.
|
|
1814
|
+
label: "Payments",
|
|
1815
|
+
icon: icons.CreditCard
|
|
1816
1816
|
});
|
|
1817
1817
|
const getStatusBadgeClass$3 = (status) => {
|
|
1818
1818
|
const s2 = status.toLowerCase();
|
|
@@ -2007,234 +2007,119 @@ const config$3 = adminSdk.defineRouteConfig({
|
|
|
2007
2007
|
icon: icons.Receipt
|
|
2008
2008
|
});
|
|
2009
2009
|
const getStatusBadgeClass$2 = (status) => {
|
|
2010
|
-
const
|
|
2011
|
-
if (
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
if (
|
|
2010
|
+
const statusLower = status.toLowerCase();
|
|
2011
|
+
if (statusLower === "requested") {
|
|
2012
|
+
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
2013
|
+
}
|
|
2014
|
+
if (statusLower === "approved") {
|
|
2015
|
+
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
2016
|
+
}
|
|
2017
|
+
if (statusLower === "rejected") {
|
|
2018
|
+
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
2019
|
+
}
|
|
2020
|
+
if (statusLower === "completed") {
|
|
2021
|
+
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
2022
|
+
}
|
|
2023
|
+
if (statusLower === "cancelled" || statusLower === "canceled") {
|
|
2024
|
+
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
2025
|
+
}
|
|
2026
|
+
if (statusLower === "pending") {
|
|
2027
|
+
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
2028
|
+
}
|
|
2015
2029
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
2016
2030
|
};
|
|
2017
|
-
const
|
|
2018
|
-
var _a;
|
|
2019
|
-
const navigate = reactRouterDom.useNavigate();
|
|
2020
|
-
const params = reactRouterDom.useParams();
|
|
2021
|
-
const id = (_a = params == null ? void 0 : params.id) == null ? void 0 : _a.trim();
|
|
2022
|
-
const [detail, setDetail] = react.useState(null);
|
|
2023
|
-
const [loading, setLoading] = react.useState(!!id);
|
|
2024
|
-
const [error, setError] = react.useState(null);
|
|
2025
|
-
react.useEffect(() => {
|
|
2026
|
-
if (!id) {
|
|
2027
|
-
setLoading(false);
|
|
2028
|
-
return;
|
|
2029
|
-
}
|
|
2030
|
-
let cancelled = false;
|
|
2031
|
-
setLoading(true);
|
|
2032
|
-
setError(null);
|
|
2033
|
-
fetch(`/admin/payment-transactions/${id}`, { credentials: "include" }).then((res) => {
|
|
2034
|
-
if (!res.ok) throw new Error(res.statusText || "Failed to load");
|
|
2035
|
-
return res.json();
|
|
2036
|
-
}).then((data) => {
|
|
2037
|
-
if (!cancelled) setDetail(data);
|
|
2038
|
-
}).catch((e) => {
|
|
2039
|
-
if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
|
|
2040
|
-
}).finally(() => {
|
|
2041
|
-
if (!cancelled) setLoading(false);
|
|
2042
|
-
});
|
|
2043
|
-
return () => {
|
|
2044
|
-
cancelled = true;
|
|
2045
|
-
};
|
|
2046
|
-
}, [id]);
|
|
2047
|
-
const displayStatus = detail ? (detail.payment_id != null && detail.payment_status != null && detail.payment_status !== "" ? detail.payment_status : detail.session_status ?? "") || "—" : "";
|
|
2048
|
-
const sessionStatusRaw = (detail == null ? void 0 : detail.session_status) ?? "—";
|
|
2049
|
-
const paymentStatusRaw = (detail == null ? void 0 : detail.payment_id) != null ? (detail == null ? void 0 : detail.payment_status) ?? "—" : "—";
|
|
2050
|
-
const displayAmount = detail ? `${(detail.currency_code ?? "USD").toUpperCase()} ${Number(detail.amount)}` : "";
|
|
2051
|
-
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: [
|
|
2052
|
-
/* @__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: [
|
|
2053
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => navigate("/payments"), children: "← Payments" }),
|
|
2054
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Payment session" }),
|
|
2055
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: id ?? "—" })
|
|
2056
|
-
] }) }),
|
|
2057
|
-
error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
2058
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
2059
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/payments"), children: "Back to list" })
|
|
2060
|
-
] }) : 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: [
|
|
2061
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl border border-ui-border-base p-6 flex flex-col gap-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
2062
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2063
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Order ID" }),
|
|
2064
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: detail.order_id ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2065
|
-
ui.Button,
|
|
2066
|
-
{
|
|
2067
|
-
variant: "transparent",
|
|
2068
|
-
size: "small",
|
|
2069
|
-
onClick: () => navigate(`/orders/${detail.order_id}`),
|
|
2070
|
-
children: detail.order_id
|
|
2071
|
-
}
|
|
2072
|
-
) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "—" }) })
|
|
2073
|
-
] }),
|
|
2074
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2075
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
|
|
2076
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: displayAmount })
|
|
2077
|
-
] }),
|
|
2078
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2079
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
|
|
2080
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.provider_id })
|
|
2081
|
-
] }),
|
|
2082
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2083
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
|
|
2084
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2085
|
-
ui.Badge,
|
|
2086
|
-
{
|
|
2087
|
-
size: "2xsmall",
|
|
2088
|
-
className: `uppercase ${getStatusBadgeClass$2(displayStatus)}`,
|
|
2089
|
-
children: displayStatus !== "—" ? displayStatus.replace(/_/g, " ") : "—"
|
|
2090
|
-
}
|
|
2091
|
-
) })
|
|
2092
|
-
] }),
|
|
2093
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2094
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Session status (DB)" }),
|
|
2095
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: sessionStatusRaw })
|
|
2096
|
-
] }),
|
|
2097
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2098
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Payment status (DB)" }),
|
|
2099
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: paymentStatusRaw })
|
|
2100
|
-
] }),
|
|
2101
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2102
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Finalized" }),
|
|
2103
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.payment_id != null ? "Yes" : "No" })
|
|
2104
|
-
] }),
|
|
2105
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2106
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created" }),
|
|
2107
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: new Date(detail.created_at).toLocaleDateString("en-US", {
|
|
2108
|
-
year: "numeric",
|
|
2109
|
-
month: "short",
|
|
2110
|
-
day: "numeric",
|
|
2111
|
-
hour: "numeric",
|
|
2112
|
-
minute: "2-digit",
|
|
2113
|
-
hour12: true
|
|
2114
|
-
}) })
|
|
2115
|
-
] })
|
|
2116
|
-
] }) }),
|
|
2117
|
-
Object.keys(detail.data ?? {}).length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2118
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Provider data" }),
|
|
2119
|
-
/* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-xs bg-ui-bg-subtle p-4 rounded-lg overflow-auto max-h-96", children: JSON.stringify(detail.data, null, 2) })
|
|
2120
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl border border-ui-border-base p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No provider data for this session." }) })
|
|
2121
|
-
] }) : null
|
|
2122
|
-
] }) });
|
|
2123
|
-
};
|
|
2124
|
-
const config$2 = adminSdk.defineRouteConfig({
|
|
2125
|
-
label: "Payment details",
|
|
2126
|
-
icon: icons.CreditCard
|
|
2127
|
-
});
|
|
2128
|
-
const getStatusBadgeClass$1 = (status) => {
|
|
2129
|
-
const statusLower = status.toLowerCase();
|
|
2130
|
-
if (statusLower === "requested") {
|
|
2131
|
-
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
2132
|
-
}
|
|
2133
|
-
if (statusLower === "approved") {
|
|
2134
|
-
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
2135
|
-
}
|
|
2136
|
-
if (statusLower === "rejected") {
|
|
2137
|
-
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
2138
|
-
}
|
|
2139
|
-
if (statusLower === "received") {
|
|
2140
|
-
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
2141
|
-
}
|
|
2142
|
-
if (statusLower === "refunded") {
|
|
2143
|
-
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
2144
|
-
}
|
|
2145
|
-
if (statusLower === "completed") {
|
|
2146
|
-
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
2147
|
-
}
|
|
2148
|
-
if (statusLower === "cancelled") {
|
|
2149
|
-
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
2150
|
-
}
|
|
2151
|
-
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
2152
|
-
};
|
|
2153
|
-
const ReturnDetailPage = () => {
|
|
2154
|
-
var _a, _b;
|
|
2031
|
+
const SwapDetailPage = () => {
|
|
2032
|
+
var _a, _b, _c;
|
|
2155
2033
|
const navigate = reactRouterDom.useNavigate();
|
|
2156
2034
|
const { id } = reactRouterDom.useParams();
|
|
2157
|
-
const [
|
|
2035
|
+
const [swap, setSwap] = react.useState(null);
|
|
2036
|
+
const [order, setOrder] = react.useState(null);
|
|
2158
2037
|
const [isLoading, setIsLoading] = react.useState(true);
|
|
2159
|
-
|
|
2038
|
+
react.useState(false);
|
|
2039
|
+
const [isCancelling, setIsCancelling] = react.useState(false);
|
|
2160
2040
|
const [error, setError] = react.useState(null);
|
|
2161
2041
|
const [updateError, setUpdateError] = react.useState(null);
|
|
2162
2042
|
const [updateSuccess, setUpdateSuccess] = react.useState(false);
|
|
2163
2043
|
react.useEffect(() => {
|
|
2164
2044
|
if (!id) {
|
|
2165
|
-
navigate("/
|
|
2045
|
+
navigate("/swaps");
|
|
2166
2046
|
return;
|
|
2167
2047
|
}
|
|
2168
|
-
const
|
|
2048
|
+
const loadSwap = async () => {
|
|
2169
2049
|
try {
|
|
2170
2050
|
setIsLoading(true);
|
|
2171
2051
|
setError(null);
|
|
2172
|
-
const response = await fetch(`/admin/
|
|
2052
|
+
const response = await fetch(`/admin/swaps/${id}`, {
|
|
2173
2053
|
credentials: "include"
|
|
2174
2054
|
});
|
|
2175
2055
|
if (!response.ok) {
|
|
2176
2056
|
const message = await response.text();
|
|
2177
|
-
throw new Error(message || "Unable to load
|
|
2057
|
+
throw new Error(message || "Unable to load swap");
|
|
2178
2058
|
}
|
|
2179
2059
|
const payload = await response.json();
|
|
2180
|
-
|
|
2060
|
+
setSwap(payload.swap);
|
|
2061
|
+
setOrder(payload.order || null);
|
|
2181
2062
|
} catch (loadError) {
|
|
2182
|
-
const message = loadError instanceof Error ? loadError.message : "Unable to load
|
|
2063
|
+
const message = loadError instanceof Error ? loadError.message : "Unable to load swap";
|
|
2183
2064
|
setError(message);
|
|
2184
2065
|
} finally {
|
|
2185
2066
|
setIsLoading(false);
|
|
2186
2067
|
}
|
|
2187
2068
|
};
|
|
2188
|
-
void
|
|
2069
|
+
void loadSwap();
|
|
2189
2070
|
}, [id, navigate]);
|
|
2190
|
-
const
|
|
2071
|
+
const handleCancelExchange = async () => {
|
|
2191
2072
|
if (!id) {
|
|
2192
2073
|
return;
|
|
2193
2074
|
}
|
|
2194
2075
|
try {
|
|
2195
|
-
|
|
2076
|
+
setIsCancelling(true);
|
|
2196
2077
|
setUpdateError(null);
|
|
2197
2078
|
setUpdateSuccess(false);
|
|
2198
|
-
const response = await fetch(`/admin/
|
|
2079
|
+
const response = await fetch(`/admin/swaps/${id}/cancel`, {
|
|
2199
2080
|
method: "POST",
|
|
2200
2081
|
headers: {
|
|
2201
2082
|
"Content-Type": "application/json"
|
|
2202
2083
|
},
|
|
2203
|
-
credentials: "include"
|
|
2204
|
-
body: JSON.stringify({ reason: "Rejected by admin" })
|
|
2084
|
+
credentials: "include"
|
|
2205
2085
|
});
|
|
2206
2086
|
if (!response.ok) {
|
|
2207
2087
|
const message = await response.text();
|
|
2208
|
-
throw new Error(message || "Unable to
|
|
2088
|
+
throw new Error(message || "Unable to cancel exchange");
|
|
2209
2089
|
}
|
|
2210
2090
|
const payload = await response.json();
|
|
2211
|
-
|
|
2091
|
+
setSwap(payload.swap);
|
|
2212
2092
|
setUpdateSuccess(true);
|
|
2213
2093
|
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
2214
|
-
const detailResponse = await fetch(`/admin/
|
|
2094
|
+
const detailResponse = await fetch(`/admin/swaps/${id}`, {
|
|
2215
2095
|
credentials: "include"
|
|
2216
2096
|
});
|
|
2217
2097
|
if (detailResponse.ok) {
|
|
2218
2098
|
const detailPayload = await detailResponse.json();
|
|
2219
|
-
|
|
2099
|
+
setSwap(detailPayload.swap);
|
|
2100
|
+
setOrder(detailPayload.order || null);
|
|
2220
2101
|
}
|
|
2221
|
-
} catch (
|
|
2222
|
-
const message =
|
|
2102
|
+
} catch (cancelErr) {
|
|
2103
|
+
const message = cancelErr instanceof Error ? cancelErr.message : "Unable to cancel exchange";
|
|
2223
2104
|
setUpdateError(message);
|
|
2224
2105
|
} finally {
|
|
2225
|
-
|
|
2106
|
+
setIsCancelling(false);
|
|
2226
2107
|
}
|
|
2227
2108
|
};
|
|
2109
|
+
const isOrderExchange = Boolean(swap == null ? void 0 : swap.exchange_id);
|
|
2110
|
+
const canCancelExchange = isOrderExchange && swap && !["cancelled", "canceled", "completed", "declined"].includes(
|
|
2111
|
+
((_a = swap.status) == null ? void 0 : _a.toLowerCase()) ?? ""
|
|
2112
|
+
);
|
|
2228
2113
|
if (isLoading) {
|
|
2229
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading
|
|
2114
|
+
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..." }) }) }) });
|
|
2230
2115
|
}
|
|
2231
|
-
if (error || !
|
|
2116
|
+
if (error || !swap) {
|
|
2232
2117
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
2233
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "
|
|
2234
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/
|
|
2118
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "Swap not found" }),
|
|
2119
|
+
/* @__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" }) })
|
|
2235
2120
|
] }) }) });
|
|
2236
2121
|
}
|
|
2237
|
-
const statusHistory = ((
|
|
2122
|
+
const statusHistory = ((_b = swap.metadata) == null ? void 0 : _b.status_history) || [];
|
|
2238
2123
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: [
|
|
2239
2124
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
|
|
2240
2125
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -2242,7 +2127,7 @@ const ReturnDetailPage = () => {
|
|
|
2242
2127
|
{
|
|
2243
2128
|
variant: "transparent",
|
|
2244
2129
|
size: "small",
|
|
2245
|
-
onClick: () => navigate("/
|
|
2130
|
+
onClick: () => navigate("/swaps"),
|
|
2246
2131
|
className: "w-fit",
|
|
2247
2132
|
children: [
|
|
2248
2133
|
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, { className: "mr-2" }),
|
|
@@ -2252,81 +2137,67 @@ const ReturnDetailPage = () => {
|
|
|
2252
2137
|
),
|
|
2253
2138
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 md:flex-row md:items-center md:justify-between", children: [
|
|
2254
2139
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
2255
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "
|
|
2256
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children:
|
|
2140
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Exchange Details" }),
|
|
2141
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: swap.id })
|
|
2257
2142
|
] }),
|
|
2258
2143
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2259
2144
|
ui.Badge,
|
|
2260
2145
|
{
|
|
2261
2146
|
size: "small",
|
|
2262
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
2263
|
-
children:
|
|
2147
|
+
className: `uppercase ${getStatusBadgeClass$2(swap.status)}`,
|
|
2148
|
+
children: swap.status.replace(/_/g, " ")
|
|
2264
2149
|
}
|
|
2265
2150
|
)
|
|
2266
2151
|
] })
|
|
2267
2152
|
] }),
|
|
2268
|
-
|
|
2153
|
+
canCancelExchange && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
2269
2154
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2270
2155
|
ui.Button,
|
|
2271
2156
|
{
|
|
2272
2157
|
variant: "danger",
|
|
2273
|
-
onClick:
|
|
2274
|
-
disabled:
|
|
2275
|
-
isLoading:
|
|
2276
|
-
children: "
|
|
2158
|
+
onClick: handleCancelExchange,
|
|
2159
|
+
disabled: isCancelling,
|
|
2160
|
+
isLoading: isCancelling,
|
|
2161
|
+
children: "Cancel Exchange"
|
|
2277
2162
|
}
|
|
2278
2163
|
) }),
|
|
2279
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children:
|
|
2280
|
-
] }),
|
|
2281
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2282
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Information" }),
|
|
2283
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
2284
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2285
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Return ID" }),
|
|
2286
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.id })
|
|
2287
|
-
] }),
|
|
2288
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2289
|
-
ui.Button,
|
|
2290
|
-
{
|
|
2291
|
-
variant: "secondary",
|
|
2292
|
-
onClick: () => {
|
|
2293
|
-
window.open(
|
|
2294
|
-
`/app/orders/${returnOrder.order_id}`,
|
|
2295
|
-
"_blank"
|
|
2296
|
-
);
|
|
2297
|
-
},
|
|
2298
|
-
children: "View order"
|
|
2299
|
-
}
|
|
2300
|
-
) })
|
|
2301
|
-
] })
|
|
2164
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "This will cancel the exchange request. The order will remain unchanged." })
|
|
2302
2165
|
] }),
|
|
2303
2166
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
|
|
2304
2167
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2305
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "
|
|
2168
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Exchange Information" }),
|
|
2306
2169
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
2307
2170
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2308
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
2309
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
2171
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
|
|
2172
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.id })
|
|
2310
2173
|
] }),
|
|
2311
2174
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2312
2175
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Status" }),
|
|
2313
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
2176
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.status })
|
|
2314
2177
|
] }),
|
|
2315
|
-
|
|
2178
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2179
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Difference Due" }),
|
|
2180
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.difference_due != null ? `${swap.currency_code || "$"}${(Number(swap.difference_due) / 100).toFixed(2)}` : "—" })
|
|
2181
|
+
] }),
|
|
2182
|
+
swap.reason && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2316
2183
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Reason" }),
|
|
2317
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
2184
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.reason })
|
|
2318
2185
|
] }),
|
|
2319
|
-
|
|
2186
|
+
swap.note && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2320
2187
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Note" }),
|
|
2321
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
2188
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.note })
|
|
2322
2189
|
] }),
|
|
2323
2190
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2324
2191
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Created" }),
|
|
2325
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(
|
|
2192
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(swap.created_at).toLocaleString() })
|
|
2326
2193
|
] }),
|
|
2327
2194
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2328
2195
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Last Updated" }),
|
|
2329
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(
|
|
2196
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(swap.updated_at).toLocaleString() })
|
|
2197
|
+
] }),
|
|
2198
|
+
swap.exchange_id && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2199
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
|
|
2200
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.exchange_id })
|
|
2330
2201
|
] })
|
|
2331
2202
|
] })
|
|
2332
2203
|
] }),
|
|
@@ -2341,7 +2212,7 @@ const ReturnDetailPage = () => {
|
|
|
2341
2212
|
ui.Badge,
|
|
2342
2213
|
{
|
|
2343
2214
|
size: "2xsmall",
|
|
2344
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
2215
|
+
className: `uppercase ${getStatusBadgeClass$2(entry.status)}`,
|
|
2345
2216
|
children: entry.status.replace(/_/g, " ")
|
|
2346
2217
|
}
|
|
2347
2218
|
) }),
|
|
@@ -2356,31 +2227,31 @@ const ReturnDetailPage = () => {
|
|
|
2356
2227
|
)) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No status history available" })
|
|
2357
2228
|
] })
|
|
2358
2229
|
] }),
|
|
2359
|
-
|
|
2230
|
+
order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2360
2231
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Related Order Information" }),
|
|
2361
2232
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
2362
2233
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2363
2234
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order ID" }),
|
|
2364
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
2235
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.id })
|
|
2365
2236
|
] }),
|
|
2366
2237
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2367
2238
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Status" }),
|
|
2368
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
2239
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.status || "—" })
|
|
2369
2240
|
] }),
|
|
2370
2241
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2371
2242
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
|
|
2372
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((
|
|
2243
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_c = order.customer) == null ? void 0 : _c.email) || order.email || "—" })
|
|
2373
2244
|
] }),
|
|
2374
|
-
|
|
2245
|
+
order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2375
2246
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
|
|
2376
2247
|
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "font-medium", children: [
|
|
2377
|
-
|
|
2378
|
-
(Number(
|
|
2248
|
+
order.currency_code || "$",
|
|
2249
|
+
(Number(order.total) / 100).toFixed(2)
|
|
2379
2250
|
] })
|
|
2380
2251
|
] })
|
|
2381
2252
|
] })
|
|
2382
2253
|
] }),
|
|
2383
|
-
|
|
2254
|
+
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: [
|
|
2384
2255
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Items" }),
|
|
2385
2256
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
|
|
2386
2257
|
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
@@ -2388,22 +2259,33 @@ const ReturnDetailPage = () => {
|
|
|
2388
2259
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" }),
|
|
2389
2260
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Reason" })
|
|
2390
2261
|
] }) }),
|
|
2391
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children:
|
|
2262
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.return_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
2392
2263
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.id }),
|
|
2393
2264
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity }),
|
|
2394
2265
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.reason || "—" })
|
|
2395
2266
|
] }, item.id || index)) })
|
|
2396
2267
|
] }) })
|
|
2397
2268
|
] }),
|
|
2398
|
-
|
|
2399
|
-
|
|
2269
|
+
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: [
|
|
2270
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "New Items" }),
|
|
2271
|
+
/* @__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: [
|
|
2272
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
2273
|
+
/* @__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" }),
|
|
2274
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" })
|
|
2275
|
+
] }) }),
|
|
2276
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.new_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
2277
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.variant_id }),
|
|
2278
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity })
|
|
2279
|
+
] }, item.variant_id || index)) })
|
|
2280
|
+
] }) })
|
|
2281
|
+
] })
|
|
2400
2282
|
] }) });
|
|
2401
2283
|
};
|
|
2402
|
-
const config$
|
|
2403
|
-
label: "
|
|
2404
|
-
icon: icons.
|
|
2284
|
+
const config$2 = adminSdk.defineRouteConfig({
|
|
2285
|
+
label: "Swap Details",
|
|
2286
|
+
icon: icons.ArrowPath
|
|
2405
2287
|
});
|
|
2406
|
-
const getStatusBadgeClass = (status) => {
|
|
2288
|
+
const getStatusBadgeClass$1 = (status) => {
|
|
2407
2289
|
const statusLower = status.toLowerCase();
|
|
2408
2290
|
if (statusLower === "requested") {
|
|
2409
2291
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
@@ -2414,109 +2296,105 @@ const getStatusBadgeClass = (status) => {
|
|
|
2414
2296
|
if (statusLower === "rejected") {
|
|
2415
2297
|
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
2416
2298
|
}
|
|
2299
|
+
if (statusLower === "received") {
|
|
2300
|
+
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
2301
|
+
}
|
|
2302
|
+
if (statusLower === "refunded") {
|
|
2303
|
+
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
2304
|
+
}
|
|
2417
2305
|
if (statusLower === "completed") {
|
|
2418
2306
|
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
2419
2307
|
}
|
|
2420
|
-
if (statusLower === "cancelled"
|
|
2308
|
+
if (statusLower === "cancelled") {
|
|
2421
2309
|
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
2422
2310
|
}
|
|
2423
|
-
if (statusLower === "pending") {
|
|
2424
|
-
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
2425
|
-
}
|
|
2426
2311
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
2427
2312
|
};
|
|
2428
|
-
const
|
|
2429
|
-
var _a, _b
|
|
2313
|
+
const ReturnDetailPage = () => {
|
|
2314
|
+
var _a, _b;
|
|
2430
2315
|
const navigate = reactRouterDom.useNavigate();
|
|
2431
2316
|
const { id } = reactRouterDom.useParams();
|
|
2432
|
-
const [
|
|
2433
|
-
const [order, setOrder] = react.useState(null);
|
|
2317
|
+
const [returnOrder, setReturnOrder] = react.useState(null);
|
|
2434
2318
|
const [isLoading, setIsLoading] = react.useState(true);
|
|
2435
|
-
react.useState(false);
|
|
2436
|
-
const [isCancelling, setIsCancelling] = react.useState(false);
|
|
2319
|
+
const [isRejecting, setIsRejecting] = react.useState(false);
|
|
2437
2320
|
const [error, setError] = react.useState(null);
|
|
2438
2321
|
const [updateError, setUpdateError] = react.useState(null);
|
|
2439
2322
|
const [updateSuccess, setUpdateSuccess] = react.useState(false);
|
|
2440
2323
|
react.useEffect(() => {
|
|
2441
2324
|
if (!id) {
|
|
2442
|
-
navigate("/
|
|
2325
|
+
navigate("/returns");
|
|
2443
2326
|
return;
|
|
2444
2327
|
}
|
|
2445
|
-
const
|
|
2328
|
+
const loadReturn = async () => {
|
|
2446
2329
|
try {
|
|
2447
2330
|
setIsLoading(true);
|
|
2448
2331
|
setError(null);
|
|
2449
|
-
const response = await fetch(`/admin/
|
|
2332
|
+
const response = await fetch(`/admin/returns/${id}`, {
|
|
2450
2333
|
credentials: "include"
|
|
2451
2334
|
});
|
|
2452
2335
|
if (!response.ok) {
|
|
2453
2336
|
const message = await response.text();
|
|
2454
|
-
throw new Error(message || "Unable to load
|
|
2337
|
+
throw new Error(message || "Unable to load return order");
|
|
2455
2338
|
}
|
|
2456
2339
|
const payload = await response.json();
|
|
2457
|
-
|
|
2458
|
-
setOrder(payload.order || null);
|
|
2340
|
+
setReturnOrder(payload.return);
|
|
2459
2341
|
} catch (loadError) {
|
|
2460
|
-
const message = loadError instanceof Error ? loadError.message : "Unable to load
|
|
2342
|
+
const message = loadError instanceof Error ? loadError.message : "Unable to load return order";
|
|
2461
2343
|
setError(message);
|
|
2462
2344
|
} finally {
|
|
2463
2345
|
setIsLoading(false);
|
|
2464
2346
|
}
|
|
2465
2347
|
};
|
|
2466
|
-
void
|
|
2348
|
+
void loadReturn();
|
|
2467
2349
|
}, [id, navigate]);
|
|
2468
|
-
const
|
|
2350
|
+
const handleReject = async () => {
|
|
2469
2351
|
if (!id) {
|
|
2470
2352
|
return;
|
|
2471
2353
|
}
|
|
2472
2354
|
try {
|
|
2473
|
-
|
|
2355
|
+
setIsRejecting(true);
|
|
2474
2356
|
setUpdateError(null);
|
|
2475
2357
|
setUpdateSuccess(false);
|
|
2476
|
-
const response = await fetch(`/admin/
|
|
2358
|
+
const response = await fetch(`/admin/returns/${id}/reject`, {
|
|
2477
2359
|
method: "POST",
|
|
2478
2360
|
headers: {
|
|
2479
2361
|
"Content-Type": "application/json"
|
|
2480
2362
|
},
|
|
2481
|
-
credentials: "include"
|
|
2363
|
+
credentials: "include",
|
|
2364
|
+
body: JSON.stringify({ reason: "Rejected by admin" })
|
|
2482
2365
|
});
|
|
2483
2366
|
if (!response.ok) {
|
|
2484
2367
|
const message = await response.text();
|
|
2485
|
-
throw new Error(message || "Unable to
|
|
2368
|
+
throw new Error(message || "Unable to reject return");
|
|
2486
2369
|
}
|
|
2487
2370
|
const payload = await response.json();
|
|
2488
|
-
|
|
2371
|
+
setReturnOrder(payload.return);
|
|
2489
2372
|
setUpdateSuccess(true);
|
|
2490
2373
|
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
2491
|
-
const detailResponse = await fetch(`/admin/
|
|
2374
|
+
const detailResponse = await fetch(`/admin/returns/${id}`, {
|
|
2492
2375
|
credentials: "include"
|
|
2493
2376
|
});
|
|
2494
2377
|
if (detailResponse.ok) {
|
|
2495
2378
|
const detailPayload = await detailResponse.json();
|
|
2496
|
-
|
|
2497
|
-
setOrder(detailPayload.order || null);
|
|
2379
|
+
setReturnOrder(detailPayload.return);
|
|
2498
2380
|
}
|
|
2499
|
-
} catch (
|
|
2500
|
-
const message =
|
|
2381
|
+
} catch (updateErr) {
|
|
2382
|
+
const message = updateErr instanceof Error ? updateErr.message : "Unable to reject return";
|
|
2501
2383
|
setUpdateError(message);
|
|
2502
2384
|
} finally {
|
|
2503
|
-
|
|
2385
|
+
setIsRejecting(false);
|
|
2504
2386
|
}
|
|
2505
2387
|
};
|
|
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
2388
|
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
|
|
2389
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading return order..." }) }) }) });
|
|
2512
2390
|
}
|
|
2513
|
-
if (error || !
|
|
2391
|
+
if (error || !returnOrder) {
|
|
2514
2392
|
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 || "
|
|
2516
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/
|
|
2393
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "Return order not found" }),
|
|
2394
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/returns"), children: "Back to list" }) })
|
|
2517
2395
|
] }) }) });
|
|
2518
2396
|
}
|
|
2519
|
-
const statusHistory = ((
|
|
2397
|
+
const statusHistory = ((_a = returnOrder.metadata) == null ? void 0 : _a.status_history) || [];
|
|
2520
2398
|
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
2399
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
|
|
2522
2400
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -2524,7 +2402,7 @@ const SwapDetailPage = () => {
|
|
|
2524
2402
|
{
|
|
2525
2403
|
variant: "transparent",
|
|
2526
2404
|
size: "small",
|
|
2527
|
-
onClick: () => navigate("/
|
|
2405
|
+
onClick: () => navigate("/returns"),
|
|
2528
2406
|
className: "w-fit",
|
|
2529
2407
|
children: [
|
|
2530
2408
|
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, { className: "mr-2" }),
|
|
@@ -2534,67 +2412,81 @@ const SwapDetailPage = () => {
|
|
|
2534
2412
|
),
|
|
2535
2413
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 md:flex-row md:items-center md:justify-between", children: [
|
|
2536
2414
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
2537
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "
|
|
2538
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children:
|
|
2415
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Return Order Details" }),
|
|
2416
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: returnOrder.id })
|
|
2539
2417
|
] }),
|
|
2540
2418
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2541
2419
|
ui.Badge,
|
|
2542
2420
|
{
|
|
2543
2421
|
size: "small",
|
|
2544
|
-
className: `uppercase ${getStatusBadgeClass(
|
|
2545
|
-
children:
|
|
2422
|
+
className: `uppercase ${getStatusBadgeClass$1(returnOrder.status)}`,
|
|
2423
|
+
children: returnOrder.status.replace(/_/g, " ")
|
|
2424
|
+
}
|
|
2425
|
+
)
|
|
2426
|
+
] })
|
|
2427
|
+
] }),
|
|
2428
|
+
returnOrder.status === "requested" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
2429
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2430
|
+
ui.Button,
|
|
2431
|
+
{
|
|
2432
|
+
variant: "danger",
|
|
2433
|
+
onClick: handleReject,
|
|
2434
|
+
disabled: isRejecting,
|
|
2435
|
+
isLoading: isRejecting,
|
|
2436
|
+
children: "Reject (Cancel) Return"
|
|
2437
|
+
}
|
|
2438
|
+
) }),
|
|
2439
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: 'Cancel this return request. Use "Mark as received" when items are received.' })
|
|
2440
|
+
] }),
|
|
2441
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2442
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Information" }),
|
|
2443
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
2444
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2445
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Return ID" }),
|
|
2446
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.id })
|
|
2447
|
+
] }),
|
|
2448
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2449
|
+
ui.Button,
|
|
2450
|
+
{
|
|
2451
|
+
variant: "secondary",
|
|
2452
|
+
onClick: () => {
|
|
2453
|
+
window.open(
|
|
2454
|
+
`/app/orders/${returnOrder.order_id}`,
|
|
2455
|
+
"_blank"
|
|
2456
|
+
);
|
|
2457
|
+
},
|
|
2458
|
+
children: "View order"
|
|
2546
2459
|
}
|
|
2547
|
-
)
|
|
2460
|
+
) })
|
|
2548
2461
|
] })
|
|
2549
2462
|
] }),
|
|
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
2463
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
|
|
2564
2464
|
/* @__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: "
|
|
2465
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Details" }),
|
|
2566
2466
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
2567
2467
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2568
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
2569
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
2468
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Return ID" }),
|
|
2469
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.id })
|
|
2570
2470
|
] }),
|
|
2571
2471
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2572
2472
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Status" }),
|
|
2573
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
2574
|
-
] }),
|
|
2575
|
-
/* @__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)}` : "—" })
|
|
2473
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.status })
|
|
2578
2474
|
] }),
|
|
2579
|
-
|
|
2475
|
+
returnOrder.reason && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2580
2476
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Reason" }),
|
|
2581
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
2477
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.reason })
|
|
2582
2478
|
] }),
|
|
2583
|
-
|
|
2479
|
+
returnOrder.note && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2584
2480
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Note" }),
|
|
2585
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
2481
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.note })
|
|
2586
2482
|
] }),
|
|
2587
2483
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2588
2484
|
/* @__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(
|
|
2485
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(returnOrder.created_at).toLocaleString() })
|
|
2590
2486
|
] }),
|
|
2591
2487
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2592
2488
|
/* @__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(
|
|
2594
|
-
] }),
|
|
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 })
|
|
2489
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(returnOrder.updated_at).toLocaleString() })
|
|
2598
2490
|
] })
|
|
2599
2491
|
] })
|
|
2600
2492
|
] }),
|
|
@@ -2609,7 +2501,7 @@ const SwapDetailPage = () => {
|
|
|
2609
2501
|
ui.Badge,
|
|
2610
2502
|
{
|
|
2611
2503
|
size: "2xsmall",
|
|
2612
|
-
className: `uppercase ${getStatusBadgeClass(entry.status)}`,
|
|
2504
|
+
className: `uppercase ${getStatusBadgeClass$1(entry.status)}`,
|
|
2613
2505
|
children: entry.status.replace(/_/g, " ")
|
|
2614
2506
|
}
|
|
2615
2507
|
) }),
|
|
@@ -2624,31 +2516,31 @@ const SwapDetailPage = () => {
|
|
|
2624
2516
|
)) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No status history available" })
|
|
2625
2517
|
] })
|
|
2626
2518
|
] }),
|
|
2627
|
-
order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2519
|
+
returnOrder.order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2628
2520
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Related Order Information" }),
|
|
2629
2521
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
2630
2522
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2631
2523
|
/* @__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 })
|
|
2524
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.id })
|
|
2633
2525
|
] }),
|
|
2634
2526
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2635
2527
|
/* @__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 || "—" })
|
|
2528
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.status || "—" })
|
|
2637
2529
|
] }),
|
|
2638
2530
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2639
2531
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
|
|
2640
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((
|
|
2532
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_b = returnOrder.order.customer) == null ? void 0 : _b.email) || returnOrder.order.email || "—" })
|
|
2641
2533
|
] }),
|
|
2642
|
-
order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2534
|
+
returnOrder.order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2643
2535
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
|
|
2644
2536
|
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "font-medium", children: [
|
|
2645
|
-
order.currency_code || "$",
|
|
2646
|
-
(Number(order.total) / 100).toFixed(2)
|
|
2537
|
+
returnOrder.order.currency_code || "$",
|
|
2538
|
+
(Number(returnOrder.order.total) / 100).toFixed(2)
|
|
2647
2539
|
] })
|
|
2648
2540
|
] })
|
|
2649
2541
|
] })
|
|
2650
2542
|
] }),
|
|
2651
|
-
|
|
2543
|
+
returnOrder.return_items && returnOrder.return_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2652
2544
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Items" }),
|
|
2653
2545
|
/* @__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
2546
|
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
@@ -2656,31 +2548,139 @@ const SwapDetailPage = () => {
|
|
|
2656
2548
|
/* @__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
2549
|
/* @__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
2550
|
] }) }),
|
|
2659
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children:
|
|
2551
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: returnOrder.return_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
2660
2552
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.id }),
|
|
2661
2553
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity }),
|
|
2662
2554
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.reason || "—" })
|
|
2663
2555
|
] }, item.id || index)) })
|
|
2664
2556
|
] }) })
|
|
2665
2557
|
] }),
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2558
|
+
updateError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-ui-border-error bg-ui-bg-error-subtle p-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-error", children: updateError }) }),
|
|
2559
|
+
updateSuccess && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-ui-border-success bg-ui-bg-success-subtle p-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-success", children: "Action completed successfully" }) })
|
|
2560
|
+
] }) });
|
|
2561
|
+
};
|
|
2562
|
+
const config$1 = adminSdk.defineRouteConfig({
|
|
2563
|
+
label: "Return Order Details",
|
|
2564
|
+
icon: icons.CheckCircle
|
|
2565
|
+
});
|
|
2566
|
+
const getStatusBadgeClass = (status) => {
|
|
2567
|
+
const s2 = status.toLowerCase();
|
|
2568
|
+
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
2569
|
+
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
2570
|
+
if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
2571
|
+
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
2572
|
+
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
2573
|
+
};
|
|
2574
|
+
const PaymentDetailPage = () => {
|
|
2575
|
+
var _a;
|
|
2576
|
+
const navigate = reactRouterDom.useNavigate();
|
|
2577
|
+
const params = reactRouterDom.useParams();
|
|
2578
|
+
const id = (_a = params == null ? void 0 : params.id) == null ? void 0 : _a.trim();
|
|
2579
|
+
const [detail, setDetail] = react.useState(null);
|
|
2580
|
+
const [loading, setLoading] = react.useState(!!id);
|
|
2581
|
+
const [error, setError] = react.useState(null);
|
|
2582
|
+
react.useEffect(() => {
|
|
2583
|
+
if (!id) {
|
|
2584
|
+
setLoading(false);
|
|
2585
|
+
return;
|
|
2586
|
+
}
|
|
2587
|
+
let cancelled = false;
|
|
2588
|
+
setLoading(true);
|
|
2589
|
+
setError(null);
|
|
2590
|
+
fetch(`/admin/payment-transactions/${id}`, { credentials: "include" }).then((res) => {
|
|
2591
|
+
if (!res.ok) throw new Error(res.statusText || "Failed to load");
|
|
2592
|
+
return res.json();
|
|
2593
|
+
}).then((data) => {
|
|
2594
|
+
if (!cancelled) setDetail(data);
|
|
2595
|
+
}).catch((e) => {
|
|
2596
|
+
if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
|
|
2597
|
+
}).finally(() => {
|
|
2598
|
+
if (!cancelled) setLoading(false);
|
|
2599
|
+
});
|
|
2600
|
+
return () => {
|
|
2601
|
+
cancelled = true;
|
|
2602
|
+
};
|
|
2603
|
+
}, [id]);
|
|
2604
|
+
const displayStatus = detail ? (detail.payment_id != null && detail.payment_status != null && detail.payment_status !== "" ? detail.payment_status : detail.session_status ?? "") || "—" : "";
|
|
2605
|
+
const sessionStatusRaw = (detail == null ? void 0 : detail.session_status) ?? "—";
|
|
2606
|
+
const paymentStatusRaw = (detail == null ? void 0 : detail.payment_id) != null ? (detail == null ? void 0 : detail.payment_status) ?? "—" : "—";
|
|
2607
|
+
const displayAmount = detail ? `${(detail.currency_code ?? "USD").toUpperCase()} ${Number(detail.amount)}` : "";
|
|
2608
|
+
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: [
|
|
2609
|
+
/* @__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: [
|
|
2610
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => navigate("/payments"), children: "← Payments" }),
|
|
2611
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Payment session" }),
|
|
2612
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: id ?? "—" })
|
|
2613
|
+
] }) }),
|
|
2614
|
+
error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
2615
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
2616
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/payments"), children: "Back to list" })
|
|
2617
|
+
] }) : 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: [
|
|
2618
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl border border-ui-border-base p-6 flex flex-col gap-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
2619
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2620
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Order ID" }),
|
|
2621
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: detail.order_id ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2622
|
+
ui.Button,
|
|
2623
|
+
{
|
|
2624
|
+
variant: "transparent",
|
|
2625
|
+
size: "small",
|
|
2626
|
+
onClick: () => navigate(`/orders/${detail.order_id}`),
|
|
2627
|
+
children: detail.order_id
|
|
2628
|
+
}
|
|
2629
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "—" }) })
|
|
2630
|
+
] }),
|
|
2631
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2632
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
|
|
2633
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: displayAmount })
|
|
2634
|
+
] }),
|
|
2635
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2636
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
|
|
2637
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.provider_id })
|
|
2638
|
+
] }),
|
|
2639
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2640
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
|
|
2641
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2642
|
+
ui.Badge,
|
|
2643
|
+
{
|
|
2644
|
+
size: "2xsmall",
|
|
2645
|
+
className: `uppercase ${getStatusBadgeClass(displayStatus)}`,
|
|
2646
|
+
children: displayStatus !== "—" ? displayStatus.replace(/_/g, " ") : "—"
|
|
2647
|
+
}
|
|
2648
|
+
) })
|
|
2649
|
+
] }),
|
|
2650
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2651
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Session status (DB)" }),
|
|
2652
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: sessionStatusRaw })
|
|
2653
|
+
] }),
|
|
2654
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2655
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Payment status (DB)" }),
|
|
2656
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: paymentStatusRaw })
|
|
2657
|
+
] }),
|
|
2658
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2659
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Finalized" }),
|
|
2660
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.payment_id != null ? "Yes" : "No" })
|
|
2661
|
+
] }),
|
|
2662
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2663
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created" }),
|
|
2664
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: new Date(detail.created_at).toLocaleDateString("en-US", {
|
|
2665
|
+
year: "numeric",
|
|
2666
|
+
month: "short",
|
|
2667
|
+
day: "numeric",
|
|
2668
|
+
hour: "numeric",
|
|
2669
|
+
minute: "2-digit",
|
|
2670
|
+
hour12: true
|
|
2671
|
+
}) })
|
|
2672
|
+
] })
|
|
2673
|
+
] }) }),
|
|
2674
|
+
Object.keys(detail.data ?? {}).length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2675
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Provider data" }),
|
|
2676
|
+
/* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-xs bg-ui-bg-subtle p-4 rounded-lg overflow-auto max-h-96", children: JSON.stringify(detail.data, null, 2) })
|
|
2677
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl border border-ui-border-base p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No provider data for this session." }) })
|
|
2678
|
+
] }) : null
|
|
2679
2679
|
] }) });
|
|
2680
2680
|
};
|
|
2681
2681
|
const config = adminSdk.defineRouteConfig({
|
|
2682
|
-
label: "
|
|
2683
|
-
icon: icons.
|
|
2682
|
+
label: "Payment details",
|
|
2683
|
+
icon: icons.CreditCard
|
|
2684
2684
|
});
|
|
2685
2685
|
const i18nTranslations0 = {};
|
|
2686
2686
|
const widgetModule = { widgets: [
|
|
@@ -2700,43 +2700,49 @@ const routeModule = {
|
|
|
2700
2700
|
path: "/refunds"
|
|
2701
2701
|
},
|
|
2702
2702
|
{
|
|
2703
|
-
Component:
|
|
2704
|
-
path: "/
|
|
2703
|
+
Component: SwapsPage,
|
|
2704
|
+
path: "/swaps"
|
|
2705
2705
|
},
|
|
2706
2706
|
{
|
|
2707
2707
|
Component: ReturnsPage,
|
|
2708
2708
|
path: "/returns"
|
|
2709
2709
|
},
|
|
2710
2710
|
{
|
|
2711
|
-
Component:
|
|
2712
|
-
path: "/
|
|
2711
|
+
Component: PaymentsPage,
|
|
2712
|
+
path: "/payments"
|
|
2713
2713
|
},
|
|
2714
2714
|
{
|
|
2715
2715
|
Component: RefundDetailPage,
|
|
2716
2716
|
path: "/refunds/:id"
|
|
2717
2717
|
},
|
|
2718
2718
|
{
|
|
2719
|
-
Component:
|
|
2720
|
-
path: "/
|
|
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:
|
|
2728
|
-
path: "/
|
|
2727
|
+
Component: PaymentDetailPage,
|
|
2728
|
+
path: "/payments/:id"
|
|
2729
2729
|
}
|
|
2730
2730
|
]
|
|
2731
2731
|
};
|
|
2732
2732
|
const menuItemModule = {
|
|
2733
2733
|
menuItems: [
|
|
2734
2734
|
{
|
|
2735
|
-
label: config$
|
|
2736
|
-
icon: config$
|
|
2735
|
+
label: config$4.label,
|
|
2736
|
+
icon: config$4.icon,
|
|
2737
2737
|
path: "/payments",
|
|
2738
2738
|
nested: void 0
|
|
2739
2739
|
},
|
|
2740
|
+
{
|
|
2741
|
+
label: config$5.label,
|
|
2742
|
+
icon: config$5.icon,
|
|
2743
|
+
path: "/returns",
|
|
2744
|
+
nested: void 0
|
|
2745
|
+
},
|
|
2740
2746
|
{
|
|
2741
2747
|
label: config$7.label,
|
|
2742
2748
|
icon: config$7.icon,
|
|
@@ -2744,15 +2750,21 @@ const menuItemModule = {
|
|
|
2744
2750
|
nested: void 0
|
|
2745
2751
|
},
|
|
2746
2752
|
{
|
|
2747
|
-
label: config$
|
|
2748
|
-
icon: config$
|
|
2749
|
-
path: "/
|
|
2753
|
+
label: config$6.label,
|
|
2754
|
+
icon: config$6.icon,
|
|
2755
|
+
path: "/swaps",
|
|
2750
2756
|
nested: void 0
|
|
2751
2757
|
},
|
|
2752
2758
|
{
|
|
2753
|
-
label: config
|
|
2754
|
-
icon: config
|
|
2755
|
-
path: "/
|
|
2759
|
+
label: config.label,
|
|
2760
|
+
icon: config.icon,
|
|
2761
|
+
path: "/payments/:id",
|
|
2762
|
+
nested: void 0
|
|
2763
|
+
},
|
|
2764
|
+
{
|
|
2765
|
+
label: config$1.label,
|
|
2766
|
+
icon: config$1.icon,
|
|
2767
|
+
path: "/returns/:id",
|
|
2756
2768
|
nested: void 0
|
|
2757
2769
|
},
|
|
2758
2770
|
{
|
|
@@ -2764,20 +2776,8 @@ const menuItemModule = {
|
|
|
2764
2776
|
{
|
|
2765
2777
|
label: config$2.label,
|
|
2766
2778
|
icon: config$2.icon,
|
|
2767
|
-
path: "/payments/:id",
|
|
2768
|
-
nested: void 0
|
|
2769
|
-
},
|
|
2770
|
-
{
|
|
2771
|
-
label: config.label,
|
|
2772
|
-
icon: config.icon,
|
|
2773
2779
|
path: "/swaps/:id",
|
|
2774
2780
|
nested: void 0
|
|
2775
|
-
},
|
|
2776
|
-
{
|
|
2777
|
-
label: config$1.label,
|
|
2778
|
-
icon: config$1.icon,
|
|
2779
|
-
path: "/returns/:id",
|
|
2780
|
-
nested: void 0
|
|
2781
2781
|
}
|
|
2782
2782
|
]
|
|
2783
2783
|
};
|