order-management 0.0.75 → 0.0.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.medusa/server/src/admin/index.js +456 -456
- package/.medusa/server/src/admin/index.mjs +457 -457
- package/.medusa/server/src/api/store/orders/reorder/[order_id]/route.js +72 -13
- package/.medusa/server/src/workflows/reorder-workflow.js +3 -2
- package/.medusa/server/src/workflows/steps/retrieve-order-step.js +4 -131
- package/.medusa/server/src/workflows/steps/transform-order-to-cart-step.js +193 -4
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
|
2
2
|
import { defineWidgetConfig, defineRouteConfig } from "@medusajs/admin-sdk";
|
|
3
3
|
import { useState, useEffect, useRef, useCallback, useMemo } from "react";
|
|
4
4
|
import { Container, Text, Heading, Badge, Button, Label, Select, Textarea, Input } from "@medusajs/ui";
|
|
5
|
-
import { CashSolid, PencilSquareSolid, Trash,
|
|
5
|
+
import { CashSolid, PencilSquareSolid, Trash, Receipt, CreditCard, ArrowPath, CheckCircle, ArrowLeft } from "@medusajs/icons";
|
|
6
6
|
import { useNavigate, useParams } from "react-router-dom";
|
|
7
7
|
function roundRectPath(ctx, x, y, w, h, r) {
|
|
8
8
|
ctx.beginPath();
|
|
@@ -872,19 +872,27 @@ const getStatusBadgeClass$7 = (status) => {
|
|
|
872
872
|
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
873
873
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
874
874
|
};
|
|
875
|
-
const
|
|
875
|
+
const RefundsPage = () => {
|
|
876
876
|
const navigate = useNavigate();
|
|
877
877
|
const [items, setItems] = useState([]);
|
|
878
|
-
const [statusFilter, setStatusFilter] = useState("all");
|
|
879
878
|
const [orderIdSearch, setOrderIdSearch] = useState("");
|
|
880
879
|
const debouncedOrderId = useDebounce$3(orderIdSearch, 300);
|
|
880
|
+
const [paymentStatusFilter, setPaymentStatusFilter] = useState("all");
|
|
881
|
+
const [providerSearch, setProviderSearch] = useState("");
|
|
882
|
+
const debouncedProvider = useDebounce$3(providerSearch, 300);
|
|
883
|
+
const [currencySearch, setCurrencySearch] = useState("");
|
|
884
|
+
const debouncedCurrency = useDebounce$3(currencySearch, 300);
|
|
885
|
+
const [dateFrom, setDateFrom] = useState("");
|
|
886
|
+
const [dateTo, setDateTo] = useState("");
|
|
887
|
+
const [amountMin, setAmountMin] = useState("");
|
|
888
|
+
const [amountMax, setAmountMax] = useState("");
|
|
881
889
|
const [isLoading, setIsLoading] = useState(true);
|
|
882
890
|
const [isFetchingMore, setIsFetchingMore] = useState(false);
|
|
883
891
|
const [error, setError] = useState(null);
|
|
884
892
|
const [offset, setOffset] = useState(0);
|
|
885
893
|
const [count, setCount] = useState(0);
|
|
886
894
|
const limit = 50;
|
|
887
|
-
const
|
|
895
|
+
const loadRefunds = useCallback(
|
|
888
896
|
async (nextOffset, replace) => {
|
|
889
897
|
try {
|
|
890
898
|
if (replace) setIsLoading(true);
|
|
@@ -893,18 +901,25 @@ const PaymentsPage = () => {
|
|
|
893
901
|
const params = new URLSearchParams();
|
|
894
902
|
params.set("limit", String(limit));
|
|
895
903
|
params.set("offset", String(nextOffset));
|
|
896
|
-
if (statusFilter !== "all") params.set("status", statusFilter);
|
|
897
904
|
if (debouncedOrderId.trim()) params.set("order_id", debouncedOrderId.trim());
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
);
|
|
905
|
+
if (paymentStatusFilter !== "all") params.set("payment_status", paymentStatusFilter);
|
|
906
|
+
if (debouncedProvider.trim()) params.set("provider_id", debouncedProvider.trim());
|
|
907
|
+
if (debouncedCurrency.trim()) params.set("currency_code", debouncedCurrency.trim());
|
|
908
|
+
if (dateFrom.trim()) params.set("date_from", dateFrom.trim());
|
|
909
|
+
if (dateTo.trim()) params.set("date_to", dateTo.trim());
|
|
910
|
+
const min = amountMin.trim() ? Number(amountMin) : void 0;
|
|
911
|
+
const max = amountMax.trim() ? Number(amountMax) : void 0;
|
|
912
|
+
if (min != null && !Number.isNaN(min)) params.set("amount_min", String(min));
|
|
913
|
+
if (max != null && !Number.isNaN(max)) params.set("amount_max", String(max));
|
|
914
|
+
const response = await fetch(`/admin/refunds?${params.toString()}`, {
|
|
915
|
+
credentials: "include"
|
|
916
|
+
});
|
|
902
917
|
if (!response.ok) {
|
|
903
918
|
const text = await response.text();
|
|
904
|
-
throw new Error(text || "Failed to load
|
|
919
|
+
throw new Error(text || "Failed to load refunds");
|
|
905
920
|
}
|
|
906
921
|
const payload = await response.json();
|
|
907
|
-
const list = payload.
|
|
922
|
+
const list = payload.refunds ?? [];
|
|
908
923
|
setCount(payload.count ?? 0);
|
|
909
924
|
setOffset(nextOffset + list.length);
|
|
910
925
|
setItems((prev) => replace ? list : [...prev, ...list]);
|
|
@@ -915,46 +930,75 @@ const PaymentsPage = () => {
|
|
|
915
930
|
setIsFetchingMore(false);
|
|
916
931
|
}
|
|
917
932
|
},
|
|
918
|
-
[
|
|
933
|
+
[
|
|
934
|
+
debouncedOrderId,
|
|
935
|
+
paymentStatusFilter,
|
|
936
|
+
debouncedProvider,
|
|
937
|
+
debouncedCurrency,
|
|
938
|
+
dateFrom,
|
|
939
|
+
dateTo,
|
|
940
|
+
amountMin,
|
|
941
|
+
amountMax
|
|
942
|
+
]
|
|
919
943
|
);
|
|
920
944
|
useEffect(() => {
|
|
921
|
-
void
|
|
922
|
-
}, [
|
|
945
|
+
void loadRefunds(0, true);
|
|
946
|
+
}, [loadRefunds]);
|
|
923
947
|
const hasMore = useMemo(() => offset < count, [offset, count]);
|
|
924
|
-
const
|
|
925
|
-
const
|
|
926
|
-
return
|
|
948
|
+
const displayAmount = (r) => {
|
|
949
|
+
const code = (r.currency_code ?? "USD").toUpperCase();
|
|
950
|
+
return `${code} ${Number(r.amount)}`;
|
|
927
951
|
};
|
|
928
|
-
const
|
|
929
|
-
const
|
|
930
|
-
return
|
|
952
|
+
const displayStatus = (r) => {
|
|
953
|
+
const s2 = r.payment_status ?? "";
|
|
954
|
+
return s2 !== "" ? s2 : "—";
|
|
931
955
|
};
|
|
932
956
|
return /* @__PURE__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxs(Container, { className: "mx-auto flex w-full max-w-7xl flex-col gap-6 p-6", children: [
|
|
933
957
|
/* @__PURE__ */ jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
934
958
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
935
|
-
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "
|
|
936
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
959
|
+
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "Refunds" }),
|
|
960
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Refund records — amount, order, payment status" })
|
|
937
961
|
] }),
|
|
938
|
-
/* @__PURE__ */ jsx(Button, { variant: "primary", onClick: () =>
|
|
962
|
+
/* @__PURE__ */ jsx(Button, { variant: "primary", onClick: () => loadRefunds(0, true), children: "Refresh" })
|
|
939
963
|
] }),
|
|
940
|
-
/* @__PURE__ */
|
|
964
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
941
965
|
/* @__PURE__ */ jsx(
|
|
942
966
|
Input,
|
|
943
967
|
{
|
|
944
|
-
placeholder: "
|
|
968
|
+
placeholder: "Order ID",
|
|
945
969
|
value: orderIdSearch,
|
|
946
970
|
onChange: (e) => setOrderIdSearch(e.target.value),
|
|
947
|
-
className: "md:max-w-
|
|
948
|
-
"aria-label": "
|
|
971
|
+
className: "md:max-w-[180px]",
|
|
972
|
+
"aria-label": "Filter by order ID"
|
|
949
973
|
}
|
|
950
974
|
),
|
|
951
|
-
/* @__PURE__ */ jsx(
|
|
975
|
+
/* @__PURE__ */ jsx(
|
|
976
|
+
Input,
|
|
977
|
+
{
|
|
978
|
+
placeholder: "Provider",
|
|
979
|
+
value: providerSearch,
|
|
980
|
+
onChange: (e) => setProviderSearch(e.target.value),
|
|
981
|
+
className: "md:max-w-[140px]",
|
|
982
|
+
"aria-label": "Filter by provider"
|
|
983
|
+
}
|
|
984
|
+
),
|
|
985
|
+
/* @__PURE__ */ jsx(
|
|
986
|
+
Input,
|
|
987
|
+
{
|
|
988
|
+
placeholder: "Currency",
|
|
989
|
+
value: currencySearch,
|
|
990
|
+
onChange: (e) => setCurrencySearch(e.target.value),
|
|
991
|
+
className: "md:max-w-[100px]",
|
|
992
|
+
"aria-label": "Filter by currency"
|
|
993
|
+
}
|
|
994
|
+
),
|
|
995
|
+
/* @__PURE__ */ jsxs(
|
|
952
996
|
"select",
|
|
953
997
|
{
|
|
954
|
-
value:
|
|
955
|
-
onChange: (e) =>
|
|
956
|
-
className: "h-9 rounded-md border border-ui-border-base bg-transparent px-3 text-sm text-ui-fg-base outline-none transition focus:ring-2 focus:ring-ui-fg-interactive md:max-w-
|
|
957
|
-
"aria-label": "Filter by status",
|
|
998
|
+
value: paymentStatusFilter,
|
|
999
|
+
onChange: (e) => setPaymentStatusFilter(e.target.value),
|
|
1000
|
+
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-[160px]",
|
|
1001
|
+
"aria-label": "Filter by payment status",
|
|
958
1002
|
children: [
|
|
959
1003
|
/* @__PURE__ */ jsx("option", { value: "all", children: "All statuses" }),
|
|
960
1004
|
/* @__PURE__ */ jsx("option", { value: "pending", children: "Pending" }),
|
|
@@ -965,52 +1009,103 @@ const PaymentsPage = () => {
|
|
|
965
1009
|
/* @__PURE__ */ jsx("option", { value: "captured", children: "Captured" })
|
|
966
1010
|
]
|
|
967
1011
|
}
|
|
968
|
-
)
|
|
969
|
-
|
|
1012
|
+
),
|
|
1013
|
+
/* @__PURE__ */ jsx(
|
|
1014
|
+
Input,
|
|
1015
|
+
{
|
|
1016
|
+
type: "date",
|
|
1017
|
+
placeholder: "From",
|
|
1018
|
+
value: dateFrom,
|
|
1019
|
+
onChange: (e) => setDateFrom(e.target.value),
|
|
1020
|
+
className: "md:max-w-[140px]",
|
|
1021
|
+
"aria-label": "Date from"
|
|
1022
|
+
}
|
|
1023
|
+
),
|
|
1024
|
+
/* @__PURE__ */ jsx(
|
|
1025
|
+
Input,
|
|
1026
|
+
{
|
|
1027
|
+
type: "date",
|
|
1028
|
+
placeholder: "To",
|
|
1029
|
+
value: dateTo,
|
|
1030
|
+
onChange: (e) => setDateTo(e.target.value),
|
|
1031
|
+
className: "md:max-w-[140px]",
|
|
1032
|
+
"aria-label": "Date to"
|
|
1033
|
+
}
|
|
1034
|
+
),
|
|
1035
|
+
/* @__PURE__ */ jsx(
|
|
1036
|
+
Input,
|
|
1037
|
+
{
|
|
1038
|
+
placeholder: "Amount min",
|
|
1039
|
+
value: amountMin,
|
|
1040
|
+
onChange: (e) => setAmountMin(e.target.value),
|
|
1041
|
+
type: "number",
|
|
1042
|
+
min: 0,
|
|
1043
|
+
className: "md:max-w-[100px]",
|
|
1044
|
+
"aria-label": "Refund amount minimum"
|
|
1045
|
+
}
|
|
1046
|
+
),
|
|
1047
|
+
/* @__PURE__ */ jsx(
|
|
1048
|
+
Input,
|
|
1049
|
+
{
|
|
1050
|
+
placeholder: "Amount max",
|
|
1051
|
+
value: amountMax,
|
|
1052
|
+
onChange: (e) => setAmountMax(e.target.value),
|
|
1053
|
+
type: "number",
|
|
1054
|
+
min: 0,
|
|
1055
|
+
className: "md:max-w-[100px]",
|
|
1056
|
+
"aria-label": "Refund amount maximum"
|
|
1057
|
+
}
|
|
1058
|
+
)
|
|
1059
|
+
] }) }),
|
|
970
1060
|
error ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
971
1061
|
/* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
972
|
-
/* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () =>
|
|
1062
|
+
/* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => loadRefunds(0, true), children: "Try again" }) })
|
|
973
1063
|
] }) : null,
|
|
974
|
-
isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading
|
|
975
|
-
/* @__PURE__ */ jsx(Heading, { level: "h3", className: "text-xl", children: "No
|
|
976
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "
|
|
977
|
-
] }) : /* @__PURE__ */ jsx("div", { className: "overflow-
|
|
1064
|
+
isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading refunds…" }) }) : items.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
|
|
1065
|
+
/* @__PURE__ */ jsx(Heading, { level: "h3", className: "text-xl", children: "No refunds yet" }),
|
|
1066
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Refund records will appear here." })
|
|
1067
|
+
] }) : /* @__PURE__ */ jsx("div", { className: "w-full overflow-x-auto rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxs("table", { className: "w-full table-fixed divide-y divide-ui-border-base", style: { minWidth: 0 }, children: [
|
|
978
1068
|
/* @__PURE__ */ jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
979
|
-
/* @__PURE__ */ jsx("th", { className: "px-
|
|
980
|
-
/* @__PURE__ */ jsx("th", { className: "px-
|
|
981
|
-
/* @__PURE__ */ jsx("th", { className: "px-
|
|
982
|
-
/* @__PURE__ */ jsx("th", { className: "px-
|
|
983
|
-
/* @__PURE__ */ jsx("th", { className: "px-
|
|
984
|
-
/* @__PURE__ */ jsx("th", { className: "px-
|
|
985
|
-
/* @__PURE__ */ jsx("th", { className: "px-
|
|
1069
|
+
/* @__PURE__ */ jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Refund ID" }),
|
|
1070
|
+
/* @__PURE__ */ jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
|
|
1071
|
+
/* @__PURE__ */ jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Payment ID" }),
|
|
1072
|
+
/* @__PURE__ */ jsx("th", { className: "w-[8%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Amount" }),
|
|
1073
|
+
/* @__PURE__ */ jsx("th", { className: "w-[6%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Currency" }),
|
|
1074
|
+
/* @__PURE__ */ jsx("th", { className: "w-[10%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Provider" }),
|
|
1075
|
+
/* @__PURE__ */ jsx("th", { className: "w-[10%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Payment Status" }),
|
|
1076
|
+
/* @__PURE__ */ jsx("th", { className: "w-[14%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Note" }),
|
|
1077
|
+
/* @__PURE__ */ jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
1078
|
+
/* @__PURE__ */ jsx("th", { className: "w-[8%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
986
1079
|
] }) }),
|
|
987
|
-
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((
|
|
1080
|
+
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((r) => /* @__PURE__ */ jsxs(
|
|
988
1081
|
"tr",
|
|
989
1082
|
{
|
|
990
|
-
className: "hover:bg-ui-bg-subtle/60
|
|
991
|
-
onClick: () => navigate(`/
|
|
1083
|
+
className: "cursor-pointer hover:bg-ui-bg-subtle/60",
|
|
1084
|
+
onClick: () => navigate(`/refunds/${r.refund_id}`),
|
|
992
1085
|
children: [
|
|
993
|
-
/* @__PURE__ */ jsx("td", { className: "px-
|
|
994
|
-
/* @__PURE__ */ jsx("td", { className: "px-
|
|
995
|
-
/* @__PURE__ */ jsx("td", { className: "px-
|
|
996
|
-
/* @__PURE__ */ jsx("td", { className: "px-
|
|
1086
|
+
/* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 font-mono text-sm text-ui-fg-base", title: r.refund_id, children: r.refund_id }),
|
|
1087
|
+
/* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 font-medium text-ui-fg-base", title: r.order_id ?? void 0, children: r.order_id ?? "—" }),
|
|
1088
|
+
/* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 font-mono text-sm text-ui-fg-subtle", title: r.payment_id, children: r.payment_id }),
|
|
1089
|
+
/* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle", children: displayAmount(r) }),
|
|
1090
|
+
/* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle uppercase", children: r.currency_code || "—" }),
|
|
1091
|
+
/* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle", title: r.provider_id || void 0, children: r.provider_id || "—" }),
|
|
1092
|
+
/* @__PURE__ */ jsx("td", { className: "min-w-0 px-3 py-3", children: /* @__PURE__ */ jsx(
|
|
997
1093
|
Badge,
|
|
998
1094
|
{
|
|
999
1095
|
size: "2xsmall",
|
|
1000
|
-
className: `uppercase ${getStatusBadgeClass$7(displayStatus(
|
|
1001
|
-
children: displayStatus(
|
|
1096
|
+
className: `uppercase ${getStatusBadgeClass$7(displayStatus(r))}`,
|
|
1097
|
+
children: displayStatus(r) !== "—" ? displayStatus(r).replace(/_/g, " ") : "—"
|
|
1002
1098
|
}
|
|
1003
1099
|
) }),
|
|
1004
|
-
/* @__PURE__ */ jsx("td", { className: "px-
|
|
1005
|
-
/* @__PURE__ */ jsx("td", { className: "px-
|
|
1006
|
-
year: "numeric",
|
|
1100
|
+
/* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle", title: r.note ?? void 0, children: r.note ?? "—" }),
|
|
1101
|
+
/* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle text-xs", children: new Date(r.created_at).toLocaleDateString("en-US", {
|
|
1007
1102
|
month: "short",
|
|
1008
1103
|
day: "numeric",
|
|
1009
1104
|
hour: "numeric",
|
|
1010
1105
|
minute: "2-digit",
|
|
1011
1106
|
hour12: true
|
|
1012
1107
|
}) }),
|
|
1013
|
-
/* @__PURE__ */
|
|
1108
|
+
/* @__PURE__ */ jsx("td", { className: "min-w-0 px-3 py-3", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-1", children: [
|
|
1014
1109
|
/* @__PURE__ */ jsx(
|
|
1015
1110
|
Button,
|
|
1016
1111
|
{
|
|
@@ -1018,27 +1113,27 @@ const PaymentsPage = () => {
|
|
|
1018
1113
|
size: "small",
|
|
1019
1114
|
onClick: (e) => {
|
|
1020
1115
|
e.stopPropagation();
|
|
1021
|
-
navigate(`/
|
|
1116
|
+
navigate(`/refunds/${r.refund_id}`);
|
|
1022
1117
|
},
|
|
1023
|
-
children: "
|
|
1118
|
+
children: "Details"
|
|
1024
1119
|
}
|
|
1025
1120
|
),
|
|
1026
|
-
|
|
1121
|
+
r.order_id ? /* @__PURE__ */ jsx(
|
|
1027
1122
|
Button,
|
|
1028
1123
|
{
|
|
1029
1124
|
variant: "transparent",
|
|
1030
1125
|
size: "small",
|
|
1031
1126
|
onClick: (e) => {
|
|
1032
1127
|
e.stopPropagation();
|
|
1033
|
-
navigate(`/orders/${
|
|
1128
|
+
navigate(`/orders/${r.order_id}`);
|
|
1034
1129
|
},
|
|
1035
1130
|
children: "Order"
|
|
1036
1131
|
}
|
|
1037
1132
|
) : null
|
|
1038
|
-
] })
|
|
1133
|
+
] }) })
|
|
1039
1134
|
]
|
|
1040
1135
|
},
|
|
1041
|
-
|
|
1136
|
+
r.refund_id
|
|
1042
1137
|
)) })
|
|
1043
1138
|
] }) }),
|
|
1044
1139
|
hasMore ? /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(
|
|
@@ -1046,15 +1141,15 @@ const PaymentsPage = () => {
|
|
|
1046
1141
|
{
|
|
1047
1142
|
variant: "secondary",
|
|
1048
1143
|
isLoading: isFetchingMore,
|
|
1049
|
-
onClick: () =>
|
|
1144
|
+
onClick: () => loadRefunds(offset, false),
|
|
1050
1145
|
children: "Load more"
|
|
1051
1146
|
}
|
|
1052
1147
|
) }) : null
|
|
1053
1148
|
] }) });
|
|
1054
1149
|
};
|
|
1055
1150
|
const config$7 = defineRouteConfig({
|
|
1056
|
-
label: "
|
|
1057
|
-
icon:
|
|
1151
|
+
label: "Refunds",
|
|
1152
|
+
icon: Receipt
|
|
1058
1153
|
});
|
|
1059
1154
|
const useDebounce$2 = (value, delay) => {
|
|
1060
1155
|
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
@@ -1072,27 +1167,19 @@ const getStatusBadgeClass$6 = (status) => {
|
|
|
1072
1167
|
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
1073
1168
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
1074
1169
|
};
|
|
1075
|
-
const
|
|
1170
|
+
const PaymentsPage = () => {
|
|
1076
1171
|
const navigate = useNavigate();
|
|
1077
1172
|
const [items, setItems] = useState([]);
|
|
1173
|
+
const [statusFilter, setStatusFilter] = useState("all");
|
|
1078
1174
|
const [orderIdSearch, setOrderIdSearch] = useState("");
|
|
1079
1175
|
const debouncedOrderId = useDebounce$2(orderIdSearch, 300);
|
|
1080
|
-
const [paymentStatusFilter, setPaymentStatusFilter] = useState("all");
|
|
1081
|
-
const [providerSearch, setProviderSearch] = useState("");
|
|
1082
|
-
const debouncedProvider = useDebounce$2(providerSearch, 300);
|
|
1083
|
-
const [currencySearch, setCurrencySearch] = useState("");
|
|
1084
|
-
const debouncedCurrency = useDebounce$2(currencySearch, 300);
|
|
1085
|
-
const [dateFrom, setDateFrom] = useState("");
|
|
1086
|
-
const [dateTo, setDateTo] = useState("");
|
|
1087
|
-
const [amountMin, setAmountMin] = useState("");
|
|
1088
|
-
const [amountMax, setAmountMax] = useState("");
|
|
1089
1176
|
const [isLoading, setIsLoading] = useState(true);
|
|
1090
1177
|
const [isFetchingMore, setIsFetchingMore] = useState(false);
|
|
1091
1178
|
const [error, setError] = useState(null);
|
|
1092
1179
|
const [offset, setOffset] = useState(0);
|
|
1093
1180
|
const [count, setCount] = useState(0);
|
|
1094
1181
|
const limit = 50;
|
|
1095
|
-
const
|
|
1182
|
+
const loadTransactions = useCallback(
|
|
1096
1183
|
async (nextOffset, replace) => {
|
|
1097
1184
|
try {
|
|
1098
1185
|
if (replace) setIsLoading(true);
|
|
@@ -1101,25 +1188,18 @@ const RefundsPage = () => {
|
|
|
1101
1188
|
const params = new URLSearchParams();
|
|
1102
1189
|
params.set("limit", String(limit));
|
|
1103
1190
|
params.set("offset", String(nextOffset));
|
|
1191
|
+
if (statusFilter !== "all") params.set("status", statusFilter);
|
|
1104
1192
|
if (debouncedOrderId.trim()) params.set("order_id", debouncedOrderId.trim());
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
if (dateTo.trim()) params.set("date_to", dateTo.trim());
|
|
1110
|
-
const min = amountMin.trim() ? Number(amountMin) : void 0;
|
|
1111
|
-
const max = amountMax.trim() ? Number(amountMax) : void 0;
|
|
1112
|
-
if (min != null && !Number.isNaN(min)) params.set("amount_min", String(min));
|
|
1113
|
-
if (max != null && !Number.isNaN(max)) params.set("amount_max", String(max));
|
|
1114
|
-
const response = await fetch(`/admin/refunds?${params.toString()}`, {
|
|
1115
|
-
credentials: "include"
|
|
1116
|
-
});
|
|
1193
|
+
const response = await fetch(
|
|
1194
|
+
`/admin/payment-transactions?${params.toString()}`,
|
|
1195
|
+
{ credentials: "include" }
|
|
1196
|
+
);
|
|
1117
1197
|
if (!response.ok) {
|
|
1118
1198
|
const text = await response.text();
|
|
1119
|
-
throw new Error(text || "Failed to load
|
|
1199
|
+
throw new Error(text || "Failed to load payment transactions");
|
|
1120
1200
|
}
|
|
1121
1201
|
const payload = await response.json();
|
|
1122
|
-
const list = payload.
|
|
1202
|
+
const list = payload.transactions ?? [];
|
|
1123
1203
|
setCount(payload.count ?? 0);
|
|
1124
1204
|
setOffset(nextOffset + list.length);
|
|
1125
1205
|
setItems((prev) => replace ? list : [...prev, ...list]);
|
|
@@ -1130,75 +1210,46 @@ const RefundsPage = () => {
|
|
|
1130
1210
|
setIsFetchingMore(false);
|
|
1131
1211
|
}
|
|
1132
1212
|
},
|
|
1133
|
-
[
|
|
1134
|
-
debouncedOrderId,
|
|
1135
|
-
paymentStatusFilter,
|
|
1136
|
-
debouncedProvider,
|
|
1137
|
-
debouncedCurrency,
|
|
1138
|
-
dateFrom,
|
|
1139
|
-
dateTo,
|
|
1140
|
-
amountMin,
|
|
1141
|
-
amountMax
|
|
1142
|
-
]
|
|
1213
|
+
[statusFilter, debouncedOrderId]
|
|
1143
1214
|
);
|
|
1144
1215
|
useEffect(() => {
|
|
1145
|
-
void
|
|
1146
|
-
}, [
|
|
1216
|
+
void loadTransactions(0, true);
|
|
1217
|
+
}, [loadTransactions]);
|
|
1147
1218
|
const hasMore = useMemo(() => offset < count, [offset, count]);
|
|
1148
|
-
const
|
|
1149
|
-
const
|
|
1150
|
-
return `${code} ${Number(r.amount)}`;
|
|
1151
|
-
};
|
|
1152
|
-
const displayStatus = (r) => {
|
|
1153
|
-
const s2 = r.payment_status ?? "";
|
|
1219
|
+
const displayStatus = (t) => {
|
|
1220
|
+
const s2 = t.payment_id != null && t.payment_status != null && t.payment_status !== "" ? t.payment_status : t.session_status ?? "";
|
|
1154
1221
|
return s2 !== "" ? s2 : "—";
|
|
1155
1222
|
};
|
|
1223
|
+
const displayAmount = (t) => {
|
|
1224
|
+
const code = (t.currency_code ?? "USD").toUpperCase();
|
|
1225
|
+
return `${code} ${Number(t.amount)}`;
|
|
1226
|
+
};
|
|
1156
1227
|
return /* @__PURE__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxs(Container, { className: "mx-auto flex w-full max-w-7xl flex-col gap-6 p-6", children: [
|
|
1157
1228
|
/* @__PURE__ */ jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1158
1229
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1159
|
-
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "
|
|
1160
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
1230
|
+
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "Payments" }),
|
|
1231
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "All payment attempts — completed, pending, failed, requires action" })
|
|
1161
1232
|
] }),
|
|
1162
|
-
/* @__PURE__ */ jsx(Button, { variant: "primary", onClick: () =>
|
|
1233
|
+
/* @__PURE__ */ jsx(Button, { variant: "primary", onClick: () => loadTransactions(0, true), children: "Refresh" })
|
|
1163
1234
|
] }),
|
|
1164
|
-
/* @__PURE__ */
|
|
1235
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1165
1236
|
/* @__PURE__ */ jsx(
|
|
1166
1237
|
Input,
|
|
1167
1238
|
{
|
|
1168
|
-
placeholder: "Order ID",
|
|
1239
|
+
placeholder: "Search by Order ID",
|
|
1169
1240
|
value: orderIdSearch,
|
|
1170
1241
|
onChange: (e) => setOrderIdSearch(e.target.value),
|
|
1171
|
-
className: "md:max-w-
|
|
1172
|
-
"aria-label": "
|
|
1173
|
-
}
|
|
1174
|
-
),
|
|
1175
|
-
/* @__PURE__ */ jsx(
|
|
1176
|
-
Input,
|
|
1177
|
-
{
|
|
1178
|
-
placeholder: "Provider",
|
|
1179
|
-
value: providerSearch,
|
|
1180
|
-
onChange: (e) => setProviderSearch(e.target.value),
|
|
1181
|
-
className: "md:max-w-[140px]",
|
|
1182
|
-
"aria-label": "Filter by provider"
|
|
1183
|
-
}
|
|
1184
|
-
),
|
|
1185
|
-
/* @__PURE__ */ jsx(
|
|
1186
|
-
Input,
|
|
1187
|
-
{
|
|
1188
|
-
placeholder: "Currency",
|
|
1189
|
-
value: currencySearch,
|
|
1190
|
-
onChange: (e) => setCurrencySearch(e.target.value),
|
|
1191
|
-
className: "md:max-w-[100px]",
|
|
1192
|
-
"aria-label": "Filter by currency"
|
|
1242
|
+
className: "md:max-w-sm",
|
|
1243
|
+
"aria-label": "Search by order ID"
|
|
1193
1244
|
}
|
|
1194
1245
|
),
|
|
1195
|
-
/* @__PURE__ */ jsxs(
|
|
1246
|
+
/* @__PURE__ */ jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxs(
|
|
1196
1247
|
"select",
|
|
1197
1248
|
{
|
|
1198
|
-
value:
|
|
1199
|
-
onChange: (e) =>
|
|
1200
|
-
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-
|
|
1201
|
-
"aria-label": "Filter by
|
|
1249
|
+
value: statusFilter,
|
|
1250
|
+
onChange: (e) => setStatusFilter(e.target.value),
|
|
1251
|
+
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",
|
|
1252
|
+
"aria-label": "Filter by status",
|
|
1202
1253
|
children: [
|
|
1203
1254
|
/* @__PURE__ */ jsx("option", { value: "all", children: "All statuses" }),
|
|
1204
1255
|
/* @__PURE__ */ jsx("option", { value: "pending", children: "Pending" }),
|
|
@@ -1209,103 +1260,52 @@ const RefundsPage = () => {
|
|
|
1209
1260
|
/* @__PURE__ */ jsx("option", { value: "captured", children: "Captured" })
|
|
1210
1261
|
]
|
|
1211
1262
|
}
|
|
1212
|
-
)
|
|
1213
|
-
|
|
1214
|
-
Input,
|
|
1215
|
-
{
|
|
1216
|
-
type: "date",
|
|
1217
|
-
placeholder: "From",
|
|
1218
|
-
value: dateFrom,
|
|
1219
|
-
onChange: (e) => setDateFrom(e.target.value),
|
|
1220
|
-
className: "md:max-w-[140px]",
|
|
1221
|
-
"aria-label": "Date from"
|
|
1222
|
-
}
|
|
1223
|
-
),
|
|
1224
|
-
/* @__PURE__ */ jsx(
|
|
1225
|
-
Input,
|
|
1226
|
-
{
|
|
1227
|
-
type: "date",
|
|
1228
|
-
placeholder: "To",
|
|
1229
|
-
value: dateTo,
|
|
1230
|
-
onChange: (e) => setDateTo(e.target.value),
|
|
1231
|
-
className: "md:max-w-[140px]",
|
|
1232
|
-
"aria-label": "Date to"
|
|
1233
|
-
}
|
|
1234
|
-
),
|
|
1235
|
-
/* @__PURE__ */ jsx(
|
|
1236
|
-
Input,
|
|
1237
|
-
{
|
|
1238
|
-
placeholder: "Amount min",
|
|
1239
|
-
value: amountMin,
|
|
1240
|
-
onChange: (e) => setAmountMin(e.target.value),
|
|
1241
|
-
type: "number",
|
|
1242
|
-
min: 0,
|
|
1243
|
-
className: "md:max-w-[100px]",
|
|
1244
|
-
"aria-label": "Refund amount minimum"
|
|
1245
|
-
}
|
|
1246
|
-
),
|
|
1247
|
-
/* @__PURE__ */ jsx(
|
|
1248
|
-
Input,
|
|
1249
|
-
{
|
|
1250
|
-
placeholder: "Amount max",
|
|
1251
|
-
value: amountMax,
|
|
1252
|
-
onChange: (e) => setAmountMax(e.target.value),
|
|
1253
|
-
type: "number",
|
|
1254
|
-
min: 0,
|
|
1255
|
-
className: "md:max-w-[100px]",
|
|
1256
|
-
"aria-label": "Refund amount maximum"
|
|
1257
|
-
}
|
|
1258
|
-
)
|
|
1259
|
-
] }) }),
|
|
1263
|
+
) })
|
|
1264
|
+
] }),
|
|
1260
1265
|
error ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
1261
1266
|
/* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
1262
|
-
/* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () =>
|
|
1267
|
+
/* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => loadTransactions(0, true), children: "Try again" }) })
|
|
1263
1268
|
] }) : null,
|
|
1264
|
-
isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading
|
|
1265
|
-
/* @__PURE__ */ jsx(Heading, { level: "h3", className: "text-xl", children: "No
|
|
1266
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "
|
|
1267
|
-
] }) : /* @__PURE__ */ jsx("div", { className: "
|
|
1269
|
+
isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading payments…" }) }) : items.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
|
|
1270
|
+
/* @__PURE__ */ jsx(Heading, { level: "h3", className: "text-xl", children: "No payment transactions yet" }),
|
|
1271
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Payment attempts will appear here." })
|
|
1272
|
+
] }) : /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
|
|
1268
1273
|
/* @__PURE__ */ jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
1269
|
-
/* @__PURE__ */ jsx("th", { className: "
|
|
1270
|
-
/* @__PURE__ */ jsx("th", { className: "
|
|
1271
|
-
/* @__PURE__ */ jsx("th", { className: "
|
|
1272
|
-
/* @__PURE__ */ jsx("th", { className: "
|
|
1273
|
-
/* @__PURE__ */ jsx("th", { className: "
|
|
1274
|
-
/* @__PURE__ */ jsx("th", { className: "
|
|
1275
|
-
/* @__PURE__ */ jsx("th", { className: "
|
|
1276
|
-
/* @__PURE__ */ jsx("th", { className: "w-[14%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Note" }),
|
|
1277
|
-
/* @__PURE__ */ jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
1278
|
-
/* @__PURE__ */ jsx("th", { className: "w-[8%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
1274
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
|
|
1275
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Amount" }),
|
|
1276
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Provider" }),
|
|
1277
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
|
|
1278
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Finalized" }),
|
|
1279
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
1280
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
1279
1281
|
] }) }),
|
|
1280
|
-
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((
|
|
1282
|
+
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((t) => /* @__PURE__ */ jsxs(
|
|
1281
1283
|
"tr",
|
|
1282
1284
|
{
|
|
1283
|
-
className: "
|
|
1284
|
-
onClick: () => navigate(`/
|
|
1285
|
+
className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
|
|
1286
|
+
onClick: () => navigate(`/payments/${t.payment_session_id}`),
|
|
1285
1287
|
children: [
|
|
1286
|
-
/* @__PURE__ */ jsx("td", { className: "
|
|
1287
|
-
/* @__PURE__ */ jsx("td", { className: "
|
|
1288
|
-
/* @__PURE__ */ jsx("td", { className: "
|
|
1289
|
-
/* @__PURE__ */ jsx("td", { className: "
|
|
1290
|
-
/* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle uppercase", children: r.currency_code || "—" }),
|
|
1291
|
-
/* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle", title: r.provider_id || void 0, children: r.provider_id || "—" }),
|
|
1292
|
-
/* @__PURE__ */ jsx("td", { className: "min-w-0 px-3 py-3", children: /* @__PURE__ */ jsx(
|
|
1288
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: t.order_id ?? "—" }),
|
|
1289
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: displayAmount(t) }),
|
|
1290
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: t.provider_id }),
|
|
1291
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsx(
|
|
1293
1292
|
Badge,
|
|
1294
1293
|
{
|
|
1295
1294
|
size: "2xsmall",
|
|
1296
|
-
className: `uppercase ${getStatusBadgeClass$6(displayStatus(
|
|
1297
|
-
children: displayStatus(
|
|
1295
|
+
className: `uppercase ${getStatusBadgeClass$6(displayStatus(t))}`,
|
|
1296
|
+
children: displayStatus(t) !== "—" ? displayStatus(t).replace(/_/g, " ") : "—"
|
|
1298
1297
|
}
|
|
1299
1298
|
) }),
|
|
1300
|
-
/* @__PURE__ */ jsx("td", { className: "
|
|
1301
|
-
/* @__PURE__ */ jsx("td", { className: "
|
|
1299
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: t.payment_id != null ? "Yes" : "No" }),
|
|
1300
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(t.created_at).toLocaleDateString("en-US", {
|
|
1301
|
+
year: "numeric",
|
|
1302
1302
|
month: "short",
|
|
1303
1303
|
day: "numeric",
|
|
1304
1304
|
hour: "numeric",
|
|
1305
1305
|
minute: "2-digit",
|
|
1306
1306
|
hour12: true
|
|
1307
1307
|
}) }),
|
|
1308
|
-
/* @__PURE__ */
|
|
1308
|
+
/* @__PURE__ */ jsxs("td", { className: "px-4 py-4", children: [
|
|
1309
1309
|
/* @__PURE__ */ jsx(
|
|
1310
1310
|
Button,
|
|
1311
1311
|
{
|
|
@@ -1313,27 +1313,27 @@ const RefundsPage = () => {
|
|
|
1313
1313
|
size: "small",
|
|
1314
1314
|
onClick: (e) => {
|
|
1315
1315
|
e.stopPropagation();
|
|
1316
|
-
navigate(`/
|
|
1316
|
+
navigate(`/payments/${t.payment_session_id}`);
|
|
1317
1317
|
},
|
|
1318
|
-
children: "
|
|
1318
|
+
children: "View details"
|
|
1319
1319
|
}
|
|
1320
1320
|
),
|
|
1321
|
-
|
|
1321
|
+
t.order_id ? /* @__PURE__ */ jsx(
|
|
1322
1322
|
Button,
|
|
1323
1323
|
{
|
|
1324
1324
|
variant: "transparent",
|
|
1325
1325
|
size: "small",
|
|
1326
1326
|
onClick: (e) => {
|
|
1327
1327
|
e.stopPropagation();
|
|
1328
|
-
navigate(`/orders/${
|
|
1328
|
+
navigate(`/orders/${t.order_id}`);
|
|
1329
1329
|
},
|
|
1330
1330
|
children: "Order"
|
|
1331
1331
|
}
|
|
1332
1332
|
) : null
|
|
1333
|
-
] })
|
|
1333
|
+
] })
|
|
1334
1334
|
]
|
|
1335
1335
|
},
|
|
1336
|
-
|
|
1336
|
+
t.payment_session_id
|
|
1337
1337
|
)) })
|
|
1338
1338
|
] }) }),
|
|
1339
1339
|
hasMore ? /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(
|
|
@@ -1341,15 +1341,15 @@ const RefundsPage = () => {
|
|
|
1341
1341
|
{
|
|
1342
1342
|
variant: "secondary",
|
|
1343
1343
|
isLoading: isFetchingMore,
|
|
1344
|
-
onClick: () =>
|
|
1344
|
+
onClick: () => loadTransactions(offset, false),
|
|
1345
1345
|
children: "Load more"
|
|
1346
1346
|
}
|
|
1347
1347
|
) }) : null
|
|
1348
1348
|
] }) });
|
|
1349
1349
|
};
|
|
1350
1350
|
const config$6 = defineRouteConfig({
|
|
1351
|
-
label: "
|
|
1352
|
-
icon:
|
|
1351
|
+
label: "Payments",
|
|
1352
|
+
icon: CreditCard
|
|
1353
1353
|
});
|
|
1354
1354
|
const useDebounce$1 = (value, delay) => {
|
|
1355
1355
|
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
@@ -1725,214 +1725,95 @@ const SwapsPage = () => {
|
|
|
1725
1725
|
] })
|
|
1726
1726
|
] }),
|
|
1727
1727
|
error ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
1728
|
-
/* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
1729
|
-
/* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx(
|
|
1730
|
-
Button,
|
|
1731
|
-
{
|
|
1732
|
-
variant: "secondary",
|
|
1733
|
-
onClick: () => loadSwaps(0, true),
|
|
1734
|
-
children: "Try again"
|
|
1735
|
-
}
|
|
1736
|
-
) })
|
|
1737
|
-
] }) : null,
|
|
1738
|
-
isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading swaps..." }) }) : items.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
|
|
1739
|
-
/* @__PURE__ */ jsx(Heading, { level: "h3", className: "text-xl", children: "No exchanges yet" }),
|
|
1740
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Exchange requests created by customers will appear here." })
|
|
1741
|
-
] }) : /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
|
|
1742
|
-
/* @__PURE__ */ jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
1743
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Exchange ID" }),
|
|
1744
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
|
|
1745
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
|
|
1746
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Difference Due" }),
|
|
1747
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
1748
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
1749
|
-
] }) }),
|
|
1750
|
-
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((swap) => /* @__PURE__ */ jsxs(
|
|
1751
|
-
"tr",
|
|
1752
|
-
{
|
|
1753
|
-
className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
|
|
1754
|
-
onClick: () => navigate(`/swaps/${swap.id}`),
|
|
1755
|
-
children: [
|
|
1756
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-0.5", children: /* @__PURE__ */ jsx("span", { children: swap.id }) }) }),
|
|
1757
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: swap.order_id }),
|
|
1758
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsx(
|
|
1759
|
-
Badge,
|
|
1760
|
-
{
|
|
1761
|
-
size: "2xsmall",
|
|
1762
|
-
className: `uppercase ${getStatusBadgeClass$4(swap.status)}`,
|
|
1763
|
-
children: swap.status.replace(/_/g, " ")
|
|
1764
|
-
}
|
|
1765
|
-
) }),
|
|
1766
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
|
|
1767
|
-
const amount = swap.difference_due;
|
|
1768
|
-
if (amount == null || amount === void 0) {
|
|
1769
|
-
return "—";
|
|
1770
|
-
}
|
|
1771
|
-
const displayAmount = Number(amount) / 100;
|
|
1772
|
-
const currency = swap.currency_code || "$";
|
|
1773
|
-
const sign = displayAmount >= 0 ? "+" : "";
|
|
1774
|
-
return `${sign}${currency}${displayAmount.toFixed(2)}`;
|
|
1775
|
-
})() }),
|
|
1776
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(swap.created_at).toLocaleDateString("en-US", {
|
|
1777
|
-
year: "numeric",
|
|
1778
|
-
month: "short",
|
|
1779
|
-
day: "numeric",
|
|
1780
|
-
hour: "numeric",
|
|
1781
|
-
minute: "2-digit",
|
|
1782
|
-
hour12: true
|
|
1783
|
-
}) }),
|
|
1784
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsx(
|
|
1785
|
-
Button,
|
|
1786
|
-
{
|
|
1787
|
-
variant: "transparent",
|
|
1788
|
-
size: "small",
|
|
1789
|
-
onClick: (e) => {
|
|
1790
|
-
e.stopPropagation();
|
|
1791
|
-
navigate(`/app/orders/${swap.order_id}`);
|
|
1792
|
-
},
|
|
1793
|
-
children: "Go to order"
|
|
1794
|
-
}
|
|
1795
|
-
) })
|
|
1796
|
-
]
|
|
1797
|
-
},
|
|
1798
|
-
swap.id
|
|
1799
|
-
)) })
|
|
1800
|
-
] }) }),
|
|
1801
|
-
hasMore ? /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(
|
|
1802
|
-
Button,
|
|
1803
|
-
{
|
|
1804
|
-
variant: "secondary",
|
|
1805
|
-
isLoading: isFetchingMore,
|
|
1806
|
-
onClick: () => loadSwaps(offset, false),
|
|
1807
|
-
children: "Load more"
|
|
1808
|
-
}
|
|
1809
|
-
) }) : null
|
|
1810
|
-
] }) });
|
|
1811
|
-
};
|
|
1812
|
-
const config$4 = defineRouteConfig({
|
|
1813
|
-
label: "Exchanges",
|
|
1814
|
-
icon: ArrowPath
|
|
1815
|
-
});
|
|
1816
|
-
const getStatusBadgeClass$3 = (status) => {
|
|
1817
|
-
const s2 = status.toLowerCase();
|
|
1818
|
-
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1819
|
-
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
1820
|
-
if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
1821
|
-
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
1822
|
-
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
1823
|
-
};
|
|
1824
|
-
const PaymentDetailPage = () => {
|
|
1825
|
-
var _a;
|
|
1826
|
-
const navigate = useNavigate();
|
|
1827
|
-
const params = useParams();
|
|
1828
|
-
const id = (_a = params == null ? void 0 : params.id) == null ? void 0 : _a.trim();
|
|
1829
|
-
const [detail, setDetail] = useState(null);
|
|
1830
|
-
const [loading, setLoading] = useState(!!id);
|
|
1831
|
-
const [error, setError] = useState(null);
|
|
1832
|
-
useEffect(() => {
|
|
1833
|
-
if (!id) {
|
|
1834
|
-
setLoading(false);
|
|
1835
|
-
return;
|
|
1836
|
-
}
|
|
1837
|
-
let cancelled = false;
|
|
1838
|
-
setLoading(true);
|
|
1839
|
-
setError(null);
|
|
1840
|
-
fetch(`/admin/payment-transactions/${id}`, { credentials: "include" }).then((res) => {
|
|
1841
|
-
if (!res.ok) throw new Error(res.statusText || "Failed to load");
|
|
1842
|
-
return res.json();
|
|
1843
|
-
}).then((data) => {
|
|
1844
|
-
if (!cancelled) setDetail(data);
|
|
1845
|
-
}).catch((e) => {
|
|
1846
|
-
if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
|
|
1847
|
-
}).finally(() => {
|
|
1848
|
-
if (!cancelled) setLoading(false);
|
|
1849
|
-
});
|
|
1850
|
-
return () => {
|
|
1851
|
-
cancelled = true;
|
|
1852
|
-
};
|
|
1853
|
-
}, [id]);
|
|
1854
|
-
const displayStatus = detail ? (detail.payment_id != null && detail.payment_status != null && detail.payment_status !== "" ? detail.payment_status : detail.session_status ?? "") || "—" : "";
|
|
1855
|
-
const sessionStatusRaw = (detail == null ? void 0 : detail.session_status) ?? "—";
|
|
1856
|
-
const paymentStatusRaw = (detail == null ? void 0 : detail.payment_id) != null ? (detail == null ? void 0 : detail.payment_status) ?? "—" : "—";
|
|
1857
|
-
const displayAmount = detail ? `${(detail.currency_code ?? "USD").toUpperCase()} ${Number(detail.amount)}` : "";
|
|
1858
|
-
return /* @__PURE__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxs(Container, { className: "mx-auto flex w-full max-w-4xl flex-col gap-6 p-6", children: [
|
|
1859
|
-
/* @__PURE__ */ jsx("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1860
|
-
/* @__PURE__ */ jsx(Button, { variant: "transparent", size: "small", onClick: () => navigate("/payments"), children: "← Payments" }),
|
|
1861
|
-
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "Payment session" }),
|
|
1862
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: id ?? "—" })
|
|
1863
|
-
] }) }),
|
|
1864
|
-
error ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
1865
|
-
/* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
1866
|
-
/* @__PURE__ */ jsx(Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/payments"), children: "Back to list" })
|
|
1867
|
-
] }) : loading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading…" }) }) : detail ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
1868
|
-
/* @__PURE__ */ jsx("div", { className: "rounded-xl border border-ui-border-base p-6 flex flex-col gap-4", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
1869
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1870
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Order ID" }),
|
|
1871
|
-
/* @__PURE__ */ jsx("div", { className: "mt-1", children: detail.order_id ? /* @__PURE__ */ jsx(
|
|
1872
|
-
Button,
|
|
1873
|
-
{
|
|
1874
|
-
variant: "transparent",
|
|
1875
|
-
size: "small",
|
|
1876
|
-
onClick: () => navigate(`/orders/${detail.order_id}`),
|
|
1877
|
-
children: detail.order_id
|
|
1878
|
-
}
|
|
1879
|
-
) : /* @__PURE__ */ jsx(Text, { children: "—" }) })
|
|
1880
|
-
] }),
|
|
1881
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1882
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
|
|
1883
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: displayAmount })
|
|
1884
|
-
] }),
|
|
1885
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1886
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
|
|
1887
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.provider_id })
|
|
1888
|
-
] }),
|
|
1889
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1890
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
|
|
1891
|
-
/* @__PURE__ */ jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsx(
|
|
1892
|
-
Badge,
|
|
1893
|
-
{
|
|
1894
|
-
size: "2xsmall",
|
|
1895
|
-
className: `uppercase ${getStatusBadgeClass$3(displayStatus)}`,
|
|
1896
|
-
children: displayStatus !== "—" ? displayStatus.replace(/_/g, " ") : "—"
|
|
1897
|
-
}
|
|
1898
|
-
) })
|
|
1899
|
-
] }),
|
|
1900
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1901
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Session status (DB)" }),
|
|
1902
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: sessionStatusRaw })
|
|
1903
|
-
] }),
|
|
1904
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1905
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Payment status (DB)" }),
|
|
1906
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: paymentStatusRaw })
|
|
1907
|
-
] }),
|
|
1908
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1909
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Finalized" }),
|
|
1910
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.payment_id != null ? "Yes" : "No" })
|
|
1911
|
-
] }),
|
|
1912
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1913
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Created" }),
|
|
1914
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: new Date(detail.created_at).toLocaleDateString("en-US", {
|
|
1915
|
-
year: "numeric",
|
|
1916
|
-
month: "short",
|
|
1917
|
-
day: "numeric",
|
|
1918
|
-
hour: "numeric",
|
|
1919
|
-
minute: "2-digit",
|
|
1920
|
-
hour12: true
|
|
1921
|
-
}) })
|
|
1922
|
-
] })
|
|
1728
|
+
/* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
1729
|
+
/* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx(
|
|
1730
|
+
Button,
|
|
1731
|
+
{
|
|
1732
|
+
variant: "secondary",
|
|
1733
|
+
onClick: () => loadSwaps(0, true),
|
|
1734
|
+
children: "Try again"
|
|
1735
|
+
}
|
|
1736
|
+
) })
|
|
1737
|
+
] }) : null,
|
|
1738
|
+
isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading swaps..." }) }) : items.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
|
|
1739
|
+
/* @__PURE__ */ jsx(Heading, { level: "h3", className: "text-xl", children: "No exchanges yet" }),
|
|
1740
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Exchange requests created by customers will appear here." })
|
|
1741
|
+
] }) : /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
|
|
1742
|
+
/* @__PURE__ */ jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
1743
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Exchange ID" }),
|
|
1744
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
|
|
1745
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
|
|
1746
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Difference Due" }),
|
|
1747
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
1748
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
1923
1749
|
] }) }),
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1750
|
+
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((swap) => /* @__PURE__ */ jsxs(
|
|
1751
|
+
"tr",
|
|
1752
|
+
{
|
|
1753
|
+
className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
|
|
1754
|
+
onClick: () => navigate(`/swaps/${swap.id}`),
|
|
1755
|
+
children: [
|
|
1756
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-0.5", children: /* @__PURE__ */ jsx("span", { children: swap.id }) }) }),
|
|
1757
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: swap.order_id }),
|
|
1758
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsx(
|
|
1759
|
+
Badge,
|
|
1760
|
+
{
|
|
1761
|
+
size: "2xsmall",
|
|
1762
|
+
className: `uppercase ${getStatusBadgeClass$4(swap.status)}`,
|
|
1763
|
+
children: swap.status.replace(/_/g, " ")
|
|
1764
|
+
}
|
|
1765
|
+
) }),
|
|
1766
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
|
|
1767
|
+
const amount = swap.difference_due;
|
|
1768
|
+
if (amount == null || amount === void 0) {
|
|
1769
|
+
return "—";
|
|
1770
|
+
}
|
|
1771
|
+
const displayAmount = Number(amount) / 100;
|
|
1772
|
+
const currency = swap.currency_code || "$";
|
|
1773
|
+
const sign = displayAmount >= 0 ? "+" : "";
|
|
1774
|
+
return `${sign}${currency}${displayAmount.toFixed(2)}`;
|
|
1775
|
+
})() }),
|
|
1776
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(swap.created_at).toLocaleDateString("en-US", {
|
|
1777
|
+
year: "numeric",
|
|
1778
|
+
month: "short",
|
|
1779
|
+
day: "numeric",
|
|
1780
|
+
hour: "numeric",
|
|
1781
|
+
minute: "2-digit",
|
|
1782
|
+
hour12: true
|
|
1783
|
+
}) }),
|
|
1784
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsx(
|
|
1785
|
+
Button,
|
|
1786
|
+
{
|
|
1787
|
+
variant: "transparent",
|
|
1788
|
+
size: "small",
|
|
1789
|
+
onClick: (e) => {
|
|
1790
|
+
e.stopPropagation();
|
|
1791
|
+
navigate(`/app/orders/${swap.order_id}`);
|
|
1792
|
+
},
|
|
1793
|
+
children: "Go to order"
|
|
1794
|
+
}
|
|
1795
|
+
) })
|
|
1796
|
+
]
|
|
1797
|
+
},
|
|
1798
|
+
swap.id
|
|
1799
|
+
)) })
|
|
1800
|
+
] }) }),
|
|
1801
|
+
hasMore ? /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(
|
|
1802
|
+
Button,
|
|
1803
|
+
{
|
|
1804
|
+
variant: "secondary",
|
|
1805
|
+
isLoading: isFetchingMore,
|
|
1806
|
+
onClick: () => loadSwaps(offset, false),
|
|
1807
|
+
children: "Load more"
|
|
1808
|
+
}
|
|
1809
|
+
) }) : null
|
|
1929
1810
|
] }) });
|
|
1930
1811
|
};
|
|
1931
|
-
const config$
|
|
1932
|
-
label: "
|
|
1933
|
-
icon:
|
|
1812
|
+
const config$4 = defineRouteConfig({
|
|
1813
|
+
label: "Exchanges",
|
|
1814
|
+
icon: ArrowPath
|
|
1934
1815
|
});
|
|
1935
|
-
const getStatusBadgeClass$
|
|
1816
|
+
const getStatusBadgeClass$3 = (status) => {
|
|
1936
1817
|
const s2 = status.toLowerCase();
|
|
1937
1818
|
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1938
1819
|
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
@@ -2043,7 +1924,7 @@ const RefundDetailPage = () => {
|
|
|
2043
1924
|
Badge,
|
|
2044
1925
|
{
|
|
2045
1926
|
size: "2xsmall",
|
|
2046
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
1927
|
+
className: `uppercase ${getStatusBadgeClass$3(paymentStatus)}`,
|
|
2047
1928
|
children: paymentStatus !== "—" ? paymentStatus.replace(/_/g, " ") : "—"
|
|
2048
1929
|
}
|
|
2049
1930
|
) })
|
|
@@ -2120,10 +2001,129 @@ const RefundDetailPage = () => {
|
|
|
2120
2001
|
] }) : null
|
|
2121
2002
|
] }) });
|
|
2122
2003
|
};
|
|
2123
|
-
const config$
|
|
2004
|
+
const config$3 = defineRouteConfig({
|
|
2124
2005
|
label: "Refund details",
|
|
2125
2006
|
icon: Receipt
|
|
2126
2007
|
});
|
|
2008
|
+
const getStatusBadgeClass$2 = (status) => {
|
|
2009
|
+
const s2 = status.toLowerCase();
|
|
2010
|
+
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
2011
|
+
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
2012
|
+
if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
2013
|
+
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
2014
|
+
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
2015
|
+
};
|
|
2016
|
+
const PaymentDetailPage = () => {
|
|
2017
|
+
var _a;
|
|
2018
|
+
const navigate = useNavigate();
|
|
2019
|
+
const params = useParams();
|
|
2020
|
+
const id = (_a = params == null ? void 0 : params.id) == null ? void 0 : _a.trim();
|
|
2021
|
+
const [detail, setDetail] = useState(null);
|
|
2022
|
+
const [loading, setLoading] = useState(!!id);
|
|
2023
|
+
const [error, setError] = useState(null);
|
|
2024
|
+
useEffect(() => {
|
|
2025
|
+
if (!id) {
|
|
2026
|
+
setLoading(false);
|
|
2027
|
+
return;
|
|
2028
|
+
}
|
|
2029
|
+
let cancelled = false;
|
|
2030
|
+
setLoading(true);
|
|
2031
|
+
setError(null);
|
|
2032
|
+
fetch(`/admin/payment-transactions/${id}`, { credentials: "include" }).then((res) => {
|
|
2033
|
+
if (!res.ok) throw new Error(res.statusText || "Failed to load");
|
|
2034
|
+
return res.json();
|
|
2035
|
+
}).then((data) => {
|
|
2036
|
+
if (!cancelled) setDetail(data);
|
|
2037
|
+
}).catch((e) => {
|
|
2038
|
+
if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
|
|
2039
|
+
}).finally(() => {
|
|
2040
|
+
if (!cancelled) setLoading(false);
|
|
2041
|
+
});
|
|
2042
|
+
return () => {
|
|
2043
|
+
cancelled = true;
|
|
2044
|
+
};
|
|
2045
|
+
}, [id]);
|
|
2046
|
+
const displayStatus = detail ? (detail.payment_id != null && detail.payment_status != null && detail.payment_status !== "" ? detail.payment_status : detail.session_status ?? "") || "—" : "";
|
|
2047
|
+
const sessionStatusRaw = (detail == null ? void 0 : detail.session_status) ?? "—";
|
|
2048
|
+
const paymentStatusRaw = (detail == null ? void 0 : detail.payment_id) != null ? (detail == null ? void 0 : detail.payment_status) ?? "—" : "—";
|
|
2049
|
+
const displayAmount = detail ? `${(detail.currency_code ?? "USD").toUpperCase()} ${Number(detail.amount)}` : "";
|
|
2050
|
+
return /* @__PURE__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxs(Container, { className: "mx-auto flex w-full max-w-4xl flex-col gap-6 p-6", children: [
|
|
2051
|
+
/* @__PURE__ */ jsx("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
2052
|
+
/* @__PURE__ */ jsx(Button, { variant: "transparent", size: "small", onClick: () => navigate("/payments"), children: "← Payments" }),
|
|
2053
|
+
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "Payment session" }),
|
|
2054
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: id ?? "—" })
|
|
2055
|
+
] }) }),
|
|
2056
|
+
error ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
2057
|
+
/* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
2058
|
+
/* @__PURE__ */ jsx(Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/payments"), children: "Back to list" })
|
|
2059
|
+
] }) : loading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading…" }) }) : detail ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
2060
|
+
/* @__PURE__ */ jsx("div", { className: "rounded-xl border border-ui-border-base p-6 flex flex-col gap-4", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
2061
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2062
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Order ID" }),
|
|
2063
|
+
/* @__PURE__ */ jsx("div", { className: "mt-1", children: detail.order_id ? /* @__PURE__ */ jsx(
|
|
2064
|
+
Button,
|
|
2065
|
+
{
|
|
2066
|
+
variant: "transparent",
|
|
2067
|
+
size: "small",
|
|
2068
|
+
onClick: () => navigate(`/orders/${detail.order_id}`),
|
|
2069
|
+
children: detail.order_id
|
|
2070
|
+
}
|
|
2071
|
+
) : /* @__PURE__ */ jsx(Text, { children: "—" }) })
|
|
2072
|
+
] }),
|
|
2073
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2074
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
|
|
2075
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: displayAmount })
|
|
2076
|
+
] }),
|
|
2077
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2078
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
|
|
2079
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.provider_id })
|
|
2080
|
+
] }),
|
|
2081
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2082
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
|
|
2083
|
+
/* @__PURE__ */ jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsx(
|
|
2084
|
+
Badge,
|
|
2085
|
+
{
|
|
2086
|
+
size: "2xsmall",
|
|
2087
|
+
className: `uppercase ${getStatusBadgeClass$2(displayStatus)}`,
|
|
2088
|
+
children: displayStatus !== "—" ? displayStatus.replace(/_/g, " ") : "—"
|
|
2089
|
+
}
|
|
2090
|
+
) })
|
|
2091
|
+
] }),
|
|
2092
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2093
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Session status (DB)" }),
|
|
2094
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: sessionStatusRaw })
|
|
2095
|
+
] }),
|
|
2096
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2097
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Payment status (DB)" }),
|
|
2098
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: paymentStatusRaw })
|
|
2099
|
+
] }),
|
|
2100
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2101
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Finalized" }),
|
|
2102
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.payment_id != null ? "Yes" : "No" })
|
|
2103
|
+
] }),
|
|
2104
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2105
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Created" }),
|
|
2106
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: new Date(detail.created_at).toLocaleDateString("en-US", {
|
|
2107
|
+
year: "numeric",
|
|
2108
|
+
month: "short",
|
|
2109
|
+
day: "numeric",
|
|
2110
|
+
hour: "numeric",
|
|
2111
|
+
minute: "2-digit",
|
|
2112
|
+
hour12: true
|
|
2113
|
+
}) })
|
|
2114
|
+
] })
|
|
2115
|
+
] }) }),
|
|
2116
|
+
Object.keys(detail.data ?? {}).length > 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2117
|
+
/* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg mb-4", children: "Provider data" }),
|
|
2118
|
+
/* @__PURE__ */ jsx("pre", { className: "text-xs bg-ui-bg-subtle p-4 rounded-lg overflow-auto max-h-96", children: JSON.stringify(detail.data, null, 2) })
|
|
2119
|
+
] }) : /* @__PURE__ */ jsx("div", { className: "rounded-xl border border-ui-border-base p-6", children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "No provider data for this session." }) })
|
|
2120
|
+
] }) : null
|
|
2121
|
+
] }) });
|
|
2122
|
+
};
|
|
2123
|
+
const config$2 = defineRouteConfig({
|
|
2124
|
+
label: "Payment details",
|
|
2125
|
+
icon: CreditCard
|
|
2126
|
+
});
|
|
2127
2127
|
const getStatusBadgeClass$1 = (status) => {
|
|
2128
2128
|
const statusLower = status.toLowerCase();
|
|
2129
2129
|
if (statusLower === "requested") {
|
|
@@ -2694,14 +2694,14 @@ const widgetModule = { widgets: [
|
|
|
2694
2694
|
] };
|
|
2695
2695
|
const routeModule = {
|
|
2696
2696
|
routes: [
|
|
2697
|
-
{
|
|
2698
|
-
Component: PaymentsPage,
|
|
2699
|
-
path: "/payments"
|
|
2700
|
-
},
|
|
2701
2697
|
{
|
|
2702
2698
|
Component: RefundsPage,
|
|
2703
2699
|
path: "/refunds"
|
|
2704
2700
|
},
|
|
2701
|
+
{
|
|
2702
|
+
Component: PaymentsPage,
|
|
2703
|
+
path: "/payments"
|
|
2704
|
+
},
|
|
2705
2705
|
{
|
|
2706
2706
|
Component: ReturnsPage,
|
|
2707
2707
|
path: "/returns"
|
|
@@ -2710,14 +2710,14 @@ const routeModule = {
|
|
|
2710
2710
|
Component: SwapsPage,
|
|
2711
2711
|
path: "/swaps"
|
|
2712
2712
|
},
|
|
2713
|
-
{
|
|
2714
|
-
Component: PaymentDetailPage,
|
|
2715
|
-
path: "/payments/:id"
|
|
2716
|
-
},
|
|
2717
2713
|
{
|
|
2718
2714
|
Component: RefundDetailPage,
|
|
2719
2715
|
path: "/refunds/:id"
|
|
2720
2716
|
},
|
|
2717
|
+
{
|
|
2718
|
+
Component: PaymentDetailPage,
|
|
2719
|
+
path: "/payments/:id"
|
|
2720
|
+
},
|
|
2721
2721
|
{
|
|
2722
2722
|
Component: ReturnDetailPage,
|
|
2723
2723
|
path: "/returns/:id"
|
|
@@ -2733,6 +2733,12 @@ const menuItemModule = {
|
|
|
2733
2733
|
{
|
|
2734
2734
|
label: config$6.label,
|
|
2735
2735
|
icon: config$6.icon,
|
|
2736
|
+
path: "/payments",
|
|
2737
|
+
nested: void 0
|
|
2738
|
+
},
|
|
2739
|
+
{
|
|
2740
|
+
label: config$7.label,
|
|
2741
|
+
icon: config$7.icon,
|
|
2736
2742
|
path: "/refunds",
|
|
2737
2743
|
nested: void 0
|
|
2738
2744
|
},
|
|
@@ -2749,21 +2755,15 @@ const menuItemModule = {
|
|
|
2749
2755
|
nested: void 0
|
|
2750
2756
|
},
|
|
2751
2757
|
{
|
|
2752
|
-
label: config$
|
|
2753
|
-
icon: config$
|
|
2754
|
-
path: "/
|
|
2758
|
+
label: config$3.label,
|
|
2759
|
+
icon: config$3.icon,
|
|
2760
|
+
path: "/refunds/:id",
|
|
2755
2761
|
nested: void 0
|
|
2756
2762
|
},
|
|
2757
2763
|
{
|
|
2758
2764
|
label: config$2.label,
|
|
2759
2765
|
icon: config$2.icon,
|
|
2760
|
-
path: "/
|
|
2761
|
-
nested: void 0
|
|
2762
|
-
},
|
|
2763
|
-
{
|
|
2764
|
-
label: config$1.label,
|
|
2765
|
-
icon: config$1.icon,
|
|
2766
|
-
path: "/returns/:id",
|
|
2766
|
+
path: "/payments/:id",
|
|
2767
2767
|
nested: void 0
|
|
2768
2768
|
},
|
|
2769
2769
|
{
|
|
@@ -2773,9 +2773,9 @@ const menuItemModule = {
|
|
|
2773
2773
|
nested: void 0
|
|
2774
2774
|
},
|
|
2775
2775
|
{
|
|
2776
|
-
label: config$
|
|
2777
|
-
icon: config$
|
|
2778
|
-
path: "/
|
|
2776
|
+
label: config$1.label,
|
|
2777
|
+
icon: config$1.icon,
|
|
2778
|
+
path: "/returns/:id",
|
|
2779
2779
|
nested: void 0
|
|
2780
2780
|
}
|
|
2781
2781
|
]
|