order-management 0.0.91 → 0.0.92
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 +525 -492
- package/.medusa/server/src/admin/index.mjs +526 -493
- package/.medusa/server/src/api/admin/orders/[order_id]/refund-context/route.js +71 -25
- package/.medusa/server/src/api/admin/refund-payment-mapping/[return_id]/mark-refunded/route.js +38 -1
- package/.medusa/server/src/api/admin/return/[id]/route.js +11 -1
- package/.medusa/server/src/api/middlewares/block-refund-until-return-received.js +97 -0
- package/.medusa/server/src/api/middlewares.js +7 -1
- package/.medusa/server/src/helpers/detect-cod.js +81 -13
- package/.medusa/server/src/helpers/index.js +2 -1
- package/.medusa/server/src/helpers/refund-calculation.js +3 -2
- package/.medusa/server/src/helpers/refund-receive-guard.js +48 -0
- package/.medusa/server/src/modules/payment-detail/service.js +9 -1
- package/README.md +31 -8
- package/package.json +1 -1
|
@@ -533,7 +533,7 @@ function getOrderIdFromPath() {
|
|
|
533
533
|
return m ? m[1] : void 0;
|
|
534
534
|
}
|
|
535
535
|
const OrderRefundContextWidget = (props) => {
|
|
536
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
536
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
537
537
|
const orderId = ((_a = props.order) == null ? void 0 : _a.id) ?? ((_c = (_b = props.data) == null ? void 0 : _b.order) == null ? void 0 : _c.id) ?? getOrderIdFromPath();
|
|
538
538
|
const [context, setContext] = react.useState(null);
|
|
539
539
|
const [loading, setLoading] = react.useState(!!orderId);
|
|
@@ -572,7 +572,9 @@ const OrderRefundContextWidget = (props) => {
|
|
|
572
572
|
};
|
|
573
573
|
}, [orderId]);
|
|
574
574
|
const handleMarkRefunded = async () => {
|
|
575
|
-
if (!(context == null ? void 0 : context.return_id) || !(context == null ? void 0 : context.refund_mapping) || context.refund_mapping.is_refunded)
|
|
575
|
+
if (!(context == null ? void 0 : context.return_id) || !(context == null ? void 0 : context.refund_mapping) || context.refund_mapping.is_refunded || !context.can_process_refund) {
|
|
576
|
+
return;
|
|
577
|
+
}
|
|
576
578
|
setMarking(true);
|
|
577
579
|
setMarkError(null);
|
|
578
580
|
try {
|
|
@@ -591,6 +593,7 @@ const OrderRefundContextWidget = (props) => {
|
|
|
591
593
|
var _a2;
|
|
592
594
|
return prev && prev.refund_mapping ? {
|
|
593
595
|
...prev,
|
|
596
|
+
can_process_refund: false,
|
|
594
597
|
refund_mapping: {
|
|
595
598
|
...prev.refund_mapping,
|
|
596
599
|
is_refunded: ((_a2 = data.refund_payment_mapping) == null ? void 0 : _a2.is_refunded) ?? true
|
|
@@ -687,29 +690,47 @@ const OrderRefundContextWidget = (props) => {
|
|
|
687
690
|
}
|
|
688
691
|
const hasReturn = !!(context == null ? void 0 : context.return_id);
|
|
689
692
|
const hasMapping = !!(context == null ? void 0 : context.refund_mapping);
|
|
690
|
-
const canMarkRefunded =
|
|
693
|
+
const canMarkRefunded = Boolean(context == null ? void 0 : context.can_process_refund);
|
|
694
|
+
const returnStatus = (context == null ? void 0 : context.return_status) ?? null;
|
|
695
|
+
const showReceiveFirstHint = hasReturn && !((_d = context == null ? void 0 : context.refund_mapping) == null ? void 0 : _d.is_refunded) && returnStatus !== "received" && returnStatus !== "canceled";
|
|
691
696
|
const paymentDetail = context == null ? void 0 : context.payment_detail;
|
|
697
|
+
const orderPayment = context == null ? void 0 : context.order_payment;
|
|
692
698
|
return /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mt-6 divide-y p-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4 py-4", children: [
|
|
693
699
|
/* @__PURE__ */ jsxRuntime.jsxs(ui.Heading, { level: "h2", className: "flex items-center gap-2", children: [
|
|
694
700
|
/* @__PURE__ */ jsxRuntime.jsx(icons.CashSolid, { className: "text-ui-fg-subtle" }),
|
|
695
701
|
"Refund payment"
|
|
696
702
|
] }),
|
|
697
703
|
!hasReturn && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No return for this order." }),
|
|
704
|
+
showReceiveFirstHint && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Receive returned items before processing a refund. Do not refund from Payments until items are received." }),
|
|
698
705
|
hasMapping && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-4", children: [
|
|
699
706
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
700
707
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "text-ui-fg-subtle", children: "Return" }),
|
|
701
708
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", children: context.return_id }),
|
|
702
|
-
((
|
|
709
|
+
((_e = context.refund_mapping) == null ? void 0 : _e.is_refunded) ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "green", children: "Refunded" }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "orange", children: "Not refunded" })
|
|
703
710
|
] }),
|
|
704
711
|
context.refund ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 border-t border-ui-border-base pt-3", children: /* @__PURE__ */ jsxRuntime.jsx(RefundCalculationBlock, { refund: context.refund }) }) : null,
|
|
712
|
+
orderPayment && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 space-y-2 border-t border-ui-border-base pt-3", children: [
|
|
713
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "text-ui-fg-subtle", children: "Order payment method" }),
|
|
714
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
715
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { children: orderPayment.label }),
|
|
716
|
+
orderPayment.is_cod ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "orange", children: "COD" }) : null
|
|
717
|
+
] }),
|
|
718
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: orderPayment.provider_id })
|
|
719
|
+
] }),
|
|
705
720
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 space-y-2 border-t border-ui-border-base pt-3", children: [
|
|
706
721
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
707
722
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "text-ui-fg-subtle", children: "Payment method (refund destination)" }),
|
|
708
|
-
((
|
|
723
|
+
((_f = context.refund_mapping) == null ? void 0 : _f.payment_id) ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "green", children: "Customer specified" }) : paymentDetail ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "orange", children: "Customer default" }) : orderPayment && !orderPayment.is_cod ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "blue", children: "Original payment method" }) : null
|
|
709
724
|
] }),
|
|
710
|
-
((
|
|
711
|
-
!((
|
|
712
|
-
!((
|
|
725
|
+
((_g = context.refund_mapping) == null ? void 0 : _g.payment_id) && !paymentDetail && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-orange-200 bg-orange-50 px-3 py-2", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: "The customer specified a payment method for this return, but that payment method has since been removed from their account. Ask the customer to update their refund payment method." }) }),
|
|
726
|
+
!((_h = context.refund_mapping) == null ? void 0 : _h.payment_id) && (paymentDetail == null ? void 0 : paymentDetail.source) === "default" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-ui-border-base bg-ui-bg-subtle px-3 py-2", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: "The customer did not specify a payment method for this return. Showing their default payment method." }) }),
|
|
727
|
+
!((_i = context.refund_mapping) == null ? void 0 : _i.payment_id) && !paymentDetail && orderPayment && !orderPayment.is_cod && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-ui-border-base bg-ui-bg-subtle px-3 py-2", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: [
|
|
728
|
+
"Refund will go to the original payment method (",
|
|
729
|
+
orderPayment.label,
|
|
730
|
+
")."
|
|
731
|
+
] }) }),
|
|
732
|
+
!((_j = context.refund_mapping) == null ? void 0 : _j.payment_id) && !paymentDetail && (context.is_cod || (orderPayment == null ? void 0 : orderPayment.is_cod)) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-ui-border-base bg-ui-bg-subtle px-3 py-2", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: "This order was paid with Cash on Delivery. No stored bank/UPI refund destination." }) }),
|
|
733
|
+
!((_k = context.refund_mapping) == null ? void 0 : _k.payment_id) && !paymentDetail && !orderPayment && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-ui-border-base bg-ui-bg-subtle px-3 py-2", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: "No payment method found for this customer." }) }),
|
|
713
734
|
paymentDetail && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
714
735
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
|
|
715
736
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { children: paymentDetail.type.toUpperCase() }),
|
|
@@ -863,7 +884,7 @@ const OrderRefundContextWidget = (props) => {
|
|
|
863
884
|
] }),
|
|
864
885
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
865
886
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", weight: "plus", className: "text-ui-fg-muted", children: "Images" }),
|
|
866
|
-
((
|
|
887
|
+
((_l = context.refund_mapping.images) == null ? void 0 : _l.length) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 flex flex-wrap gap-2", children: context.refund_mapping.images.map((url, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
867
888
|
"a",
|
|
868
889
|
{
|
|
869
890
|
href: url,
|
|
@@ -892,10 +913,18 @@ const OrderRefundContextWidget = (props) => {
|
|
|
892
913
|
}
|
|
893
914
|
),
|
|
894
915
|
markError && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-error", children: markError })
|
|
895
|
-
] })
|
|
916
|
+
] }),
|
|
917
|
+
hasMapping && !canMarkRefunded && !((_m = context.refund_mapping) == null ? void 0 : _m.is_refunded) && showReceiveFirstHint && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-4 text-ui-fg-muted", children: "Mark refunded is available after the return is received." })
|
|
896
918
|
] }),
|
|
897
919
|
hasReturn && !hasMapping && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-4", children: [
|
|
898
920
|
(context == null ? void 0 : context.refund) ? /* @__PURE__ */ jsxRuntime.jsx(RefundCalculationBlock, { refund: context.refund }) : null,
|
|
921
|
+
orderPayment && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-3 space-y-1", children: [
|
|
922
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "text-ui-fg-subtle", children: "Order payment method" }),
|
|
923
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
924
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { children: orderPayment.label }),
|
|
925
|
+
orderPayment.is_cod ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "orange", children: "COD" }) : null
|
|
926
|
+
] })
|
|
927
|
+
] }),
|
|
899
928
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No refund payment mapping for this return. Ensure the refund_payment_mapping module is registered and a mapping was created when the return was created." })
|
|
900
929
|
] })
|
|
901
930
|
] }) });
|
|
@@ -1112,6 +1141,248 @@ const useDebounce$2 = (value, delay) => {
|
|
|
1112
1141
|
return debouncedValue;
|
|
1113
1142
|
};
|
|
1114
1143
|
const getStatusBadgeClass$6 = (status) => {
|
|
1144
|
+
const statusLower = status.toLowerCase();
|
|
1145
|
+
if (statusLower === "requested") {
|
|
1146
|
+
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
1147
|
+
}
|
|
1148
|
+
if (statusLower === "received") {
|
|
1149
|
+
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
1150
|
+
}
|
|
1151
|
+
if (statusLower === "requires_action") {
|
|
1152
|
+
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
1153
|
+
}
|
|
1154
|
+
if (statusLower === "completed") {
|
|
1155
|
+
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1156
|
+
}
|
|
1157
|
+
if (statusLower === "canceled") {
|
|
1158
|
+
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
1159
|
+
}
|
|
1160
|
+
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
1161
|
+
};
|
|
1162
|
+
const ReturnsPage = () => {
|
|
1163
|
+
const navigate = reactRouterDom.useNavigate();
|
|
1164
|
+
const [items, setItems] = react.useState([]);
|
|
1165
|
+
const [statusFilter, setStatusFilter] = react.useState("all");
|
|
1166
|
+
const [createdByFilter, setCreatedByFilter] = react.useState("all");
|
|
1167
|
+
const [searchQuery, setSearchQuery] = react.useState("");
|
|
1168
|
+
const debouncedSearchQuery = useDebounce$2(searchQuery, 300);
|
|
1169
|
+
const [isLoading, setIsLoading] = react.useState(true);
|
|
1170
|
+
const [isFetchingMore, setIsFetchingMore] = react.useState(false);
|
|
1171
|
+
const [error, setError] = react.useState(null);
|
|
1172
|
+
const [offset, setOffset] = react.useState(0);
|
|
1173
|
+
const [count, setCount] = react.useState(0);
|
|
1174
|
+
const limit = 50;
|
|
1175
|
+
const loadReturns = react.useCallback(
|
|
1176
|
+
async (nextOffset, replace = false) => {
|
|
1177
|
+
var _a;
|
|
1178
|
+
try {
|
|
1179
|
+
if (replace) {
|
|
1180
|
+
setIsLoading(true);
|
|
1181
|
+
} else {
|
|
1182
|
+
setIsFetchingMore(true);
|
|
1183
|
+
}
|
|
1184
|
+
setError(null);
|
|
1185
|
+
const params = new URLSearchParams();
|
|
1186
|
+
params.set("limit", String(limit));
|
|
1187
|
+
params.set("offset", String(nextOffset));
|
|
1188
|
+
if (statusFilter !== "all") {
|
|
1189
|
+
params.set("status", statusFilter);
|
|
1190
|
+
}
|
|
1191
|
+
if (debouncedSearchQuery.trim()) {
|
|
1192
|
+
params.set("q", debouncedSearchQuery.trim());
|
|
1193
|
+
}
|
|
1194
|
+
if (createdByFilter !== "all") {
|
|
1195
|
+
params.set("created_by", createdByFilter);
|
|
1196
|
+
}
|
|
1197
|
+
params.set("order", "created_at");
|
|
1198
|
+
const response = await fetch(
|
|
1199
|
+
`/admin/return?${params.toString()}`,
|
|
1200
|
+
{ credentials: "include" }
|
|
1201
|
+
);
|
|
1202
|
+
if (!response.ok) {
|
|
1203
|
+
const message = await response.text();
|
|
1204
|
+
throw new Error(message || "Unable to load return orders");
|
|
1205
|
+
}
|
|
1206
|
+
const payload = await response.json();
|
|
1207
|
+
setCount(payload.count ?? 0);
|
|
1208
|
+
setOffset(nextOffset + (((_a = payload.returns) == null ? void 0 : _a.length) ?? 0));
|
|
1209
|
+
setItems(
|
|
1210
|
+
(prev) => replace ? payload.returns ?? [] : [...prev, ...payload.returns ?? []]
|
|
1211
|
+
);
|
|
1212
|
+
} catch (loadError) {
|
|
1213
|
+
const message = loadError instanceof Error ? loadError.message : "Unable to load return orders";
|
|
1214
|
+
setError(message);
|
|
1215
|
+
} finally {
|
|
1216
|
+
setIsLoading(false);
|
|
1217
|
+
setIsFetchingMore(false);
|
|
1218
|
+
}
|
|
1219
|
+
},
|
|
1220
|
+
[statusFilter, createdByFilter, debouncedSearchQuery]
|
|
1221
|
+
);
|
|
1222
|
+
react.useEffect(() => {
|
|
1223
|
+
void loadReturns(0, true);
|
|
1224
|
+
}, [statusFilter, createdByFilter, debouncedSearchQuery, loadReturns]);
|
|
1225
|
+
const hasMore = react.useMemo(() => offset < count, [offset, count]);
|
|
1226
|
+
const availableStatuses = react.useMemo(() => {
|
|
1227
|
+
const statuses = /* @__PURE__ */ new Set();
|
|
1228
|
+
items.forEach((item) => statuses.add(item.status));
|
|
1229
|
+
return Array.from(statuses).sort();
|
|
1230
|
+
}, [items]);
|
|
1231
|
+
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: [
|
|
1232
|
+
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1233
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1234
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Return Orders" }),
|
|
1235
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer return orders" })
|
|
1236
|
+
] }),
|
|
1237
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadReturns(0, true), children: "Refresh" })
|
|
1238
|
+
] }),
|
|
1239
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1240
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1241
|
+
ui.Input,
|
|
1242
|
+
{
|
|
1243
|
+
placeholder: "Search by return ID, order ID, or customer email",
|
|
1244
|
+
value: searchQuery,
|
|
1245
|
+
onChange: (event) => setSearchQuery(event.target.value),
|
|
1246
|
+
className: "md:max-w-sm"
|
|
1247
|
+
}
|
|
1248
|
+
),
|
|
1249
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
|
|
1250
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1251
|
+
"select",
|
|
1252
|
+
{
|
|
1253
|
+
value: createdByFilter,
|
|
1254
|
+
onChange: (event) => setCreatedByFilter(event.target.value),
|
|
1255
|
+
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",
|
|
1256
|
+
children: [
|
|
1257
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All (Created by)" }),
|
|
1258
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "customer", children: "Customer" }),
|
|
1259
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "admin", children: "Admin" })
|
|
1260
|
+
]
|
|
1261
|
+
}
|
|
1262
|
+
),
|
|
1263
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1264
|
+
"select",
|
|
1265
|
+
{
|
|
1266
|
+
value: statusFilter,
|
|
1267
|
+
onChange: (event) => setStatusFilter(event.target.value),
|
|
1268
|
+
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",
|
|
1269
|
+
children: [
|
|
1270
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All Statuses" }),
|
|
1271
|
+
availableStatuses.map((status) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
|
|
1272
|
+
]
|
|
1273
|
+
}
|
|
1274
|
+
)
|
|
1275
|
+
] })
|
|
1276
|
+
] }),
|
|
1277
|
+
error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
1278
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
1279
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1280
|
+
ui.Button,
|
|
1281
|
+
{
|
|
1282
|
+
variant: "secondary",
|
|
1283
|
+
onClick: () => loadReturns(0, true),
|
|
1284
|
+
children: "Try again"
|
|
1285
|
+
}
|
|
1286
|
+
) })
|
|
1287
|
+
] }) : null,
|
|
1288
|
+
isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading return orders..." }) }) : items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
|
|
1289
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No return orders yet" }),
|
|
1290
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Return orders created by customers will appear here." })
|
|
1291
|
+
] }) : /* @__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: [
|
|
1292
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1293
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Return ID" }),
|
|
1294
|
+
/* @__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" }),
|
|
1295
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Customer" }),
|
|
1296
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
|
|
1297
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Refund Amount" }),
|
|
1298
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
1299
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
1300
|
+
] }) }),
|
|
1301
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((returnOrder) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1302
|
+
"tr",
|
|
1303
|
+
{
|
|
1304
|
+
className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
|
|
1305
|
+
onClick: () => navigate(`/returns/${returnOrder.id}`),
|
|
1306
|
+
children: [
|
|
1307
|
+
/* @__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: returnOrder.id }) }) }),
|
|
1308
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.order_id }),
|
|
1309
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.customer_email || returnOrder.order_email || "—" }),
|
|
1310
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1311
|
+
ui.Badge,
|
|
1312
|
+
{
|
|
1313
|
+
size: "2xsmall",
|
|
1314
|
+
className: `uppercase ${getStatusBadgeClass$6(returnOrder.status)}`,
|
|
1315
|
+
children: returnOrder.status.replace(/_/g, " ")
|
|
1316
|
+
}
|
|
1317
|
+
) }),
|
|
1318
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
|
|
1319
|
+
const calc = returnOrder.refund;
|
|
1320
|
+
if ((calc == null ? void 0 : calc.is_processed) && calc.final_refund_amount != null) {
|
|
1321
|
+
return formatRefundCurrency(
|
|
1322
|
+
calc.final_refund_amount,
|
|
1323
|
+
calc.currency_code || returnOrder.currency_code
|
|
1324
|
+
);
|
|
1325
|
+
}
|
|
1326
|
+
if (calc) {
|
|
1327
|
+
return "Pending";
|
|
1328
|
+
}
|
|
1329
|
+
if (returnOrder.refund_amount == null) {
|
|
1330
|
+
return "—";
|
|
1331
|
+
}
|
|
1332
|
+
return formatRefundCurrency(
|
|
1333
|
+
Number(returnOrder.refund_amount),
|
|
1334
|
+
returnOrder.currency_code
|
|
1335
|
+
);
|
|
1336
|
+
})() }),
|
|
1337
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(returnOrder.created_at).toLocaleDateString("en-US", {
|
|
1338
|
+
year: "numeric",
|
|
1339
|
+
month: "short",
|
|
1340
|
+
day: "numeric",
|
|
1341
|
+
hour: "numeric",
|
|
1342
|
+
minute: "2-digit",
|
|
1343
|
+
hour12: true
|
|
1344
|
+
}) }),
|
|
1345
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1346
|
+
ui.Button,
|
|
1347
|
+
{
|
|
1348
|
+
variant: "transparent",
|
|
1349
|
+
size: "small",
|
|
1350
|
+
onClick: (e) => {
|
|
1351
|
+
e.stopPropagation();
|
|
1352
|
+
navigate(`/app/orders/${returnOrder.order_id}`);
|
|
1353
|
+
},
|
|
1354
|
+
children: "Go to order"
|
|
1355
|
+
}
|
|
1356
|
+
) })
|
|
1357
|
+
]
|
|
1358
|
+
},
|
|
1359
|
+
returnOrder.id
|
|
1360
|
+
)) })
|
|
1361
|
+
] }) }),
|
|
1362
|
+
hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1363
|
+
ui.Button,
|
|
1364
|
+
{
|
|
1365
|
+
variant: "secondary",
|
|
1366
|
+
isLoading: isFetchingMore,
|
|
1367
|
+
onClick: () => loadReturns(offset, false),
|
|
1368
|
+
children: "Load more"
|
|
1369
|
+
}
|
|
1370
|
+
) }) : null
|
|
1371
|
+
] }) });
|
|
1372
|
+
};
|
|
1373
|
+
const config$6 = adminSdk.defineRouteConfig({
|
|
1374
|
+
label: "Return Orders",
|
|
1375
|
+
icon: icons.ArrowPath
|
|
1376
|
+
});
|
|
1377
|
+
const useDebounce$1 = (value, delay) => {
|
|
1378
|
+
const [debouncedValue, setDebouncedValue] = react.useState(value);
|
|
1379
|
+
react.useEffect(() => {
|
|
1380
|
+
const handler = setTimeout(() => setDebouncedValue(value), delay);
|
|
1381
|
+
return () => clearTimeout(handler);
|
|
1382
|
+
}, [value, delay]);
|
|
1383
|
+
return debouncedValue;
|
|
1384
|
+
};
|
|
1385
|
+
const getStatusBadgeClass$5 = (status) => {
|
|
1115
1386
|
const s2 = status.toLowerCase();
|
|
1116
1387
|
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1117
1388
|
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
@@ -1123,12 +1394,12 @@ const RefundsPage = () => {
|
|
|
1123
1394
|
const navigate = reactRouterDom.useNavigate();
|
|
1124
1395
|
const [items, setItems] = react.useState([]);
|
|
1125
1396
|
const [orderIdSearch, setOrderIdSearch] = react.useState("");
|
|
1126
|
-
const debouncedOrderId = useDebounce$
|
|
1397
|
+
const debouncedOrderId = useDebounce$1(orderIdSearch, 300);
|
|
1127
1398
|
const [paymentStatusFilter, setPaymentStatusFilter] = react.useState("all");
|
|
1128
1399
|
const [providerSearch, setProviderSearch] = react.useState("");
|
|
1129
|
-
const debouncedProvider = useDebounce$
|
|
1400
|
+
const debouncedProvider = useDebounce$1(providerSearch, 300);
|
|
1130
1401
|
const [currencySearch, setCurrencySearch] = react.useState("");
|
|
1131
|
-
const debouncedCurrency = useDebounce$
|
|
1402
|
+
const debouncedCurrency = useDebounce$1(currencySearch, 300);
|
|
1132
1403
|
const [dateFrom, setDateFrom] = react.useState("");
|
|
1133
1404
|
const [dateTo, setDateTo] = react.useState("");
|
|
1134
1405
|
const [amountMin, setAmountMin] = react.useState("");
|
|
@@ -1340,7 +1611,7 @@ const RefundsPage = () => {
|
|
|
1340
1611
|
ui.Badge,
|
|
1341
1612
|
{
|
|
1342
1613
|
size: "2xsmall",
|
|
1343
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
1614
|
+
className: `uppercase ${getStatusBadgeClass$5(displayStatus(r))}`,
|
|
1344
1615
|
children: displayStatus(r) !== "—" ? displayStatus(r).replace(/_/g, " ") : "—"
|
|
1345
1616
|
}
|
|
1346
1617
|
) }),
|
|
@@ -1394,11 +1665,11 @@ const RefundsPage = () => {
|
|
|
1394
1665
|
) }) : null
|
|
1395
1666
|
] }) });
|
|
1396
1667
|
};
|
|
1397
|
-
const config$
|
|
1668
|
+
const config$5 = adminSdk.defineRouteConfig({
|
|
1398
1669
|
label: "Refunds",
|
|
1399
1670
|
icon: icons.Receipt
|
|
1400
1671
|
});
|
|
1401
|
-
const useDebounce
|
|
1672
|
+
const useDebounce = (value, delay) => {
|
|
1402
1673
|
const [debouncedValue, setDebouncedValue] = react.useState(value);
|
|
1403
1674
|
react.useEffect(() => {
|
|
1404
1675
|
const handler = setTimeout(() => setDebouncedValue(value), delay);
|
|
@@ -1406,249 +1677,7 @@ const useDebounce$1 = (value, delay) => {
|
|
|
1406
1677
|
}, [value, delay]);
|
|
1407
1678
|
return debouncedValue;
|
|
1408
1679
|
};
|
|
1409
|
-
const getStatusBadgeClass$
|
|
1410
|
-
const statusLower = status.toLowerCase();
|
|
1411
|
-
if (statusLower === "requested") {
|
|
1412
|
-
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
1413
|
-
}
|
|
1414
|
-
if (statusLower === "received") {
|
|
1415
|
-
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
1416
|
-
}
|
|
1417
|
-
if (statusLower === "requires_action") {
|
|
1418
|
-
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
1419
|
-
}
|
|
1420
|
-
if (statusLower === "completed") {
|
|
1421
|
-
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1422
|
-
}
|
|
1423
|
-
if (statusLower === "canceled") {
|
|
1424
|
-
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
1425
|
-
}
|
|
1426
|
-
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
1427
|
-
};
|
|
1428
|
-
const ReturnsPage = () => {
|
|
1429
|
-
const navigate = reactRouterDom.useNavigate();
|
|
1430
|
-
const [items, setItems] = react.useState([]);
|
|
1431
|
-
const [statusFilter, setStatusFilter] = react.useState("all");
|
|
1432
|
-
const [createdByFilter, setCreatedByFilter] = react.useState("all");
|
|
1433
|
-
const [searchQuery, setSearchQuery] = react.useState("");
|
|
1434
|
-
const debouncedSearchQuery = useDebounce$1(searchQuery, 300);
|
|
1435
|
-
const [isLoading, setIsLoading] = react.useState(true);
|
|
1436
|
-
const [isFetchingMore, setIsFetchingMore] = react.useState(false);
|
|
1437
|
-
const [error, setError] = react.useState(null);
|
|
1438
|
-
const [offset, setOffset] = react.useState(0);
|
|
1439
|
-
const [count, setCount] = react.useState(0);
|
|
1440
|
-
const limit = 50;
|
|
1441
|
-
const loadReturns = react.useCallback(
|
|
1442
|
-
async (nextOffset, replace = false) => {
|
|
1443
|
-
var _a;
|
|
1444
|
-
try {
|
|
1445
|
-
if (replace) {
|
|
1446
|
-
setIsLoading(true);
|
|
1447
|
-
} else {
|
|
1448
|
-
setIsFetchingMore(true);
|
|
1449
|
-
}
|
|
1450
|
-
setError(null);
|
|
1451
|
-
const params = new URLSearchParams();
|
|
1452
|
-
params.set("limit", String(limit));
|
|
1453
|
-
params.set("offset", String(nextOffset));
|
|
1454
|
-
if (statusFilter !== "all") {
|
|
1455
|
-
params.set("status", statusFilter);
|
|
1456
|
-
}
|
|
1457
|
-
if (debouncedSearchQuery.trim()) {
|
|
1458
|
-
params.set("q", debouncedSearchQuery.trim());
|
|
1459
|
-
}
|
|
1460
|
-
if (createdByFilter !== "all") {
|
|
1461
|
-
params.set("created_by", createdByFilter);
|
|
1462
|
-
}
|
|
1463
|
-
params.set("order", "created_at");
|
|
1464
|
-
const response = await fetch(
|
|
1465
|
-
`/admin/return?${params.toString()}`,
|
|
1466
|
-
{ credentials: "include" }
|
|
1467
|
-
);
|
|
1468
|
-
if (!response.ok) {
|
|
1469
|
-
const message = await response.text();
|
|
1470
|
-
throw new Error(message || "Unable to load return orders");
|
|
1471
|
-
}
|
|
1472
|
-
const payload = await response.json();
|
|
1473
|
-
setCount(payload.count ?? 0);
|
|
1474
|
-
setOffset(nextOffset + (((_a = payload.returns) == null ? void 0 : _a.length) ?? 0));
|
|
1475
|
-
setItems(
|
|
1476
|
-
(prev) => replace ? payload.returns ?? [] : [...prev, ...payload.returns ?? []]
|
|
1477
|
-
);
|
|
1478
|
-
} catch (loadError) {
|
|
1479
|
-
const message = loadError instanceof Error ? loadError.message : "Unable to load return orders";
|
|
1480
|
-
setError(message);
|
|
1481
|
-
} finally {
|
|
1482
|
-
setIsLoading(false);
|
|
1483
|
-
setIsFetchingMore(false);
|
|
1484
|
-
}
|
|
1485
|
-
},
|
|
1486
|
-
[statusFilter, createdByFilter, debouncedSearchQuery]
|
|
1487
|
-
);
|
|
1488
|
-
react.useEffect(() => {
|
|
1489
|
-
void loadReturns(0, true);
|
|
1490
|
-
}, [statusFilter, createdByFilter, debouncedSearchQuery, loadReturns]);
|
|
1491
|
-
const hasMore = react.useMemo(() => offset < count, [offset, count]);
|
|
1492
|
-
const availableStatuses = react.useMemo(() => {
|
|
1493
|
-
const statuses = /* @__PURE__ */ new Set();
|
|
1494
|
-
items.forEach((item) => statuses.add(item.status));
|
|
1495
|
-
return Array.from(statuses).sort();
|
|
1496
|
-
}, [items]);
|
|
1497
|
-
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: [
|
|
1498
|
-
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1499
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1500
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Return Orders" }),
|
|
1501
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer return orders" })
|
|
1502
|
-
] }),
|
|
1503
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadReturns(0, true), children: "Refresh" })
|
|
1504
|
-
] }),
|
|
1505
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1506
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1507
|
-
ui.Input,
|
|
1508
|
-
{
|
|
1509
|
-
placeholder: "Search by return ID, order ID, or customer email",
|
|
1510
|
-
value: searchQuery,
|
|
1511
|
-
onChange: (event) => setSearchQuery(event.target.value),
|
|
1512
|
-
className: "md:max-w-sm"
|
|
1513
|
-
}
|
|
1514
|
-
),
|
|
1515
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
|
|
1516
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1517
|
-
"select",
|
|
1518
|
-
{
|
|
1519
|
-
value: createdByFilter,
|
|
1520
|
-
onChange: (event) => setCreatedByFilter(event.target.value),
|
|
1521
|
-
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",
|
|
1522
|
-
children: [
|
|
1523
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All (Created by)" }),
|
|
1524
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "customer", children: "Customer" }),
|
|
1525
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "admin", children: "Admin" })
|
|
1526
|
-
]
|
|
1527
|
-
}
|
|
1528
|
-
),
|
|
1529
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1530
|
-
"select",
|
|
1531
|
-
{
|
|
1532
|
-
value: statusFilter,
|
|
1533
|
-
onChange: (event) => setStatusFilter(event.target.value),
|
|
1534
|
-
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",
|
|
1535
|
-
children: [
|
|
1536
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All Statuses" }),
|
|
1537
|
-
availableStatuses.map((status) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
|
|
1538
|
-
]
|
|
1539
|
-
}
|
|
1540
|
-
)
|
|
1541
|
-
] })
|
|
1542
|
-
] }),
|
|
1543
|
-
error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
1544
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
1545
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1546
|
-
ui.Button,
|
|
1547
|
-
{
|
|
1548
|
-
variant: "secondary",
|
|
1549
|
-
onClick: () => loadReturns(0, true),
|
|
1550
|
-
children: "Try again"
|
|
1551
|
-
}
|
|
1552
|
-
) })
|
|
1553
|
-
] }) : null,
|
|
1554
|
-
isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading return orders..." }) }) : items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
|
|
1555
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No return orders yet" }),
|
|
1556
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Return orders created by customers will appear here." })
|
|
1557
|
-
] }) : /* @__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: [
|
|
1558
|
-
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1559
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Return ID" }),
|
|
1560
|
-
/* @__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" }),
|
|
1561
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Customer" }),
|
|
1562
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
|
|
1563
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Refund Amount" }),
|
|
1564
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
1565
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
1566
|
-
] }) }),
|
|
1567
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((returnOrder) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1568
|
-
"tr",
|
|
1569
|
-
{
|
|
1570
|
-
className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
|
|
1571
|
-
onClick: () => navigate(`/returns/${returnOrder.id}`),
|
|
1572
|
-
children: [
|
|
1573
|
-
/* @__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: returnOrder.id }) }) }),
|
|
1574
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.order_id }),
|
|
1575
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.customer_email || returnOrder.order_email || "—" }),
|
|
1576
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1577
|
-
ui.Badge,
|
|
1578
|
-
{
|
|
1579
|
-
size: "2xsmall",
|
|
1580
|
-
className: `uppercase ${getStatusBadgeClass$5(returnOrder.status)}`,
|
|
1581
|
-
children: returnOrder.status.replace(/_/g, " ")
|
|
1582
|
-
}
|
|
1583
|
-
) }),
|
|
1584
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
|
|
1585
|
-
const calc = returnOrder.refund;
|
|
1586
|
-
if ((calc == null ? void 0 : calc.is_processed) && calc.final_refund_amount != null) {
|
|
1587
|
-
return formatRefundCurrency(
|
|
1588
|
-
calc.final_refund_amount,
|
|
1589
|
-
calc.currency_code || returnOrder.currency_code
|
|
1590
|
-
);
|
|
1591
|
-
}
|
|
1592
|
-
if (calc) {
|
|
1593
|
-
return "Pending";
|
|
1594
|
-
}
|
|
1595
|
-
if (returnOrder.refund_amount == null) {
|
|
1596
|
-
return "—";
|
|
1597
|
-
}
|
|
1598
|
-
return formatRefundCurrency(
|
|
1599
|
-
Number(returnOrder.refund_amount),
|
|
1600
|
-
returnOrder.currency_code
|
|
1601
|
-
);
|
|
1602
|
-
})() }),
|
|
1603
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(returnOrder.created_at).toLocaleDateString("en-US", {
|
|
1604
|
-
year: "numeric",
|
|
1605
|
-
month: "short",
|
|
1606
|
-
day: "numeric",
|
|
1607
|
-
hour: "numeric",
|
|
1608
|
-
minute: "2-digit",
|
|
1609
|
-
hour12: true
|
|
1610
|
-
}) }),
|
|
1611
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1612
|
-
ui.Button,
|
|
1613
|
-
{
|
|
1614
|
-
variant: "transparent",
|
|
1615
|
-
size: "small",
|
|
1616
|
-
onClick: (e) => {
|
|
1617
|
-
e.stopPropagation();
|
|
1618
|
-
navigate(`/app/orders/${returnOrder.order_id}`);
|
|
1619
|
-
},
|
|
1620
|
-
children: "Go to order"
|
|
1621
|
-
}
|
|
1622
|
-
) })
|
|
1623
|
-
]
|
|
1624
|
-
},
|
|
1625
|
-
returnOrder.id
|
|
1626
|
-
)) })
|
|
1627
|
-
] }) }),
|
|
1628
|
-
hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1629
|
-
ui.Button,
|
|
1630
|
-
{
|
|
1631
|
-
variant: "secondary",
|
|
1632
|
-
isLoading: isFetchingMore,
|
|
1633
|
-
onClick: () => loadReturns(offset, false),
|
|
1634
|
-
children: "Load more"
|
|
1635
|
-
}
|
|
1636
|
-
) }) : null
|
|
1637
|
-
] }) });
|
|
1638
|
-
};
|
|
1639
|
-
const config$5 = adminSdk.defineRouteConfig({
|
|
1640
|
-
label: "Return Orders",
|
|
1641
|
-
icon: icons.ArrowPath
|
|
1642
|
-
});
|
|
1643
|
-
const useDebounce = (value, delay) => {
|
|
1644
|
-
const [debouncedValue, setDebouncedValue] = react.useState(value);
|
|
1645
|
-
react.useEffect(() => {
|
|
1646
|
-
const handler = setTimeout(() => setDebouncedValue(value), delay);
|
|
1647
|
-
return () => clearTimeout(handler);
|
|
1648
|
-
}, [value, delay]);
|
|
1649
|
-
return debouncedValue;
|
|
1650
|
-
};
|
|
1651
|
-
const getStatusBadgeClass$4 = (status) => {
|
|
1680
|
+
const getStatusBadgeClass$4 = (status) => {
|
|
1652
1681
|
const statusLower = status.toLowerCase();
|
|
1653
1682
|
if (statusLower === "requested") {
|
|
1654
1683
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
@@ -1968,220 +1997,28 @@ const PaymentDetailPage = () => {
|
|
|
1968
1997
|
] }),
|
|
1969
1998
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1970
1999
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created" }),
|
|
1971
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: new Date(detail.created_at).toLocaleDateString("en-US", {
|
|
1972
|
-
year: "numeric",
|
|
1973
|
-
month: "short",
|
|
1974
|
-
day: "numeric",
|
|
1975
|
-
hour: "numeric",
|
|
1976
|
-
minute: "2-digit",
|
|
1977
|
-
hour12: true
|
|
1978
|
-
}) })
|
|
1979
|
-
] })
|
|
1980
|
-
] }) }),
|
|
1981
|
-
Object.keys(detail.data ?? {}).length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
1982
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Provider data" }),
|
|
1983
|
-
/* @__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) })
|
|
1984
|
-
] }) : /* @__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." }) })
|
|
1985
|
-
] }) : null
|
|
1986
|
-
] }) });
|
|
1987
|
-
};
|
|
1988
|
-
const config$3 = adminSdk.defineRouteConfig({
|
|
1989
|
-
label: "Payment details",
|
|
1990
|
-
icon: icons.CreditCard
|
|
1991
|
-
});
|
|
1992
|
-
const getStatusBadgeClass$2 = (status) => {
|
|
1993
|
-
const s2 = status.toLowerCase();
|
|
1994
|
-
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1995
|
-
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
1996
|
-
if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
1997
|
-
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
1998
|
-
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
1999
|
-
};
|
|
2000
|
-
const formatAmount = (value) => {
|
|
2001
|
-
return String(value);
|
|
2002
|
-
};
|
|
2003
|
-
const RefundDetailPage = () => {
|
|
2004
|
-
var _a, _b, _c;
|
|
2005
|
-
const navigate = reactRouterDom.useNavigate();
|
|
2006
|
-
const params = reactRouterDom.useParams();
|
|
2007
|
-
const id = (_a = params == null ? void 0 : params.id) == null ? void 0 : _a.trim();
|
|
2008
|
-
const [detail, setDetail] = react.useState(null);
|
|
2009
|
-
const [loading, setLoading] = react.useState(!!id);
|
|
2010
|
-
const [error, setError] = react.useState(null);
|
|
2011
|
-
const [gatewayExpanded, setGatewayExpanded] = react.useState(false);
|
|
2012
|
-
react.useEffect(() => {
|
|
2013
|
-
if (!id) {
|
|
2014
|
-
setLoading(false);
|
|
2015
|
-
return;
|
|
2016
|
-
}
|
|
2017
|
-
let cancelled = false;
|
|
2018
|
-
setLoading(true);
|
|
2019
|
-
setError(null);
|
|
2020
|
-
fetch(`/admin/refunds/${id}`, { credentials: "include" }).then((res) => {
|
|
2021
|
-
if (!res.ok) throw new Error(res.statusText || "Failed to load");
|
|
2022
|
-
return res.json();
|
|
2023
|
-
}).then((data) => {
|
|
2024
|
-
if (!cancelled) setDetail(data);
|
|
2025
|
-
}).catch((e) => {
|
|
2026
|
-
if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
|
|
2027
|
-
}).finally(() => {
|
|
2028
|
-
if (!cancelled) setLoading(false);
|
|
2029
|
-
});
|
|
2030
|
-
return () => {
|
|
2031
|
-
cancelled = true;
|
|
2032
|
-
};
|
|
2033
|
-
}, [id]);
|
|
2034
|
-
const paymentStatus = ((_b = detail == null ? void 0 : detail.payment) == null ? void 0 : _b.status) ?? "—";
|
|
2035
|
-
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;
|
|
2036
|
-
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: [
|
|
2037
|
-
/* @__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: [
|
|
2038
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => navigate("/refunds"), children: "← Refunds" }),
|
|
2039
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Refund details" }),
|
|
2040
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle font-mono", children: id ?? "—" })
|
|
2041
|
-
] }) }),
|
|
2042
|
-
error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
2043
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
2044
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/refunds"), children: "Back to list" })
|
|
2045
|
-
] }) : 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: [
|
|
2046
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2047
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Refund summary" }),
|
|
2048
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
2049
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2050
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refund ID" }),
|
|
2051
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.id })
|
|
2052
|
-
] }),
|
|
2053
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2054
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
|
|
2055
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.refund.amount) })
|
|
2056
|
-
] }),
|
|
2057
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2058
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Note" }),
|
|
2059
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.refund.note ?? "—" })
|
|
2060
|
-
] }),
|
|
2061
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2062
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created at" }),
|
|
2063
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: new Date(detail.refund.created_at).toLocaleDateString("en-US", {
|
|
2064
|
-
year: "numeric",
|
|
2065
|
-
month: "short",
|
|
2066
|
-
day: "numeric",
|
|
2067
|
-
hour: "numeric",
|
|
2068
|
-
minute: "2-digit",
|
|
2069
|
-
hour12: true
|
|
2070
|
-
}) })
|
|
2071
|
-
] }),
|
|
2072
|
-
detail.refund.created_by ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2073
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created by" }),
|
|
2074
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.created_by })
|
|
2075
|
-
] }) : null
|
|
2076
|
-
] })
|
|
2077
|
-
] }),
|
|
2078
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2079
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Payment summary" }),
|
|
2080
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
2081
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2082
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Payment amount" }),
|
|
2083
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.payment_amount) })
|
|
2084
|
-
] }),
|
|
2085
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2086
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Captured amount" }),
|
|
2087
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.captured_amount) })
|
|
2088
|
-
] }),
|
|
2089
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2090
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refunded amount" }),
|
|
2091
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.refunded_amount) })
|
|
2092
|
-
] }),
|
|
2093
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2094
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
|
|
2095
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.payment.provider_id || "—" })
|
|
2096
|
-
] }),
|
|
2097
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2098
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
|
|
2099
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2100
|
-
ui.Badge,
|
|
2101
|
-
{
|
|
2102
|
-
size: "2xsmall",
|
|
2103
|
-
className: `uppercase ${getStatusBadgeClass$2(paymentStatus)}`,
|
|
2104
|
-
children: paymentStatus !== "—" ? paymentStatus.replace(/_/g, " ") : "—"
|
|
2105
|
-
}
|
|
2106
|
-
) })
|
|
2107
|
-
] }),
|
|
2108
|
-
detail.computed ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2109
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2110
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Full refund" }),
|
|
2111
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.computed.is_full_refund ? "Yes" : "No" })
|
|
2112
|
-
] }),
|
|
2113
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2114
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Remaining refundable" }),
|
|
2115
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.computed.remaining_refundable_amount) })
|
|
2116
|
-
] }),
|
|
2117
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2118
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refund %" }),
|
|
2119
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "mt-1 block", children: [
|
|
2120
|
-
detail.computed.refund_percentage.toFixed(1),
|
|
2121
|
-
"%"
|
|
2122
|
-
] })
|
|
2123
|
-
] })
|
|
2124
|
-
] }) : null
|
|
2125
|
-
] })
|
|
2126
|
-
] }),
|
|
2127
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2128
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Order summary" }),
|
|
2129
|
-
detail.order ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
2130
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2131
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Order" }),
|
|
2132
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2133
|
-
ui.Button,
|
|
2134
|
-
{
|
|
2135
|
-
variant: "transparent",
|
|
2136
|
-
size: "small",
|
|
2137
|
-
onClick: () => navigate(`/orders/${detail.order.order_id}`),
|
|
2138
|
-
children: detail.order.order_number ?? detail.order.order_id
|
|
2139
|
-
}
|
|
2140
|
-
) })
|
|
2141
|
-
] }),
|
|
2142
|
-
detail.order.total != null ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2143
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Total" }),
|
|
2144
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.order.total) })
|
|
2145
|
-
] }) : null,
|
|
2146
|
-
detail.order.customer_id ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2147
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Customer ID" }),
|
|
2148
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.order.customer_id })
|
|
2149
|
-
] }) : null,
|
|
2150
|
-
detail.order.region ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2151
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Region" }),
|
|
2152
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.region })
|
|
2153
|
-
] }) : null,
|
|
2154
|
-
detail.order.fulfillment_status ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2155
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Fulfillment status" }),
|
|
2156
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.fulfillment_status })
|
|
2157
|
-
] }) : null
|
|
2158
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No order linked to this refund." })
|
|
2159
|
-
] }),
|
|
2160
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2161
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2162
|
-
"button",
|
|
2163
|
-
{
|
|
2164
|
-
type: "button",
|
|
2165
|
-
className: "flex w-full items-center justify-between text-left",
|
|
2166
|
-
onClick: () => setGatewayExpanded((prev) => !prev),
|
|
2167
|
-
"aria-expanded": gatewayExpanded,
|
|
2168
|
-
"aria-label": gatewayExpanded ? "Collapse gateway data" : "Expand gateway data",
|
|
2169
|
-
children: [
|
|
2170
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg", children: "Gateway data" }),
|
|
2171
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: gatewayExpanded ? "Collapse" : "Expand" })
|
|
2172
|
-
]
|
|
2173
|
-
}
|
|
2174
|
-
),
|
|
2175
|
-
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." }) })
|
|
2176
|
-
] })
|
|
2000
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: new Date(detail.created_at).toLocaleDateString("en-US", {
|
|
2001
|
+
year: "numeric",
|
|
2002
|
+
month: "short",
|
|
2003
|
+
day: "numeric",
|
|
2004
|
+
hour: "numeric",
|
|
2005
|
+
minute: "2-digit",
|
|
2006
|
+
hour12: true
|
|
2007
|
+
}) })
|
|
2008
|
+
] })
|
|
2009
|
+
] }) }),
|
|
2010
|
+
Object.keys(detail.data ?? {}).length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2011
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Provider data" }),
|
|
2012
|
+
/* @__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) })
|
|
2013
|
+
] }) : /* @__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." }) })
|
|
2177
2014
|
] }) : null
|
|
2178
2015
|
] }) });
|
|
2179
2016
|
};
|
|
2180
|
-
const config$
|
|
2181
|
-
label: "
|
|
2182
|
-
icon: icons.
|
|
2017
|
+
const config$3 = adminSdk.defineRouteConfig({
|
|
2018
|
+
label: "Payment details",
|
|
2019
|
+
icon: icons.CreditCard
|
|
2183
2020
|
});
|
|
2184
|
-
const getStatusBadgeClass$
|
|
2021
|
+
const getStatusBadgeClass$2 = (status) => {
|
|
2185
2022
|
const statusLower = status.toLowerCase();
|
|
2186
2023
|
if (statusLower === "requested") {
|
|
2187
2024
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
@@ -2207,7 +2044,7 @@ const getStatusBadgeClass$1 = (status) => {
|
|
|
2207
2044
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
2208
2045
|
};
|
|
2209
2046
|
const ReturnDetailPage = () => {
|
|
2210
|
-
var _a, _b;
|
|
2047
|
+
var _a, _b, _c;
|
|
2211
2048
|
const navigate = reactRouterDom.useNavigate();
|
|
2212
2049
|
const { id } = reactRouterDom.useParams();
|
|
2213
2050
|
const [returnOrder, setReturnOrder] = react.useState(null);
|
|
@@ -2315,7 +2152,7 @@ const ReturnDetailPage = () => {
|
|
|
2315
2152
|
ui.Badge,
|
|
2316
2153
|
{
|
|
2317
2154
|
size: "small",
|
|
2318
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
2155
|
+
className: `uppercase ${getStatusBadgeClass$2(returnOrder.status)}`,
|
|
2319
2156
|
children: returnOrder.status.replace(/_/g, " ")
|
|
2320
2157
|
}
|
|
2321
2158
|
)
|
|
@@ -2398,7 +2235,7 @@ const ReturnDetailPage = () => {
|
|
|
2398
2235
|
ui.Badge,
|
|
2399
2236
|
{
|
|
2400
2237
|
size: "2xsmall",
|
|
2401
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
2238
|
+
className: `uppercase ${getStatusBadgeClass$2(entry.status)}`,
|
|
2402
2239
|
children: entry.status.replace(/_/g, " ")
|
|
2403
2240
|
}
|
|
2404
2241
|
) }),
|
|
@@ -2428,6 +2265,10 @@ const ReturnDetailPage = () => {
|
|
|
2428
2265
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
|
|
2429
2266
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_b = returnOrder.order.customer) == null ? void 0 : _b.email) || returnOrder.order.email || "—" })
|
|
2430
2267
|
] }),
|
|
2268
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2269
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Payment method" }),
|
|
2270
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_c = returnOrder.order.order_payment) == null ? void 0 : _c.label) || "—" })
|
|
2271
|
+
] }),
|
|
2431
2272
|
returnOrder.order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2432
2273
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
|
|
2433
2274
|
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "font-medium", children: [
|
|
@@ -2456,10 +2297,202 @@ const ReturnDetailPage = () => {
|
|
|
2456
2297
|
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" }) })
|
|
2457
2298
|
] }) });
|
|
2458
2299
|
};
|
|
2459
|
-
const config$
|
|
2300
|
+
const config$2 = adminSdk.defineRouteConfig({
|
|
2460
2301
|
label: "Return Order Details",
|
|
2461
2302
|
icon: icons.CheckCircle
|
|
2462
2303
|
});
|
|
2304
|
+
const getStatusBadgeClass$1 = (status) => {
|
|
2305
|
+
const s2 = status.toLowerCase();
|
|
2306
|
+
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
2307
|
+
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
2308
|
+
if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
2309
|
+
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
2310
|
+
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
2311
|
+
};
|
|
2312
|
+
const formatAmount = (value) => {
|
|
2313
|
+
return String(value);
|
|
2314
|
+
};
|
|
2315
|
+
const RefundDetailPage = () => {
|
|
2316
|
+
var _a, _b, _c;
|
|
2317
|
+
const navigate = reactRouterDom.useNavigate();
|
|
2318
|
+
const params = reactRouterDom.useParams();
|
|
2319
|
+
const id = (_a = params == null ? void 0 : params.id) == null ? void 0 : _a.trim();
|
|
2320
|
+
const [detail, setDetail] = react.useState(null);
|
|
2321
|
+
const [loading, setLoading] = react.useState(!!id);
|
|
2322
|
+
const [error, setError] = react.useState(null);
|
|
2323
|
+
const [gatewayExpanded, setGatewayExpanded] = react.useState(false);
|
|
2324
|
+
react.useEffect(() => {
|
|
2325
|
+
if (!id) {
|
|
2326
|
+
setLoading(false);
|
|
2327
|
+
return;
|
|
2328
|
+
}
|
|
2329
|
+
let cancelled = false;
|
|
2330
|
+
setLoading(true);
|
|
2331
|
+
setError(null);
|
|
2332
|
+
fetch(`/admin/refunds/${id}`, { credentials: "include" }).then((res) => {
|
|
2333
|
+
if (!res.ok) throw new Error(res.statusText || "Failed to load");
|
|
2334
|
+
return res.json();
|
|
2335
|
+
}).then((data) => {
|
|
2336
|
+
if (!cancelled) setDetail(data);
|
|
2337
|
+
}).catch((e) => {
|
|
2338
|
+
if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
|
|
2339
|
+
}).finally(() => {
|
|
2340
|
+
if (!cancelled) setLoading(false);
|
|
2341
|
+
});
|
|
2342
|
+
return () => {
|
|
2343
|
+
cancelled = true;
|
|
2344
|
+
};
|
|
2345
|
+
}, [id]);
|
|
2346
|
+
const paymentStatus = ((_b = detail == null ? void 0 : detail.payment) == null ? void 0 : _b.status) ?? "—";
|
|
2347
|
+
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;
|
|
2348
|
+
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: [
|
|
2349
|
+
/* @__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: [
|
|
2350
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => navigate("/refunds"), children: "← Refunds" }),
|
|
2351
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Refund details" }),
|
|
2352
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle font-mono", children: id ?? "—" })
|
|
2353
|
+
] }) }),
|
|
2354
|
+
error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
2355
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
2356
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/refunds"), children: "Back to list" })
|
|
2357
|
+
] }) : 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: [
|
|
2358
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2359
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Refund summary" }),
|
|
2360
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
2361
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2362
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refund ID" }),
|
|
2363
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.id })
|
|
2364
|
+
] }),
|
|
2365
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2366
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
|
|
2367
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.refund.amount) })
|
|
2368
|
+
] }),
|
|
2369
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2370
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Note" }),
|
|
2371
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.refund.note ?? "—" })
|
|
2372
|
+
] }),
|
|
2373
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2374
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created at" }),
|
|
2375
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: new Date(detail.refund.created_at).toLocaleDateString("en-US", {
|
|
2376
|
+
year: "numeric",
|
|
2377
|
+
month: "short",
|
|
2378
|
+
day: "numeric",
|
|
2379
|
+
hour: "numeric",
|
|
2380
|
+
minute: "2-digit",
|
|
2381
|
+
hour12: true
|
|
2382
|
+
}) })
|
|
2383
|
+
] }),
|
|
2384
|
+
detail.refund.created_by ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2385
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created by" }),
|
|
2386
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.created_by })
|
|
2387
|
+
] }) : null
|
|
2388
|
+
] })
|
|
2389
|
+
] }),
|
|
2390
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2391
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Payment summary" }),
|
|
2392
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
2393
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2394
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Payment amount" }),
|
|
2395
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.payment_amount) })
|
|
2396
|
+
] }),
|
|
2397
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2398
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Captured amount" }),
|
|
2399
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.captured_amount) })
|
|
2400
|
+
] }),
|
|
2401
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2402
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refunded amount" }),
|
|
2403
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.refunded_amount) })
|
|
2404
|
+
] }),
|
|
2405
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2406
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
|
|
2407
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.payment.provider_id || "—" })
|
|
2408
|
+
] }),
|
|
2409
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2410
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
|
|
2411
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2412
|
+
ui.Badge,
|
|
2413
|
+
{
|
|
2414
|
+
size: "2xsmall",
|
|
2415
|
+
className: `uppercase ${getStatusBadgeClass$1(paymentStatus)}`,
|
|
2416
|
+
children: paymentStatus !== "—" ? paymentStatus.replace(/_/g, " ") : "—"
|
|
2417
|
+
}
|
|
2418
|
+
) })
|
|
2419
|
+
] }),
|
|
2420
|
+
detail.computed ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2421
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2422
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Full refund" }),
|
|
2423
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.computed.is_full_refund ? "Yes" : "No" })
|
|
2424
|
+
] }),
|
|
2425
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2426
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Remaining refundable" }),
|
|
2427
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.computed.remaining_refundable_amount) })
|
|
2428
|
+
] }),
|
|
2429
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2430
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refund %" }),
|
|
2431
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "mt-1 block", children: [
|
|
2432
|
+
detail.computed.refund_percentage.toFixed(1),
|
|
2433
|
+
"%"
|
|
2434
|
+
] })
|
|
2435
|
+
] })
|
|
2436
|
+
] }) : null
|
|
2437
|
+
] })
|
|
2438
|
+
] }),
|
|
2439
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2440
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Order summary" }),
|
|
2441
|
+
detail.order ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
2442
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2443
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Order" }),
|
|
2444
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2445
|
+
ui.Button,
|
|
2446
|
+
{
|
|
2447
|
+
variant: "transparent",
|
|
2448
|
+
size: "small",
|
|
2449
|
+
onClick: () => navigate(`/orders/${detail.order.order_id}`),
|
|
2450
|
+
children: detail.order.order_number ?? detail.order.order_id
|
|
2451
|
+
}
|
|
2452
|
+
) })
|
|
2453
|
+
] }),
|
|
2454
|
+
detail.order.total != null ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2455
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Total" }),
|
|
2456
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.order.total) })
|
|
2457
|
+
] }) : null,
|
|
2458
|
+
detail.order.customer_id ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2459
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Customer ID" }),
|
|
2460
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.order.customer_id })
|
|
2461
|
+
] }) : null,
|
|
2462
|
+
detail.order.region ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2463
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Region" }),
|
|
2464
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.region })
|
|
2465
|
+
] }) : null,
|
|
2466
|
+
detail.order.fulfillment_status ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2467
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Fulfillment status" }),
|
|
2468
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.fulfillment_status })
|
|
2469
|
+
] }) : null
|
|
2470
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No order linked to this refund." })
|
|
2471
|
+
] }),
|
|
2472
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2473
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2474
|
+
"button",
|
|
2475
|
+
{
|
|
2476
|
+
type: "button",
|
|
2477
|
+
className: "flex w-full items-center justify-between text-left",
|
|
2478
|
+
onClick: () => setGatewayExpanded((prev) => !prev),
|
|
2479
|
+
"aria-expanded": gatewayExpanded,
|
|
2480
|
+
"aria-label": gatewayExpanded ? "Collapse gateway data" : "Expand gateway data",
|
|
2481
|
+
children: [
|
|
2482
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg", children: "Gateway data" }),
|
|
2483
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: gatewayExpanded ? "Collapse" : "Expand" })
|
|
2484
|
+
]
|
|
2485
|
+
}
|
|
2486
|
+
),
|
|
2487
|
+
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." }) })
|
|
2488
|
+
] })
|
|
2489
|
+
] }) : null
|
|
2490
|
+
] }) });
|
|
2491
|
+
};
|
|
2492
|
+
const config$1 = adminSdk.defineRouteConfig({
|
|
2493
|
+
label: "Refund details",
|
|
2494
|
+
icon: icons.Receipt
|
|
2495
|
+
});
|
|
2463
2496
|
const getStatusBadgeClass = (status) => {
|
|
2464
2497
|
const statusLower = status.toLowerCase();
|
|
2465
2498
|
if (statusLower === "requested") {
|
|
@@ -2756,14 +2789,14 @@ const routeModule = {
|
|
|
2756
2789
|
Component: PaymentsPage,
|
|
2757
2790
|
path: "/payments"
|
|
2758
2791
|
},
|
|
2759
|
-
{
|
|
2760
|
-
Component: RefundsPage,
|
|
2761
|
-
path: "/refunds"
|
|
2762
|
-
},
|
|
2763
2792
|
{
|
|
2764
2793
|
Component: ReturnsPage,
|
|
2765
2794
|
path: "/returns"
|
|
2766
2795
|
},
|
|
2796
|
+
{
|
|
2797
|
+
Component: RefundsPage,
|
|
2798
|
+
path: "/refunds"
|
|
2799
|
+
},
|
|
2767
2800
|
{
|
|
2768
2801
|
Component: SwapsPage,
|
|
2769
2802
|
path: "/swaps"
|
|
@@ -2772,14 +2805,14 @@ const routeModule = {
|
|
|
2772
2805
|
Component: PaymentDetailPage,
|
|
2773
2806
|
path: "/payments/:id"
|
|
2774
2807
|
},
|
|
2775
|
-
{
|
|
2776
|
-
Component: RefundDetailPage,
|
|
2777
|
-
path: "/refunds/:id"
|
|
2778
|
-
},
|
|
2779
2808
|
{
|
|
2780
2809
|
Component: ReturnDetailPage,
|
|
2781
2810
|
path: "/returns/:id"
|
|
2782
2811
|
},
|
|
2812
|
+
{
|
|
2813
|
+
Component: RefundDetailPage,
|
|
2814
|
+
path: "/refunds/:id"
|
|
2815
|
+
},
|
|
2783
2816
|
{
|
|
2784
2817
|
Component: SwapDetailPage,
|
|
2785
2818
|
path: "/swaps/:id"
|
|
@@ -2791,12 +2824,6 @@ const menuItemModule = {
|
|
|
2791
2824
|
{
|
|
2792
2825
|
label: config$6.label,
|
|
2793
2826
|
icon: config$6.icon,
|
|
2794
|
-
path: "/refunds",
|
|
2795
|
-
nested: void 0
|
|
2796
|
-
},
|
|
2797
|
-
{
|
|
2798
|
-
label: config$5.label,
|
|
2799
|
-
icon: config$5.icon,
|
|
2800
2827
|
path: "/returns",
|
|
2801
2828
|
nested: void 0
|
|
2802
2829
|
},
|
|
@@ -2813,14 +2840,14 @@ const menuItemModule = {
|
|
|
2813
2840
|
nested: void 0
|
|
2814
2841
|
},
|
|
2815
2842
|
{
|
|
2816
|
-
label: config$
|
|
2817
|
-
icon: config$
|
|
2818
|
-
path: "/refunds
|
|
2843
|
+
label: config$5.label,
|
|
2844
|
+
icon: config$5.icon,
|
|
2845
|
+
path: "/refunds",
|
|
2819
2846
|
nested: void 0
|
|
2820
2847
|
},
|
|
2821
2848
|
{
|
|
2822
|
-
label: config$
|
|
2823
|
-
icon: config$
|
|
2849
|
+
label: config$2.label,
|
|
2850
|
+
icon: config$2.icon,
|
|
2824
2851
|
path: "/returns/:id",
|
|
2825
2852
|
nested: void 0
|
|
2826
2853
|
},
|
|
@@ -2835,6 +2862,12 @@ const menuItemModule = {
|
|
|
2835
2862
|
icon: config$3.icon,
|
|
2836
2863
|
path: "/payments/:id",
|
|
2837
2864
|
nested: void 0
|
|
2865
|
+
},
|
|
2866
|
+
{
|
|
2867
|
+
label: config$1.label,
|
|
2868
|
+
icon: config$1.icon,
|
|
2869
|
+
path: "/refunds/:id",
|
|
2870
|
+
nested: void 0
|
|
2838
2871
|
}
|
|
2839
2872
|
]
|
|
2840
2873
|
};
|