order-management 0.0.84 → 0.0.86
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.
|
@@ -866,6 +866,236 @@ const useDebounce$3 = (value, delay) => {
|
|
|
866
866
|
return debouncedValue;
|
|
867
867
|
};
|
|
868
868
|
const getStatusBadgeClass$7 = (status) => {
|
|
869
|
+
const statusLower = status.toLowerCase();
|
|
870
|
+
if (statusLower === "requested") {
|
|
871
|
+
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
872
|
+
}
|
|
873
|
+
if (statusLower === "approved") {
|
|
874
|
+
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
875
|
+
}
|
|
876
|
+
if (statusLower === "rejected") {
|
|
877
|
+
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
878
|
+
}
|
|
879
|
+
if (statusLower === "completed") {
|
|
880
|
+
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
881
|
+
}
|
|
882
|
+
if (statusLower === "cancelled") {
|
|
883
|
+
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
884
|
+
}
|
|
885
|
+
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
886
|
+
};
|
|
887
|
+
const SwapsPage = () => {
|
|
888
|
+
const navigate = reactRouterDom.useNavigate();
|
|
889
|
+
const [items, setItems] = react.useState([]);
|
|
890
|
+
const [statusFilter, setStatusFilter] = react.useState("all");
|
|
891
|
+
const [createdByFilter, setCreatedByFilter] = react.useState("all");
|
|
892
|
+
const [searchQuery, setSearchQuery] = react.useState("");
|
|
893
|
+
const debouncedSearchQuery = useDebounce$3(searchQuery, 300);
|
|
894
|
+
const [isLoading, setIsLoading] = react.useState(true);
|
|
895
|
+
const [isFetchingMore, setIsFetchingMore] = react.useState(false);
|
|
896
|
+
const [error, setError] = react.useState(null);
|
|
897
|
+
const [offset, setOffset] = react.useState(0);
|
|
898
|
+
const [count, setCount] = react.useState(0);
|
|
899
|
+
const limit = 50;
|
|
900
|
+
const loadSwaps = react.useCallback(
|
|
901
|
+
async (nextOffset, replace = false) => {
|
|
902
|
+
var _a;
|
|
903
|
+
try {
|
|
904
|
+
if (replace) {
|
|
905
|
+
setIsLoading(true);
|
|
906
|
+
} else {
|
|
907
|
+
setIsFetchingMore(true);
|
|
908
|
+
}
|
|
909
|
+
setError(null);
|
|
910
|
+
const params = new URLSearchParams();
|
|
911
|
+
params.set("limit", String(limit));
|
|
912
|
+
params.set("offset", String(nextOffset));
|
|
913
|
+
if (statusFilter !== "all") {
|
|
914
|
+
params.set("status", statusFilter);
|
|
915
|
+
}
|
|
916
|
+
if (debouncedSearchQuery.trim()) {
|
|
917
|
+
params.set("order_id", debouncedSearchQuery.trim());
|
|
918
|
+
}
|
|
919
|
+
if (createdByFilter !== "all") {
|
|
920
|
+
params.set("created_by", createdByFilter);
|
|
921
|
+
}
|
|
922
|
+
const response = await fetch(
|
|
923
|
+
`/admin/swaps?${params.toString()}`,
|
|
924
|
+
{ credentials: "include" }
|
|
925
|
+
);
|
|
926
|
+
if (!response.ok) {
|
|
927
|
+
const message = await response.text();
|
|
928
|
+
throw new Error(message || "Unable to load swaps");
|
|
929
|
+
}
|
|
930
|
+
const payload = await response.json();
|
|
931
|
+
setCount(payload.count ?? 0);
|
|
932
|
+
setOffset(nextOffset + (((_a = payload.swaps) == null ? void 0 : _a.length) ?? 0));
|
|
933
|
+
setItems(
|
|
934
|
+
(prev) => replace ? payload.swaps ?? [] : [...prev, ...payload.swaps ?? []]
|
|
935
|
+
);
|
|
936
|
+
} catch (loadError) {
|
|
937
|
+
const message = loadError instanceof Error ? loadError.message : "Unable to load swaps";
|
|
938
|
+
setError(message);
|
|
939
|
+
} finally {
|
|
940
|
+
setIsLoading(false);
|
|
941
|
+
setIsFetchingMore(false);
|
|
942
|
+
}
|
|
943
|
+
},
|
|
944
|
+
[statusFilter, createdByFilter, debouncedSearchQuery]
|
|
945
|
+
);
|
|
946
|
+
react.useEffect(() => {
|
|
947
|
+
void loadSwaps(0, true);
|
|
948
|
+
}, [statusFilter, createdByFilter, debouncedSearchQuery, loadSwaps]);
|
|
949
|
+
const hasMore = react.useMemo(() => offset < count, [offset, count]);
|
|
950
|
+
const availableStatuses = react.useMemo(() => {
|
|
951
|
+
const statuses = /* @__PURE__ */ new Set();
|
|
952
|
+
items.forEach((item) => statuses.add(item.status));
|
|
953
|
+
return Array.from(statuses).sort();
|
|
954
|
+
}, [items]);
|
|
955
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-7xl flex-col gap-6 p-6", children: [
|
|
956
|
+
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
957
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
958
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Exchanges" }),
|
|
959
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer exchange requests" })
|
|
960
|
+
] }),
|
|
961
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadSwaps(0, true), children: "Refresh" })
|
|
962
|
+
] }),
|
|
963
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
964
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
965
|
+
ui.Input,
|
|
966
|
+
{
|
|
967
|
+
placeholder: "Search by swap ID or order ID",
|
|
968
|
+
value: searchQuery,
|
|
969
|
+
onChange: (event) => setSearchQuery(event.target.value),
|
|
970
|
+
className: "md:max-w-sm"
|
|
971
|
+
}
|
|
972
|
+
),
|
|
973
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
|
|
974
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
975
|
+
"select",
|
|
976
|
+
{
|
|
977
|
+
value: createdByFilter,
|
|
978
|
+
onChange: (event) => setCreatedByFilter(event.target.value),
|
|
979
|
+
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",
|
|
980
|
+
children: [
|
|
981
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All (Created by)" }),
|
|
982
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "customer", children: "Customer" }),
|
|
983
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "admin", children: "Admin" })
|
|
984
|
+
]
|
|
985
|
+
}
|
|
986
|
+
),
|
|
987
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
988
|
+
"select",
|
|
989
|
+
{
|
|
990
|
+
value: statusFilter,
|
|
991
|
+
onChange: (event) => setStatusFilter(event.target.value),
|
|
992
|
+
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",
|
|
993
|
+
children: [
|
|
994
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All Statuses" }),
|
|
995
|
+
availableStatuses.map((status) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
|
|
996
|
+
]
|
|
997
|
+
}
|
|
998
|
+
)
|
|
999
|
+
] })
|
|
1000
|
+
] }),
|
|
1001
|
+
error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
1002
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
1003
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1004
|
+
ui.Button,
|
|
1005
|
+
{
|
|
1006
|
+
variant: "secondary",
|
|
1007
|
+
onClick: () => loadSwaps(0, true),
|
|
1008
|
+
children: "Try again"
|
|
1009
|
+
}
|
|
1010
|
+
) })
|
|
1011
|
+
] }) : null,
|
|
1012
|
+
isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading swaps..." }) }) : items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
|
|
1013
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No exchanges yet" }),
|
|
1014
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Exchange requests created by customers will appear here." })
|
|
1015
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
|
|
1016
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1017
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Exchange ID" }),
|
|
1018
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
|
|
1019
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
|
|
1020
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Difference Due" }),
|
|
1021
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
1022
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
1023
|
+
] }) }),
|
|
1024
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((swap) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1025
|
+
"tr",
|
|
1026
|
+
{
|
|
1027
|
+
className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
|
|
1028
|
+
onClick: () => navigate(`/swaps/${swap.id}`),
|
|
1029
|
+
children: [
|
|
1030
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-0.5", children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: swap.id }) }) }),
|
|
1031
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: swap.order_id }),
|
|
1032
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1033
|
+
ui.Badge,
|
|
1034
|
+
{
|
|
1035
|
+
size: "2xsmall",
|
|
1036
|
+
className: `uppercase ${getStatusBadgeClass$7(swap.status)}`,
|
|
1037
|
+
children: swap.status.replace(/_/g, " ")
|
|
1038
|
+
}
|
|
1039
|
+
) }),
|
|
1040
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
|
|
1041
|
+
const amount = swap.difference_due;
|
|
1042
|
+
if (amount == null || amount === void 0) {
|
|
1043
|
+
return "—";
|
|
1044
|
+
}
|
|
1045
|
+
const displayAmount = Number(amount) / 100;
|
|
1046
|
+
const currency = swap.currency_code || "$";
|
|
1047
|
+
const sign = displayAmount >= 0 ? "+" : "";
|
|
1048
|
+
return `${sign}${currency}${displayAmount.toFixed(2)}`;
|
|
1049
|
+
})() }),
|
|
1050
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(swap.created_at).toLocaleDateString("en-US", {
|
|
1051
|
+
year: "numeric",
|
|
1052
|
+
month: "short",
|
|
1053
|
+
day: "numeric",
|
|
1054
|
+
hour: "numeric",
|
|
1055
|
+
minute: "2-digit",
|
|
1056
|
+
hour12: true
|
|
1057
|
+
}) }),
|
|
1058
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1059
|
+
ui.Button,
|
|
1060
|
+
{
|
|
1061
|
+
variant: "transparent",
|
|
1062
|
+
size: "small",
|
|
1063
|
+
onClick: (e) => {
|
|
1064
|
+
e.stopPropagation();
|
|
1065
|
+
navigate(`/app/orders/${swap.order_id}`);
|
|
1066
|
+
},
|
|
1067
|
+
children: "Go to order"
|
|
1068
|
+
}
|
|
1069
|
+
) })
|
|
1070
|
+
]
|
|
1071
|
+
},
|
|
1072
|
+
swap.id
|
|
1073
|
+
)) })
|
|
1074
|
+
] }) }),
|
|
1075
|
+
hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1076
|
+
ui.Button,
|
|
1077
|
+
{
|
|
1078
|
+
variant: "secondary",
|
|
1079
|
+
isLoading: isFetchingMore,
|
|
1080
|
+
onClick: () => loadSwaps(offset, false),
|
|
1081
|
+
children: "Load more"
|
|
1082
|
+
}
|
|
1083
|
+
) }) : null
|
|
1084
|
+
] }) });
|
|
1085
|
+
};
|
|
1086
|
+
const config$7 = adminSdk.defineRouteConfig({
|
|
1087
|
+
label: "Exchanges",
|
|
1088
|
+
icon: icons.ArrowPath
|
|
1089
|
+
});
|
|
1090
|
+
const useDebounce$2 = (value, delay) => {
|
|
1091
|
+
const [debouncedValue, setDebouncedValue] = react.useState(value);
|
|
1092
|
+
react.useEffect(() => {
|
|
1093
|
+
const handler = setTimeout(() => setDebouncedValue(value), delay);
|
|
1094
|
+
return () => clearTimeout(handler);
|
|
1095
|
+
}, [value, delay]);
|
|
1096
|
+
return debouncedValue;
|
|
1097
|
+
};
|
|
1098
|
+
const getStatusBadgeClass$6 = (status) => {
|
|
869
1099
|
const statusLower = status.toLowerCase();
|
|
870
1100
|
if (statusLower === "requested") {
|
|
871
1101
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
@@ -890,7 +1120,7 @@ const ReturnsPage = () => {
|
|
|
890
1120
|
const [statusFilter, setStatusFilter] = react.useState("all");
|
|
891
1121
|
const [createdByFilter, setCreatedByFilter] = react.useState("all");
|
|
892
1122
|
const [searchQuery, setSearchQuery] = react.useState("");
|
|
893
|
-
const debouncedSearchQuery = useDebounce$
|
|
1123
|
+
const debouncedSearchQuery = useDebounce$2(searchQuery, 300);
|
|
894
1124
|
const [isLoading, setIsLoading] = react.useState(true);
|
|
895
1125
|
const [isFetchingMore, setIsFetchingMore] = react.useState(false);
|
|
896
1126
|
const [error, setError] = react.useState(null);
|
|
@@ -1036,7 +1266,7 @@ const ReturnsPage = () => {
|
|
|
1036
1266
|
ui.Badge,
|
|
1037
1267
|
{
|
|
1038
1268
|
size: "2xsmall",
|
|
1039
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
1269
|
+
className: `uppercase ${getStatusBadgeClass$6(returnOrder.status)}`,
|
|
1040
1270
|
children: returnOrder.status.replace(/_/g, " ")
|
|
1041
1271
|
}
|
|
1042
1272
|
) }),
|
|
@@ -1085,11 +1315,11 @@ const ReturnsPage = () => {
|
|
|
1085
1315
|
) }) : null
|
|
1086
1316
|
] }) });
|
|
1087
1317
|
};
|
|
1088
|
-
const config$
|
|
1318
|
+
const config$6 = adminSdk.defineRouteConfig({
|
|
1089
1319
|
label: "Return Orders",
|
|
1090
1320
|
icon: icons.ArrowPath
|
|
1091
1321
|
});
|
|
1092
|
-
const useDebounce$
|
|
1322
|
+
const useDebounce$1 = (value, delay) => {
|
|
1093
1323
|
const [debouncedValue, setDebouncedValue] = react.useState(value);
|
|
1094
1324
|
react.useEffect(() => {
|
|
1095
1325
|
const handler = setTimeout(() => setDebouncedValue(value), delay);
|
|
@@ -1097,7 +1327,7 @@ const useDebounce$2 = (value, delay) => {
|
|
|
1097
1327
|
}, [value, delay]);
|
|
1098
1328
|
return debouncedValue;
|
|
1099
1329
|
};
|
|
1100
|
-
const getStatusBadgeClass$
|
|
1330
|
+
const getStatusBadgeClass$5 = (status) => {
|
|
1101
1331
|
const s2 = status.toLowerCase();
|
|
1102
1332
|
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1103
1333
|
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
@@ -1110,7 +1340,7 @@ const PaymentsPage = () => {
|
|
|
1110
1340
|
const [items, setItems] = react.useState([]);
|
|
1111
1341
|
const [statusFilter, setStatusFilter] = react.useState("all");
|
|
1112
1342
|
const [orderIdSearch, setOrderIdSearch] = react.useState("");
|
|
1113
|
-
const debouncedOrderId = useDebounce$
|
|
1343
|
+
const debouncedOrderId = useDebounce$1(orderIdSearch, 300);
|
|
1114
1344
|
const [isLoading, setIsLoading] = react.useState(true);
|
|
1115
1345
|
const [isFetchingMore, setIsFetchingMore] = react.useState(false);
|
|
1116
1346
|
const [error, setError] = react.useState(null);
|
|
@@ -1230,7 +1460,7 @@ const PaymentsPage = () => {
|
|
|
1230
1460
|
ui.Badge,
|
|
1231
1461
|
{
|
|
1232
1462
|
size: "2xsmall",
|
|
1233
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
1463
|
+
className: `uppercase ${getStatusBadgeClass$5(displayStatus(t))}`,
|
|
1234
1464
|
children: displayStatus(t) !== "—" ? displayStatus(t).replace(/_/g, " ") : "—"
|
|
1235
1465
|
}
|
|
1236
1466
|
) }),
|
|
@@ -1285,11 +1515,11 @@ const PaymentsPage = () => {
|
|
|
1285
1515
|
) }) : null
|
|
1286
1516
|
] }) });
|
|
1287
1517
|
};
|
|
1288
|
-
const config$
|
|
1518
|
+
const config$5 = adminSdk.defineRouteConfig({
|
|
1289
1519
|
label: "Payments",
|
|
1290
1520
|
icon: icons.CreditCard
|
|
1291
1521
|
});
|
|
1292
|
-
const useDebounce
|
|
1522
|
+
const useDebounce = (value, delay) => {
|
|
1293
1523
|
const [debouncedValue, setDebouncedValue] = react.useState(value);
|
|
1294
1524
|
react.useEffect(() => {
|
|
1295
1525
|
const handler = setTimeout(() => setDebouncedValue(value), delay);
|
|
@@ -1297,7 +1527,7 @@ const useDebounce$1 = (value, delay) => {
|
|
|
1297
1527
|
}, [value, delay]);
|
|
1298
1528
|
return debouncedValue;
|
|
1299
1529
|
};
|
|
1300
|
-
const getStatusBadgeClass$
|
|
1530
|
+
const getStatusBadgeClass$4 = (status) => {
|
|
1301
1531
|
const s2 = status.toLowerCase();
|
|
1302
1532
|
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1303
1533
|
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
@@ -1309,12 +1539,12 @@ const RefundsPage = () => {
|
|
|
1309
1539
|
const navigate = reactRouterDom.useNavigate();
|
|
1310
1540
|
const [items, setItems] = react.useState([]);
|
|
1311
1541
|
const [orderIdSearch, setOrderIdSearch] = react.useState("");
|
|
1312
|
-
const debouncedOrderId = useDebounce
|
|
1542
|
+
const debouncedOrderId = useDebounce(orderIdSearch, 300);
|
|
1313
1543
|
const [paymentStatusFilter, setPaymentStatusFilter] = react.useState("all");
|
|
1314
1544
|
const [providerSearch, setProviderSearch] = react.useState("");
|
|
1315
|
-
const debouncedProvider = useDebounce
|
|
1545
|
+
const debouncedProvider = useDebounce(providerSearch, 300);
|
|
1316
1546
|
const [currencySearch, setCurrencySearch] = react.useState("");
|
|
1317
|
-
const debouncedCurrency = useDebounce
|
|
1547
|
+
const debouncedCurrency = useDebounce(currencySearch, 300);
|
|
1318
1548
|
const [dateFrom, setDateFrom] = react.useState("");
|
|
1319
1549
|
const [dateTo, setDateTo] = react.useState("");
|
|
1320
1550
|
const [amountMin, setAmountMin] = react.useState("");
|
|
@@ -1526,7 +1756,7 @@ const RefundsPage = () => {
|
|
|
1526
1756
|
ui.Badge,
|
|
1527
1757
|
{
|
|
1528
1758
|
size: "2xsmall",
|
|
1529
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
1759
|
+
className: `uppercase ${getStatusBadgeClass$4(displayStatus(r))}`,
|
|
1530
1760
|
children: displayStatus(r) !== "—" ? displayStatus(r).replace(/_/g, " ") : "—"
|
|
1531
1761
|
}
|
|
1532
1762
|
) }),
|
|
@@ -1580,19 +1810,11 @@ const RefundsPage = () => {
|
|
|
1580
1810
|
) }) : null
|
|
1581
1811
|
] }) });
|
|
1582
1812
|
};
|
|
1583
|
-
const config$
|
|
1813
|
+
const config$4 = adminSdk.defineRouteConfig({
|
|
1584
1814
|
label: "Refunds",
|
|
1585
1815
|
icon: icons.Receipt
|
|
1586
1816
|
});
|
|
1587
|
-
const
|
|
1588
|
-
const [debouncedValue, setDebouncedValue] = react.useState(value);
|
|
1589
|
-
react.useEffect(() => {
|
|
1590
|
-
const handler = setTimeout(() => setDebouncedValue(value), delay);
|
|
1591
|
-
return () => clearTimeout(handler);
|
|
1592
|
-
}, [value, delay]);
|
|
1593
|
-
return debouncedValue;
|
|
1594
|
-
};
|
|
1595
|
-
const getStatusBadgeClass$4 = (status) => {
|
|
1817
|
+
const getStatusBadgeClass$3 = (status) => {
|
|
1596
1818
|
const statusLower = status.toLowerCase();
|
|
1597
1819
|
if (statusLower === "requested") {
|
|
1598
1820
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
@@ -1606,324 +1828,106 @@ const getStatusBadgeClass$4 = (status) => {
|
|
|
1606
1828
|
if (statusLower === "completed") {
|
|
1607
1829
|
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1608
1830
|
}
|
|
1609
|
-
if (statusLower === "cancelled") {
|
|
1831
|
+
if (statusLower === "cancelled" || statusLower === "canceled") {
|
|
1610
1832
|
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
1611
1833
|
}
|
|
1612
|
-
|
|
1613
|
-
};
|
|
1614
|
-
const SwapsPage = () => {
|
|
1615
|
-
const navigate = reactRouterDom.useNavigate();
|
|
1616
|
-
const [items, setItems] = react.useState([]);
|
|
1617
|
-
const [statusFilter, setStatusFilter] = react.useState("all");
|
|
1618
|
-
const [createdByFilter, setCreatedByFilter] = react.useState("all");
|
|
1619
|
-
const [searchQuery, setSearchQuery] = react.useState("");
|
|
1620
|
-
const debouncedSearchQuery = useDebounce(searchQuery, 300);
|
|
1621
|
-
const [isLoading, setIsLoading] = react.useState(true);
|
|
1622
|
-
const [isFetchingMore, setIsFetchingMore] = react.useState(false);
|
|
1623
|
-
const [error, setError] = react.useState(null);
|
|
1624
|
-
const [offset, setOffset] = react.useState(0);
|
|
1625
|
-
const [count, setCount] = react.useState(0);
|
|
1626
|
-
const limit = 50;
|
|
1627
|
-
const loadSwaps = react.useCallback(
|
|
1628
|
-
async (nextOffset, replace = false) => {
|
|
1629
|
-
var _a;
|
|
1630
|
-
try {
|
|
1631
|
-
if (replace) {
|
|
1632
|
-
setIsLoading(true);
|
|
1633
|
-
} else {
|
|
1634
|
-
setIsFetchingMore(true);
|
|
1635
|
-
}
|
|
1636
|
-
setError(null);
|
|
1637
|
-
const params = new URLSearchParams();
|
|
1638
|
-
params.set("limit", String(limit));
|
|
1639
|
-
params.set("offset", String(nextOffset));
|
|
1640
|
-
if (statusFilter !== "all") {
|
|
1641
|
-
params.set("status", statusFilter);
|
|
1642
|
-
}
|
|
1643
|
-
if (debouncedSearchQuery.trim()) {
|
|
1644
|
-
params.set("order_id", debouncedSearchQuery.trim());
|
|
1645
|
-
}
|
|
1646
|
-
if (createdByFilter !== "all") {
|
|
1647
|
-
params.set("created_by", createdByFilter);
|
|
1648
|
-
}
|
|
1649
|
-
const response = await fetch(
|
|
1650
|
-
`/admin/swaps?${params.toString()}`,
|
|
1651
|
-
{ credentials: "include" }
|
|
1652
|
-
);
|
|
1653
|
-
if (!response.ok) {
|
|
1654
|
-
const message = await response.text();
|
|
1655
|
-
throw new Error(message || "Unable to load swaps");
|
|
1656
|
-
}
|
|
1657
|
-
const payload = await response.json();
|
|
1658
|
-
setCount(payload.count ?? 0);
|
|
1659
|
-
setOffset(nextOffset + (((_a = payload.swaps) == null ? void 0 : _a.length) ?? 0));
|
|
1660
|
-
setItems(
|
|
1661
|
-
(prev) => replace ? payload.swaps ?? [] : [...prev, ...payload.swaps ?? []]
|
|
1662
|
-
);
|
|
1663
|
-
} catch (loadError) {
|
|
1664
|
-
const message = loadError instanceof Error ? loadError.message : "Unable to load swaps";
|
|
1665
|
-
setError(message);
|
|
1666
|
-
} finally {
|
|
1667
|
-
setIsLoading(false);
|
|
1668
|
-
setIsFetchingMore(false);
|
|
1669
|
-
}
|
|
1670
|
-
},
|
|
1671
|
-
[statusFilter, createdByFilter, debouncedSearchQuery]
|
|
1672
|
-
);
|
|
1673
|
-
react.useEffect(() => {
|
|
1674
|
-
void loadSwaps(0, true);
|
|
1675
|
-
}, [statusFilter, createdByFilter, debouncedSearchQuery, loadSwaps]);
|
|
1676
|
-
const hasMore = react.useMemo(() => offset < count, [offset, count]);
|
|
1677
|
-
const availableStatuses = react.useMemo(() => {
|
|
1678
|
-
const statuses = /* @__PURE__ */ new Set();
|
|
1679
|
-
items.forEach((item) => statuses.add(item.status));
|
|
1680
|
-
return Array.from(statuses).sort();
|
|
1681
|
-
}, [items]);
|
|
1682
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-7xl flex-col gap-6 p-6", children: [
|
|
1683
|
-
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1684
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1685
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Exchanges" }),
|
|
1686
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer exchange requests" })
|
|
1687
|
-
] }),
|
|
1688
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadSwaps(0, true), children: "Refresh" })
|
|
1689
|
-
] }),
|
|
1690
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1691
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1692
|
-
ui.Input,
|
|
1693
|
-
{
|
|
1694
|
-
placeholder: "Search by swap ID or order ID",
|
|
1695
|
-
value: searchQuery,
|
|
1696
|
-
onChange: (event) => setSearchQuery(event.target.value),
|
|
1697
|
-
className: "md:max-w-sm"
|
|
1698
|
-
}
|
|
1699
|
-
),
|
|
1700
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
|
|
1701
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1702
|
-
"select",
|
|
1703
|
-
{
|
|
1704
|
-
value: createdByFilter,
|
|
1705
|
-
onChange: (event) => setCreatedByFilter(event.target.value),
|
|
1706
|
-
className: "h-9 rounded-md border border-ui-border-base bg-transparent px-3 text-sm text-ui-fg-base outline-none transition focus:ring-2 focus:ring-ui-fg-interactive md:max-w-xs",
|
|
1707
|
-
children: [
|
|
1708
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All (Created by)" }),
|
|
1709
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "customer", children: "Customer" }),
|
|
1710
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "admin", children: "Admin" })
|
|
1711
|
-
]
|
|
1712
|
-
}
|
|
1713
|
-
),
|
|
1714
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1715
|
-
"select",
|
|
1716
|
-
{
|
|
1717
|
-
value: statusFilter,
|
|
1718
|
-
onChange: (event) => setStatusFilter(event.target.value),
|
|
1719
|
-
className: "h-9 rounded-md border border-ui-border-base bg-transparent px-3 text-sm text-ui-fg-base outline-none transition focus:ring-2 focus:ring-ui-fg-interactive md:max-w-xs",
|
|
1720
|
-
children: [
|
|
1721
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All Statuses" }),
|
|
1722
|
-
availableStatuses.map((status) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
|
|
1723
|
-
]
|
|
1724
|
-
}
|
|
1725
|
-
)
|
|
1726
|
-
] })
|
|
1727
|
-
] }),
|
|
1728
|
-
error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
1729
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
1730
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1731
|
-
ui.Button,
|
|
1732
|
-
{
|
|
1733
|
-
variant: "secondary",
|
|
1734
|
-
onClick: () => loadSwaps(0, true),
|
|
1735
|
-
children: "Try again"
|
|
1736
|
-
}
|
|
1737
|
-
) })
|
|
1738
|
-
] }) : null,
|
|
1739
|
-
isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading swaps..." }) }) : items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
|
|
1740
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No exchanges yet" }),
|
|
1741
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Exchange requests created by customers will appear here." })
|
|
1742
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
|
|
1743
|
-
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1744
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Exchange ID" }),
|
|
1745
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
|
|
1746
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
|
|
1747
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Difference Due" }),
|
|
1748
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
1749
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
1750
|
-
] }) }),
|
|
1751
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((swap) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1752
|
-
"tr",
|
|
1753
|
-
{
|
|
1754
|
-
className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
|
|
1755
|
-
onClick: () => navigate(`/swaps/${swap.id}`),
|
|
1756
|
-
children: [
|
|
1757
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-0.5", children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: swap.id }) }) }),
|
|
1758
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: swap.order_id }),
|
|
1759
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1760
|
-
ui.Badge,
|
|
1761
|
-
{
|
|
1762
|
-
size: "2xsmall",
|
|
1763
|
-
className: `uppercase ${getStatusBadgeClass$4(swap.status)}`,
|
|
1764
|
-
children: swap.status.replace(/_/g, " ")
|
|
1765
|
-
}
|
|
1766
|
-
) }),
|
|
1767
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
|
|
1768
|
-
const amount = swap.difference_due;
|
|
1769
|
-
if (amount == null || amount === void 0) {
|
|
1770
|
-
return "—";
|
|
1771
|
-
}
|
|
1772
|
-
const displayAmount = Number(amount) / 100;
|
|
1773
|
-
const currency = swap.currency_code || "$";
|
|
1774
|
-
const sign = displayAmount >= 0 ? "+" : "";
|
|
1775
|
-
return `${sign}${currency}${displayAmount.toFixed(2)}`;
|
|
1776
|
-
})() }),
|
|
1777
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(swap.created_at).toLocaleDateString("en-US", {
|
|
1778
|
-
year: "numeric",
|
|
1779
|
-
month: "short",
|
|
1780
|
-
day: "numeric",
|
|
1781
|
-
hour: "numeric",
|
|
1782
|
-
minute: "2-digit",
|
|
1783
|
-
hour12: true
|
|
1784
|
-
}) }),
|
|
1785
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1786
|
-
ui.Button,
|
|
1787
|
-
{
|
|
1788
|
-
variant: "transparent",
|
|
1789
|
-
size: "small",
|
|
1790
|
-
onClick: (e) => {
|
|
1791
|
-
e.stopPropagation();
|
|
1792
|
-
navigate(`/app/orders/${swap.order_id}`);
|
|
1793
|
-
},
|
|
1794
|
-
children: "Go to order"
|
|
1795
|
-
}
|
|
1796
|
-
) })
|
|
1797
|
-
]
|
|
1798
|
-
},
|
|
1799
|
-
swap.id
|
|
1800
|
-
)) })
|
|
1801
|
-
] }) }),
|
|
1802
|
-
hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1803
|
-
ui.Button,
|
|
1804
|
-
{
|
|
1805
|
-
variant: "secondary",
|
|
1806
|
-
isLoading: isFetchingMore,
|
|
1807
|
-
onClick: () => loadSwaps(offset, false),
|
|
1808
|
-
children: "Load more"
|
|
1809
|
-
}
|
|
1810
|
-
) }) : null
|
|
1811
|
-
] }) });
|
|
1812
|
-
};
|
|
1813
|
-
const config$4 = adminSdk.defineRouteConfig({
|
|
1814
|
-
label: "Exchanges",
|
|
1815
|
-
icon: icons.ArrowPath
|
|
1816
|
-
});
|
|
1817
|
-
const getStatusBadgeClass$3 = (status) => {
|
|
1818
|
-
const statusLower = status.toLowerCase();
|
|
1819
|
-
if (statusLower === "requested") {
|
|
1834
|
+
if (statusLower === "pending") {
|
|
1820
1835
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
1821
1836
|
}
|
|
1822
|
-
if (statusLower === "approved") {
|
|
1823
|
-
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
1824
|
-
}
|
|
1825
|
-
if (statusLower === "rejected") {
|
|
1826
|
-
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
1827
|
-
}
|
|
1828
|
-
if (statusLower === "received") {
|
|
1829
|
-
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
1830
|
-
}
|
|
1831
|
-
if (statusLower === "refunded") {
|
|
1832
|
-
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1833
|
-
}
|
|
1834
|
-
if (statusLower === "completed") {
|
|
1835
|
-
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1836
|
-
}
|
|
1837
|
-
if (statusLower === "cancelled") {
|
|
1838
|
-
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
1839
|
-
}
|
|
1840
1837
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
1841
1838
|
};
|
|
1842
|
-
const
|
|
1843
|
-
var _a, _b;
|
|
1839
|
+
const SwapDetailPage = () => {
|
|
1840
|
+
var _a, _b, _c;
|
|
1844
1841
|
const navigate = reactRouterDom.useNavigate();
|
|
1845
1842
|
const { id } = reactRouterDom.useParams();
|
|
1846
|
-
const [
|
|
1843
|
+
const [swap, setSwap] = react.useState(null);
|
|
1844
|
+
const [order, setOrder] = react.useState(null);
|
|
1847
1845
|
const [isLoading, setIsLoading] = react.useState(true);
|
|
1848
|
-
|
|
1846
|
+
react.useState(false);
|
|
1847
|
+
const [isCancelling, setIsCancelling] = react.useState(false);
|
|
1849
1848
|
const [error, setError] = react.useState(null);
|
|
1850
1849
|
const [updateError, setUpdateError] = react.useState(null);
|
|
1851
1850
|
const [updateSuccess, setUpdateSuccess] = react.useState(false);
|
|
1852
1851
|
react.useEffect(() => {
|
|
1853
1852
|
if (!id) {
|
|
1854
|
-
navigate("/
|
|
1853
|
+
navigate("/swaps");
|
|
1855
1854
|
return;
|
|
1856
1855
|
}
|
|
1857
|
-
const
|
|
1856
|
+
const loadSwap = async () => {
|
|
1858
1857
|
try {
|
|
1859
1858
|
setIsLoading(true);
|
|
1860
1859
|
setError(null);
|
|
1861
|
-
const response = await fetch(`/admin/
|
|
1860
|
+
const response = await fetch(`/admin/swaps/${id}`, {
|
|
1862
1861
|
credentials: "include"
|
|
1863
1862
|
});
|
|
1864
1863
|
if (!response.ok) {
|
|
1865
1864
|
const message = await response.text();
|
|
1866
|
-
throw new Error(message || "Unable to load
|
|
1865
|
+
throw new Error(message || "Unable to load swap");
|
|
1867
1866
|
}
|
|
1868
1867
|
const payload = await response.json();
|
|
1869
|
-
|
|
1868
|
+
setSwap(payload.swap);
|
|
1869
|
+
setOrder(payload.order || null);
|
|
1870
1870
|
} catch (loadError) {
|
|
1871
|
-
const message = loadError instanceof Error ? loadError.message : "Unable to load
|
|
1871
|
+
const message = loadError instanceof Error ? loadError.message : "Unable to load swap";
|
|
1872
1872
|
setError(message);
|
|
1873
1873
|
} finally {
|
|
1874
1874
|
setIsLoading(false);
|
|
1875
1875
|
}
|
|
1876
1876
|
};
|
|
1877
|
-
void
|
|
1877
|
+
void loadSwap();
|
|
1878
1878
|
}, [id, navigate]);
|
|
1879
|
-
const
|
|
1879
|
+
const handleCancelExchange = async () => {
|
|
1880
1880
|
if (!id) {
|
|
1881
1881
|
return;
|
|
1882
1882
|
}
|
|
1883
1883
|
try {
|
|
1884
|
-
|
|
1884
|
+
setIsCancelling(true);
|
|
1885
1885
|
setUpdateError(null);
|
|
1886
1886
|
setUpdateSuccess(false);
|
|
1887
|
-
const response = await fetch(`/admin/
|
|
1887
|
+
const response = await fetch(`/admin/swaps/${id}/cancel`, {
|
|
1888
1888
|
method: "POST",
|
|
1889
1889
|
headers: {
|
|
1890
1890
|
"Content-Type": "application/json"
|
|
1891
1891
|
},
|
|
1892
|
-
credentials: "include"
|
|
1893
|
-
body: JSON.stringify({ reason: "Rejected by admin" })
|
|
1892
|
+
credentials: "include"
|
|
1894
1893
|
});
|
|
1895
1894
|
if (!response.ok) {
|
|
1896
1895
|
const message = await response.text();
|
|
1897
|
-
throw new Error(message || "Unable to
|
|
1896
|
+
throw new Error(message || "Unable to cancel exchange");
|
|
1898
1897
|
}
|
|
1899
1898
|
const payload = await response.json();
|
|
1900
|
-
|
|
1899
|
+
setSwap(payload.swap);
|
|
1901
1900
|
setUpdateSuccess(true);
|
|
1902
1901
|
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
1903
|
-
const detailResponse = await fetch(`/admin/
|
|
1902
|
+
const detailResponse = await fetch(`/admin/swaps/${id}`, {
|
|
1904
1903
|
credentials: "include"
|
|
1905
1904
|
});
|
|
1906
1905
|
if (detailResponse.ok) {
|
|
1907
1906
|
const detailPayload = await detailResponse.json();
|
|
1908
|
-
|
|
1907
|
+
setSwap(detailPayload.swap);
|
|
1908
|
+
setOrder(detailPayload.order || null);
|
|
1909
1909
|
}
|
|
1910
|
-
} catch (
|
|
1911
|
-
const message =
|
|
1910
|
+
} catch (cancelErr) {
|
|
1911
|
+
const message = cancelErr instanceof Error ? cancelErr.message : "Unable to cancel exchange";
|
|
1912
1912
|
setUpdateError(message);
|
|
1913
1913
|
} finally {
|
|
1914
|
-
|
|
1914
|
+
setIsCancelling(false);
|
|
1915
1915
|
}
|
|
1916
1916
|
};
|
|
1917
|
+
const isOrderExchange = Boolean(swap == null ? void 0 : swap.exchange_id);
|
|
1918
|
+
const canCancelExchange = isOrderExchange && swap && !["cancelled", "canceled", "completed", "declined"].includes(
|
|
1919
|
+
((_a = swap.status) == null ? void 0 : _a.toLowerCase()) ?? ""
|
|
1920
|
+
);
|
|
1917
1921
|
if (isLoading) {
|
|
1918
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading
|
|
1922
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading swap..." }) }) }) });
|
|
1919
1923
|
}
|
|
1920
|
-
if (error || !
|
|
1924
|
+
if (error || !swap) {
|
|
1921
1925
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
1922
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "
|
|
1923
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/
|
|
1926
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "Swap not found" }),
|
|
1927
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/swaps"), children: "Back to list" }) })
|
|
1924
1928
|
] }) }) });
|
|
1925
1929
|
}
|
|
1926
|
-
const statusHistory = ((
|
|
1930
|
+
const statusHistory = ((_b = swap.metadata) == null ? void 0 : _b.status_history) || [];
|
|
1927
1931
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: [
|
|
1928
1932
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
|
|
1929
1933
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -1931,7 +1935,7 @@ const ReturnDetailPage = () => {
|
|
|
1931
1935
|
{
|
|
1932
1936
|
variant: "transparent",
|
|
1933
1937
|
size: "small",
|
|
1934
|
-
onClick: () => navigate("/
|
|
1938
|
+
onClick: () => navigate("/swaps"),
|
|
1935
1939
|
className: "w-fit",
|
|
1936
1940
|
children: [
|
|
1937
1941
|
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, { className: "mr-2" }),
|
|
@@ -1941,81 +1945,67 @@ const ReturnDetailPage = () => {
|
|
|
1941
1945
|
),
|
|
1942
1946
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 md:flex-row md:items-center md:justify-between", children: [
|
|
1943
1947
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1944
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "
|
|
1945
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children:
|
|
1948
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Exchange Details" }),
|
|
1949
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: swap.id })
|
|
1946
1950
|
] }),
|
|
1947
1951
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1948
1952
|
ui.Badge,
|
|
1949
1953
|
{
|
|
1950
1954
|
size: "small",
|
|
1951
|
-
className: `uppercase ${getStatusBadgeClass$3(
|
|
1952
|
-
children:
|
|
1955
|
+
className: `uppercase ${getStatusBadgeClass$3(swap.status)}`,
|
|
1956
|
+
children: swap.status.replace(/_/g, " ")
|
|
1953
1957
|
}
|
|
1954
1958
|
)
|
|
1955
1959
|
] })
|
|
1956
1960
|
] }),
|
|
1957
|
-
|
|
1961
|
+
canCancelExchange && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
1958
1962
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1959
1963
|
ui.Button,
|
|
1960
1964
|
{
|
|
1961
1965
|
variant: "danger",
|
|
1962
|
-
onClick:
|
|
1963
|
-
disabled:
|
|
1964
|
-
isLoading:
|
|
1965
|
-
children: "
|
|
1966
|
+
onClick: handleCancelExchange,
|
|
1967
|
+
disabled: isCancelling,
|
|
1968
|
+
isLoading: isCancelling,
|
|
1969
|
+
children: "Cancel Exchange"
|
|
1966
1970
|
}
|
|
1967
1971
|
) }),
|
|
1968
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children:
|
|
1969
|
-
] }),
|
|
1970
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
1971
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Information" }),
|
|
1972
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
1973
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1974
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Return ID" }),
|
|
1975
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.id })
|
|
1976
|
-
] }),
|
|
1977
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1978
|
-
ui.Button,
|
|
1979
|
-
{
|
|
1980
|
-
variant: "secondary",
|
|
1981
|
-
onClick: () => {
|
|
1982
|
-
window.open(
|
|
1983
|
-
`/app/orders/${returnOrder.order_id}`,
|
|
1984
|
-
"_blank"
|
|
1985
|
-
);
|
|
1986
|
-
},
|
|
1987
|
-
children: "View order"
|
|
1988
|
-
}
|
|
1989
|
-
) })
|
|
1990
|
-
] })
|
|
1972
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "This will cancel the exchange request. The order will remain unchanged." })
|
|
1991
1973
|
] }),
|
|
1992
1974
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
|
|
1993
1975
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
1994
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "
|
|
1976
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Exchange Information" }),
|
|
1995
1977
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
1996
1978
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1997
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
1998
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
1979
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
|
|
1980
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.id })
|
|
1999
1981
|
] }),
|
|
2000
1982
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2001
1983
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Status" }),
|
|
2002
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
1984
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.status })
|
|
2003
1985
|
] }),
|
|
2004
|
-
|
|
1986
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1987
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Difference Due" }),
|
|
1988
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.difference_due != null ? `${swap.currency_code || "$"}${(Number(swap.difference_due) / 100).toFixed(2)}` : "—" })
|
|
1989
|
+
] }),
|
|
1990
|
+
swap.reason && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2005
1991
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Reason" }),
|
|
2006
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
1992
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.reason })
|
|
2007
1993
|
] }),
|
|
2008
|
-
|
|
1994
|
+
swap.note && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2009
1995
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Note" }),
|
|
2010
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
1996
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.note })
|
|
2011
1997
|
] }),
|
|
2012
1998
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2013
1999
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Created" }),
|
|
2014
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(
|
|
2000
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(swap.created_at).toLocaleString() })
|
|
2015
2001
|
] }),
|
|
2016
2002
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2017
2003
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Last Updated" }),
|
|
2018
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(
|
|
2004
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(swap.updated_at).toLocaleString() })
|
|
2005
|
+
] }),
|
|
2006
|
+
swap.exchange_id && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2007
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
|
|
2008
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.exchange_id })
|
|
2019
2009
|
] })
|
|
2020
2010
|
] })
|
|
2021
2011
|
] }),
|
|
@@ -2045,31 +2035,31 @@ const ReturnDetailPage = () => {
|
|
|
2045
2035
|
)) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No status history available" })
|
|
2046
2036
|
] })
|
|
2047
2037
|
] }),
|
|
2048
|
-
|
|
2038
|
+
order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2049
2039
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Related Order Information" }),
|
|
2050
2040
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
2051
2041
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2052
2042
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order ID" }),
|
|
2053
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
2043
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.id })
|
|
2054
2044
|
] }),
|
|
2055
2045
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2056
2046
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Status" }),
|
|
2057
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
2047
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.status || "—" })
|
|
2058
2048
|
] }),
|
|
2059
2049
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2060
2050
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
|
|
2061
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((
|
|
2051
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_c = order.customer) == null ? void 0 : _c.email) || order.email || "—" })
|
|
2062
2052
|
] }),
|
|
2063
|
-
|
|
2053
|
+
order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2064
2054
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
|
|
2065
2055
|
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "font-medium", children: [
|
|
2066
|
-
|
|
2067
|
-
(Number(
|
|
2056
|
+
order.currency_code || "$",
|
|
2057
|
+
(Number(order.total) / 100).toFixed(2)
|
|
2068
2058
|
] })
|
|
2069
2059
|
] })
|
|
2070
2060
|
] })
|
|
2071
2061
|
] }),
|
|
2072
|
-
|
|
2062
|
+
swap.return_items && swap.return_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2073
2063
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Items" }),
|
|
2074
2064
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
|
|
2075
2065
|
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
@@ -2077,139 +2067,309 @@ const ReturnDetailPage = () => {
|
|
|
2077
2067
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" }),
|
|
2078
2068
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Reason" })
|
|
2079
2069
|
] }) }),
|
|
2080
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children:
|
|
2070
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.return_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
2081
2071
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.id }),
|
|
2082
2072
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity }),
|
|
2083
2073
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.reason || "—" })
|
|
2084
2074
|
] }, item.id || index)) })
|
|
2085
2075
|
] }) })
|
|
2086
2076
|
] }),
|
|
2087
|
-
|
|
2088
|
-
|
|
2077
|
+
swap.new_items && swap.new_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2078
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "New Items" }),
|
|
2079
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
|
|
2080
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
2081
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Variant ID" }),
|
|
2082
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" })
|
|
2083
|
+
] }) }),
|
|
2084
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.new_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
2085
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.variant_id }),
|
|
2086
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity })
|
|
2087
|
+
] }, item.variant_id || index)) })
|
|
2088
|
+
] }) })
|
|
2089
|
+
] })
|
|
2089
2090
|
] }) });
|
|
2090
2091
|
};
|
|
2091
2092
|
const config$3 = adminSdk.defineRouteConfig({
|
|
2092
|
-
label: "
|
|
2093
|
-
icon: icons.
|
|
2093
|
+
label: "Swap Details",
|
|
2094
|
+
icon: icons.ArrowPath
|
|
2094
2095
|
});
|
|
2095
2096
|
const getStatusBadgeClass$2 = (status) => {
|
|
2096
|
-
const
|
|
2097
|
-
if (
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
if (
|
|
2097
|
+
const statusLower = status.toLowerCase();
|
|
2098
|
+
if (statusLower === "requested") {
|
|
2099
|
+
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
2100
|
+
}
|
|
2101
|
+
if (statusLower === "approved") {
|
|
2102
|
+
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
2103
|
+
}
|
|
2104
|
+
if (statusLower === "rejected") {
|
|
2105
|
+
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
2106
|
+
}
|
|
2107
|
+
if (statusLower === "received") {
|
|
2108
|
+
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
2109
|
+
}
|
|
2110
|
+
if (statusLower === "refunded") {
|
|
2111
|
+
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
2112
|
+
}
|
|
2113
|
+
if (statusLower === "completed") {
|
|
2114
|
+
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
2115
|
+
}
|
|
2116
|
+
if (statusLower === "cancelled") {
|
|
2117
|
+
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
2118
|
+
}
|
|
2101
2119
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
2102
2120
|
};
|
|
2103
|
-
const
|
|
2104
|
-
var _a;
|
|
2121
|
+
const ReturnDetailPage = () => {
|
|
2122
|
+
var _a, _b;
|
|
2105
2123
|
const navigate = reactRouterDom.useNavigate();
|
|
2106
|
-
const
|
|
2107
|
-
const
|
|
2108
|
-
const [
|
|
2109
|
-
const [
|
|
2124
|
+
const { id } = reactRouterDom.useParams();
|
|
2125
|
+
const [returnOrder, setReturnOrder] = react.useState(null);
|
|
2126
|
+
const [isLoading, setIsLoading] = react.useState(true);
|
|
2127
|
+
const [isRejecting, setIsRejecting] = react.useState(false);
|
|
2110
2128
|
const [error, setError] = react.useState(null);
|
|
2129
|
+
const [updateError, setUpdateError] = react.useState(null);
|
|
2130
|
+
const [updateSuccess, setUpdateSuccess] = react.useState(false);
|
|
2111
2131
|
react.useEffect(() => {
|
|
2112
2132
|
if (!id) {
|
|
2113
|
-
|
|
2133
|
+
navigate("/returns");
|
|
2114
2134
|
return;
|
|
2115
2135
|
}
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2136
|
+
const loadReturn = async () => {
|
|
2137
|
+
try {
|
|
2138
|
+
setIsLoading(true);
|
|
2139
|
+
setError(null);
|
|
2140
|
+
const response = await fetch(`/admin/returns/${id}`, {
|
|
2141
|
+
credentials: "include"
|
|
2142
|
+
});
|
|
2143
|
+
if (!response.ok) {
|
|
2144
|
+
const message = await response.text();
|
|
2145
|
+
throw new Error(message || "Unable to load return order");
|
|
2146
|
+
}
|
|
2147
|
+
const payload = await response.json();
|
|
2148
|
+
setReturnOrder(payload.return);
|
|
2149
|
+
} catch (loadError) {
|
|
2150
|
+
const message = loadError instanceof Error ? loadError.message : "Unable to load return order";
|
|
2151
|
+
setError(message);
|
|
2152
|
+
} finally {
|
|
2153
|
+
setIsLoading(false);
|
|
2154
|
+
}
|
|
2131
2155
|
};
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
const
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2156
|
+
void loadReturn();
|
|
2157
|
+
}, [id, navigate]);
|
|
2158
|
+
const handleReject = async () => {
|
|
2159
|
+
if (!id) {
|
|
2160
|
+
return;
|
|
2161
|
+
}
|
|
2162
|
+
try {
|
|
2163
|
+
setIsRejecting(true);
|
|
2164
|
+
setUpdateError(null);
|
|
2165
|
+
setUpdateSuccess(false);
|
|
2166
|
+
const response = await fetch(`/admin/returns/${id}/reject`, {
|
|
2167
|
+
method: "POST",
|
|
2168
|
+
headers: {
|
|
2169
|
+
"Content-Type": "application/json"
|
|
2170
|
+
},
|
|
2171
|
+
credentials: "include",
|
|
2172
|
+
body: JSON.stringify({ reason: "Rejected by admin" })
|
|
2173
|
+
});
|
|
2174
|
+
if (!response.ok) {
|
|
2175
|
+
const message = await response.text();
|
|
2176
|
+
throw new Error(message || "Unable to reject return");
|
|
2177
|
+
}
|
|
2178
|
+
const payload = await response.json();
|
|
2179
|
+
setReturnOrder(payload.return);
|
|
2180
|
+
setUpdateSuccess(true);
|
|
2181
|
+
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
2182
|
+
const detailResponse = await fetch(`/admin/returns/${id}`, {
|
|
2183
|
+
credentials: "include"
|
|
2184
|
+
});
|
|
2185
|
+
if (detailResponse.ok) {
|
|
2186
|
+
const detailPayload = await detailResponse.json();
|
|
2187
|
+
setReturnOrder(detailPayload.return);
|
|
2188
|
+
}
|
|
2189
|
+
} catch (updateErr) {
|
|
2190
|
+
const message = updateErr instanceof Error ? updateErr.message : "Unable to reject return";
|
|
2191
|
+
setUpdateError(message);
|
|
2192
|
+
} finally {
|
|
2193
|
+
setIsRejecting(false);
|
|
2194
|
+
}
|
|
2195
|
+
};
|
|
2196
|
+
if (isLoading) {
|
|
2197
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading return order..." }) }) }) });
|
|
2198
|
+
}
|
|
2199
|
+
if (error || !returnOrder) {
|
|
2200
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
2201
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "Return order not found" }),
|
|
2202
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/returns"), children: "Back to list" }) })
|
|
2203
|
+
] }) }) });
|
|
2204
|
+
}
|
|
2205
|
+
const statusHistory = ((_a = returnOrder.metadata) == null ? void 0 : _a.status_history) || [];
|
|
2206
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: [
|
|
2207
|
+
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
|
|
2208
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2209
|
+
ui.Button,
|
|
2210
|
+
{
|
|
2211
|
+
variant: "transparent",
|
|
2212
|
+
size: "small",
|
|
2213
|
+
onClick: () => navigate("/returns"),
|
|
2214
|
+
className: "w-fit",
|
|
2215
|
+
children: [
|
|
2216
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, { className: "mr-2" }),
|
|
2217
|
+
"Back to list"
|
|
2218
|
+
]
|
|
2219
|
+
}
|
|
2220
|
+
),
|
|
2221
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 md:flex-row md:items-center md:justify-between", children: [
|
|
2222
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
2223
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Return Order Details" }),
|
|
2224
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: returnOrder.id })
|
|
2178
2225
|
] }),
|
|
2226
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2227
|
+
ui.Badge,
|
|
2228
|
+
{
|
|
2229
|
+
size: "small",
|
|
2230
|
+
className: `uppercase ${getStatusBadgeClass$2(returnOrder.status)}`,
|
|
2231
|
+
children: returnOrder.status.replace(/_/g, " ")
|
|
2232
|
+
}
|
|
2233
|
+
)
|
|
2234
|
+
] })
|
|
2235
|
+
] }),
|
|
2236
|
+
returnOrder.status === "requested" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
2237
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2238
|
+
ui.Button,
|
|
2239
|
+
{
|
|
2240
|
+
variant: "danger",
|
|
2241
|
+
onClick: handleReject,
|
|
2242
|
+
disabled: isRejecting,
|
|
2243
|
+
isLoading: isRejecting,
|
|
2244
|
+
children: "Reject (Cancel) Return"
|
|
2245
|
+
}
|
|
2246
|
+
) }),
|
|
2247
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: 'Cancel this return request. Use "Mark as received" when items are received.' })
|
|
2248
|
+
] }),
|
|
2249
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2250
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Information" }),
|
|
2251
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
2179
2252
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2180
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-
|
|
2181
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "
|
|
2253
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Return ID" }),
|
|
2254
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.id })
|
|
2182
2255
|
] }),
|
|
2256
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2257
|
+
ui.Button,
|
|
2258
|
+
{
|
|
2259
|
+
variant: "secondary",
|
|
2260
|
+
onClick: () => {
|
|
2261
|
+
window.open(
|
|
2262
|
+
`/app/orders/${returnOrder.order_id}`,
|
|
2263
|
+
"_blank"
|
|
2264
|
+
);
|
|
2265
|
+
},
|
|
2266
|
+
children: "View order"
|
|
2267
|
+
}
|
|
2268
|
+
) })
|
|
2269
|
+
] })
|
|
2270
|
+
] }),
|
|
2271
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
|
|
2272
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2273
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Details" }),
|
|
2274
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
2275
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2276
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Return ID" }),
|
|
2277
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.id })
|
|
2278
|
+
] }),
|
|
2279
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2280
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Status" }),
|
|
2281
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.status })
|
|
2282
|
+
] }),
|
|
2283
|
+
returnOrder.reason && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2284
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Reason" }),
|
|
2285
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.reason })
|
|
2286
|
+
] }),
|
|
2287
|
+
returnOrder.note && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2288
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Note" }),
|
|
2289
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.note })
|
|
2290
|
+
] }),
|
|
2291
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2292
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Created" }),
|
|
2293
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(returnOrder.created_at).toLocaleString() })
|
|
2294
|
+
] }),
|
|
2295
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2296
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Last Updated" }),
|
|
2297
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(returnOrder.updated_at).toLocaleString() })
|
|
2298
|
+
] })
|
|
2299
|
+
] })
|
|
2300
|
+
] }),
|
|
2301
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2302
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Status History" }),
|
|
2303
|
+
statusHistory.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: statusHistory.map((entry, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2304
|
+
"div",
|
|
2305
|
+
{
|
|
2306
|
+
className: "flex items-center justify-between border-b border-ui-border-subtle pb-2 last:border-0",
|
|
2307
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
2308
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2309
|
+
ui.Badge,
|
|
2310
|
+
{
|
|
2311
|
+
size: "2xsmall",
|
|
2312
|
+
className: `uppercase ${getStatusBadgeClass$2(entry.status)}`,
|
|
2313
|
+
children: entry.status.replace(/_/g, " ")
|
|
2314
|
+
}
|
|
2315
|
+
) }),
|
|
2316
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
|
|
2317
|
+
new Date(entry.timestamp).toLocaleString(),
|
|
2318
|
+
entry.admin_id && ` by ${entry.admin_id}`,
|
|
2319
|
+
entry.reason && ` - ${entry.reason}`
|
|
2320
|
+
] })
|
|
2321
|
+
] })
|
|
2322
|
+
},
|
|
2323
|
+
index
|
|
2324
|
+
)) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No status history available" })
|
|
2325
|
+
] })
|
|
2326
|
+
] }),
|
|
2327
|
+
returnOrder.order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2328
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Related Order Information" }),
|
|
2329
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
2183
2330
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2184
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-
|
|
2185
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "
|
|
2331
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order ID" }),
|
|
2332
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.id })
|
|
2186
2333
|
] }),
|
|
2187
2334
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2188
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-
|
|
2189
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "
|
|
2335
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Status" }),
|
|
2336
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.status || "—" })
|
|
2190
2337
|
] }),
|
|
2191
2338
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2192
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-
|
|
2193
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2339
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
|
|
2340
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_b = returnOrder.order.customer) == null ? void 0 : _b.email) || returnOrder.order.email || "—" })
|
|
2341
|
+
] }),
|
|
2342
|
+
returnOrder.order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2343
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
|
|
2344
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "font-medium", children: [
|
|
2345
|
+
returnOrder.order.currency_code || "$",
|
|
2346
|
+
(Number(returnOrder.order.total) / 100).toFixed(2)
|
|
2347
|
+
] })
|
|
2201
2348
|
] })
|
|
2202
|
-
] })
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2349
|
+
] })
|
|
2350
|
+
] }),
|
|
2351
|
+
returnOrder.return_items && returnOrder.return_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2352
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Items" }),
|
|
2353
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
|
|
2354
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
2355
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Item ID" }),
|
|
2356
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" }),
|
|
2357
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Reason" })
|
|
2358
|
+
] }) }),
|
|
2359
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: returnOrder.return_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
2360
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.id }),
|
|
2361
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity }),
|
|
2362
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.reason || "—" })
|
|
2363
|
+
] }, item.id || index)) })
|
|
2364
|
+
] }) })
|
|
2365
|
+
] }),
|
|
2366
|
+
updateError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-ui-border-error bg-ui-bg-error-subtle p-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-error", children: updateError }) }),
|
|
2367
|
+
updateSuccess && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-ui-border-success bg-ui-bg-success-subtle p-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-success", children: "Action completed successfully" }) })
|
|
2208
2368
|
] }) });
|
|
2209
2369
|
};
|
|
2210
2370
|
const config$2 = adminSdk.defineRouteConfig({
|
|
2211
|
-
label: "
|
|
2212
|
-
icon: icons.
|
|
2371
|
+
label: "Return Order Details",
|
|
2372
|
+
icon: icons.CheckCircle
|
|
2213
2373
|
});
|
|
2214
2374
|
const getStatusBadgeClass$1 = (status) => {
|
|
2215
2375
|
const s2 = status.toLowerCase();
|
|
@@ -2219,18 +2379,14 @@ const getStatusBadgeClass$1 = (status) => {
|
|
|
2219
2379
|
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
2220
2380
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
2221
2381
|
};
|
|
2222
|
-
const
|
|
2223
|
-
|
|
2224
|
-
};
|
|
2225
|
-
const RefundDetailPage = () => {
|
|
2226
|
-
var _a, _b, _c;
|
|
2382
|
+
const PaymentDetailPage = () => {
|
|
2383
|
+
var _a;
|
|
2227
2384
|
const navigate = reactRouterDom.useNavigate();
|
|
2228
2385
|
const params = reactRouterDom.useParams();
|
|
2229
2386
|
const id = (_a = params == null ? void 0 : params.id) == null ? void 0 : _a.trim();
|
|
2230
2387
|
const [detail, setDetail] = react.useState(null);
|
|
2231
2388
|
const [loading, setLoading] = react.useState(!!id);
|
|
2232
2389
|
const [error, setError] = react.useState(null);
|
|
2233
|
-
const [gatewayExpanded, setGatewayExpanded] = react.useState(false);
|
|
2234
2390
|
react.useEffect(() => {
|
|
2235
2391
|
if (!id) {
|
|
2236
2392
|
setLoading(false);
|
|
@@ -2239,7 +2395,7 @@ const RefundDetailPage = () => {
|
|
|
2239
2395
|
let cancelled = false;
|
|
2240
2396
|
setLoading(true);
|
|
2241
2397
|
setError(null);
|
|
2242
|
-
fetch(`/admin/
|
|
2398
|
+
fetch(`/admin/payment-transactions/${id}`, { credentials: "include" }).then((res) => {
|
|
2243
2399
|
if (!res.ok) throw new Error(res.statusText || "Failed to load");
|
|
2244
2400
|
return res.json();
|
|
2245
2401
|
}).then((data) => {
|
|
@@ -2253,434 +2409,278 @@ const RefundDetailPage = () => {
|
|
|
2253
2409
|
cancelled = true;
|
|
2254
2410
|
};
|
|
2255
2411
|
}, [id]);
|
|
2256
|
-
const
|
|
2257
|
-
const
|
|
2412
|
+
const displayStatus = detail ? (detail.payment_id != null && detail.payment_status != null && detail.payment_status !== "" ? detail.payment_status : detail.session_status ?? "") || "—" : "";
|
|
2413
|
+
const sessionStatusRaw = (detail == null ? void 0 : detail.session_status) ?? "—";
|
|
2414
|
+
const paymentStatusRaw = (detail == null ? void 0 : detail.payment_id) != null ? (detail == null ? void 0 : detail.payment_status) ?? "—" : "—";
|
|
2415
|
+
const displayAmount = detail ? `${(detail.currency_code ?? "USD").toUpperCase()} ${Number(detail.amount)}` : "";
|
|
2258
2416
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-4xl flex-col gap-6 p-6", children: [
|
|
2259
2417
|
/* @__PURE__ */ jsxRuntime.jsx("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
2260
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => navigate("/
|
|
2261
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "
|
|
2262
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle
|
|
2418
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => navigate("/payments"), children: "← Payments" }),
|
|
2419
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Payment session" }),
|
|
2420
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: id ?? "—" })
|
|
2263
2421
|
] }) }),
|
|
2264
2422
|
error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
2265
2423
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
2266
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/
|
|
2424
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/payments"), children: "Back to list" })
|
|
2267
2425
|
] }) : loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading…" }) }) : detail ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
2268
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2269
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2270
|
-
|
|
2271
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
ui.Badge,
|
|
2323
|
-
{
|
|
2324
|
-
size: "2xsmall",
|
|
2325
|
-
className: `uppercase ${getStatusBadgeClass$1(paymentStatus)}`,
|
|
2326
|
-
children: paymentStatus !== "—" ? paymentStatus.replace(/_/g, " ") : "—"
|
|
2327
|
-
}
|
|
2328
|
-
) })
|
|
2329
|
-
] }),
|
|
2330
|
-
detail.computed ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2331
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2332
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Full refund" }),
|
|
2333
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.computed.is_full_refund ? "Yes" : "No" })
|
|
2334
|
-
] }),
|
|
2335
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2336
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Remaining refundable" }),
|
|
2337
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.computed.remaining_refundable_amount) })
|
|
2338
|
-
] }),
|
|
2339
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2340
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refund %" }),
|
|
2341
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "mt-1 block", children: [
|
|
2342
|
-
detail.computed.refund_percentage.toFixed(1),
|
|
2343
|
-
"%"
|
|
2344
|
-
] })
|
|
2345
|
-
] })
|
|
2346
|
-
] }) : null
|
|
2426
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl border border-ui-border-base p-6 flex flex-col gap-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
2427
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2428
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Order ID" }),
|
|
2429
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: detail.order_id ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2430
|
+
ui.Button,
|
|
2431
|
+
{
|
|
2432
|
+
variant: "transparent",
|
|
2433
|
+
size: "small",
|
|
2434
|
+
onClick: () => navigate(`/orders/${detail.order_id}`),
|
|
2435
|
+
children: detail.order_id
|
|
2436
|
+
}
|
|
2437
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "—" }) })
|
|
2438
|
+
] }),
|
|
2439
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2440
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
|
|
2441
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: displayAmount })
|
|
2442
|
+
] }),
|
|
2443
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2444
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
|
|
2445
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.provider_id })
|
|
2446
|
+
] }),
|
|
2447
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2448
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
|
|
2449
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2450
|
+
ui.Badge,
|
|
2451
|
+
{
|
|
2452
|
+
size: "2xsmall",
|
|
2453
|
+
className: `uppercase ${getStatusBadgeClass$1(displayStatus)}`,
|
|
2454
|
+
children: displayStatus !== "—" ? displayStatus.replace(/_/g, " ") : "—"
|
|
2455
|
+
}
|
|
2456
|
+
) })
|
|
2457
|
+
] }),
|
|
2458
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2459
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Session status (DB)" }),
|
|
2460
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: sessionStatusRaw })
|
|
2461
|
+
] }),
|
|
2462
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2463
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Payment status (DB)" }),
|
|
2464
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: paymentStatusRaw })
|
|
2465
|
+
] }),
|
|
2466
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2467
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Finalized" }),
|
|
2468
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.payment_id != null ? "Yes" : "No" })
|
|
2469
|
+
] }),
|
|
2470
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2471
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created" }),
|
|
2472
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: new Date(detail.created_at).toLocaleDateString("en-US", {
|
|
2473
|
+
year: "numeric",
|
|
2474
|
+
month: "short",
|
|
2475
|
+
day: "numeric",
|
|
2476
|
+
hour: "numeric",
|
|
2477
|
+
minute: "2-digit",
|
|
2478
|
+
hour12: true
|
|
2479
|
+
}) })
|
|
2347
2480
|
] })
|
|
2348
|
-
] }),
|
|
2349
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2350
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Order" }),
|
|
2354
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2355
|
-
ui.Button,
|
|
2356
|
-
{
|
|
2357
|
-
variant: "transparent",
|
|
2358
|
-
size: "small",
|
|
2359
|
-
onClick: () => navigate(`/orders/${detail.order.order_id}`),
|
|
2360
|
-
children: detail.order.order_number ?? detail.order.order_id
|
|
2361
|
-
}
|
|
2362
|
-
) })
|
|
2363
|
-
] }),
|
|
2364
|
-
detail.order.total != null ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2365
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Total" }),
|
|
2366
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.order.total) })
|
|
2367
|
-
] }) : null,
|
|
2368
|
-
detail.order.customer_id ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2369
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Customer ID" }),
|
|
2370
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.order.customer_id })
|
|
2371
|
-
] }) : null,
|
|
2372
|
-
detail.order.region ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2373
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Region" }),
|
|
2374
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.region })
|
|
2375
|
-
] }) : null,
|
|
2376
|
-
detail.order.fulfillment_status ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2377
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Fulfillment status" }),
|
|
2378
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.fulfillment_status })
|
|
2379
|
-
] }) : null
|
|
2380
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No order linked to this refund." })
|
|
2381
|
-
] }),
|
|
2382
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2383
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2384
|
-
"button",
|
|
2385
|
-
{
|
|
2386
|
-
type: "button",
|
|
2387
|
-
className: "flex w-full items-center justify-between text-left",
|
|
2388
|
-
onClick: () => setGatewayExpanded((prev) => !prev),
|
|
2389
|
-
"aria-expanded": gatewayExpanded,
|
|
2390
|
-
"aria-label": gatewayExpanded ? "Collapse gateway data" : "Expand gateway data",
|
|
2391
|
-
children: [
|
|
2392
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg", children: "Gateway data" }),
|
|
2393
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: gatewayExpanded ? "Collapse" : "Expand" })
|
|
2394
|
-
]
|
|
2395
|
-
}
|
|
2396
|
-
),
|
|
2397
|
-
gatewayExpanded && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4", children: hasGatewayData ? /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-xs bg-ui-bg-subtle p-4 rounded-lg overflow-auto max-h-96", children: JSON.stringify(detail.payment.payment_data, null, 2) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No gateway payload for this payment." }) })
|
|
2398
|
-
] })
|
|
2481
|
+
] }) }),
|
|
2482
|
+
Object.keys(detail.data ?? {}).length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2483
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Provider data" }),
|
|
2484
|
+
/* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-xs bg-ui-bg-subtle p-4 rounded-lg overflow-auto max-h-96", children: JSON.stringify(detail.data, null, 2) })
|
|
2485
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl border border-ui-border-base p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No provider data for this session." }) })
|
|
2399
2486
|
] }) : null
|
|
2400
2487
|
] }) });
|
|
2401
2488
|
};
|
|
2402
2489
|
const config$1 = adminSdk.defineRouteConfig({
|
|
2403
|
-
label: "
|
|
2404
|
-
icon: icons.
|
|
2490
|
+
label: "Payment details",
|
|
2491
|
+
icon: icons.CreditCard
|
|
2405
2492
|
});
|
|
2406
2493
|
const getStatusBadgeClass = (status) => {
|
|
2407
|
-
const
|
|
2408
|
-
if (
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
if (
|
|
2412
|
-
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
2413
|
-
}
|
|
2414
|
-
if (statusLower === "rejected") {
|
|
2415
|
-
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
2416
|
-
}
|
|
2417
|
-
if (statusLower === "completed") {
|
|
2418
|
-
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
2419
|
-
}
|
|
2420
|
-
if (statusLower === "cancelled" || statusLower === "canceled") {
|
|
2421
|
-
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
2422
|
-
}
|
|
2423
|
-
if (statusLower === "pending") {
|
|
2424
|
-
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
2425
|
-
}
|
|
2494
|
+
const s2 = status.toLowerCase();
|
|
2495
|
+
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
2496
|
+
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
2497
|
+
if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
2498
|
+
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
2426
2499
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
2427
2500
|
};
|
|
2428
|
-
const
|
|
2501
|
+
const formatAmount = (value) => {
|
|
2502
|
+
return String(value);
|
|
2503
|
+
};
|
|
2504
|
+
const RefundDetailPage = () => {
|
|
2429
2505
|
var _a, _b, _c;
|
|
2430
2506
|
const navigate = reactRouterDom.useNavigate();
|
|
2431
|
-
const
|
|
2432
|
-
const
|
|
2433
|
-
const [
|
|
2434
|
-
const [
|
|
2435
|
-
react.useState(false);
|
|
2436
|
-
const [isCancelling, setIsCancelling] = react.useState(false);
|
|
2507
|
+
const params = reactRouterDom.useParams();
|
|
2508
|
+
const id = (_a = params == null ? void 0 : params.id) == null ? void 0 : _a.trim();
|
|
2509
|
+
const [detail, setDetail] = react.useState(null);
|
|
2510
|
+
const [loading, setLoading] = react.useState(!!id);
|
|
2437
2511
|
const [error, setError] = react.useState(null);
|
|
2438
|
-
const [
|
|
2439
|
-
const [updateSuccess, setUpdateSuccess] = react.useState(false);
|
|
2512
|
+
const [gatewayExpanded, setGatewayExpanded] = react.useState(false);
|
|
2440
2513
|
react.useEffect(() => {
|
|
2441
2514
|
if (!id) {
|
|
2442
|
-
|
|
2515
|
+
setLoading(false);
|
|
2443
2516
|
return;
|
|
2444
2517
|
}
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
const message = loadError instanceof Error ? loadError.message : "Unable to load swap";
|
|
2461
|
-
setError(message);
|
|
2462
|
-
} finally {
|
|
2463
|
-
setIsLoading(false);
|
|
2464
|
-
}
|
|
2518
|
+
let cancelled = false;
|
|
2519
|
+
setLoading(true);
|
|
2520
|
+
setError(null);
|
|
2521
|
+
fetch(`/admin/refunds/${id}`, { credentials: "include" }).then((res) => {
|
|
2522
|
+
if (!res.ok) throw new Error(res.statusText || "Failed to load");
|
|
2523
|
+
return res.json();
|
|
2524
|
+
}).then((data) => {
|
|
2525
|
+
if (!cancelled) setDetail(data);
|
|
2526
|
+
}).catch((e) => {
|
|
2527
|
+
if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
|
|
2528
|
+
}).finally(() => {
|
|
2529
|
+
if (!cancelled) setLoading(false);
|
|
2530
|
+
});
|
|
2531
|
+
return () => {
|
|
2532
|
+
cancelled = true;
|
|
2465
2533
|
};
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
const
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
},
|
|
2481
|
-
|
|
2482
|
-
});
|
|
2483
|
-
if (!response.ok) {
|
|
2484
|
-
const message = await response.text();
|
|
2485
|
-
throw new Error(message || "Unable to cancel exchange");
|
|
2486
|
-
}
|
|
2487
|
-
const payload = await response.json();
|
|
2488
|
-
setSwap(payload.swap);
|
|
2489
|
-
setUpdateSuccess(true);
|
|
2490
|
-
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
2491
|
-
const detailResponse = await fetch(`/admin/swaps/${id}`, {
|
|
2492
|
-
credentials: "include"
|
|
2493
|
-
});
|
|
2494
|
-
if (detailResponse.ok) {
|
|
2495
|
-
const detailPayload = await detailResponse.json();
|
|
2496
|
-
setSwap(detailPayload.swap);
|
|
2497
|
-
setOrder(detailPayload.order || null);
|
|
2498
|
-
}
|
|
2499
|
-
} catch (cancelErr) {
|
|
2500
|
-
const message = cancelErr instanceof Error ? cancelErr.message : "Unable to cancel exchange";
|
|
2501
|
-
setUpdateError(message);
|
|
2502
|
-
} finally {
|
|
2503
|
-
setIsCancelling(false);
|
|
2504
|
-
}
|
|
2505
|
-
};
|
|
2506
|
-
const isOrderExchange = Boolean(swap == null ? void 0 : swap.exchange_id);
|
|
2507
|
-
const canCancelExchange = isOrderExchange && swap && !["cancelled", "canceled", "completed", "declined"].includes(
|
|
2508
|
-
((_a = swap.status) == null ? void 0 : _a.toLowerCase()) ?? ""
|
|
2509
|
-
);
|
|
2510
|
-
if (isLoading) {
|
|
2511
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading swap..." }) }) }) });
|
|
2512
|
-
}
|
|
2513
|
-
if (error || !swap) {
|
|
2514
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
2515
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "Swap not found" }),
|
|
2516
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/swaps"), children: "Back to list" }) })
|
|
2517
|
-
] }) }) });
|
|
2518
|
-
}
|
|
2519
|
-
const statusHistory = ((_b = swap.metadata) == null ? void 0 : _b.status_history) || [];
|
|
2520
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: [
|
|
2521
|
-
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
|
|
2522
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2523
|
-
ui.Button,
|
|
2524
|
-
{
|
|
2525
|
-
variant: "transparent",
|
|
2526
|
-
size: "small",
|
|
2527
|
-
onClick: () => navigate("/swaps"),
|
|
2528
|
-
className: "w-fit",
|
|
2529
|
-
children: [
|
|
2530
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, { className: "mr-2" }),
|
|
2531
|
-
"Back to list"
|
|
2532
|
-
]
|
|
2533
|
-
}
|
|
2534
|
-
),
|
|
2535
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 md:flex-row md:items-center md:justify-between", children: [
|
|
2536
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
2537
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Exchange Details" }),
|
|
2538
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: swap.id })
|
|
2539
|
-
] }),
|
|
2540
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2541
|
-
ui.Badge,
|
|
2542
|
-
{
|
|
2543
|
-
size: "small",
|
|
2544
|
-
className: `uppercase ${getStatusBadgeClass(swap.status)}`,
|
|
2545
|
-
children: swap.status.replace(/_/g, " ")
|
|
2546
|
-
}
|
|
2547
|
-
)
|
|
2548
|
-
] })
|
|
2549
|
-
] }),
|
|
2550
|
-
canCancelExchange && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
2551
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2552
|
-
ui.Button,
|
|
2553
|
-
{
|
|
2554
|
-
variant: "danger",
|
|
2555
|
-
onClick: handleCancelExchange,
|
|
2556
|
-
disabled: isCancelling,
|
|
2557
|
-
isLoading: isCancelling,
|
|
2558
|
-
children: "Cancel Exchange"
|
|
2559
|
-
}
|
|
2560
|
-
) }),
|
|
2561
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "This will cancel the exchange request. The order will remain unchanged." })
|
|
2562
|
-
] }),
|
|
2563
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
|
|
2564
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2565
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Exchange Information" }),
|
|
2566
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
2534
|
+
}, [id]);
|
|
2535
|
+
const paymentStatus = ((_b = detail == null ? void 0 : detail.payment) == null ? void 0 : _b.status) ?? "—";
|
|
2536
|
+
const hasGatewayData = ((_c = detail == null ? void 0 : detail.payment) == null ? void 0 : _c.payment_data) && typeof detail.payment.payment_data === "object" && Object.keys(detail.payment.payment_data).length > 0;
|
|
2537
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-4xl flex-col gap-6 p-6", children: [
|
|
2538
|
+
/* @__PURE__ */ jsxRuntime.jsx("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
2539
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => navigate("/refunds"), children: "← Refunds" }),
|
|
2540
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Refund details" }),
|
|
2541
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle font-mono", children: id ?? "—" })
|
|
2542
|
+
] }) }),
|
|
2543
|
+
error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
2544
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
2545
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/refunds"), children: "Back to list" })
|
|
2546
|
+
] }) : loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading…" }) }) : detail ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
2547
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2548
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Refund summary" }),
|
|
2549
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
2567
2550
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2568
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-
|
|
2569
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-
|
|
2551
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refund ID" }),
|
|
2552
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.id })
|
|
2570
2553
|
] }),
|
|
2571
2554
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2572
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-
|
|
2573
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "
|
|
2555
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
|
|
2556
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.refund.amount) })
|
|
2574
2557
|
] }),
|
|
2575
2558
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2576
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-
|
|
2577
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "
|
|
2559
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Note" }),
|
|
2560
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.refund.note ?? "—" })
|
|
2578
2561
|
] }),
|
|
2579
|
-
|
|
2580
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-
|
|
2581
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "
|
|
2562
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2563
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created at" }),
|
|
2564
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: new Date(detail.refund.created_at).toLocaleDateString("en-US", {
|
|
2565
|
+
year: "numeric",
|
|
2566
|
+
month: "short",
|
|
2567
|
+
day: "numeric",
|
|
2568
|
+
hour: "numeric",
|
|
2569
|
+
minute: "2-digit",
|
|
2570
|
+
hour12: true
|
|
2571
|
+
}) })
|
|
2582
2572
|
] }),
|
|
2583
|
-
|
|
2584
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-
|
|
2585
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-
|
|
2573
|
+
detail.refund.created_by ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2574
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created by" }),
|
|
2575
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.created_by })
|
|
2576
|
+
] }) : null
|
|
2577
|
+
] })
|
|
2578
|
+
] }),
|
|
2579
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2580
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Payment summary" }),
|
|
2581
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
2582
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2583
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Payment amount" }),
|
|
2584
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.payment_amount) })
|
|
2586
2585
|
] }),
|
|
2587
2586
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2588
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-
|
|
2589
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "
|
|
2587
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Captured amount" }),
|
|
2588
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.captured_amount) })
|
|
2590
2589
|
] }),
|
|
2591
2590
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2592
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-
|
|
2593
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "
|
|
2591
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refunded amount" }),
|
|
2592
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.refunded_amount) })
|
|
2594
2593
|
] }),
|
|
2595
|
-
|
|
2596
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-
|
|
2597
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "
|
|
2598
|
-
] })
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2594
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2595
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
|
|
2596
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.payment.provider_id || "—" })
|
|
2597
|
+
] }),
|
|
2598
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2599
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
|
|
2600
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2601
|
+
ui.Badge,
|
|
2602
|
+
{
|
|
2603
|
+
size: "2xsmall",
|
|
2604
|
+
className: `uppercase ${getStatusBadgeClass(paymentStatus)}`,
|
|
2605
|
+
children: paymentStatus !== "—" ? paymentStatus.replace(/_/g, " ") : "—"
|
|
2606
|
+
}
|
|
2607
|
+
) })
|
|
2608
|
+
] }),
|
|
2609
|
+
detail.computed ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2610
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2611
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Full refund" }),
|
|
2612
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.computed.is_full_refund ? "Yes" : "No" })
|
|
2613
|
+
] }),
|
|
2614
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2615
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Remaining refundable" }),
|
|
2616
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.computed.remaining_refundable_amount) })
|
|
2617
|
+
] }),
|
|
2618
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2619
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refund %" }),
|
|
2620
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "mt-1 block", children: [
|
|
2621
|
+
detail.computed.refund_percentage.toFixed(1),
|
|
2622
|
+
"%"
|
|
2620
2623
|
] })
|
|
2621
2624
|
] })
|
|
2622
|
-
}
|
|
2623
|
-
index
|
|
2624
|
-
)) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No status history available" })
|
|
2625
|
-
] })
|
|
2626
|
-
] }),
|
|
2627
|
-
order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2628
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Related Order Information" }),
|
|
2629
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
2630
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2631
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order ID" }),
|
|
2632
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.id })
|
|
2633
|
-
] }),
|
|
2634
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2635
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Status" }),
|
|
2636
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.status || "—" })
|
|
2637
|
-
] }),
|
|
2638
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2639
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
|
|
2640
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_c = order.customer) == null ? void 0 : _c.email) || order.email || "—" })
|
|
2641
|
-
] }),
|
|
2642
|
-
order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2643
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
|
|
2644
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "font-medium", children: [
|
|
2645
|
-
order.currency_code || "$",
|
|
2646
|
-
(Number(order.total) / 100).toFixed(2)
|
|
2647
|
-
] })
|
|
2625
|
+
] }) : null
|
|
2648
2626
|
] })
|
|
2627
|
+
] }),
|
|
2628
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2629
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Order summary" }),
|
|
2630
|
+
detail.order ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
2631
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2632
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Order" }),
|
|
2633
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2634
|
+
ui.Button,
|
|
2635
|
+
{
|
|
2636
|
+
variant: "transparent",
|
|
2637
|
+
size: "small",
|
|
2638
|
+
onClick: () => navigate(`/orders/${detail.order.order_id}`),
|
|
2639
|
+
children: detail.order.order_number ?? detail.order.order_id
|
|
2640
|
+
}
|
|
2641
|
+
) })
|
|
2642
|
+
] }),
|
|
2643
|
+
detail.order.total != null ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2644
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Total" }),
|
|
2645
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.order.total) })
|
|
2646
|
+
] }) : null,
|
|
2647
|
+
detail.order.customer_id ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2648
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Customer ID" }),
|
|
2649
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.order.customer_id })
|
|
2650
|
+
] }) : null,
|
|
2651
|
+
detail.order.region ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2652
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Region" }),
|
|
2653
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.region })
|
|
2654
|
+
] }) : null,
|
|
2655
|
+
detail.order.fulfillment_status ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2656
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Fulfillment status" }),
|
|
2657
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.fulfillment_status })
|
|
2658
|
+
] }) : null
|
|
2659
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No order linked to this refund." })
|
|
2660
|
+
] }),
|
|
2661
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2662
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2663
|
+
"button",
|
|
2664
|
+
{
|
|
2665
|
+
type: "button",
|
|
2666
|
+
className: "flex w-full items-center justify-between text-left",
|
|
2667
|
+
onClick: () => setGatewayExpanded((prev) => !prev),
|
|
2668
|
+
"aria-expanded": gatewayExpanded,
|
|
2669
|
+
"aria-label": gatewayExpanded ? "Collapse gateway data" : "Expand gateway data",
|
|
2670
|
+
children: [
|
|
2671
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg", children: "Gateway data" }),
|
|
2672
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: gatewayExpanded ? "Collapse" : "Expand" })
|
|
2673
|
+
]
|
|
2674
|
+
}
|
|
2675
|
+
),
|
|
2676
|
+
gatewayExpanded && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4", children: hasGatewayData ? /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-xs bg-ui-bg-subtle p-4 rounded-lg overflow-auto max-h-96", children: JSON.stringify(detail.payment.payment_data, null, 2) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No gateway payload for this payment." }) })
|
|
2649
2677
|
] })
|
|
2650
|
-
] })
|
|
2651
|
-
swap.return_items && swap.return_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2652
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Items" }),
|
|
2653
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
|
|
2654
|
-
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
2655
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Item ID" }),
|
|
2656
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" }),
|
|
2657
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Reason" })
|
|
2658
|
-
] }) }),
|
|
2659
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.return_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
2660
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.id }),
|
|
2661
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity }),
|
|
2662
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.reason || "—" })
|
|
2663
|
-
] }, item.id || index)) })
|
|
2664
|
-
] }) })
|
|
2665
|
-
] }),
|
|
2666
|
-
swap.new_items && swap.new_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
2667
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "New Items" }),
|
|
2668
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
|
|
2669
|
-
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
2670
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Variant ID" }),
|
|
2671
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" })
|
|
2672
|
-
] }) }),
|
|
2673
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.new_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
2674
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.variant_id }),
|
|
2675
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity })
|
|
2676
|
-
] }, item.variant_id || index)) })
|
|
2677
|
-
] }) })
|
|
2678
|
-
] })
|
|
2678
|
+
] }) : null
|
|
2679
2679
|
] }) });
|
|
2680
2680
|
};
|
|
2681
2681
|
const config = adminSdk.defineRouteConfig({
|
|
2682
|
-
label: "
|
|
2683
|
-
icon: icons.
|
|
2682
|
+
label: "Refund details",
|
|
2683
|
+
icon: icons.Receipt
|
|
2684
2684
|
});
|
|
2685
2685
|
const i18nTranslations0 = {};
|
|
2686
2686
|
const widgetModule = { widgets: [
|
|
@@ -2695,6 +2695,10 @@ const widgetModule = { widgets: [
|
|
|
2695
2695
|
] };
|
|
2696
2696
|
const routeModule = {
|
|
2697
2697
|
routes: [
|
|
2698
|
+
{
|
|
2699
|
+
Component: SwapsPage,
|
|
2700
|
+
path: "/swaps"
|
|
2701
|
+
},
|
|
2698
2702
|
{
|
|
2699
2703
|
Component: ReturnsPage,
|
|
2700
2704
|
path: "/returns"
|
|
@@ -2708,8 +2712,8 @@ const routeModule = {
|
|
|
2708
2712
|
path: "/refunds"
|
|
2709
2713
|
},
|
|
2710
2714
|
{
|
|
2711
|
-
Component:
|
|
2712
|
-
path: "/swaps"
|
|
2715
|
+
Component: SwapDetailPage,
|
|
2716
|
+
path: "/swaps/:id"
|
|
2713
2717
|
},
|
|
2714
2718
|
{
|
|
2715
2719
|
Component: ReturnDetailPage,
|
|
@@ -2722,10 +2726,6 @@ const routeModule = {
|
|
|
2722
2726
|
{
|
|
2723
2727
|
Component: RefundDetailPage,
|
|
2724
2728
|
path: "/refunds/:id"
|
|
2725
|
-
},
|
|
2726
|
-
{
|
|
2727
|
-
Component: SwapDetailPage,
|
|
2728
|
-
path: "/swaps/:id"
|
|
2729
2729
|
}
|
|
2730
2730
|
]
|
|
2731
2731
|
};
|
|
@@ -2734,49 +2734,49 @@ const menuItemModule = {
|
|
|
2734
2734
|
{
|
|
2735
2735
|
label: config$4.label,
|
|
2736
2736
|
icon: config$4.icon,
|
|
2737
|
-
path: "/
|
|
2737
|
+
path: "/refunds",
|
|
2738
2738
|
nested: void 0
|
|
2739
2739
|
},
|
|
2740
2740
|
{
|
|
2741
2741
|
label: config$5.label,
|
|
2742
2742
|
icon: config$5.icon,
|
|
2743
|
-
path: "/
|
|
2743
|
+
path: "/payments",
|
|
2744
2744
|
nested: void 0
|
|
2745
2745
|
},
|
|
2746
2746
|
{
|
|
2747
2747
|
label: config$7.label,
|
|
2748
2748
|
icon: config$7.icon,
|
|
2749
|
-
path: "/
|
|
2749
|
+
path: "/swaps",
|
|
2750
2750
|
nested: void 0
|
|
2751
2751
|
},
|
|
2752
2752
|
{
|
|
2753
2753
|
label: config$6.label,
|
|
2754
2754
|
icon: config$6.icon,
|
|
2755
|
-
path: "/
|
|
2755
|
+
path: "/returns",
|
|
2756
2756
|
nested: void 0
|
|
2757
2757
|
},
|
|
2758
2758
|
{
|
|
2759
2759
|
label: config.label,
|
|
2760
2760
|
icon: config.icon,
|
|
2761
|
-
path: "/
|
|
2761
|
+
path: "/refunds/:id",
|
|
2762
2762
|
nested: void 0
|
|
2763
2763
|
},
|
|
2764
2764
|
{
|
|
2765
2765
|
label: config$1.label,
|
|
2766
2766
|
icon: config$1.icon,
|
|
2767
|
-
path: "/
|
|
2767
|
+
path: "/payments/:id",
|
|
2768
2768
|
nested: void 0
|
|
2769
2769
|
},
|
|
2770
2770
|
{
|
|
2771
|
-
label: config$
|
|
2772
|
-
icon: config$
|
|
2771
|
+
label: config$2.label,
|
|
2772
|
+
icon: config$2.icon,
|
|
2773
2773
|
path: "/returns/:id",
|
|
2774
2774
|
nested: void 0
|
|
2775
2775
|
},
|
|
2776
2776
|
{
|
|
2777
|
-
label: config$
|
|
2778
|
-
icon: config$
|
|
2779
|
-
path: "/
|
|
2777
|
+
label: config$3.label,
|
|
2778
|
+
icon: config$3.icon,
|
|
2779
|
+
path: "/swaps/:id",
|
|
2780
2780
|
nested: void 0
|
|
2781
2781
|
}
|
|
2782
2782
|
]
|