order-management 0.0.77 → 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.
|
@@ -2,7 +2,7 @@ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
|
2
2
|
import { defineWidgetConfig, defineRouteConfig } from "@medusajs/admin-sdk";
|
|
3
3
|
import { useState, useEffect, useRef, useCallback, useMemo } from "react";
|
|
4
4
|
import { Container, Text, Heading, Badge, Button, Label, Select, Textarea, Input } from "@medusajs/ui";
|
|
5
|
-
import { CashSolid, PencilSquareSolid, Trash,
|
|
5
|
+
import { CashSolid, PencilSquareSolid, Trash, Receipt, ArrowPath, CreditCard, ArrowLeft, CheckCircle } from "@medusajs/icons";
|
|
6
6
|
import { useNavigate, useParams } from "react-router-dom";
|
|
7
7
|
function roundRectPath(ctx, x, y, w, h, r) {
|
|
8
8
|
ctx.beginPath();
|
|
@@ -872,216 +872,16 @@ const getStatusBadgeClass$7 = (status) => {
|
|
|
872
872
|
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
873
873
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
874
874
|
};
|
|
875
|
-
const PaymentsPage = () => {
|
|
876
|
-
const navigate = useNavigate();
|
|
877
|
-
const [items, setItems] = useState([]);
|
|
878
|
-
const [statusFilter, setStatusFilter] = useState("all");
|
|
879
|
-
const [orderIdSearch, setOrderIdSearch] = useState("");
|
|
880
|
-
const debouncedOrderId = useDebounce$3(orderIdSearch, 300);
|
|
881
|
-
const [isLoading, setIsLoading] = useState(true);
|
|
882
|
-
const [isFetchingMore, setIsFetchingMore] = useState(false);
|
|
883
|
-
const [error, setError] = useState(null);
|
|
884
|
-
const [offset, setOffset] = useState(0);
|
|
885
|
-
const [count, setCount] = useState(0);
|
|
886
|
-
const limit = 50;
|
|
887
|
-
const loadTransactions = useCallback(
|
|
888
|
-
async (nextOffset, replace) => {
|
|
889
|
-
try {
|
|
890
|
-
if (replace) setIsLoading(true);
|
|
891
|
-
else setIsFetchingMore(true);
|
|
892
|
-
setError(null);
|
|
893
|
-
const params = new URLSearchParams();
|
|
894
|
-
params.set("limit", String(limit));
|
|
895
|
-
params.set("offset", String(nextOffset));
|
|
896
|
-
if (statusFilter !== "all") params.set("status", statusFilter);
|
|
897
|
-
if (debouncedOrderId.trim()) params.set("order_id", debouncedOrderId.trim());
|
|
898
|
-
const response = await fetch(
|
|
899
|
-
`/admin/payment-transactions?${params.toString()}`,
|
|
900
|
-
{ credentials: "include" }
|
|
901
|
-
);
|
|
902
|
-
if (!response.ok) {
|
|
903
|
-
const text = await response.text();
|
|
904
|
-
throw new Error(text || "Failed to load payment transactions");
|
|
905
|
-
}
|
|
906
|
-
const payload = await response.json();
|
|
907
|
-
const list = payload.transactions ?? [];
|
|
908
|
-
setCount(payload.count ?? 0);
|
|
909
|
-
setOffset(nextOffset + list.length);
|
|
910
|
-
setItems((prev) => replace ? list : [...prev, ...list]);
|
|
911
|
-
} catch (e) {
|
|
912
|
-
setError(e instanceof Error ? e.message : "Failed to load");
|
|
913
|
-
} finally {
|
|
914
|
-
setIsLoading(false);
|
|
915
|
-
setIsFetchingMore(false);
|
|
916
|
-
}
|
|
917
|
-
},
|
|
918
|
-
[statusFilter, debouncedOrderId]
|
|
919
|
-
);
|
|
920
|
-
useEffect(() => {
|
|
921
|
-
void loadTransactions(0, true);
|
|
922
|
-
}, [loadTransactions]);
|
|
923
|
-
const hasMore = useMemo(() => offset < count, [offset, count]);
|
|
924
|
-
const displayStatus = (t) => {
|
|
925
|
-
const s2 = t.payment_id != null && t.payment_status != null && t.payment_status !== "" ? t.payment_status : t.session_status ?? "";
|
|
926
|
-
return s2 !== "" ? s2 : "—";
|
|
927
|
-
};
|
|
928
|
-
const displayAmount = (t) => {
|
|
929
|
-
const code = (t.currency_code ?? "USD").toUpperCase();
|
|
930
|
-
return `${code} ${Number(t.amount)}`;
|
|
931
|
-
};
|
|
932
|
-
return /* @__PURE__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxs(Container, { className: "mx-auto flex w-full max-w-7xl flex-col gap-6 p-6", children: [
|
|
933
|
-
/* @__PURE__ */ jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
934
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
935
|
-
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "Payments" }),
|
|
936
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "All payment attempts — completed, pending, failed, requires action" })
|
|
937
|
-
] }),
|
|
938
|
-
/* @__PURE__ */ jsx(Button, { variant: "primary", onClick: () => loadTransactions(0, true), children: "Refresh" })
|
|
939
|
-
] }),
|
|
940
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
941
|
-
/* @__PURE__ */ jsx(
|
|
942
|
-
Input,
|
|
943
|
-
{
|
|
944
|
-
placeholder: "Search by Order ID",
|
|
945
|
-
value: orderIdSearch,
|
|
946
|
-
onChange: (e) => setOrderIdSearch(e.target.value),
|
|
947
|
-
className: "md:max-w-sm",
|
|
948
|
-
"aria-label": "Search by order ID"
|
|
949
|
-
}
|
|
950
|
-
),
|
|
951
|
-
/* @__PURE__ */ jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxs(
|
|
952
|
-
"select",
|
|
953
|
-
{
|
|
954
|
-
value: statusFilter,
|
|
955
|
-
onChange: (e) => setStatusFilter(e.target.value),
|
|
956
|
-
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",
|
|
957
|
-
"aria-label": "Filter by status",
|
|
958
|
-
children: [
|
|
959
|
-
/* @__PURE__ */ jsx("option", { value: "all", children: "All statuses" }),
|
|
960
|
-
/* @__PURE__ */ jsx("option", { value: "pending", children: "Pending" }),
|
|
961
|
-
/* @__PURE__ */ jsx("option", { value: "requires_more", children: "Requires more" }),
|
|
962
|
-
/* @__PURE__ */ jsx("option", { value: "error", children: "Error" }),
|
|
963
|
-
/* @__PURE__ */ jsx("option", { value: "canceled", children: "Canceled" }),
|
|
964
|
-
/* @__PURE__ */ jsx("option", { value: "authorized", children: "Authorized" }),
|
|
965
|
-
/* @__PURE__ */ jsx("option", { value: "captured", children: "Captured" })
|
|
966
|
-
]
|
|
967
|
-
}
|
|
968
|
-
) })
|
|
969
|
-
] }),
|
|
970
|
-
error ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
971
|
-
/* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
972
|
-
/* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => loadTransactions(0, true), children: "Try again" }) })
|
|
973
|
-
] }) : null,
|
|
974
|
-
isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading payments…" }) }) : items.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
|
|
975
|
-
/* @__PURE__ */ jsx(Heading, { level: "h3", className: "text-xl", children: "No payment transactions yet" }),
|
|
976
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Payment attempts will appear here." })
|
|
977
|
-
] }) : /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
|
|
978
|
-
/* @__PURE__ */ jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
979
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
|
|
980
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Amount" }),
|
|
981
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Provider" }),
|
|
982
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
|
|
983
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Finalized" }),
|
|
984
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
985
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
986
|
-
] }) }),
|
|
987
|
-
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((t) => /* @__PURE__ */ jsxs(
|
|
988
|
-
"tr",
|
|
989
|
-
{
|
|
990
|
-
className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
|
|
991
|
-
onClick: () => navigate(`/payments/${t.payment_session_id}`),
|
|
992
|
-
children: [
|
|
993
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: t.order_id ?? "—" }),
|
|
994
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: displayAmount(t) }),
|
|
995
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: t.provider_id }),
|
|
996
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsx(
|
|
997
|
-
Badge,
|
|
998
|
-
{
|
|
999
|
-
size: "2xsmall",
|
|
1000
|
-
className: `uppercase ${getStatusBadgeClass$7(displayStatus(t))}`,
|
|
1001
|
-
children: displayStatus(t) !== "—" ? displayStatus(t).replace(/_/g, " ") : "—"
|
|
1002
|
-
}
|
|
1003
|
-
) }),
|
|
1004
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: t.payment_id != null ? "Yes" : "No" }),
|
|
1005
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(t.created_at).toLocaleDateString("en-US", {
|
|
1006
|
-
year: "numeric",
|
|
1007
|
-
month: "short",
|
|
1008
|
-
day: "numeric",
|
|
1009
|
-
hour: "numeric",
|
|
1010
|
-
minute: "2-digit",
|
|
1011
|
-
hour12: true
|
|
1012
|
-
}) }),
|
|
1013
|
-
/* @__PURE__ */ jsxs("td", { className: "px-4 py-4", children: [
|
|
1014
|
-
/* @__PURE__ */ jsx(
|
|
1015
|
-
Button,
|
|
1016
|
-
{
|
|
1017
|
-
variant: "transparent",
|
|
1018
|
-
size: "small",
|
|
1019
|
-
onClick: (e) => {
|
|
1020
|
-
e.stopPropagation();
|
|
1021
|
-
navigate(`/payments/${t.payment_session_id}`);
|
|
1022
|
-
},
|
|
1023
|
-
children: "View details"
|
|
1024
|
-
}
|
|
1025
|
-
),
|
|
1026
|
-
t.order_id ? /* @__PURE__ */ jsx(
|
|
1027
|
-
Button,
|
|
1028
|
-
{
|
|
1029
|
-
variant: "transparent",
|
|
1030
|
-
size: "small",
|
|
1031
|
-
onClick: (e) => {
|
|
1032
|
-
e.stopPropagation();
|
|
1033
|
-
navigate(`/orders/${t.order_id}`);
|
|
1034
|
-
},
|
|
1035
|
-
children: "Order"
|
|
1036
|
-
}
|
|
1037
|
-
) : null
|
|
1038
|
-
] })
|
|
1039
|
-
]
|
|
1040
|
-
},
|
|
1041
|
-
t.payment_session_id
|
|
1042
|
-
)) })
|
|
1043
|
-
] }) }),
|
|
1044
|
-
hasMore ? /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(
|
|
1045
|
-
Button,
|
|
1046
|
-
{
|
|
1047
|
-
variant: "secondary",
|
|
1048
|
-
isLoading: isFetchingMore,
|
|
1049
|
-
onClick: () => loadTransactions(offset, false),
|
|
1050
|
-
children: "Load more"
|
|
1051
|
-
}
|
|
1052
|
-
) }) : null
|
|
1053
|
-
] }) });
|
|
1054
|
-
};
|
|
1055
|
-
const config$7 = defineRouteConfig({
|
|
1056
|
-
label: "Payments",
|
|
1057
|
-
icon: CreditCard
|
|
1058
|
-
});
|
|
1059
|
-
const useDebounce$2 = (value, delay) => {
|
|
1060
|
-
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
1061
|
-
useEffect(() => {
|
|
1062
|
-
const handler = setTimeout(() => setDebouncedValue(value), delay);
|
|
1063
|
-
return () => clearTimeout(handler);
|
|
1064
|
-
}, [value, delay]);
|
|
1065
|
-
return debouncedValue;
|
|
1066
|
-
};
|
|
1067
|
-
const getStatusBadgeClass$6 = (status) => {
|
|
1068
|
-
const s2 = status.toLowerCase();
|
|
1069
|
-
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1070
|
-
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
1071
|
-
if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
1072
|
-
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
1073
|
-
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
1074
|
-
};
|
|
1075
875
|
const RefundsPage = () => {
|
|
1076
876
|
const navigate = useNavigate();
|
|
1077
877
|
const [items, setItems] = useState([]);
|
|
1078
878
|
const [orderIdSearch, setOrderIdSearch] = useState("");
|
|
1079
|
-
const debouncedOrderId = useDebounce$
|
|
879
|
+
const debouncedOrderId = useDebounce$3(orderIdSearch, 300);
|
|
1080
880
|
const [paymentStatusFilter, setPaymentStatusFilter] = useState("all");
|
|
1081
881
|
const [providerSearch, setProviderSearch] = useState("");
|
|
1082
|
-
const debouncedProvider = useDebounce$
|
|
882
|
+
const debouncedProvider = useDebounce$3(providerSearch, 300);
|
|
1083
883
|
const [currencySearch, setCurrencySearch] = useState("");
|
|
1084
|
-
const debouncedCurrency = useDebounce$
|
|
884
|
+
const debouncedCurrency = useDebounce$3(currencySearch, 300);
|
|
1085
885
|
const [dateFrom, setDateFrom] = useState("");
|
|
1086
886
|
const [dateTo, setDateTo] = useState("");
|
|
1087
887
|
const [amountMin, setAmountMin] = useState("");
|
|
@@ -1293,7 +1093,7 @@ const RefundsPage = () => {
|
|
|
1293
1093
|
Badge,
|
|
1294
1094
|
{
|
|
1295
1095
|
size: "2xsmall",
|
|
1296
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
1096
|
+
className: `uppercase ${getStatusBadgeClass$7(displayStatus(r))}`,
|
|
1297
1097
|
children: displayStatus(r) !== "—" ? displayStatus(r).replace(/_/g, " ") : "—"
|
|
1298
1098
|
}
|
|
1299
1099
|
) }),
|
|
@@ -1347,11 +1147,11 @@ const RefundsPage = () => {
|
|
|
1347
1147
|
) }) : null
|
|
1348
1148
|
] }) });
|
|
1349
1149
|
};
|
|
1350
|
-
const config$
|
|
1150
|
+
const config$7 = defineRouteConfig({
|
|
1351
1151
|
label: "Refunds",
|
|
1352
1152
|
icon: Receipt
|
|
1353
1153
|
});
|
|
1354
|
-
const useDebounce$
|
|
1154
|
+
const useDebounce$2 = (value, delay) => {
|
|
1355
1155
|
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
1356
1156
|
useEffect(() => {
|
|
1357
1157
|
const handler = setTimeout(() => setDebouncedValue(value), delay);
|
|
@@ -1359,39 +1159,39 @@ const useDebounce$1 = (value, delay) => {
|
|
|
1359
1159
|
}, [value, delay]);
|
|
1360
1160
|
return debouncedValue;
|
|
1361
1161
|
};
|
|
1362
|
-
const getStatusBadgeClass$
|
|
1162
|
+
const getStatusBadgeClass$6 = (status) => {
|
|
1363
1163
|
const statusLower = status.toLowerCase();
|
|
1364
1164
|
if (statusLower === "requested") {
|
|
1365
1165
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
1366
1166
|
}
|
|
1367
|
-
if (statusLower === "
|
|
1167
|
+
if (statusLower === "approved") {
|
|
1368
1168
|
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
1369
1169
|
}
|
|
1370
|
-
if (statusLower === "
|
|
1170
|
+
if (statusLower === "rejected") {
|
|
1371
1171
|
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
1372
1172
|
}
|
|
1373
1173
|
if (statusLower === "completed") {
|
|
1374
1174
|
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1375
1175
|
}
|
|
1376
|
-
if (statusLower === "
|
|
1176
|
+
if (statusLower === "cancelled") {
|
|
1377
1177
|
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
1378
1178
|
}
|
|
1379
1179
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
1380
1180
|
};
|
|
1381
|
-
const
|
|
1181
|
+
const SwapsPage = () => {
|
|
1382
1182
|
const navigate = useNavigate();
|
|
1383
1183
|
const [items, setItems] = useState([]);
|
|
1384
1184
|
const [statusFilter, setStatusFilter] = useState("all");
|
|
1385
1185
|
const [createdByFilter, setCreatedByFilter] = useState("all");
|
|
1386
1186
|
const [searchQuery, setSearchQuery] = useState("");
|
|
1387
|
-
const debouncedSearchQuery = useDebounce$
|
|
1187
|
+
const debouncedSearchQuery = useDebounce$2(searchQuery, 300);
|
|
1388
1188
|
const [isLoading, setIsLoading] = useState(true);
|
|
1389
1189
|
const [isFetchingMore, setIsFetchingMore] = useState(false);
|
|
1390
1190
|
const [error, setError] = useState(null);
|
|
1391
1191
|
const [offset, setOffset] = useState(0);
|
|
1392
1192
|
const [count, setCount] = useState(0);
|
|
1393
1193
|
const limit = 50;
|
|
1394
|
-
const
|
|
1194
|
+
const loadSwaps = useCallback(
|
|
1395
1195
|
async (nextOffset, replace = false) => {
|
|
1396
1196
|
var _a;
|
|
1397
1197
|
try {
|
|
@@ -1408,28 +1208,27 @@ const ReturnsPage = () => {
|
|
|
1408
1208
|
params.set("status", statusFilter);
|
|
1409
1209
|
}
|
|
1410
1210
|
if (debouncedSearchQuery.trim()) {
|
|
1411
|
-
params.set("
|
|
1211
|
+
params.set("order_id", debouncedSearchQuery.trim());
|
|
1412
1212
|
}
|
|
1413
1213
|
if (createdByFilter !== "all") {
|
|
1414
1214
|
params.set("created_by", createdByFilter);
|
|
1415
1215
|
}
|
|
1416
|
-
params.set("order", "created_at");
|
|
1417
1216
|
const response = await fetch(
|
|
1418
|
-
`/admin/
|
|
1217
|
+
`/admin/swaps?${params.toString()}`,
|
|
1419
1218
|
{ credentials: "include" }
|
|
1420
1219
|
);
|
|
1421
1220
|
if (!response.ok) {
|
|
1422
1221
|
const message = await response.text();
|
|
1423
|
-
throw new Error(message || "Unable to load
|
|
1222
|
+
throw new Error(message || "Unable to load swaps");
|
|
1424
1223
|
}
|
|
1425
1224
|
const payload = await response.json();
|
|
1426
1225
|
setCount(payload.count ?? 0);
|
|
1427
|
-
setOffset(nextOffset + (((_a = payload.
|
|
1226
|
+
setOffset(nextOffset + (((_a = payload.swaps) == null ? void 0 : _a.length) ?? 0));
|
|
1428
1227
|
setItems(
|
|
1429
|
-
(prev) => replace ? payload.
|
|
1228
|
+
(prev) => replace ? payload.swaps ?? [] : [...prev, ...payload.swaps ?? []]
|
|
1430
1229
|
);
|
|
1431
1230
|
} catch (loadError) {
|
|
1432
|
-
const message = loadError instanceof Error ? loadError.message : "Unable to load
|
|
1231
|
+
const message = loadError instanceof Error ? loadError.message : "Unable to load swaps";
|
|
1433
1232
|
setError(message);
|
|
1434
1233
|
} finally {
|
|
1435
1234
|
setIsLoading(false);
|
|
@@ -1439,8 +1238,8 @@ const ReturnsPage = () => {
|
|
|
1439
1238
|
[statusFilter, createdByFilter, debouncedSearchQuery]
|
|
1440
1239
|
);
|
|
1441
1240
|
useEffect(() => {
|
|
1442
|
-
void
|
|
1443
|
-
}, [statusFilter, createdByFilter, debouncedSearchQuery,
|
|
1241
|
+
void loadSwaps(0, true);
|
|
1242
|
+
}, [statusFilter, createdByFilter, debouncedSearchQuery, loadSwaps]);
|
|
1444
1243
|
const hasMore = useMemo(() => offset < count, [offset, count]);
|
|
1445
1244
|
const availableStatuses = useMemo(() => {
|
|
1446
1245
|
const statuses = /* @__PURE__ */ new Set();
|
|
@@ -1450,16 +1249,16 @@ const ReturnsPage = () => {
|
|
|
1450
1249
|
return /* @__PURE__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxs(Container, { className: "mx-auto flex w-full max-w-7xl flex-col gap-6 p-6", children: [
|
|
1451
1250
|
/* @__PURE__ */ jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1452
1251
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1453
|
-
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "
|
|
1454
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer
|
|
1252
|
+
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "Exchanges" }),
|
|
1253
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer exchange requests" })
|
|
1455
1254
|
] }),
|
|
1456
|
-
/* @__PURE__ */ jsx(Button, { variant: "primary", onClick: () =>
|
|
1255
|
+
/* @__PURE__ */ jsx(Button, { variant: "primary", onClick: () => loadSwaps(0, true), children: "Refresh" })
|
|
1457
1256
|
] }),
|
|
1458
1257
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1459
1258
|
/* @__PURE__ */ jsx(
|
|
1460
1259
|
Input,
|
|
1461
1260
|
{
|
|
1462
|
-
placeholder: "Search by
|
|
1261
|
+
placeholder: "Search by swap ID or order ID",
|
|
1463
1262
|
value: searchQuery,
|
|
1464
1263
|
onChange: (event) => setSearchQuery(event.target.value),
|
|
1465
1264
|
className: "md:max-w-sm"
|
|
@@ -1499,51 +1298,50 @@ const ReturnsPage = () => {
|
|
|
1499
1298
|
Button,
|
|
1500
1299
|
{
|
|
1501
1300
|
variant: "secondary",
|
|
1502
|
-
onClick: () =>
|
|
1301
|
+
onClick: () => loadSwaps(0, true),
|
|
1503
1302
|
children: "Try again"
|
|
1504
1303
|
}
|
|
1505
1304
|
) })
|
|
1506
1305
|
] }) : null,
|
|
1507
|
-
isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading
|
|
1508
|
-
/* @__PURE__ */ jsx(Heading, { level: "h3", className: "text-xl", children: "No
|
|
1509
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "
|
|
1306
|
+
isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading swaps..." }) }) : items.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
|
|
1307
|
+
/* @__PURE__ */ jsx(Heading, { level: "h3", className: "text-xl", children: "No exchanges yet" }),
|
|
1308
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Exchange requests created by customers will appear here." })
|
|
1510
1309
|
] }) : /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
|
|
1511
1310
|
/* @__PURE__ */ jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
1512
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "
|
|
1311
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Exchange ID" }),
|
|
1513
1312
|
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
|
|
1514
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Customer" }),
|
|
1515
1313
|
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
|
|
1516
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "
|
|
1314
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Difference Due" }),
|
|
1517
1315
|
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
1518
1316
|
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
1519
1317
|
] }) }),
|
|
1520
|
-
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((
|
|
1318
|
+
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((swap) => /* @__PURE__ */ jsxs(
|
|
1521
1319
|
"tr",
|
|
1522
1320
|
{
|
|
1523
1321
|
className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
|
|
1524
|
-
onClick: () => navigate(`/
|
|
1322
|
+
onClick: () => navigate(`/swaps/${swap.id}`),
|
|
1525
1323
|
children: [
|
|
1526
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-0.5", children: /* @__PURE__ */ jsx("span", { children:
|
|
1527
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children:
|
|
1528
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.customer_email || returnOrder.order_email || "—" }),
|
|
1324
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-0.5", children: /* @__PURE__ */ jsx("span", { children: swap.id }) }) }),
|
|
1325
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: swap.order_id }),
|
|
1529
1326
|
/* @__PURE__ */ jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsx(
|
|
1530
1327
|
Badge,
|
|
1531
1328
|
{
|
|
1532
1329
|
size: "2xsmall",
|
|
1533
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
1534
|
-
children:
|
|
1330
|
+
className: `uppercase ${getStatusBadgeClass$6(swap.status)}`,
|
|
1331
|
+
children: swap.status.replace(/_/g, " ")
|
|
1535
1332
|
}
|
|
1536
1333
|
) }),
|
|
1537
1334
|
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
|
|
1538
|
-
const amount =
|
|
1335
|
+
const amount = swap.difference_due;
|
|
1539
1336
|
if (amount == null || amount === void 0) {
|
|
1540
1337
|
return "—";
|
|
1541
1338
|
}
|
|
1542
1339
|
const displayAmount = Number(amount) / 100;
|
|
1543
|
-
const currency =
|
|
1544
|
-
|
|
1340
|
+
const currency = swap.currency_code || "$";
|
|
1341
|
+
const sign = displayAmount >= 0 ? "+" : "";
|
|
1342
|
+
return `${sign}${currency}${displayAmount.toFixed(2)}`;
|
|
1545
1343
|
})() }),
|
|
1546
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(
|
|
1344
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(swap.created_at).toLocaleDateString("en-US", {
|
|
1547
1345
|
year: "numeric",
|
|
1548
1346
|
month: "short",
|
|
1549
1347
|
day: "numeric",
|
|
@@ -1558,14 +1356,14 @@ const ReturnsPage = () => {
|
|
|
1558
1356
|
size: "small",
|
|
1559
1357
|
onClick: (e) => {
|
|
1560
1358
|
e.stopPropagation();
|
|
1561
|
-
navigate(`/app/orders/${
|
|
1359
|
+
navigate(`/app/orders/${swap.order_id}`);
|
|
1562
1360
|
},
|
|
1563
1361
|
children: "Go to order"
|
|
1564
1362
|
}
|
|
1565
1363
|
) })
|
|
1566
1364
|
]
|
|
1567
1365
|
},
|
|
1568
|
-
|
|
1366
|
+
swap.id
|
|
1569
1367
|
)) })
|
|
1570
1368
|
] }) }),
|
|
1571
1369
|
hasMore ? /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(
|
|
@@ -1573,17 +1371,17 @@ const ReturnsPage = () => {
|
|
|
1573
1371
|
{
|
|
1574
1372
|
variant: "secondary",
|
|
1575
1373
|
isLoading: isFetchingMore,
|
|
1576
|
-
onClick: () =>
|
|
1374
|
+
onClick: () => loadSwaps(offset, false),
|
|
1577
1375
|
children: "Load more"
|
|
1578
1376
|
}
|
|
1579
1377
|
) }) : null
|
|
1580
1378
|
] }) });
|
|
1581
1379
|
};
|
|
1582
|
-
const config$
|
|
1583
|
-
label: "
|
|
1380
|
+
const config$6 = defineRouteConfig({
|
|
1381
|
+
label: "Exchanges",
|
|
1584
1382
|
icon: ArrowPath
|
|
1585
1383
|
});
|
|
1586
|
-
const useDebounce = (value, delay) => {
|
|
1384
|
+
const useDebounce$1 = (value, delay) => {
|
|
1587
1385
|
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
1588
1386
|
useEffect(() => {
|
|
1589
1387
|
const handler = setTimeout(() => setDebouncedValue(value), delay);
|
|
@@ -1591,39 +1389,39 @@ const useDebounce = (value, delay) => {
|
|
|
1591
1389
|
}, [value, delay]);
|
|
1592
1390
|
return debouncedValue;
|
|
1593
1391
|
};
|
|
1594
|
-
const getStatusBadgeClass$
|
|
1392
|
+
const getStatusBadgeClass$5 = (status) => {
|
|
1595
1393
|
const statusLower = status.toLowerCase();
|
|
1596
1394
|
if (statusLower === "requested") {
|
|
1597
1395
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
1598
1396
|
}
|
|
1599
|
-
if (statusLower === "
|
|
1397
|
+
if (statusLower === "received") {
|
|
1600
1398
|
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
1601
1399
|
}
|
|
1602
|
-
if (statusLower === "
|
|
1400
|
+
if (statusLower === "requires_action") {
|
|
1603
1401
|
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
1604
1402
|
}
|
|
1605
1403
|
if (statusLower === "completed") {
|
|
1606
1404
|
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1607
1405
|
}
|
|
1608
|
-
if (statusLower === "
|
|
1406
|
+
if (statusLower === "canceled") {
|
|
1609
1407
|
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
1610
1408
|
}
|
|
1611
1409
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
1612
1410
|
};
|
|
1613
|
-
const
|
|
1411
|
+
const ReturnsPage = () => {
|
|
1614
1412
|
const navigate = useNavigate();
|
|
1615
1413
|
const [items, setItems] = useState([]);
|
|
1616
1414
|
const [statusFilter, setStatusFilter] = useState("all");
|
|
1617
1415
|
const [createdByFilter, setCreatedByFilter] = useState("all");
|
|
1618
1416
|
const [searchQuery, setSearchQuery] = useState("");
|
|
1619
|
-
const debouncedSearchQuery = useDebounce(searchQuery, 300);
|
|
1417
|
+
const debouncedSearchQuery = useDebounce$1(searchQuery, 300);
|
|
1620
1418
|
const [isLoading, setIsLoading] = useState(true);
|
|
1621
1419
|
const [isFetchingMore, setIsFetchingMore] = useState(false);
|
|
1622
1420
|
const [error, setError] = useState(null);
|
|
1623
1421
|
const [offset, setOffset] = useState(0);
|
|
1624
1422
|
const [count, setCount] = useState(0);
|
|
1625
1423
|
const limit = 50;
|
|
1626
|
-
const
|
|
1424
|
+
const loadReturns = useCallback(
|
|
1627
1425
|
async (nextOffset, replace = false) => {
|
|
1628
1426
|
var _a;
|
|
1629
1427
|
try {
|
|
@@ -1640,27 +1438,28 @@ const SwapsPage = () => {
|
|
|
1640
1438
|
params.set("status", statusFilter);
|
|
1641
1439
|
}
|
|
1642
1440
|
if (debouncedSearchQuery.trim()) {
|
|
1643
|
-
params.set("
|
|
1441
|
+
params.set("q", debouncedSearchQuery.trim());
|
|
1644
1442
|
}
|
|
1645
1443
|
if (createdByFilter !== "all") {
|
|
1646
1444
|
params.set("created_by", createdByFilter);
|
|
1647
1445
|
}
|
|
1446
|
+
params.set("order", "created_at");
|
|
1648
1447
|
const response = await fetch(
|
|
1649
|
-
`/admin/
|
|
1448
|
+
`/admin/return?${params.toString()}`,
|
|
1650
1449
|
{ credentials: "include" }
|
|
1651
1450
|
);
|
|
1652
1451
|
if (!response.ok) {
|
|
1653
1452
|
const message = await response.text();
|
|
1654
|
-
throw new Error(message || "Unable to load
|
|
1453
|
+
throw new Error(message || "Unable to load return orders");
|
|
1655
1454
|
}
|
|
1656
1455
|
const payload = await response.json();
|
|
1657
1456
|
setCount(payload.count ?? 0);
|
|
1658
|
-
setOffset(nextOffset + (((_a = payload.
|
|
1457
|
+
setOffset(nextOffset + (((_a = payload.returns) == null ? void 0 : _a.length) ?? 0));
|
|
1659
1458
|
setItems(
|
|
1660
|
-
(prev) => replace ? payload.
|
|
1459
|
+
(prev) => replace ? payload.returns ?? [] : [...prev, ...payload.returns ?? []]
|
|
1661
1460
|
);
|
|
1662
1461
|
} catch (loadError) {
|
|
1663
|
-
const message = loadError instanceof Error ? loadError.message : "Unable to load
|
|
1462
|
+
const message = loadError instanceof Error ? loadError.message : "Unable to load return orders";
|
|
1664
1463
|
setError(message);
|
|
1665
1464
|
} finally {
|
|
1666
1465
|
setIsLoading(false);
|
|
@@ -1670,8 +1469,8 @@ const SwapsPage = () => {
|
|
|
1670
1469
|
[statusFilter, createdByFilter, debouncedSearchQuery]
|
|
1671
1470
|
);
|
|
1672
1471
|
useEffect(() => {
|
|
1673
|
-
void
|
|
1674
|
-
}, [statusFilter, createdByFilter, debouncedSearchQuery,
|
|
1472
|
+
void loadReturns(0, true);
|
|
1473
|
+
}, [statusFilter, createdByFilter, debouncedSearchQuery, loadReturns]);
|
|
1675
1474
|
const hasMore = useMemo(() => offset < count, [offset, count]);
|
|
1676
1475
|
const availableStatuses = useMemo(() => {
|
|
1677
1476
|
const statuses = /* @__PURE__ */ new Set();
|
|
@@ -1681,16 +1480,16 @@ const SwapsPage = () => {
|
|
|
1681
1480
|
return /* @__PURE__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxs(Container, { className: "mx-auto flex w-full max-w-7xl flex-col gap-6 p-6", children: [
|
|
1682
1481
|
/* @__PURE__ */ jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1683
1482
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1684
|
-
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "
|
|
1685
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer
|
|
1483
|
+
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "Return Orders" }),
|
|
1484
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer return orders" })
|
|
1686
1485
|
] }),
|
|
1687
|
-
/* @__PURE__ */ jsx(Button, { variant: "primary", onClick: () =>
|
|
1486
|
+
/* @__PURE__ */ jsx(Button, { variant: "primary", onClick: () => loadReturns(0, true), children: "Refresh" })
|
|
1688
1487
|
] }),
|
|
1689
1488
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1690
1489
|
/* @__PURE__ */ jsx(
|
|
1691
1490
|
Input,
|
|
1692
1491
|
{
|
|
1693
|
-
placeholder: "Search by
|
|
1492
|
+
placeholder: "Search by return ID, order ID, or customer email",
|
|
1694
1493
|
value: searchQuery,
|
|
1695
1494
|
onChange: (event) => setSearchQuery(event.target.value),
|
|
1696
1495
|
className: "md:max-w-sm"
|
|
@@ -1730,50 +1529,51 @@ const SwapsPage = () => {
|
|
|
1730
1529
|
Button,
|
|
1731
1530
|
{
|
|
1732
1531
|
variant: "secondary",
|
|
1733
|
-
onClick: () =>
|
|
1532
|
+
onClick: () => loadReturns(0, true),
|
|
1734
1533
|
children: "Try again"
|
|
1735
1534
|
}
|
|
1736
1535
|
) })
|
|
1737
1536
|
] }) : null,
|
|
1738
|
-
isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading
|
|
1739
|
-
/* @__PURE__ */ jsx(Heading, { level: "h3", className: "text-xl", children: "No
|
|
1740
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "
|
|
1537
|
+
isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading return orders..." }) }) : items.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
|
|
1538
|
+
/* @__PURE__ */ jsx(Heading, { level: "h3", className: "text-xl", children: "No return orders yet" }),
|
|
1539
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Return orders created by customers will appear here." })
|
|
1741
1540
|
] }) : /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
|
|
1742
1541
|
/* @__PURE__ */ jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
1743
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "
|
|
1542
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Return ID" }),
|
|
1744
1543
|
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
|
|
1544
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Customer" }),
|
|
1745
1545
|
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
|
|
1746
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "
|
|
1546
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Refund Amount" }),
|
|
1747
1547
|
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
1748
1548
|
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
1749
1549
|
] }) }),
|
|
1750
|
-
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((
|
|
1550
|
+
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((returnOrder) => /* @__PURE__ */ jsxs(
|
|
1751
1551
|
"tr",
|
|
1752
1552
|
{
|
|
1753
1553
|
className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
|
|
1754
|
-
onClick: () => navigate(`/
|
|
1554
|
+
onClick: () => navigate(`/returns/${returnOrder.id}`),
|
|
1755
1555
|
children: [
|
|
1756
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-0.5", children: /* @__PURE__ */ jsx("span", { children:
|
|
1757
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children:
|
|
1556
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-0.5", children: /* @__PURE__ */ jsx("span", { children: returnOrder.id }) }) }),
|
|
1557
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.order_id }),
|
|
1558
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.customer_email || returnOrder.order_email || "—" }),
|
|
1758
1559
|
/* @__PURE__ */ jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsx(
|
|
1759
1560
|
Badge,
|
|
1760
1561
|
{
|
|
1761
1562
|
size: "2xsmall",
|
|
1762
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
1763
|
-
children:
|
|
1563
|
+
className: `uppercase ${getStatusBadgeClass$5(returnOrder.status)}`,
|
|
1564
|
+
children: returnOrder.status.replace(/_/g, " ")
|
|
1764
1565
|
}
|
|
1765
1566
|
) }),
|
|
1766
1567
|
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
|
|
1767
|
-
const amount =
|
|
1568
|
+
const amount = returnOrder.refund_amount;
|
|
1768
1569
|
if (amount == null || amount === void 0) {
|
|
1769
1570
|
return "—";
|
|
1770
1571
|
}
|
|
1771
1572
|
const displayAmount = Number(amount) / 100;
|
|
1772
|
-
const currency =
|
|
1773
|
-
|
|
1774
|
-
return `${sign}${currency}${displayAmount.toFixed(2)}`;
|
|
1573
|
+
const currency = returnOrder.currency_code || "$";
|
|
1574
|
+
return `${currency}${displayAmount.toFixed(2)}`;
|
|
1775
1575
|
})() }),
|
|
1776
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(
|
|
1576
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(returnOrder.created_at).toLocaleDateString("en-US", {
|
|
1777
1577
|
year: "numeric",
|
|
1778
1578
|
month: "short",
|
|
1779
1579
|
day: "numeric",
|
|
@@ -1788,14 +1588,14 @@ const SwapsPage = () => {
|
|
|
1788
1588
|
size: "small",
|
|
1789
1589
|
onClick: (e) => {
|
|
1790
1590
|
e.stopPropagation();
|
|
1791
|
-
navigate(`/app/orders/${
|
|
1591
|
+
navigate(`/app/orders/${returnOrder.order_id}`);
|
|
1792
1592
|
},
|
|
1793
1593
|
children: "Go to order"
|
|
1794
1594
|
}
|
|
1795
1595
|
) })
|
|
1796
1596
|
]
|
|
1797
1597
|
},
|
|
1798
|
-
|
|
1598
|
+
returnOrder.id
|
|
1799
1599
|
)) })
|
|
1800
1600
|
] }) }),
|
|
1801
1601
|
hasMore ? /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(
|
|
@@ -1803,17 +1603,25 @@ const SwapsPage = () => {
|
|
|
1803
1603
|
{
|
|
1804
1604
|
variant: "secondary",
|
|
1805
1605
|
isLoading: isFetchingMore,
|
|
1806
|
-
onClick: () =>
|
|
1606
|
+
onClick: () => loadReturns(offset, false),
|
|
1807
1607
|
children: "Load more"
|
|
1808
1608
|
}
|
|
1809
1609
|
) }) : null
|
|
1810
1610
|
] }) });
|
|
1811
1611
|
};
|
|
1812
|
-
const config$
|
|
1813
|
-
label: "
|
|
1612
|
+
const config$5 = defineRouteConfig({
|
|
1613
|
+
label: "Return Orders",
|
|
1814
1614
|
icon: ArrowPath
|
|
1815
1615
|
});
|
|
1816
|
-
const
|
|
1616
|
+
const useDebounce = (value, delay) => {
|
|
1617
|
+
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
1618
|
+
useEffect(() => {
|
|
1619
|
+
const handler = setTimeout(() => setDebouncedValue(value), delay);
|
|
1620
|
+
return () => clearTimeout(handler);
|
|
1621
|
+
}, [value, delay]);
|
|
1622
|
+
return debouncedValue;
|
|
1623
|
+
};
|
|
1624
|
+
const getStatusBadgeClass$4 = (status) => {
|
|
1817
1625
|
const s2 = status.toLowerCase();
|
|
1818
1626
|
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1819
1627
|
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
@@ -1821,118 +1629,191 @@ const getStatusBadgeClass$3 = (status) => {
|
|
|
1821
1629
|
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
1822
1630
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
1823
1631
|
};
|
|
1824
|
-
const
|
|
1825
|
-
var _a;
|
|
1632
|
+
const PaymentsPage = () => {
|
|
1826
1633
|
const navigate = useNavigate();
|
|
1827
|
-
const
|
|
1828
|
-
const
|
|
1829
|
-
const [
|
|
1830
|
-
const
|
|
1634
|
+
const [items, setItems] = useState([]);
|
|
1635
|
+
const [statusFilter, setStatusFilter] = useState("all");
|
|
1636
|
+
const [orderIdSearch, setOrderIdSearch] = useState("");
|
|
1637
|
+
const debouncedOrderId = useDebounce(orderIdSearch, 300);
|
|
1638
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
1639
|
+
const [isFetchingMore, setIsFetchingMore] = useState(false);
|
|
1831
1640
|
const [error, setError] = useState(null);
|
|
1641
|
+
const [offset, setOffset] = useState(0);
|
|
1642
|
+
const [count, setCount] = useState(0);
|
|
1643
|
+
const limit = 50;
|
|
1644
|
+
const loadTransactions = useCallback(
|
|
1645
|
+
async (nextOffset, replace) => {
|
|
1646
|
+
try {
|
|
1647
|
+
if (replace) setIsLoading(true);
|
|
1648
|
+
else setIsFetchingMore(true);
|
|
1649
|
+
setError(null);
|
|
1650
|
+
const params = new URLSearchParams();
|
|
1651
|
+
params.set("limit", String(limit));
|
|
1652
|
+
params.set("offset", String(nextOffset));
|
|
1653
|
+
if (statusFilter !== "all") params.set("status", statusFilter);
|
|
1654
|
+
if (debouncedOrderId.trim()) params.set("order_id", debouncedOrderId.trim());
|
|
1655
|
+
const response = await fetch(
|
|
1656
|
+
`/admin/payment-transactions?${params.toString()}`,
|
|
1657
|
+
{ credentials: "include" }
|
|
1658
|
+
);
|
|
1659
|
+
if (!response.ok) {
|
|
1660
|
+
const text = await response.text();
|
|
1661
|
+
throw new Error(text || "Failed to load payment transactions");
|
|
1662
|
+
}
|
|
1663
|
+
const payload = await response.json();
|
|
1664
|
+
const list = payload.transactions ?? [];
|
|
1665
|
+
setCount(payload.count ?? 0);
|
|
1666
|
+
setOffset(nextOffset + list.length);
|
|
1667
|
+
setItems((prev) => replace ? list : [...prev, ...list]);
|
|
1668
|
+
} catch (e) {
|
|
1669
|
+
setError(e instanceof Error ? e.message : "Failed to load");
|
|
1670
|
+
} finally {
|
|
1671
|
+
setIsLoading(false);
|
|
1672
|
+
setIsFetchingMore(false);
|
|
1673
|
+
}
|
|
1674
|
+
},
|
|
1675
|
+
[statusFilter, debouncedOrderId]
|
|
1676
|
+
);
|
|
1832
1677
|
useEffect(() => {
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1678
|
+
void loadTransactions(0, true);
|
|
1679
|
+
}, [loadTransactions]);
|
|
1680
|
+
const hasMore = useMemo(() => offset < count, [offset, count]);
|
|
1681
|
+
const displayStatus = (t) => {
|
|
1682
|
+
const s2 = t.payment_id != null && t.payment_status != null && t.payment_status !== "" ? t.payment_status : t.session_status ?? "";
|
|
1683
|
+
return s2 !== "" ? s2 : "—";
|
|
1684
|
+
};
|
|
1685
|
+
const displayAmount = (t) => {
|
|
1686
|
+
const code = (t.currency_code ?? "USD").toUpperCase();
|
|
1687
|
+
return `${code} ${Number(t.amount)}`;
|
|
1688
|
+
};
|
|
1689
|
+
return /* @__PURE__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxs(Container, { className: "mx-auto flex w-full max-w-7xl flex-col gap-6 p-6", children: [
|
|
1690
|
+
/* @__PURE__ */ jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1691
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1692
|
+
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "Payments" }),
|
|
1693
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "All payment attempts — completed, pending, failed, requires action" })
|
|
1694
|
+
] }),
|
|
1695
|
+
/* @__PURE__ */ jsx(Button, { variant: "primary", onClick: () => loadTransactions(0, true), children: "Refresh" })
|
|
1696
|
+
] }),
|
|
1697
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1698
|
+
/* @__PURE__ */ jsx(
|
|
1699
|
+
Input,
|
|
1700
|
+
{
|
|
1701
|
+
placeholder: "Search by Order ID",
|
|
1702
|
+
value: orderIdSearch,
|
|
1703
|
+
onChange: (e) => setOrderIdSearch(e.target.value),
|
|
1704
|
+
className: "md:max-w-sm",
|
|
1705
|
+
"aria-label": "Search by order ID"
|
|
1706
|
+
}
|
|
1707
|
+
),
|
|
1708
|
+
/* @__PURE__ */ jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxs(
|
|
1709
|
+
"select",
|
|
1710
|
+
{
|
|
1711
|
+
value: statusFilter,
|
|
1712
|
+
onChange: (e) => setStatusFilter(e.target.value),
|
|
1713
|
+
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",
|
|
1714
|
+
"aria-label": "Filter by status",
|
|
1715
|
+
children: [
|
|
1716
|
+
/* @__PURE__ */ jsx("option", { value: "all", children: "All statuses" }),
|
|
1717
|
+
/* @__PURE__ */ jsx("option", { value: "pending", children: "Pending" }),
|
|
1718
|
+
/* @__PURE__ */ jsx("option", { value: "requires_more", children: "Requires more" }),
|
|
1719
|
+
/* @__PURE__ */ jsx("option", { value: "error", children: "Error" }),
|
|
1720
|
+
/* @__PURE__ */ jsx("option", { value: "canceled", children: "Canceled" }),
|
|
1721
|
+
/* @__PURE__ */ jsx("option", { value: "authorized", children: "Authorized" }),
|
|
1722
|
+
/* @__PURE__ */ jsx("option", { value: "captured", children: "Captured" })
|
|
1723
|
+
]
|
|
1724
|
+
}
|
|
1725
|
+
) })
|
|
1726
|
+
] }),
|
|
1864
1727
|
error ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
1865
1728
|
/* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
1866
|
-
/* @__PURE__ */ jsx(
|
|
1867
|
-
] }) :
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
] }),
|
|
1881
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1882
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
|
|
1883
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: displayAmount })
|
|
1884
|
-
] }),
|
|
1885
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1886
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
|
|
1887
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.provider_id })
|
|
1888
|
-
] }),
|
|
1889
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1890
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
|
|
1891
|
-
/* @__PURE__ */ jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsx(
|
|
1892
|
-
Badge,
|
|
1893
|
-
{
|
|
1894
|
-
size: "2xsmall",
|
|
1895
|
-
className: `uppercase ${getStatusBadgeClass$3(displayStatus)}`,
|
|
1896
|
-
children: displayStatus !== "—" ? displayStatus.replace(/_/g, " ") : "—"
|
|
1897
|
-
}
|
|
1898
|
-
) })
|
|
1899
|
-
] }),
|
|
1900
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1901
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Session status (DB)" }),
|
|
1902
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: sessionStatusRaw })
|
|
1903
|
-
] }),
|
|
1904
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1905
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Payment status (DB)" }),
|
|
1906
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: paymentStatusRaw })
|
|
1907
|
-
] }),
|
|
1908
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1909
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Finalized" }),
|
|
1910
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.payment_id != null ? "Yes" : "No" })
|
|
1911
|
-
] }),
|
|
1912
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1913
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Created" }),
|
|
1914
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: new Date(detail.created_at).toLocaleDateString("en-US", {
|
|
1915
|
-
year: "numeric",
|
|
1916
|
-
month: "short",
|
|
1917
|
-
day: "numeric",
|
|
1918
|
-
hour: "numeric",
|
|
1919
|
-
minute: "2-digit",
|
|
1920
|
-
hour12: true
|
|
1921
|
-
}) })
|
|
1922
|
-
] })
|
|
1729
|
+
/* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => loadTransactions(0, true), children: "Try again" }) })
|
|
1730
|
+
] }) : null,
|
|
1731
|
+
isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading payments…" }) }) : items.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
|
|
1732
|
+
/* @__PURE__ */ jsx(Heading, { level: "h3", className: "text-xl", children: "No payment transactions yet" }),
|
|
1733
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Payment attempts will appear here." })
|
|
1734
|
+
] }) : /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
|
|
1735
|
+
/* @__PURE__ */ jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
1736
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
|
|
1737
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Amount" }),
|
|
1738
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Provider" }),
|
|
1739
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
|
|
1740
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Finalized" }),
|
|
1741
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
1742
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
1923
1743
|
] }) }),
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1744
|
+
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((t) => /* @__PURE__ */ jsxs(
|
|
1745
|
+
"tr",
|
|
1746
|
+
{
|
|
1747
|
+
className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
|
|
1748
|
+
onClick: () => navigate(`/payments/${t.payment_session_id}`),
|
|
1749
|
+
children: [
|
|
1750
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: t.order_id ?? "—" }),
|
|
1751
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: displayAmount(t) }),
|
|
1752
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: t.provider_id }),
|
|
1753
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsx(
|
|
1754
|
+
Badge,
|
|
1755
|
+
{
|
|
1756
|
+
size: "2xsmall",
|
|
1757
|
+
className: `uppercase ${getStatusBadgeClass$4(displayStatus(t))}`,
|
|
1758
|
+
children: displayStatus(t) !== "—" ? displayStatus(t).replace(/_/g, " ") : "—"
|
|
1759
|
+
}
|
|
1760
|
+
) }),
|
|
1761
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: t.payment_id != null ? "Yes" : "No" }),
|
|
1762
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(t.created_at).toLocaleDateString("en-US", {
|
|
1763
|
+
year: "numeric",
|
|
1764
|
+
month: "short",
|
|
1765
|
+
day: "numeric",
|
|
1766
|
+
hour: "numeric",
|
|
1767
|
+
minute: "2-digit",
|
|
1768
|
+
hour12: true
|
|
1769
|
+
}) }),
|
|
1770
|
+
/* @__PURE__ */ jsxs("td", { className: "px-4 py-4", children: [
|
|
1771
|
+
/* @__PURE__ */ jsx(
|
|
1772
|
+
Button,
|
|
1773
|
+
{
|
|
1774
|
+
variant: "transparent",
|
|
1775
|
+
size: "small",
|
|
1776
|
+
onClick: (e) => {
|
|
1777
|
+
e.stopPropagation();
|
|
1778
|
+
navigate(`/payments/${t.payment_session_id}`);
|
|
1779
|
+
},
|
|
1780
|
+
children: "View details"
|
|
1781
|
+
}
|
|
1782
|
+
),
|
|
1783
|
+
t.order_id ? /* @__PURE__ */ jsx(
|
|
1784
|
+
Button,
|
|
1785
|
+
{
|
|
1786
|
+
variant: "transparent",
|
|
1787
|
+
size: "small",
|
|
1788
|
+
onClick: (e) => {
|
|
1789
|
+
e.stopPropagation();
|
|
1790
|
+
navigate(`/orders/${t.order_id}`);
|
|
1791
|
+
},
|
|
1792
|
+
children: "Order"
|
|
1793
|
+
}
|
|
1794
|
+
) : null
|
|
1795
|
+
] })
|
|
1796
|
+
]
|
|
1797
|
+
},
|
|
1798
|
+
t.payment_session_id
|
|
1799
|
+
)) })
|
|
1800
|
+
] }) }),
|
|
1801
|
+
hasMore ? /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(
|
|
1802
|
+
Button,
|
|
1803
|
+
{
|
|
1804
|
+
variant: "secondary",
|
|
1805
|
+
isLoading: isFetchingMore,
|
|
1806
|
+
onClick: () => loadTransactions(offset, false),
|
|
1807
|
+
children: "Load more"
|
|
1808
|
+
}
|
|
1809
|
+
) }) : null
|
|
1929
1810
|
] }) });
|
|
1930
1811
|
};
|
|
1931
|
-
const config$
|
|
1932
|
-
label: "
|
|
1812
|
+
const config$4 = defineRouteConfig({
|
|
1813
|
+
label: "Payments",
|
|
1933
1814
|
icon: CreditCard
|
|
1934
1815
|
});
|
|
1935
|
-
const getStatusBadgeClass$
|
|
1816
|
+
const getStatusBadgeClass$3 = (status) => {
|
|
1936
1817
|
const s2 = status.toLowerCase();
|
|
1937
1818
|
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1938
1819
|
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
@@ -2043,7 +1924,7 @@ const RefundDetailPage = () => {
|
|
|
2043
1924
|
Badge,
|
|
2044
1925
|
{
|
|
2045
1926
|
size: "2xsmall",
|
|
2046
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
1927
|
+
className: `uppercase ${getStatusBadgeClass$3(paymentStatus)}`,
|
|
2047
1928
|
children: paymentStatus !== "—" ? paymentStatus.replace(/_/g, " ") : "—"
|
|
2048
1929
|
}
|
|
2049
1930
|
) })
|
|
@@ -2120,11 +2001,11 @@ const RefundDetailPage = () => {
|
|
|
2120
2001
|
] }) : null
|
|
2121
2002
|
] }) });
|
|
2122
2003
|
};
|
|
2123
|
-
const config$
|
|
2004
|
+
const config$3 = defineRouteConfig({
|
|
2124
2005
|
label: "Refund details",
|
|
2125
2006
|
icon: Receipt
|
|
2126
2007
|
});
|
|
2127
|
-
const getStatusBadgeClass$
|
|
2008
|
+
const getStatusBadgeClass$2 = (status) => {
|
|
2128
2009
|
const statusLower = status.toLowerCase();
|
|
2129
2010
|
if (statusLower === "requested") {
|
|
2130
2011
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
@@ -2135,105 +2016,109 @@ const getStatusBadgeClass$1 = (status) => {
|
|
|
2135
2016
|
if (statusLower === "rejected") {
|
|
2136
2017
|
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
2137
2018
|
}
|
|
2138
|
-
if (statusLower === "received") {
|
|
2139
|
-
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
2140
|
-
}
|
|
2141
|
-
if (statusLower === "refunded") {
|
|
2142
|
-
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
2143
|
-
}
|
|
2144
2019
|
if (statusLower === "completed") {
|
|
2145
2020
|
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
2146
2021
|
}
|
|
2147
|
-
if (statusLower === "cancelled") {
|
|
2022
|
+
if (statusLower === "cancelled" || statusLower === "canceled") {
|
|
2148
2023
|
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
2149
2024
|
}
|
|
2025
|
+
if (statusLower === "pending") {
|
|
2026
|
+
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
2027
|
+
}
|
|
2150
2028
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
2151
2029
|
};
|
|
2152
|
-
const
|
|
2153
|
-
var _a, _b;
|
|
2030
|
+
const SwapDetailPage = () => {
|
|
2031
|
+
var _a, _b, _c;
|
|
2154
2032
|
const navigate = useNavigate();
|
|
2155
2033
|
const { id } = useParams();
|
|
2156
|
-
const [
|
|
2034
|
+
const [swap, setSwap] = useState(null);
|
|
2035
|
+
const [order, setOrder] = useState(null);
|
|
2157
2036
|
const [isLoading, setIsLoading] = useState(true);
|
|
2158
|
-
|
|
2037
|
+
useState(false);
|
|
2038
|
+
const [isCancelling, setIsCancelling] = useState(false);
|
|
2159
2039
|
const [error, setError] = useState(null);
|
|
2160
2040
|
const [updateError, setUpdateError] = useState(null);
|
|
2161
2041
|
const [updateSuccess, setUpdateSuccess] = useState(false);
|
|
2162
2042
|
useEffect(() => {
|
|
2163
2043
|
if (!id) {
|
|
2164
|
-
navigate("/
|
|
2044
|
+
navigate("/swaps");
|
|
2165
2045
|
return;
|
|
2166
2046
|
}
|
|
2167
|
-
const
|
|
2047
|
+
const loadSwap = async () => {
|
|
2168
2048
|
try {
|
|
2169
2049
|
setIsLoading(true);
|
|
2170
2050
|
setError(null);
|
|
2171
|
-
const response = await fetch(`/admin/
|
|
2051
|
+
const response = await fetch(`/admin/swaps/${id}`, {
|
|
2172
2052
|
credentials: "include"
|
|
2173
2053
|
});
|
|
2174
2054
|
if (!response.ok) {
|
|
2175
2055
|
const message = await response.text();
|
|
2176
|
-
throw new Error(message || "Unable to load
|
|
2056
|
+
throw new Error(message || "Unable to load swap");
|
|
2177
2057
|
}
|
|
2178
2058
|
const payload = await response.json();
|
|
2179
|
-
|
|
2059
|
+
setSwap(payload.swap);
|
|
2060
|
+
setOrder(payload.order || null);
|
|
2180
2061
|
} catch (loadError) {
|
|
2181
|
-
const message = loadError instanceof Error ? loadError.message : "Unable to load
|
|
2062
|
+
const message = loadError instanceof Error ? loadError.message : "Unable to load swap";
|
|
2182
2063
|
setError(message);
|
|
2183
2064
|
} finally {
|
|
2184
2065
|
setIsLoading(false);
|
|
2185
2066
|
}
|
|
2186
2067
|
};
|
|
2187
|
-
void
|
|
2068
|
+
void loadSwap();
|
|
2188
2069
|
}, [id, navigate]);
|
|
2189
|
-
const
|
|
2070
|
+
const handleCancelExchange = async () => {
|
|
2190
2071
|
if (!id) {
|
|
2191
2072
|
return;
|
|
2192
2073
|
}
|
|
2193
2074
|
try {
|
|
2194
|
-
|
|
2075
|
+
setIsCancelling(true);
|
|
2195
2076
|
setUpdateError(null);
|
|
2196
2077
|
setUpdateSuccess(false);
|
|
2197
|
-
const response = await fetch(`/admin/
|
|
2078
|
+
const response = await fetch(`/admin/swaps/${id}/cancel`, {
|
|
2198
2079
|
method: "POST",
|
|
2199
2080
|
headers: {
|
|
2200
2081
|
"Content-Type": "application/json"
|
|
2201
2082
|
},
|
|
2202
|
-
credentials: "include"
|
|
2203
|
-
body: JSON.stringify({ reason: "Rejected by admin" })
|
|
2083
|
+
credentials: "include"
|
|
2204
2084
|
});
|
|
2205
2085
|
if (!response.ok) {
|
|
2206
2086
|
const message = await response.text();
|
|
2207
|
-
throw new Error(message || "Unable to
|
|
2087
|
+
throw new Error(message || "Unable to cancel exchange");
|
|
2208
2088
|
}
|
|
2209
2089
|
const payload = await response.json();
|
|
2210
|
-
|
|
2090
|
+
setSwap(payload.swap);
|
|
2211
2091
|
setUpdateSuccess(true);
|
|
2212
2092
|
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
2213
|
-
const detailResponse = await fetch(`/admin/
|
|
2093
|
+
const detailResponse = await fetch(`/admin/swaps/${id}`, {
|
|
2214
2094
|
credentials: "include"
|
|
2215
2095
|
});
|
|
2216
2096
|
if (detailResponse.ok) {
|
|
2217
2097
|
const detailPayload = await detailResponse.json();
|
|
2218
|
-
|
|
2098
|
+
setSwap(detailPayload.swap);
|
|
2099
|
+
setOrder(detailPayload.order || null);
|
|
2219
2100
|
}
|
|
2220
|
-
} catch (
|
|
2221
|
-
const message =
|
|
2101
|
+
} catch (cancelErr) {
|
|
2102
|
+
const message = cancelErr instanceof Error ? cancelErr.message : "Unable to cancel exchange";
|
|
2222
2103
|
setUpdateError(message);
|
|
2223
2104
|
} finally {
|
|
2224
|
-
|
|
2105
|
+
setIsCancelling(false);
|
|
2225
2106
|
}
|
|
2226
2107
|
};
|
|
2108
|
+
const isOrderExchange = Boolean(swap == null ? void 0 : swap.exchange_id);
|
|
2109
|
+
const canCancelExchange = isOrderExchange && swap && !["cancelled", "canceled", "completed", "declined"].includes(
|
|
2110
|
+
((_a = swap.status) == null ? void 0 : _a.toLowerCase()) ?? ""
|
|
2111
|
+
);
|
|
2227
2112
|
if (isLoading) {
|
|
2228
|
-
return /* @__PURE__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsx(Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading
|
|
2113
|
+
return /* @__PURE__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsx(Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading swap..." }) }) }) });
|
|
2229
2114
|
}
|
|
2230
|
-
if (error || !
|
|
2115
|
+
if (error || !swap) {
|
|
2231
2116
|
return /* @__PURE__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsx(Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
2232
|
-
/* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error || "
|
|
2233
|
-
/* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => navigate("/
|
|
2117
|
+
/* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error || "Swap not found" }),
|
|
2118
|
+
/* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => navigate("/swaps"), children: "Back to list" }) })
|
|
2234
2119
|
] }) }) });
|
|
2235
2120
|
}
|
|
2236
|
-
const statusHistory = ((
|
|
2121
|
+
const statusHistory = ((_b = swap.metadata) == null ? void 0 : _b.status_history) || [];
|
|
2237
2122
|
return /* @__PURE__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxs(Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: [
|
|
2238
2123
|
/* @__PURE__ */ jsxs("header", { className: "flex flex-col gap-3", children: [
|
|
2239
2124
|
/* @__PURE__ */ jsxs(
|
|
@@ -2241,7 +2126,7 @@ const ReturnDetailPage = () => {
|
|
|
2241
2126
|
{
|
|
2242
2127
|
variant: "transparent",
|
|
2243
2128
|
size: "small",
|
|
2244
|
-
onClick: () => navigate("/
|
|
2129
|
+
onClick: () => navigate("/swaps"),
|
|
2245
2130
|
className: "w-fit",
|
|
2246
2131
|
children: [
|
|
2247
2132
|
/* @__PURE__ */ jsx(ArrowLeft, { className: "mr-2" }),
|
|
@@ -2251,81 +2136,67 @@ const ReturnDetailPage = () => {
|
|
|
2251
2136
|
),
|
|
2252
2137
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 md:flex-row md:items-center md:justify-between", children: [
|
|
2253
2138
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
2254
|
-
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "
|
|
2255
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children:
|
|
2139
|
+
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "Exchange Details" }),
|
|
2140
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: swap.id })
|
|
2256
2141
|
] }),
|
|
2257
2142
|
/* @__PURE__ */ jsx(
|
|
2258
2143
|
Badge,
|
|
2259
2144
|
{
|
|
2260
2145
|
size: "small",
|
|
2261
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
2262
|
-
children:
|
|
2146
|
+
className: `uppercase ${getStatusBadgeClass$2(swap.status)}`,
|
|
2147
|
+
children: swap.status.replace(/_/g, " ")
|
|
2263
2148
|
}
|
|
2264
2149
|
)
|
|
2265
2150
|
] })
|
|
2266
2151
|
] }),
|
|
2267
|
-
|
|
2152
|
+
canCancelExchange && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
2268
2153
|
/* @__PURE__ */ jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsx(
|
|
2269
2154
|
Button,
|
|
2270
2155
|
{
|
|
2271
2156
|
variant: "danger",
|
|
2272
|
-
onClick:
|
|
2273
|
-
disabled:
|
|
2274
|
-
isLoading:
|
|
2275
|
-
children: "
|
|
2157
|
+
onClick: handleCancelExchange,
|
|
2158
|
+
disabled: isCancelling,
|
|
2159
|
+
isLoading: isCancelling,
|
|
2160
|
+
children: "Cancel Exchange"
|
|
2276
2161
|
}
|
|
2277
2162
|
) }),
|
|
2278
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children:
|
|
2279
|
-
] }),
|
|
2280
|
-
/* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2281
|
-
/* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Information" }),
|
|
2282
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
2283
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2284
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Return ID" }),
|
|
2285
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: returnOrder.id })
|
|
2286
|
-
] }),
|
|
2287
|
-
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
|
|
2288
|
-
Button,
|
|
2289
|
-
{
|
|
2290
|
-
variant: "secondary",
|
|
2291
|
-
onClick: () => {
|
|
2292
|
-
window.open(
|
|
2293
|
-
`/app/orders/${returnOrder.order_id}`,
|
|
2294
|
-
"_blank"
|
|
2295
|
-
);
|
|
2296
|
-
},
|
|
2297
|
-
children: "View order"
|
|
2298
|
-
}
|
|
2299
|
-
) })
|
|
2300
|
-
] })
|
|
2163
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "This will cancel the exchange request. The order will remain unchanged." })
|
|
2301
2164
|
] }),
|
|
2302
2165
|
/* @__PURE__ */ jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
|
|
2303
2166
|
/* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2304
|
-
/* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-4 text-lg", children: "
|
|
2167
|
+
/* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-4 text-lg", children: "Exchange Information" }),
|
|
2305
2168
|
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
2306
2169
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
2307
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
2308
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children:
|
|
2170
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
|
|
2171
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: swap.id })
|
|
2309
2172
|
] }),
|
|
2310
2173
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
2311
2174
|
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Status" }),
|
|
2312
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children:
|
|
2175
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: swap.status })
|
|
2313
2176
|
] }),
|
|
2314
|
-
|
|
2177
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2178
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Difference Due" }),
|
|
2179
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: swap.difference_due != null ? `${swap.currency_code || "$"}${(Number(swap.difference_due) / 100).toFixed(2)}` : "—" })
|
|
2180
|
+
] }),
|
|
2181
|
+
swap.reason && /* @__PURE__ */ jsxs("div", { children: [
|
|
2315
2182
|
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Reason" }),
|
|
2316
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children:
|
|
2183
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: swap.reason })
|
|
2317
2184
|
] }),
|
|
2318
|
-
|
|
2185
|
+
swap.note && /* @__PURE__ */ jsxs("div", { children: [
|
|
2319
2186
|
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Note" }),
|
|
2320
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children:
|
|
2187
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: swap.note })
|
|
2321
2188
|
] }),
|
|
2322
2189
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
2323
2190
|
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Created" }),
|
|
2324
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: new Date(
|
|
2191
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: new Date(swap.created_at).toLocaleString() })
|
|
2325
2192
|
] }),
|
|
2326
2193
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
2327
2194
|
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Last Updated" }),
|
|
2328
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: new Date(
|
|
2195
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: new Date(swap.updated_at).toLocaleString() })
|
|
2196
|
+
] }),
|
|
2197
|
+
swap.exchange_id && /* @__PURE__ */ jsxs("div", { children: [
|
|
2198
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
|
|
2199
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: swap.exchange_id })
|
|
2329
2200
|
] })
|
|
2330
2201
|
] })
|
|
2331
2202
|
] }),
|
|
@@ -2340,7 +2211,7 @@ const ReturnDetailPage = () => {
|
|
|
2340
2211
|
Badge,
|
|
2341
2212
|
{
|
|
2342
2213
|
size: "2xsmall",
|
|
2343
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
2214
|
+
className: `uppercase ${getStatusBadgeClass$2(entry.status)}`,
|
|
2344
2215
|
children: entry.status.replace(/_/g, " ")
|
|
2345
2216
|
}
|
|
2346
2217
|
) }),
|
|
@@ -2355,31 +2226,31 @@ const ReturnDetailPage = () => {
|
|
|
2355
2226
|
)) }) : /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "No status history available" })
|
|
2356
2227
|
] })
|
|
2357
2228
|
] }),
|
|
2358
|
-
|
|
2229
|
+
order && /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2359
2230
|
/* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-4 text-lg", children: "Related Order Information" }),
|
|
2360
2231
|
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
2361
2232
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
2362
2233
|
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Order ID" }),
|
|
2363
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children:
|
|
2234
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: order.id })
|
|
2364
2235
|
] }),
|
|
2365
2236
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
2366
2237
|
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Status" }),
|
|
2367
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children:
|
|
2238
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: order.status || "—" })
|
|
2368
2239
|
] }),
|
|
2369
2240
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
2370
2241
|
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
|
|
2371
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: ((
|
|
2242
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: ((_c = order.customer) == null ? void 0 : _c.email) || order.email || "—" })
|
|
2372
2243
|
] }),
|
|
2373
|
-
|
|
2244
|
+
order.total && /* @__PURE__ */ jsxs("div", { children: [
|
|
2374
2245
|
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
|
|
2375
2246
|
/* @__PURE__ */ jsxs(Text, { className: "font-medium", children: [
|
|
2376
|
-
|
|
2377
|
-
(Number(
|
|
2247
|
+
order.currency_code || "$",
|
|
2248
|
+
(Number(order.total) / 100).toFixed(2)
|
|
2378
2249
|
] })
|
|
2379
2250
|
] })
|
|
2380
2251
|
] })
|
|
2381
2252
|
] }),
|
|
2382
|
-
|
|
2253
|
+
swap.return_items && swap.return_items.length > 0 && /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2383
2254
|
/* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Items" }),
|
|
2384
2255
|
/* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
|
|
2385
2256
|
/* @__PURE__ */ jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
@@ -2387,22 +2258,33 @@ const ReturnDetailPage = () => {
|
|
|
2387
2258
|
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" }),
|
|
2388
2259
|
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Reason" })
|
|
2389
2260
|
] }) }),
|
|
2390
|
-
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children:
|
|
2261
|
+
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.return_items.map((item, index) => /* @__PURE__ */ jsxs("tr", { children: [
|
|
2391
2262
|
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.id }),
|
|
2392
2263
|
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity }),
|
|
2393
2264
|
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.reason || "—" })
|
|
2394
2265
|
] }, item.id || index)) })
|
|
2395
2266
|
] }) })
|
|
2396
2267
|
] }),
|
|
2397
|
-
|
|
2398
|
-
|
|
2268
|
+
swap.new_items && swap.new_items.length > 0 && /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2269
|
+
/* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-4 text-lg", children: "New Items" }),
|
|
2270
|
+
/* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
|
|
2271
|
+
/* @__PURE__ */ jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
2272
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Variant ID" }),
|
|
2273
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" })
|
|
2274
|
+
] }) }),
|
|
2275
|
+
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.new_items.map((item, index) => /* @__PURE__ */ jsxs("tr", { children: [
|
|
2276
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.variant_id }),
|
|
2277
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity })
|
|
2278
|
+
] }, item.variant_id || index)) })
|
|
2279
|
+
] }) })
|
|
2280
|
+
] })
|
|
2399
2281
|
] }) });
|
|
2400
2282
|
};
|
|
2401
|
-
const config$
|
|
2402
|
-
label: "
|
|
2403
|
-
icon:
|
|
2283
|
+
const config$2 = defineRouteConfig({
|
|
2284
|
+
label: "Swap Details",
|
|
2285
|
+
icon: ArrowPath
|
|
2404
2286
|
});
|
|
2405
|
-
const getStatusBadgeClass = (status) => {
|
|
2287
|
+
const getStatusBadgeClass$1 = (status) => {
|
|
2406
2288
|
const statusLower = status.toLowerCase();
|
|
2407
2289
|
if (statusLower === "requested") {
|
|
2408
2290
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
@@ -2413,109 +2295,105 @@ const getStatusBadgeClass = (status) => {
|
|
|
2413
2295
|
if (statusLower === "rejected") {
|
|
2414
2296
|
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
2415
2297
|
}
|
|
2298
|
+
if (statusLower === "received") {
|
|
2299
|
+
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
2300
|
+
}
|
|
2301
|
+
if (statusLower === "refunded") {
|
|
2302
|
+
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
2303
|
+
}
|
|
2416
2304
|
if (statusLower === "completed") {
|
|
2417
2305
|
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
2418
2306
|
}
|
|
2419
|
-
if (statusLower === "cancelled"
|
|
2307
|
+
if (statusLower === "cancelled") {
|
|
2420
2308
|
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
2421
2309
|
}
|
|
2422
|
-
if (statusLower === "pending") {
|
|
2423
|
-
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
2424
|
-
}
|
|
2425
2310
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
2426
2311
|
};
|
|
2427
|
-
const
|
|
2428
|
-
var _a, _b
|
|
2312
|
+
const ReturnDetailPage = () => {
|
|
2313
|
+
var _a, _b;
|
|
2429
2314
|
const navigate = useNavigate();
|
|
2430
2315
|
const { id } = useParams();
|
|
2431
|
-
const [
|
|
2432
|
-
const [order, setOrder] = useState(null);
|
|
2316
|
+
const [returnOrder, setReturnOrder] = useState(null);
|
|
2433
2317
|
const [isLoading, setIsLoading] = useState(true);
|
|
2434
|
-
useState(false);
|
|
2435
|
-
const [isCancelling, setIsCancelling] = useState(false);
|
|
2318
|
+
const [isRejecting, setIsRejecting] = useState(false);
|
|
2436
2319
|
const [error, setError] = useState(null);
|
|
2437
2320
|
const [updateError, setUpdateError] = useState(null);
|
|
2438
2321
|
const [updateSuccess, setUpdateSuccess] = useState(false);
|
|
2439
2322
|
useEffect(() => {
|
|
2440
2323
|
if (!id) {
|
|
2441
|
-
navigate("/
|
|
2324
|
+
navigate("/returns");
|
|
2442
2325
|
return;
|
|
2443
2326
|
}
|
|
2444
|
-
const
|
|
2327
|
+
const loadReturn = async () => {
|
|
2445
2328
|
try {
|
|
2446
2329
|
setIsLoading(true);
|
|
2447
2330
|
setError(null);
|
|
2448
|
-
const response = await fetch(`/admin/
|
|
2331
|
+
const response = await fetch(`/admin/returns/${id}`, {
|
|
2449
2332
|
credentials: "include"
|
|
2450
2333
|
});
|
|
2451
2334
|
if (!response.ok) {
|
|
2452
2335
|
const message = await response.text();
|
|
2453
|
-
throw new Error(message || "Unable to load
|
|
2336
|
+
throw new Error(message || "Unable to load return order");
|
|
2454
2337
|
}
|
|
2455
2338
|
const payload = await response.json();
|
|
2456
|
-
|
|
2457
|
-
setOrder(payload.order || null);
|
|
2339
|
+
setReturnOrder(payload.return);
|
|
2458
2340
|
} catch (loadError) {
|
|
2459
|
-
const message = loadError instanceof Error ? loadError.message : "Unable to load
|
|
2341
|
+
const message = loadError instanceof Error ? loadError.message : "Unable to load return order";
|
|
2460
2342
|
setError(message);
|
|
2461
2343
|
} finally {
|
|
2462
2344
|
setIsLoading(false);
|
|
2463
2345
|
}
|
|
2464
2346
|
};
|
|
2465
|
-
void
|
|
2347
|
+
void loadReturn();
|
|
2466
2348
|
}, [id, navigate]);
|
|
2467
|
-
const
|
|
2349
|
+
const handleReject = async () => {
|
|
2468
2350
|
if (!id) {
|
|
2469
2351
|
return;
|
|
2470
2352
|
}
|
|
2471
2353
|
try {
|
|
2472
|
-
|
|
2354
|
+
setIsRejecting(true);
|
|
2473
2355
|
setUpdateError(null);
|
|
2474
2356
|
setUpdateSuccess(false);
|
|
2475
|
-
const response = await fetch(`/admin/
|
|
2357
|
+
const response = await fetch(`/admin/returns/${id}/reject`, {
|
|
2476
2358
|
method: "POST",
|
|
2477
2359
|
headers: {
|
|
2478
2360
|
"Content-Type": "application/json"
|
|
2479
2361
|
},
|
|
2480
|
-
credentials: "include"
|
|
2362
|
+
credentials: "include",
|
|
2363
|
+
body: JSON.stringify({ reason: "Rejected by admin" })
|
|
2481
2364
|
});
|
|
2482
2365
|
if (!response.ok) {
|
|
2483
2366
|
const message = await response.text();
|
|
2484
|
-
throw new Error(message || "Unable to
|
|
2367
|
+
throw new Error(message || "Unable to reject return");
|
|
2485
2368
|
}
|
|
2486
2369
|
const payload = await response.json();
|
|
2487
|
-
|
|
2370
|
+
setReturnOrder(payload.return);
|
|
2488
2371
|
setUpdateSuccess(true);
|
|
2489
2372
|
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
2490
|
-
const detailResponse = await fetch(`/admin/
|
|
2373
|
+
const detailResponse = await fetch(`/admin/returns/${id}`, {
|
|
2491
2374
|
credentials: "include"
|
|
2492
2375
|
});
|
|
2493
2376
|
if (detailResponse.ok) {
|
|
2494
2377
|
const detailPayload = await detailResponse.json();
|
|
2495
|
-
|
|
2496
|
-
setOrder(detailPayload.order || null);
|
|
2378
|
+
setReturnOrder(detailPayload.return);
|
|
2497
2379
|
}
|
|
2498
|
-
} catch (
|
|
2499
|
-
const message =
|
|
2380
|
+
} catch (updateErr) {
|
|
2381
|
+
const message = updateErr instanceof Error ? updateErr.message : "Unable to reject return";
|
|
2500
2382
|
setUpdateError(message);
|
|
2501
2383
|
} finally {
|
|
2502
|
-
|
|
2384
|
+
setIsRejecting(false);
|
|
2503
2385
|
}
|
|
2504
2386
|
};
|
|
2505
|
-
const isOrderExchange = Boolean(swap == null ? void 0 : swap.exchange_id);
|
|
2506
|
-
const canCancelExchange = isOrderExchange && swap && !["cancelled", "canceled", "completed", "declined"].includes(
|
|
2507
|
-
((_a = swap.status) == null ? void 0 : _a.toLowerCase()) ?? ""
|
|
2508
|
-
);
|
|
2509
2387
|
if (isLoading) {
|
|
2510
|
-
return /* @__PURE__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsx(Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading
|
|
2388
|
+
return /* @__PURE__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsx(Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading return order..." }) }) }) });
|
|
2511
2389
|
}
|
|
2512
|
-
if (error || !
|
|
2390
|
+
if (error || !returnOrder) {
|
|
2513
2391
|
return /* @__PURE__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsx(Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
2514
|
-
/* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error || "
|
|
2515
|
-
/* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => navigate("/
|
|
2392
|
+
/* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error || "Return order not found" }),
|
|
2393
|
+
/* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => navigate("/returns"), children: "Back to list" }) })
|
|
2516
2394
|
] }) }) });
|
|
2517
2395
|
}
|
|
2518
|
-
const statusHistory = ((
|
|
2396
|
+
const statusHistory = ((_a = returnOrder.metadata) == null ? void 0 : _a.status_history) || [];
|
|
2519
2397
|
return /* @__PURE__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxs(Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: [
|
|
2520
2398
|
/* @__PURE__ */ jsxs("header", { className: "flex flex-col gap-3", children: [
|
|
2521
2399
|
/* @__PURE__ */ jsxs(
|
|
@@ -2523,7 +2401,7 @@ const SwapDetailPage = () => {
|
|
|
2523
2401
|
{
|
|
2524
2402
|
variant: "transparent",
|
|
2525
2403
|
size: "small",
|
|
2526
|
-
onClick: () => navigate("/
|
|
2404
|
+
onClick: () => navigate("/returns"),
|
|
2527
2405
|
className: "w-fit",
|
|
2528
2406
|
children: [
|
|
2529
2407
|
/* @__PURE__ */ jsx(ArrowLeft, { className: "mr-2" }),
|
|
@@ -2533,67 +2411,81 @@ const SwapDetailPage = () => {
|
|
|
2533
2411
|
),
|
|
2534
2412
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 md:flex-row md:items-center md:justify-between", children: [
|
|
2535
2413
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
2536
|
-
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "
|
|
2537
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children:
|
|
2414
|
+
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "Return Order Details" }),
|
|
2415
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: returnOrder.id })
|
|
2538
2416
|
] }),
|
|
2539
2417
|
/* @__PURE__ */ jsx(
|
|
2540
2418
|
Badge,
|
|
2541
2419
|
{
|
|
2542
2420
|
size: "small",
|
|
2543
|
-
className: `uppercase ${getStatusBadgeClass(
|
|
2544
|
-
children:
|
|
2421
|
+
className: `uppercase ${getStatusBadgeClass$1(returnOrder.status)}`,
|
|
2422
|
+
children: returnOrder.status.replace(/_/g, " ")
|
|
2545
2423
|
}
|
|
2546
2424
|
)
|
|
2547
2425
|
] })
|
|
2548
2426
|
] }),
|
|
2549
|
-
|
|
2427
|
+
returnOrder.status === "requested" && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
2550
2428
|
/* @__PURE__ */ jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsx(
|
|
2551
2429
|
Button,
|
|
2552
2430
|
{
|
|
2553
2431
|
variant: "danger",
|
|
2554
|
-
onClick:
|
|
2555
|
-
disabled:
|
|
2556
|
-
isLoading:
|
|
2557
|
-
children: "Cancel
|
|
2432
|
+
onClick: handleReject,
|
|
2433
|
+
disabled: isRejecting,
|
|
2434
|
+
isLoading: isRejecting,
|
|
2435
|
+
children: "Reject (Cancel) Return"
|
|
2558
2436
|
}
|
|
2559
2437
|
) }),
|
|
2560
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children:
|
|
2438
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: 'Cancel this return request. Use "Mark as received" when items are received.' })
|
|
2439
|
+
] }),
|
|
2440
|
+
/* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2441
|
+
/* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Information" }),
|
|
2442
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
2443
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2444
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Return ID" }),
|
|
2445
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: returnOrder.id })
|
|
2446
|
+
] }),
|
|
2447
|
+
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
|
|
2448
|
+
Button,
|
|
2449
|
+
{
|
|
2450
|
+
variant: "secondary",
|
|
2451
|
+
onClick: () => {
|
|
2452
|
+
window.open(
|
|
2453
|
+
`/app/orders/${returnOrder.order_id}`,
|
|
2454
|
+
"_blank"
|
|
2455
|
+
);
|
|
2456
|
+
},
|
|
2457
|
+
children: "View order"
|
|
2458
|
+
}
|
|
2459
|
+
) })
|
|
2460
|
+
] })
|
|
2561
2461
|
] }),
|
|
2562
2462
|
/* @__PURE__ */ jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
|
|
2563
2463
|
/* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2564
|
-
/* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-4 text-lg", children: "
|
|
2464
|
+
/* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Details" }),
|
|
2565
2465
|
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
2566
2466
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
2567
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
2568
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children:
|
|
2467
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Return ID" }),
|
|
2468
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: returnOrder.id })
|
|
2569
2469
|
] }),
|
|
2570
2470
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
2571
2471
|
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Status" }),
|
|
2572
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children:
|
|
2573
|
-
] }),
|
|
2574
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2575
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Difference Due" }),
|
|
2576
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: swap.difference_due != null ? `${swap.currency_code || "$"}${(Number(swap.difference_due) / 100).toFixed(2)}` : "—" })
|
|
2472
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: returnOrder.status })
|
|
2577
2473
|
] }),
|
|
2578
|
-
|
|
2474
|
+
returnOrder.reason && /* @__PURE__ */ jsxs("div", { children: [
|
|
2579
2475
|
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Reason" }),
|
|
2580
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children:
|
|
2476
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: returnOrder.reason })
|
|
2581
2477
|
] }),
|
|
2582
|
-
|
|
2478
|
+
returnOrder.note && /* @__PURE__ */ jsxs("div", { children: [
|
|
2583
2479
|
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Note" }),
|
|
2584
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children:
|
|
2480
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: returnOrder.note })
|
|
2585
2481
|
] }),
|
|
2586
2482
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
2587
2483
|
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Created" }),
|
|
2588
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: new Date(
|
|
2484
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: new Date(returnOrder.created_at).toLocaleString() })
|
|
2589
2485
|
] }),
|
|
2590
2486
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
2591
2487
|
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Last Updated" }),
|
|
2592
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: new Date(
|
|
2593
|
-
] }),
|
|
2594
|
-
swap.exchange_id && /* @__PURE__ */ jsxs("div", { children: [
|
|
2595
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
|
|
2596
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: swap.exchange_id })
|
|
2488
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: new Date(returnOrder.updated_at).toLocaleString() })
|
|
2597
2489
|
] })
|
|
2598
2490
|
] })
|
|
2599
2491
|
] }),
|
|
@@ -2608,7 +2500,7 @@ const SwapDetailPage = () => {
|
|
|
2608
2500
|
Badge,
|
|
2609
2501
|
{
|
|
2610
2502
|
size: "2xsmall",
|
|
2611
|
-
className: `uppercase ${getStatusBadgeClass(entry.status)}`,
|
|
2503
|
+
className: `uppercase ${getStatusBadgeClass$1(entry.status)}`,
|
|
2612
2504
|
children: entry.status.replace(/_/g, " ")
|
|
2613
2505
|
}
|
|
2614
2506
|
) }),
|
|
@@ -2623,31 +2515,31 @@ const SwapDetailPage = () => {
|
|
|
2623
2515
|
)) }) : /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "No status history available" })
|
|
2624
2516
|
] })
|
|
2625
2517
|
] }),
|
|
2626
|
-
order && /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2518
|
+
returnOrder.order && /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2627
2519
|
/* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-4 text-lg", children: "Related Order Information" }),
|
|
2628
2520
|
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
2629
2521
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
2630
2522
|
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Order ID" }),
|
|
2631
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: order.id })
|
|
2523
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: returnOrder.order.id })
|
|
2632
2524
|
] }),
|
|
2633
2525
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
2634
2526
|
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Status" }),
|
|
2635
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: order.status || "—" })
|
|
2527
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: returnOrder.order.status || "—" })
|
|
2636
2528
|
] }),
|
|
2637
2529
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
2638
2530
|
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
|
|
2639
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: ((
|
|
2531
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: ((_b = returnOrder.order.customer) == null ? void 0 : _b.email) || returnOrder.order.email || "—" })
|
|
2640
2532
|
] }),
|
|
2641
|
-
order.total && /* @__PURE__ */ jsxs("div", { children: [
|
|
2533
|
+
returnOrder.order.total && /* @__PURE__ */ jsxs("div", { children: [
|
|
2642
2534
|
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
|
|
2643
2535
|
/* @__PURE__ */ jsxs(Text, { className: "font-medium", children: [
|
|
2644
|
-
order.currency_code || "$",
|
|
2645
|
-
(Number(order.total) / 100).toFixed(2)
|
|
2536
|
+
returnOrder.order.currency_code || "$",
|
|
2537
|
+
(Number(returnOrder.order.total) / 100).toFixed(2)
|
|
2646
2538
|
] })
|
|
2647
2539
|
] })
|
|
2648
2540
|
] })
|
|
2649
2541
|
] }),
|
|
2650
|
-
|
|
2542
|
+
returnOrder.return_items && returnOrder.return_items.length > 0 && /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2651
2543
|
/* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Items" }),
|
|
2652
2544
|
/* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
|
|
2653
2545
|
/* @__PURE__ */ jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
@@ -2655,31 +2547,139 @@ const SwapDetailPage = () => {
|
|
|
2655
2547
|
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" }),
|
|
2656
2548
|
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Reason" })
|
|
2657
2549
|
] }) }),
|
|
2658
|
-
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children:
|
|
2550
|
+
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: returnOrder.return_items.map((item, index) => /* @__PURE__ */ jsxs("tr", { children: [
|
|
2659
2551
|
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.id }),
|
|
2660
2552
|
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity }),
|
|
2661
2553
|
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.reason || "—" })
|
|
2662
2554
|
] }, item.id || index)) })
|
|
2663
2555
|
] }) })
|
|
2664
2556
|
] }),
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2557
|
+
updateError && /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-ui-border-error bg-ui-bg-error-subtle p-4", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-error", children: updateError }) }),
|
|
2558
|
+
updateSuccess && /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-ui-border-success bg-ui-bg-success-subtle p-4", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-success", children: "Action completed successfully" }) })
|
|
2559
|
+
] }) });
|
|
2560
|
+
};
|
|
2561
|
+
const config$1 = defineRouteConfig({
|
|
2562
|
+
label: "Return Order Details",
|
|
2563
|
+
icon: CheckCircle
|
|
2564
|
+
});
|
|
2565
|
+
const getStatusBadgeClass = (status) => {
|
|
2566
|
+
const s2 = status.toLowerCase();
|
|
2567
|
+
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
2568
|
+
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
2569
|
+
if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
2570
|
+
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
2571
|
+
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
2572
|
+
};
|
|
2573
|
+
const PaymentDetailPage = () => {
|
|
2574
|
+
var _a;
|
|
2575
|
+
const navigate = useNavigate();
|
|
2576
|
+
const params = useParams();
|
|
2577
|
+
const id = (_a = params == null ? void 0 : params.id) == null ? void 0 : _a.trim();
|
|
2578
|
+
const [detail, setDetail] = useState(null);
|
|
2579
|
+
const [loading, setLoading] = useState(!!id);
|
|
2580
|
+
const [error, setError] = useState(null);
|
|
2581
|
+
useEffect(() => {
|
|
2582
|
+
if (!id) {
|
|
2583
|
+
setLoading(false);
|
|
2584
|
+
return;
|
|
2585
|
+
}
|
|
2586
|
+
let cancelled = false;
|
|
2587
|
+
setLoading(true);
|
|
2588
|
+
setError(null);
|
|
2589
|
+
fetch(`/admin/payment-transactions/${id}`, { credentials: "include" }).then((res) => {
|
|
2590
|
+
if (!res.ok) throw new Error(res.statusText || "Failed to load");
|
|
2591
|
+
return res.json();
|
|
2592
|
+
}).then((data) => {
|
|
2593
|
+
if (!cancelled) setDetail(data);
|
|
2594
|
+
}).catch((e) => {
|
|
2595
|
+
if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
|
|
2596
|
+
}).finally(() => {
|
|
2597
|
+
if (!cancelled) setLoading(false);
|
|
2598
|
+
});
|
|
2599
|
+
return () => {
|
|
2600
|
+
cancelled = true;
|
|
2601
|
+
};
|
|
2602
|
+
}, [id]);
|
|
2603
|
+
const displayStatus = detail ? (detail.payment_id != null && detail.payment_status != null && detail.payment_status !== "" ? detail.payment_status : detail.session_status ?? "") || "—" : "";
|
|
2604
|
+
const sessionStatusRaw = (detail == null ? void 0 : detail.session_status) ?? "—";
|
|
2605
|
+
const paymentStatusRaw = (detail == null ? void 0 : detail.payment_id) != null ? (detail == null ? void 0 : detail.payment_status) ?? "—" : "—";
|
|
2606
|
+
const displayAmount = detail ? `${(detail.currency_code ?? "USD").toUpperCase()} ${Number(detail.amount)}` : "";
|
|
2607
|
+
return /* @__PURE__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxs(Container, { className: "mx-auto flex w-full max-w-4xl flex-col gap-6 p-6", children: [
|
|
2608
|
+
/* @__PURE__ */ jsx("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
2609
|
+
/* @__PURE__ */ jsx(Button, { variant: "transparent", size: "small", onClick: () => navigate("/payments"), children: "← Payments" }),
|
|
2610
|
+
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "Payment session" }),
|
|
2611
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: id ?? "—" })
|
|
2612
|
+
] }) }),
|
|
2613
|
+
error ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
2614
|
+
/* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
2615
|
+
/* @__PURE__ */ jsx(Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/payments"), children: "Back to list" })
|
|
2616
|
+
] }) : loading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading…" }) }) : detail ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
2617
|
+
/* @__PURE__ */ jsx("div", { className: "rounded-xl border border-ui-border-base p-6 flex flex-col gap-4", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
2618
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2619
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Order ID" }),
|
|
2620
|
+
/* @__PURE__ */ jsx("div", { className: "mt-1", children: detail.order_id ? /* @__PURE__ */ jsx(
|
|
2621
|
+
Button,
|
|
2622
|
+
{
|
|
2623
|
+
variant: "transparent",
|
|
2624
|
+
size: "small",
|
|
2625
|
+
onClick: () => navigate(`/orders/${detail.order_id}`),
|
|
2626
|
+
children: detail.order_id
|
|
2627
|
+
}
|
|
2628
|
+
) : /* @__PURE__ */ jsx(Text, { children: "—" }) })
|
|
2629
|
+
] }),
|
|
2630
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2631
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
|
|
2632
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: displayAmount })
|
|
2633
|
+
] }),
|
|
2634
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2635
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
|
|
2636
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.provider_id })
|
|
2637
|
+
] }),
|
|
2638
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2639
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
|
|
2640
|
+
/* @__PURE__ */ jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsx(
|
|
2641
|
+
Badge,
|
|
2642
|
+
{
|
|
2643
|
+
size: "2xsmall",
|
|
2644
|
+
className: `uppercase ${getStatusBadgeClass(displayStatus)}`,
|
|
2645
|
+
children: displayStatus !== "—" ? displayStatus.replace(/_/g, " ") : "—"
|
|
2646
|
+
}
|
|
2647
|
+
) })
|
|
2648
|
+
] }),
|
|
2649
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2650
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Session status (DB)" }),
|
|
2651
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: sessionStatusRaw })
|
|
2652
|
+
] }),
|
|
2653
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2654
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Payment status (DB)" }),
|
|
2655
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: paymentStatusRaw })
|
|
2656
|
+
] }),
|
|
2657
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2658
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Finalized" }),
|
|
2659
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.payment_id != null ? "Yes" : "No" })
|
|
2660
|
+
] }),
|
|
2661
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2662
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Created" }),
|
|
2663
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: new Date(detail.created_at).toLocaleDateString("en-US", {
|
|
2664
|
+
year: "numeric",
|
|
2665
|
+
month: "short",
|
|
2666
|
+
day: "numeric",
|
|
2667
|
+
hour: "numeric",
|
|
2668
|
+
minute: "2-digit",
|
|
2669
|
+
hour12: true
|
|
2670
|
+
}) })
|
|
2671
|
+
] })
|
|
2672
|
+
] }) }),
|
|
2673
|
+
Object.keys(detail.data ?? {}).length > 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2674
|
+
/* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg mb-4", children: "Provider data" }),
|
|
2675
|
+
/* @__PURE__ */ jsx("pre", { className: "text-xs bg-ui-bg-subtle p-4 rounded-lg overflow-auto max-h-96", children: JSON.stringify(detail.data, null, 2) })
|
|
2676
|
+
] }) : /* @__PURE__ */ jsx("div", { className: "rounded-xl border border-ui-border-base p-6", children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "No provider data for this session." }) })
|
|
2677
|
+
] }) : null
|
|
2678
2678
|
] }) });
|
|
2679
2679
|
};
|
|
2680
2680
|
const config = defineRouteConfig({
|
|
2681
|
-
label: "
|
|
2682
|
-
icon:
|
|
2681
|
+
label: "Payment details",
|
|
2682
|
+
icon: CreditCard
|
|
2683
2683
|
});
|
|
2684
2684
|
const i18nTranslations0 = {};
|
|
2685
2685
|
const widgetModule = { widgets: [
|
|
@@ -2694,45 +2694,45 @@ const widgetModule = { widgets: [
|
|
|
2694
2694
|
] };
|
|
2695
2695
|
const routeModule = {
|
|
2696
2696
|
routes: [
|
|
2697
|
-
{
|
|
2698
|
-
Component: PaymentsPage,
|
|
2699
|
-
path: "/payments"
|
|
2700
|
-
},
|
|
2701
2697
|
{
|
|
2702
2698
|
Component: RefundsPage,
|
|
2703
2699
|
path: "/refunds"
|
|
2704
2700
|
},
|
|
2705
|
-
{
|
|
2706
|
-
Component: ReturnsPage,
|
|
2707
|
-
path: "/returns"
|
|
2708
|
-
},
|
|
2709
2701
|
{
|
|
2710
2702
|
Component: SwapsPage,
|
|
2711
2703
|
path: "/swaps"
|
|
2712
2704
|
},
|
|
2713
2705
|
{
|
|
2714
|
-
Component:
|
|
2715
|
-
path: "/
|
|
2706
|
+
Component: ReturnsPage,
|
|
2707
|
+
path: "/returns"
|
|
2708
|
+
},
|
|
2709
|
+
{
|
|
2710
|
+
Component: PaymentsPage,
|
|
2711
|
+
path: "/payments"
|
|
2716
2712
|
},
|
|
2717
2713
|
{
|
|
2718
2714
|
Component: RefundDetailPage,
|
|
2719
2715
|
path: "/refunds/:id"
|
|
2720
2716
|
},
|
|
2717
|
+
{
|
|
2718
|
+
Component: SwapDetailPage,
|
|
2719
|
+
path: "/swaps/:id"
|
|
2720
|
+
},
|
|
2721
2721
|
{
|
|
2722
2722
|
Component: ReturnDetailPage,
|
|
2723
2723
|
path: "/returns/:id"
|
|
2724
2724
|
},
|
|
2725
2725
|
{
|
|
2726
|
-
Component:
|
|
2727
|
-
path: "/
|
|
2726
|
+
Component: PaymentDetailPage,
|
|
2727
|
+
path: "/payments/:id"
|
|
2728
2728
|
}
|
|
2729
2729
|
]
|
|
2730
2730
|
};
|
|
2731
2731
|
const menuItemModule = {
|
|
2732
2732
|
menuItems: [
|
|
2733
2733
|
{
|
|
2734
|
-
label: config$
|
|
2735
|
-
icon: config$
|
|
2734
|
+
label: config$4.label,
|
|
2735
|
+
icon: config$4.icon,
|
|
2736
2736
|
path: "/payments",
|
|
2737
2737
|
nested: void 0
|
|
2738
2738
|
},
|
|
@@ -2743,20 +2743,20 @@ const menuItemModule = {
|
|
|
2743
2743
|
nested: void 0
|
|
2744
2744
|
},
|
|
2745
2745
|
{
|
|
2746
|
-
label: config$
|
|
2747
|
-
icon: config$
|
|
2746
|
+
label: config$7.label,
|
|
2747
|
+
icon: config$7.icon,
|
|
2748
2748
|
path: "/refunds",
|
|
2749
2749
|
nested: void 0
|
|
2750
2750
|
},
|
|
2751
2751
|
{
|
|
2752
|
-
label: config$
|
|
2753
|
-
icon: config$
|
|
2752
|
+
label: config$6.label,
|
|
2753
|
+
icon: config$6.icon,
|
|
2754
2754
|
path: "/swaps",
|
|
2755
2755
|
nested: void 0
|
|
2756
2756
|
},
|
|
2757
2757
|
{
|
|
2758
|
-
label: config
|
|
2759
|
-
icon: config
|
|
2758
|
+
label: config.label,
|
|
2759
|
+
icon: config.icon,
|
|
2760
2760
|
path: "/payments/:id",
|
|
2761
2761
|
nested: void 0
|
|
2762
2762
|
},
|
|
@@ -2767,14 +2767,14 @@ const menuItemModule = {
|
|
|
2767
2767
|
nested: void 0
|
|
2768
2768
|
},
|
|
2769
2769
|
{
|
|
2770
|
-
label: config$
|
|
2771
|
-
icon: config$
|
|
2770
|
+
label: config$3.label,
|
|
2771
|
+
icon: config$3.icon,
|
|
2772
2772
|
path: "/refunds/:id",
|
|
2773
2773
|
nested: void 0
|
|
2774
2774
|
},
|
|
2775
2775
|
{
|
|
2776
|
-
label: config.label,
|
|
2777
|
-
icon: config.icon,
|
|
2776
|
+
label: config$2.label,
|
|
2777
|
+
icon: config$2.icon,
|
|
2778
2778
|
path: "/swaps/:id",
|
|
2779
2779
|
nested: void 0
|
|
2780
2780
|
}
|