order-management 0.0.92 → 0.0.93
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 +587 -569
- package/.medusa/server/src/admin/index.mjs +588 -570
- package/.medusa/server/src/api/admin/orders/[order_id]/refund-context/route.js +134 -4
- package/.medusa/server/src/api/admin/payment-transactions/validators.js +2 -2
- package/.medusa/server/src/api/admin/refund-payment-mapping/validators.js +2 -2
- package/.medusa/server/src/api/admin/refunds/validators.js +2 -2
- package/.medusa/server/src/api/admin/return/[id]/reject/route.js +3 -3
- package/.medusa/server/src/api/admin/return/[id]/route.js +10 -5
- package/.medusa/server/src/api/admin/return/route.js +4 -10
- package/.medusa/server/src/api/admin/return/validators.js +2 -2
- package/.medusa/server/src/api/admin/swaps/validators.js +3 -3
- package/.medusa/server/src/api/store/guest-orders/[id]/payment-details/route.js +161 -0
- package/.medusa/server/src/api/store/guest-orders/[id]/returns/[return_id]/refund-payment/route.js +132 -0
- package/.medusa/server/src/api/store/guest-orders/[id]/returns/route.js +132 -12
- package/.medusa/server/src/api/store/guest-orders/[id]/swaps/route.js +2 -2
- package/.medusa/server/src/api/store/orders/[order_id]/refund-payment-mappings/route.js +9 -4
- package/.medusa/server/src/api/store/payment-details/validators.js +63 -31
- package/.medusa/server/src/api/store/returns/[id]/route.js +16 -9
- package/.medusa/server/src/api/store/returns/route.js +39 -15
- package/.medusa/server/src/api/store/returns/validators.js +15 -3
- package/.medusa/server/src/api/store/swaps/route.js +2 -2
- package/.medusa/server/src/api/store/validators/cancel-order.js +2 -2
- package/.medusa/server/src/helpers/resolve-return-refund-payment.js +66 -0
- package/.medusa/server/src/helpers/returns.js +140 -2
- package/README.md +23 -4
- package/package.json +17 -17
|
@@ -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 { Text, Container, Heading, Badge, Button, Label, Select, Textarea, Input } from "@medusajs/ui";
|
|
5
|
-
import { CashSolid, PencilSquareSolid, Trash, CreditCard,
|
|
5
|
+
import { CashSolid, PencilSquareSolid, Trash, CreditCard, Receipt, 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();
|
|
@@ -374,15 +374,14 @@ const s = {
|
|
|
374
374
|
const OrderGiftItemsWidget = ({ data }) => {
|
|
375
375
|
const [fetchedItems, setFetchedItems] = useState(null);
|
|
376
376
|
useEffect(() => {
|
|
377
|
-
if (!
|
|
377
|
+
if (!data?.id) return;
|
|
378
378
|
fetch(
|
|
379
379
|
`/admin/orders/${data.id}?fields=*items,items.metadata`
|
|
380
|
-
).then((r) => r.json()).then(({ order }) => setFetchedItems(
|
|
381
|
-
}, [data
|
|
382
|
-
const items = fetchedItems ??
|
|
380
|
+
).then((r) => r.json()).then(({ order }) => setFetchedItems(order?.items ?? [])).catch(() => setFetchedItems(data?.items ?? []));
|
|
381
|
+
}, [data?.id]);
|
|
382
|
+
const items = fetchedItems ?? data?.items ?? [];
|
|
383
383
|
const giftedItems = items.filter((i) => {
|
|
384
|
-
|
|
385
|
-
const flag = (_a = i.metadata) == null ? void 0 : _a.is_gift;
|
|
384
|
+
const flag = i.metadata?.is_gift;
|
|
386
385
|
return flag === "true" || flag === true;
|
|
387
386
|
});
|
|
388
387
|
return /* @__PURE__ */ jsxs("div", { style: s.widget, children: [
|
|
@@ -411,9 +410,9 @@ const OrderGiftItemsWidget = ({ data }) => {
|
|
|
411
410
|
),
|
|
412
411
|
giftedItems.map((item) => {
|
|
413
412
|
const meta = item.metadata;
|
|
414
|
-
const from = meta
|
|
415
|
-
const to = meta
|
|
416
|
-
const message = meta
|
|
413
|
+
const from = meta?.gift_from;
|
|
414
|
+
const to = meta?.gift_to;
|
|
415
|
+
const message = meta?.gift_message;
|
|
417
416
|
return /* @__PURE__ */ jsxs("div", { style: s.card, children: [
|
|
418
417
|
/* @__PURE__ */ jsxs("div", { style: s.ribbon, children: [
|
|
419
418
|
/* @__PURE__ */ jsx("span", { style: s.bowCenter, children: "🎀" }),
|
|
@@ -477,7 +476,7 @@ function formatRefundCurrency(amount, currencyCode = "inr", options) {
|
|
|
477
476
|
minimumFractionDigits: 2,
|
|
478
477
|
maximumFractionDigits: 2
|
|
479
478
|
}).format(amount);
|
|
480
|
-
if (
|
|
479
|
+
if (options?.signed && amount > 0) {
|
|
481
480
|
return `−${formatted}`;
|
|
482
481
|
}
|
|
483
482
|
return formatted;
|
|
@@ -532,8 +531,7 @@ function getOrderIdFromPath() {
|
|
|
532
531
|
return m ? m[1] : void 0;
|
|
533
532
|
}
|
|
534
533
|
const OrderRefundContextWidget = (props) => {
|
|
535
|
-
|
|
536
|
-
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();
|
|
534
|
+
const orderId = props.order?.id ?? props.data?.order?.id ?? getOrderIdFromPath();
|
|
537
535
|
const [context, setContext] = useState(null);
|
|
538
536
|
const [loading, setLoading] = useState(!!orderId);
|
|
539
537
|
const [error, setError] = useState(null);
|
|
@@ -571,7 +569,7 @@ const OrderRefundContextWidget = (props) => {
|
|
|
571
569
|
};
|
|
572
570
|
}, [orderId]);
|
|
573
571
|
const handleMarkRefunded = async () => {
|
|
574
|
-
if (!
|
|
572
|
+
if (!context?.return_id || !context?.refund_mapping || context.refund_mapping.is_refunded || !context.can_process_refund) {
|
|
575
573
|
return;
|
|
576
574
|
}
|
|
577
575
|
setMarking(true);
|
|
@@ -588,17 +586,14 @@ const OrderRefundContextWidget = (props) => {
|
|
|
588
586
|
}
|
|
589
587
|
const data = await res.json();
|
|
590
588
|
setContext(
|
|
591
|
-
(prev) => {
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
}
|
|
600
|
-
} : prev;
|
|
601
|
-
}
|
|
589
|
+
(prev) => prev && prev.refund_mapping ? {
|
|
590
|
+
...prev,
|
|
591
|
+
can_process_refund: false,
|
|
592
|
+
refund_mapping: {
|
|
593
|
+
...prev.refund_mapping,
|
|
594
|
+
is_refunded: data.refund_payment_mapping?.is_refunded ?? true
|
|
595
|
+
}
|
|
596
|
+
} : prev
|
|
602
597
|
);
|
|
603
598
|
} catch (e) {
|
|
604
599
|
setMarkError(e instanceof Error ? e.message : "Failed to mark refunded");
|
|
@@ -607,20 +602,19 @@ const OrderRefundContextWidget = (props) => {
|
|
|
607
602
|
}
|
|
608
603
|
};
|
|
609
604
|
const handleEditClick = () => {
|
|
610
|
-
const mapping = context
|
|
611
|
-
const mode = mapping
|
|
605
|
+
const mapping = context?.refund_mapping;
|
|
606
|
+
const mode = mapping?.refund_mode;
|
|
612
607
|
setEditRefundMode(
|
|
613
608
|
mode === "offline" || mode === "online" ? mode : ""
|
|
614
609
|
);
|
|
615
|
-
setEditDetails(
|
|
616
|
-
setEditImageUrls(
|
|
610
|
+
setEditDetails(mapping?.details ?? "");
|
|
611
|
+
setEditImageUrls(mapping?.images ?? []);
|
|
617
612
|
setSaveError(null);
|
|
618
613
|
setUploadError(null);
|
|
619
614
|
setEditing(true);
|
|
620
615
|
};
|
|
621
616
|
const handleUploadImage = async (e) => {
|
|
622
|
-
|
|
623
|
-
const file = (_a2 = e.target.files) == null ? void 0 : _a2[0];
|
|
617
|
+
const file = e.target.files?.[0];
|
|
624
618
|
if (!file) return;
|
|
625
619
|
setUploading(true);
|
|
626
620
|
setUploadError(null);
|
|
@@ -637,7 +631,7 @@ const OrderRefundContextWidget = (props) => {
|
|
|
637
631
|
throw new Error(data2.message || "Upload failed");
|
|
638
632
|
}
|
|
639
633
|
const data = await res.json();
|
|
640
|
-
const url =
|
|
634
|
+
const url = data.files?.[0]?.url;
|
|
641
635
|
if (url) setEditImageUrls((prev) => [...prev, url]);
|
|
642
636
|
} catch (err) {
|
|
643
637
|
setUploadError(err instanceof Error ? err.message : "Upload failed");
|
|
@@ -650,7 +644,7 @@ const OrderRefundContextWidget = (props) => {
|
|
|
650
644
|
setEditImageUrls((prev) => prev.filter((_, i) => i !== index));
|
|
651
645
|
};
|
|
652
646
|
const handleSaveAdminFields = async () => {
|
|
653
|
-
if (!
|
|
647
|
+
if (!context?.return_id) return;
|
|
654
648
|
setSaving(true);
|
|
655
649
|
setSaveError(null);
|
|
656
650
|
try {
|
|
@@ -687,13 +681,14 @@ const OrderRefundContextWidget = (props) => {
|
|
|
687
681
|
if (error) {
|
|
688
682
|
return /* @__PURE__ */ jsx(Container, { className: "mt-6 divide-y p-0", children: /* @__PURE__ */ jsx("div", { className: "py-4", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-error", children: error }) }) });
|
|
689
683
|
}
|
|
690
|
-
const hasReturn = !!
|
|
691
|
-
const hasMapping = !!
|
|
692
|
-
const canMarkRefunded = Boolean(context
|
|
693
|
-
const returnStatus =
|
|
694
|
-
const showReceiveFirstHint = hasReturn && !
|
|
695
|
-
const paymentDetail = context
|
|
696
|
-
const
|
|
684
|
+
const hasReturn = !!context?.return_id;
|
|
685
|
+
const hasMapping = !!context?.refund_mapping;
|
|
686
|
+
const canMarkRefunded = Boolean(context?.can_process_refund);
|
|
687
|
+
const returnStatus = context?.return_status ?? null;
|
|
688
|
+
const showReceiveFirstHint = hasReturn && !context?.refund_mapping?.is_refunded && returnStatus !== "received" && returnStatus !== "canceled";
|
|
689
|
+
const paymentDetail = context?.payment_detail;
|
|
690
|
+
const paymentDetails = context?.payment_details && context.payment_details.length > 0 ? context.payment_details : paymentDetail ? [paymentDetail] : [];
|
|
691
|
+
const orderPayment = context?.order_payment;
|
|
697
692
|
return /* @__PURE__ */ jsx(Container, { className: "mt-6 divide-y p-0", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 py-4", children: [
|
|
698
693
|
/* @__PURE__ */ jsxs(Heading, { level: "h2", className: "flex items-center gap-2", children: [
|
|
699
694
|
/* @__PURE__ */ jsx(CashSolid, { className: "text-ui-fg-subtle" }),
|
|
@@ -705,7 +700,7 @@ const OrderRefundContextWidget = (props) => {
|
|
|
705
700
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
706
701
|
/* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", className: "text-ui-fg-subtle", children: "Return" }),
|
|
707
702
|
/* @__PURE__ */ jsx(Text, { size: "small", children: context.return_id }),
|
|
708
|
-
|
|
703
|
+
context.refund_mapping?.is_refunded ? /* @__PURE__ */ jsx(Badge, { color: "green", children: "Refunded" }) : /* @__PURE__ */ jsx(Badge, { color: "orange", children: "Not refunded" })
|
|
709
704
|
] }),
|
|
710
705
|
context.refund ? /* @__PURE__ */ jsx("div", { className: "mt-3 border-t border-ui-border-base pt-3", children: /* @__PURE__ */ jsx(RefundCalculationBlock, { refund: context.refund }) }) : null,
|
|
711
706
|
orderPayment && /* @__PURE__ */ jsxs("div", { className: "mt-3 space-y-2 border-t border-ui-border-base pt-3", children: [
|
|
@@ -719,29 +714,29 @@ const OrderRefundContextWidget = (props) => {
|
|
|
719
714
|
/* @__PURE__ */ jsxs("div", { className: "mt-3 space-y-2 border-t border-ui-border-base pt-3", children: [
|
|
720
715
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
721
716
|
/* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", className: "text-ui-fg-subtle", children: "Payment method (refund destination)" }),
|
|
722
|
-
|
|
717
|
+
context.refund_mapping?.payment_id ? /* @__PURE__ */ jsx(Badge, { color: "green", children: "Customer specified" }) : paymentDetail ? /* @__PURE__ */ jsx(Badge, { color: "orange", children: "Customer default" }) : orderPayment && !orderPayment.is_cod ? /* @__PURE__ */ jsx(Badge, { color: "blue", children: "Original payment method" }) : null
|
|
723
718
|
] }),
|
|
724
|
-
|
|
725
|
-
!
|
|
726
|
-
!
|
|
719
|
+
context.refund_mapping?.payment_id && !paymentDetail && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-orange-200 bg-orange-50 px-3 py-2", children: /* @__PURE__ */ jsx(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." }) }),
|
|
720
|
+
!context.refund_mapping?.payment_id && paymentDetail?.source === "default" && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-ui-border-base bg-ui-bg-subtle px-3 py-2", children: /* @__PURE__ */ jsx(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." }) }),
|
|
721
|
+
!context.refund_mapping?.payment_id && !paymentDetail && orderPayment && !orderPayment.is_cod && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-ui-border-base bg-ui-bg-subtle px-3 py-2", children: /* @__PURE__ */ jsxs(Text, { size: "xsmall", className: "text-ui-fg-muted", children: [
|
|
727
722
|
"Refund will go to the original payment method (",
|
|
728
723
|
orderPayment.label,
|
|
729
724
|
")."
|
|
730
725
|
] }) }),
|
|
731
|
-
!
|
|
732
|
-
!
|
|
733
|
-
|
|
726
|
+
!context.refund_mapping?.payment_id && !paymentDetail && (context.is_cod || orderPayment?.is_cod) && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-ui-border-base bg-ui-bg-subtle px-3 py-2", children: /* @__PURE__ */ jsx(Text, { size: "xsmall", className: "text-ui-fg-muted", children: "This order was paid with Cash on Delivery. No stored bank/UPI refund destination." }) }),
|
|
727
|
+
!context.refund_mapping?.payment_id && !paymentDetail && !orderPayment && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-ui-border-base bg-ui-bg-subtle px-3 py-2", children: /* @__PURE__ */ jsx(Text, { size: "xsmall", className: "text-ui-fg-muted", children: "No payment method found for this customer." }) }),
|
|
728
|
+
paymentDetails.length > 0 && /* @__PURE__ */ jsx("div", { className: "space-y-3", children: paymentDetails.map((detail) => /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
734
729
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
|
|
735
|
-
/* @__PURE__ */ jsx(Badge, { children:
|
|
736
|
-
|
|
730
|
+
/* @__PURE__ */ jsx(Badge, { children: detail.type.toUpperCase() }),
|
|
731
|
+
detail.is_default && /* @__PURE__ */ jsx(Badge, { color: "blue", children: "Default" })
|
|
737
732
|
] }),
|
|
738
|
-
Object.keys(
|
|
733
|
+
Object.keys(detail.detail_json).length > 0 && /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-x-6 gap-y-2", children: Object.entries(detail.detail_json).map(([k, v]) => /* @__PURE__ */ jsxs("div", { children: [
|
|
739
734
|
/* @__PURE__ */ jsx(Text, { size: "xsmall", weight: "plus", className: "text-ui-fg-muted", children: FIELD_LABELS[k] ?? k }),
|
|
740
735
|
/* @__PURE__ */ jsx(Text, { size: "small", className: "block", children: String(v) })
|
|
741
|
-
] }, k)) })
|
|
742
|
-
] })
|
|
736
|
+
] }, `${detail.id}-${k}`)) })
|
|
737
|
+
] }, detail.id)) })
|
|
743
738
|
] }),
|
|
744
|
-
|
|
739
|
+
context?.refund_mapping && /* @__PURE__ */ jsxs("div", { className: "mt-3 space-y-3 border-t border-ui-border-base pt-3", children: [
|
|
745
740
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
746
741
|
/* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", className: "text-ui-fg-subtle", children: "Refund mode, details & images" }),
|
|
747
742
|
!editing ? /* @__PURE__ */ jsxs(
|
|
@@ -829,10 +824,7 @@ const OrderRefundContextWidget = (props) => {
|
|
|
829
824
|
variant: "secondary",
|
|
830
825
|
type: "button",
|
|
831
826
|
disabled: uploading,
|
|
832
|
-
onClick: () =>
|
|
833
|
-
var _a2;
|
|
834
|
-
return (_a2 = fileInputRef.current) == null ? void 0 : _a2.click();
|
|
835
|
-
},
|
|
827
|
+
onClick: () => fileInputRef.current?.click(),
|
|
836
828
|
children: uploading ? "Uploading…" : "Upload image"
|
|
837
829
|
}
|
|
838
830
|
),
|
|
@@ -883,7 +875,7 @@ const OrderRefundContextWidget = (props) => {
|
|
|
883
875
|
] }),
|
|
884
876
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
885
877
|
/* @__PURE__ */ jsx(Text, { size: "xsmall", weight: "plus", className: "text-ui-fg-muted", children: "Images" }),
|
|
886
|
-
|
|
878
|
+
context.refund_mapping.images?.length ? /* @__PURE__ */ jsx("div", { className: "mt-1 flex flex-wrap gap-2", children: context.refund_mapping.images.map((url, i) => /* @__PURE__ */ jsxs(
|
|
887
879
|
"a",
|
|
888
880
|
{
|
|
889
881
|
href: url,
|
|
@@ -913,10 +905,10 @@ const OrderRefundContextWidget = (props) => {
|
|
|
913
905
|
),
|
|
914
906
|
markError && /* @__PURE__ */ jsx(Text, { size: "small", className: "mt-2 text-ui-fg-error", children: markError })
|
|
915
907
|
] }),
|
|
916
|
-
hasMapping && !canMarkRefunded && !
|
|
908
|
+
hasMapping && !canMarkRefunded && !context.refund_mapping?.is_refunded && showReceiveFirstHint && /* @__PURE__ */ jsx(Text, { size: "small", className: "mt-4 text-ui-fg-muted", children: "Mark refunded is available after the return is received." })
|
|
917
909
|
] }),
|
|
918
910
|
hasReturn && !hasMapping && /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-4", children: [
|
|
919
|
-
|
|
911
|
+
context?.refund ? /* @__PURE__ */ jsx(RefundCalculationBlock, { refund: context.refund }) : null,
|
|
920
912
|
orderPayment && /* @__PURE__ */ jsxs("div", { className: "mb-3 space-y-1", children: [
|
|
921
913
|
/* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", className: "text-ui-fg-subtle", children: "Order payment method" }),
|
|
922
914
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
@@ -1140,248 +1132,6 @@ const useDebounce$2 = (value, delay) => {
|
|
|
1140
1132
|
return debouncedValue;
|
|
1141
1133
|
};
|
|
1142
1134
|
const getStatusBadgeClass$6 = (status) => {
|
|
1143
|
-
const statusLower = status.toLowerCase();
|
|
1144
|
-
if (statusLower === "requested") {
|
|
1145
|
-
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
1146
|
-
}
|
|
1147
|
-
if (statusLower === "received") {
|
|
1148
|
-
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
1149
|
-
}
|
|
1150
|
-
if (statusLower === "requires_action") {
|
|
1151
|
-
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
1152
|
-
}
|
|
1153
|
-
if (statusLower === "completed") {
|
|
1154
|
-
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1155
|
-
}
|
|
1156
|
-
if (statusLower === "canceled") {
|
|
1157
|
-
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
1158
|
-
}
|
|
1159
|
-
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
1160
|
-
};
|
|
1161
|
-
const ReturnsPage = () => {
|
|
1162
|
-
const navigate = useNavigate();
|
|
1163
|
-
const [items, setItems] = useState([]);
|
|
1164
|
-
const [statusFilter, setStatusFilter] = useState("all");
|
|
1165
|
-
const [createdByFilter, setCreatedByFilter] = useState("all");
|
|
1166
|
-
const [searchQuery, setSearchQuery] = useState("");
|
|
1167
|
-
const debouncedSearchQuery = useDebounce$2(searchQuery, 300);
|
|
1168
|
-
const [isLoading, setIsLoading] = useState(true);
|
|
1169
|
-
const [isFetchingMore, setIsFetchingMore] = useState(false);
|
|
1170
|
-
const [error, setError] = useState(null);
|
|
1171
|
-
const [offset, setOffset] = useState(0);
|
|
1172
|
-
const [count, setCount] = useState(0);
|
|
1173
|
-
const limit = 50;
|
|
1174
|
-
const loadReturns = useCallback(
|
|
1175
|
-
async (nextOffset, replace = false) => {
|
|
1176
|
-
var _a;
|
|
1177
|
-
try {
|
|
1178
|
-
if (replace) {
|
|
1179
|
-
setIsLoading(true);
|
|
1180
|
-
} else {
|
|
1181
|
-
setIsFetchingMore(true);
|
|
1182
|
-
}
|
|
1183
|
-
setError(null);
|
|
1184
|
-
const params = new URLSearchParams();
|
|
1185
|
-
params.set("limit", String(limit));
|
|
1186
|
-
params.set("offset", String(nextOffset));
|
|
1187
|
-
if (statusFilter !== "all") {
|
|
1188
|
-
params.set("status", statusFilter);
|
|
1189
|
-
}
|
|
1190
|
-
if (debouncedSearchQuery.trim()) {
|
|
1191
|
-
params.set("q", debouncedSearchQuery.trim());
|
|
1192
|
-
}
|
|
1193
|
-
if (createdByFilter !== "all") {
|
|
1194
|
-
params.set("created_by", createdByFilter);
|
|
1195
|
-
}
|
|
1196
|
-
params.set("order", "created_at");
|
|
1197
|
-
const response = await fetch(
|
|
1198
|
-
`/admin/return?${params.toString()}`,
|
|
1199
|
-
{ credentials: "include" }
|
|
1200
|
-
);
|
|
1201
|
-
if (!response.ok) {
|
|
1202
|
-
const message = await response.text();
|
|
1203
|
-
throw new Error(message || "Unable to load return orders");
|
|
1204
|
-
}
|
|
1205
|
-
const payload = await response.json();
|
|
1206
|
-
setCount(payload.count ?? 0);
|
|
1207
|
-
setOffset(nextOffset + (((_a = payload.returns) == null ? void 0 : _a.length) ?? 0));
|
|
1208
|
-
setItems(
|
|
1209
|
-
(prev) => replace ? payload.returns ?? [] : [...prev, ...payload.returns ?? []]
|
|
1210
|
-
);
|
|
1211
|
-
} catch (loadError) {
|
|
1212
|
-
const message = loadError instanceof Error ? loadError.message : "Unable to load return orders";
|
|
1213
|
-
setError(message);
|
|
1214
|
-
} finally {
|
|
1215
|
-
setIsLoading(false);
|
|
1216
|
-
setIsFetchingMore(false);
|
|
1217
|
-
}
|
|
1218
|
-
},
|
|
1219
|
-
[statusFilter, createdByFilter, debouncedSearchQuery]
|
|
1220
|
-
);
|
|
1221
|
-
useEffect(() => {
|
|
1222
|
-
void loadReturns(0, true);
|
|
1223
|
-
}, [statusFilter, createdByFilter, debouncedSearchQuery, loadReturns]);
|
|
1224
|
-
const hasMore = useMemo(() => offset < count, [offset, count]);
|
|
1225
|
-
const availableStatuses = useMemo(() => {
|
|
1226
|
-
const statuses = /* @__PURE__ */ new Set();
|
|
1227
|
-
items.forEach((item) => statuses.add(item.status));
|
|
1228
|
-
return Array.from(statuses).sort();
|
|
1229
|
-
}, [items]);
|
|
1230
|
-
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: [
|
|
1231
|
-
/* @__PURE__ */ jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1232
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1233
|
-
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "Return Orders" }),
|
|
1234
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer return orders" })
|
|
1235
|
-
] }),
|
|
1236
|
-
/* @__PURE__ */ jsx(Button, { variant: "primary", onClick: () => loadReturns(0, true), children: "Refresh" })
|
|
1237
|
-
] }),
|
|
1238
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1239
|
-
/* @__PURE__ */ jsx(
|
|
1240
|
-
Input,
|
|
1241
|
-
{
|
|
1242
|
-
placeholder: "Search by return ID, order ID, or customer email",
|
|
1243
|
-
value: searchQuery,
|
|
1244
|
-
onChange: (event) => setSearchQuery(event.target.value),
|
|
1245
|
-
className: "md:max-w-sm"
|
|
1246
|
-
}
|
|
1247
|
-
),
|
|
1248
|
-
/* @__PURE__ */ jsxs("div", { className: "flex gap-3", children: [
|
|
1249
|
-
/* @__PURE__ */ jsxs(
|
|
1250
|
-
"select",
|
|
1251
|
-
{
|
|
1252
|
-
value: createdByFilter,
|
|
1253
|
-
onChange: (event) => setCreatedByFilter(event.target.value),
|
|
1254
|
-
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",
|
|
1255
|
-
children: [
|
|
1256
|
-
/* @__PURE__ */ jsx("option", { value: "all", children: "All (Created by)" }),
|
|
1257
|
-
/* @__PURE__ */ jsx("option", { value: "customer", children: "Customer" }),
|
|
1258
|
-
/* @__PURE__ */ jsx("option", { value: "admin", children: "Admin" })
|
|
1259
|
-
]
|
|
1260
|
-
}
|
|
1261
|
-
),
|
|
1262
|
-
/* @__PURE__ */ jsxs(
|
|
1263
|
-
"select",
|
|
1264
|
-
{
|
|
1265
|
-
value: statusFilter,
|
|
1266
|
-
onChange: (event) => setStatusFilter(event.target.value),
|
|
1267
|
-
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",
|
|
1268
|
-
children: [
|
|
1269
|
-
/* @__PURE__ */ jsx("option", { value: "all", children: "All Statuses" }),
|
|
1270
|
-
availableStatuses.map((status) => /* @__PURE__ */ jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
|
|
1271
|
-
]
|
|
1272
|
-
}
|
|
1273
|
-
)
|
|
1274
|
-
] })
|
|
1275
|
-
] }),
|
|
1276
|
-
error ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
1277
|
-
/* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
1278
|
-
/* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx(
|
|
1279
|
-
Button,
|
|
1280
|
-
{
|
|
1281
|
-
variant: "secondary",
|
|
1282
|
-
onClick: () => loadReturns(0, true),
|
|
1283
|
-
children: "Try again"
|
|
1284
|
-
}
|
|
1285
|
-
) })
|
|
1286
|
-
] }) : null,
|
|
1287
|
-
isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading return orders..." }) }) : items.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
|
|
1288
|
-
/* @__PURE__ */ jsx(Heading, { level: "h3", className: "text-xl", children: "No return orders yet" }),
|
|
1289
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Return orders created by customers will appear here." })
|
|
1290
|
-
] }) : /* @__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: [
|
|
1291
|
-
/* @__PURE__ */ jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
1292
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Return ID" }),
|
|
1293
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
|
|
1294
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Customer" }),
|
|
1295
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
|
|
1296
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Refund Amount" }),
|
|
1297
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
1298
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
1299
|
-
] }) }),
|
|
1300
|
-
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((returnOrder) => /* @__PURE__ */ jsxs(
|
|
1301
|
-
"tr",
|
|
1302
|
-
{
|
|
1303
|
-
className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
|
|
1304
|
-
onClick: () => navigate(`/returns/${returnOrder.id}`),
|
|
1305
|
-
children: [
|
|
1306
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-0.5", children: /* @__PURE__ */ jsx("span", { children: returnOrder.id }) }) }),
|
|
1307
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.order_id }),
|
|
1308
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.customer_email || returnOrder.order_email || "—" }),
|
|
1309
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsx(
|
|
1310
|
-
Badge,
|
|
1311
|
-
{
|
|
1312
|
-
size: "2xsmall",
|
|
1313
|
-
className: `uppercase ${getStatusBadgeClass$6(returnOrder.status)}`,
|
|
1314
|
-
children: returnOrder.status.replace(/_/g, " ")
|
|
1315
|
-
}
|
|
1316
|
-
) }),
|
|
1317
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
|
|
1318
|
-
const calc = returnOrder.refund;
|
|
1319
|
-
if ((calc == null ? void 0 : calc.is_processed) && calc.final_refund_amount != null) {
|
|
1320
|
-
return formatRefundCurrency(
|
|
1321
|
-
calc.final_refund_amount,
|
|
1322
|
-
calc.currency_code || returnOrder.currency_code
|
|
1323
|
-
);
|
|
1324
|
-
}
|
|
1325
|
-
if (calc) {
|
|
1326
|
-
return "Pending";
|
|
1327
|
-
}
|
|
1328
|
-
if (returnOrder.refund_amount == null) {
|
|
1329
|
-
return "—";
|
|
1330
|
-
}
|
|
1331
|
-
return formatRefundCurrency(
|
|
1332
|
-
Number(returnOrder.refund_amount),
|
|
1333
|
-
returnOrder.currency_code
|
|
1334
|
-
);
|
|
1335
|
-
})() }),
|
|
1336
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(returnOrder.created_at).toLocaleDateString("en-US", {
|
|
1337
|
-
year: "numeric",
|
|
1338
|
-
month: "short",
|
|
1339
|
-
day: "numeric",
|
|
1340
|
-
hour: "numeric",
|
|
1341
|
-
minute: "2-digit",
|
|
1342
|
-
hour12: true
|
|
1343
|
-
}) }),
|
|
1344
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsx(
|
|
1345
|
-
Button,
|
|
1346
|
-
{
|
|
1347
|
-
variant: "transparent",
|
|
1348
|
-
size: "small",
|
|
1349
|
-
onClick: (e) => {
|
|
1350
|
-
e.stopPropagation();
|
|
1351
|
-
navigate(`/app/orders/${returnOrder.order_id}`);
|
|
1352
|
-
},
|
|
1353
|
-
children: "Go to order"
|
|
1354
|
-
}
|
|
1355
|
-
) })
|
|
1356
|
-
]
|
|
1357
|
-
},
|
|
1358
|
-
returnOrder.id
|
|
1359
|
-
)) })
|
|
1360
|
-
] }) }),
|
|
1361
|
-
hasMore ? /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(
|
|
1362
|
-
Button,
|
|
1363
|
-
{
|
|
1364
|
-
variant: "secondary",
|
|
1365
|
-
isLoading: isFetchingMore,
|
|
1366
|
-
onClick: () => loadReturns(offset, false),
|
|
1367
|
-
children: "Load more"
|
|
1368
|
-
}
|
|
1369
|
-
) }) : null
|
|
1370
|
-
] }) });
|
|
1371
|
-
};
|
|
1372
|
-
const config$6 = defineRouteConfig({
|
|
1373
|
-
label: "Return Orders",
|
|
1374
|
-
icon: ArrowPath
|
|
1375
|
-
});
|
|
1376
|
-
const useDebounce$1 = (value, delay) => {
|
|
1377
|
-
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
1378
|
-
useEffect(() => {
|
|
1379
|
-
const handler = setTimeout(() => setDebouncedValue(value), delay);
|
|
1380
|
-
return () => clearTimeout(handler);
|
|
1381
|
-
}, [value, delay]);
|
|
1382
|
-
return debouncedValue;
|
|
1383
|
-
};
|
|
1384
|
-
const getStatusBadgeClass$5 = (status) => {
|
|
1385
1135
|
const s2 = status.toLowerCase();
|
|
1386
1136
|
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1387
1137
|
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
@@ -1393,12 +1143,12 @@ const RefundsPage = () => {
|
|
|
1393
1143
|
const navigate = useNavigate();
|
|
1394
1144
|
const [items, setItems] = useState([]);
|
|
1395
1145
|
const [orderIdSearch, setOrderIdSearch] = useState("");
|
|
1396
|
-
const debouncedOrderId = useDebounce$
|
|
1146
|
+
const debouncedOrderId = useDebounce$2(orderIdSearch, 300);
|
|
1397
1147
|
const [paymentStatusFilter, setPaymentStatusFilter] = useState("all");
|
|
1398
1148
|
const [providerSearch, setProviderSearch] = useState("");
|
|
1399
|
-
const debouncedProvider = useDebounce$
|
|
1149
|
+
const debouncedProvider = useDebounce$2(providerSearch, 300);
|
|
1400
1150
|
const [currencySearch, setCurrencySearch] = useState("");
|
|
1401
|
-
const debouncedCurrency = useDebounce$
|
|
1151
|
+
const debouncedCurrency = useDebounce$2(currencySearch, 300);
|
|
1402
1152
|
const [dateFrom, setDateFrom] = useState("");
|
|
1403
1153
|
const [dateTo, setDateTo] = useState("");
|
|
1404
1154
|
const [amountMin, setAmountMin] = useState("");
|
|
@@ -1610,7 +1360,7 @@ const RefundsPage = () => {
|
|
|
1610
1360
|
Badge,
|
|
1611
1361
|
{
|
|
1612
1362
|
size: "2xsmall",
|
|
1613
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
1363
|
+
className: `uppercase ${getStatusBadgeClass$6(displayStatus(r))}`,
|
|
1614
1364
|
children: displayStatus(r) !== "—" ? displayStatus(r).replace(/_/g, " ") : "—"
|
|
1615
1365
|
}
|
|
1616
1366
|
) }),
|
|
@@ -1664,11 +1414,11 @@ const RefundsPage = () => {
|
|
|
1664
1414
|
) }) : null
|
|
1665
1415
|
] }) });
|
|
1666
1416
|
};
|
|
1667
|
-
const config$
|
|
1417
|
+
const config$6 = defineRouteConfig({
|
|
1668
1418
|
label: "Refunds",
|
|
1669
1419
|
icon: Receipt
|
|
1670
1420
|
});
|
|
1671
|
-
const useDebounce = (value, delay) => {
|
|
1421
|
+
const useDebounce$1 = (value, delay) => {
|
|
1672
1422
|
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
1673
1423
|
useEffect(() => {
|
|
1674
1424
|
const handler = setTimeout(() => setDebouncedValue(value), delay);
|
|
@@ -1676,26 +1426,267 @@ const useDebounce = (value, delay) => {
|
|
|
1676
1426
|
}, [value, delay]);
|
|
1677
1427
|
return debouncedValue;
|
|
1678
1428
|
};
|
|
1679
|
-
const getStatusBadgeClass$
|
|
1429
|
+
const getStatusBadgeClass$5 = (status) => {
|
|
1680
1430
|
const statusLower = status.toLowerCase();
|
|
1681
1431
|
if (statusLower === "requested") {
|
|
1682
1432
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
1683
1433
|
}
|
|
1684
|
-
if (statusLower === "
|
|
1434
|
+
if (statusLower === "received") {
|
|
1685
1435
|
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
1686
1436
|
}
|
|
1687
|
-
if (statusLower === "
|
|
1437
|
+
if (statusLower === "requires_action") {
|
|
1688
1438
|
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
1689
1439
|
}
|
|
1690
1440
|
if (statusLower === "completed") {
|
|
1691
1441
|
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1692
1442
|
}
|
|
1693
|
-
if (statusLower === "
|
|
1443
|
+
if (statusLower === "canceled") {
|
|
1694
1444
|
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
1695
1445
|
}
|
|
1696
1446
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
1697
1447
|
};
|
|
1698
|
-
const
|
|
1448
|
+
const ReturnsPage = () => {
|
|
1449
|
+
const navigate = useNavigate();
|
|
1450
|
+
const [items, setItems] = useState([]);
|
|
1451
|
+
const [statusFilter, setStatusFilter] = useState("all");
|
|
1452
|
+
const [createdByFilter, setCreatedByFilter] = useState("all");
|
|
1453
|
+
const [searchQuery, setSearchQuery] = useState("");
|
|
1454
|
+
const debouncedSearchQuery = useDebounce$1(searchQuery, 300);
|
|
1455
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
1456
|
+
const [isFetchingMore, setIsFetchingMore] = useState(false);
|
|
1457
|
+
const [error, setError] = useState(null);
|
|
1458
|
+
const [offset, setOffset] = useState(0);
|
|
1459
|
+
const [count, setCount] = useState(0);
|
|
1460
|
+
const limit = 50;
|
|
1461
|
+
const loadReturns = useCallback(
|
|
1462
|
+
async (nextOffset, replace = false) => {
|
|
1463
|
+
try {
|
|
1464
|
+
if (replace) {
|
|
1465
|
+
setIsLoading(true);
|
|
1466
|
+
} else {
|
|
1467
|
+
setIsFetchingMore(true);
|
|
1468
|
+
}
|
|
1469
|
+
setError(null);
|
|
1470
|
+
const params = new URLSearchParams();
|
|
1471
|
+
params.set("limit", String(limit));
|
|
1472
|
+
params.set("offset", String(nextOffset));
|
|
1473
|
+
if (statusFilter !== "all") {
|
|
1474
|
+
params.set("status", statusFilter);
|
|
1475
|
+
}
|
|
1476
|
+
if (debouncedSearchQuery.trim()) {
|
|
1477
|
+
params.set("q", debouncedSearchQuery.trim());
|
|
1478
|
+
}
|
|
1479
|
+
if (createdByFilter !== "all") {
|
|
1480
|
+
params.set("created_by", createdByFilter);
|
|
1481
|
+
}
|
|
1482
|
+
params.set("order", "created_at");
|
|
1483
|
+
const response = await fetch(
|
|
1484
|
+
`/admin/return?${params.toString()}`,
|
|
1485
|
+
{ credentials: "include" }
|
|
1486
|
+
);
|
|
1487
|
+
if (!response.ok) {
|
|
1488
|
+
const message = await response.text();
|
|
1489
|
+
throw new Error(message || "Unable to load return orders");
|
|
1490
|
+
}
|
|
1491
|
+
const payload = await response.json();
|
|
1492
|
+
setCount(payload.count ?? 0);
|
|
1493
|
+
setOffset(nextOffset + (payload.returns?.length ?? 0));
|
|
1494
|
+
setItems(
|
|
1495
|
+
(prev) => replace ? payload.returns ?? [] : [...prev, ...payload.returns ?? []]
|
|
1496
|
+
);
|
|
1497
|
+
} catch (loadError) {
|
|
1498
|
+
const message = loadError instanceof Error ? loadError.message : "Unable to load return orders";
|
|
1499
|
+
setError(message);
|
|
1500
|
+
} finally {
|
|
1501
|
+
setIsLoading(false);
|
|
1502
|
+
setIsFetchingMore(false);
|
|
1503
|
+
}
|
|
1504
|
+
},
|
|
1505
|
+
[statusFilter, createdByFilter, debouncedSearchQuery]
|
|
1506
|
+
);
|
|
1507
|
+
useEffect(() => {
|
|
1508
|
+
void loadReturns(0, true);
|
|
1509
|
+
}, [statusFilter, createdByFilter, debouncedSearchQuery, loadReturns]);
|
|
1510
|
+
const hasMore = useMemo(() => offset < count, [offset, count]);
|
|
1511
|
+
const availableStatuses = useMemo(() => {
|
|
1512
|
+
const statuses = /* @__PURE__ */ new Set();
|
|
1513
|
+
items.forEach((item) => statuses.add(item.status));
|
|
1514
|
+
return Array.from(statuses).sort();
|
|
1515
|
+
}, [items]);
|
|
1516
|
+
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: [
|
|
1517
|
+
/* @__PURE__ */ jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1518
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1519
|
+
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "Return Orders" }),
|
|
1520
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer return orders" })
|
|
1521
|
+
] }),
|
|
1522
|
+
/* @__PURE__ */ jsx(Button, { variant: "primary", onClick: () => loadReturns(0, true), children: "Refresh" })
|
|
1523
|
+
] }),
|
|
1524
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1525
|
+
/* @__PURE__ */ jsx(
|
|
1526
|
+
Input,
|
|
1527
|
+
{
|
|
1528
|
+
placeholder: "Search by return ID, order ID, or customer email",
|
|
1529
|
+
value: searchQuery,
|
|
1530
|
+
onChange: (event) => setSearchQuery(event.target.value),
|
|
1531
|
+
className: "md:max-w-sm"
|
|
1532
|
+
}
|
|
1533
|
+
),
|
|
1534
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-3", children: [
|
|
1535
|
+
/* @__PURE__ */ jsxs(
|
|
1536
|
+
"select",
|
|
1537
|
+
{
|
|
1538
|
+
value: createdByFilter,
|
|
1539
|
+
onChange: (event) => setCreatedByFilter(event.target.value),
|
|
1540
|
+
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",
|
|
1541
|
+
children: [
|
|
1542
|
+
/* @__PURE__ */ jsx("option", { value: "all", children: "All (Created by)" }),
|
|
1543
|
+
/* @__PURE__ */ jsx("option", { value: "customer", children: "Customer" }),
|
|
1544
|
+
/* @__PURE__ */ jsx("option", { value: "admin", children: "Admin" })
|
|
1545
|
+
]
|
|
1546
|
+
}
|
|
1547
|
+
),
|
|
1548
|
+
/* @__PURE__ */ jsxs(
|
|
1549
|
+
"select",
|
|
1550
|
+
{
|
|
1551
|
+
value: statusFilter,
|
|
1552
|
+
onChange: (event) => setStatusFilter(event.target.value),
|
|
1553
|
+
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",
|
|
1554
|
+
children: [
|
|
1555
|
+
/* @__PURE__ */ jsx("option", { value: "all", children: "All Statuses" }),
|
|
1556
|
+
availableStatuses.map((status) => /* @__PURE__ */ jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
|
|
1557
|
+
]
|
|
1558
|
+
}
|
|
1559
|
+
)
|
|
1560
|
+
] })
|
|
1561
|
+
] }),
|
|
1562
|
+
error ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
1563
|
+
/* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
1564
|
+
/* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx(
|
|
1565
|
+
Button,
|
|
1566
|
+
{
|
|
1567
|
+
variant: "secondary",
|
|
1568
|
+
onClick: () => loadReturns(0, true),
|
|
1569
|
+
children: "Try again"
|
|
1570
|
+
}
|
|
1571
|
+
) })
|
|
1572
|
+
] }) : null,
|
|
1573
|
+
isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading return orders..." }) }) : items.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
|
|
1574
|
+
/* @__PURE__ */ jsx(Heading, { level: "h3", className: "text-xl", children: "No return orders yet" }),
|
|
1575
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Return orders created by customers will appear here." })
|
|
1576
|
+
] }) : /* @__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: [
|
|
1577
|
+
/* @__PURE__ */ jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
1578
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Return ID" }),
|
|
1579
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
|
|
1580
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Customer" }),
|
|
1581
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
|
|
1582
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Refund Amount" }),
|
|
1583
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
1584
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
1585
|
+
] }) }),
|
|
1586
|
+
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((returnOrder) => /* @__PURE__ */ jsxs(
|
|
1587
|
+
"tr",
|
|
1588
|
+
{
|
|
1589
|
+
className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
|
|
1590
|
+
onClick: () => navigate(`/returns/${returnOrder.id}`),
|
|
1591
|
+
children: [
|
|
1592
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-0.5", children: /* @__PURE__ */ jsx("span", { children: returnOrder.id }) }) }),
|
|
1593
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.order_id }),
|
|
1594
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.customer_email || returnOrder.order_email || "—" }),
|
|
1595
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsx(
|
|
1596
|
+
Badge,
|
|
1597
|
+
{
|
|
1598
|
+
size: "2xsmall",
|
|
1599
|
+
className: `uppercase ${getStatusBadgeClass$5(returnOrder.status)}`,
|
|
1600
|
+
children: returnOrder.status.replace(/_/g, " ")
|
|
1601
|
+
}
|
|
1602
|
+
) }),
|
|
1603
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
|
|
1604
|
+
const calc = returnOrder.refund;
|
|
1605
|
+
if (calc?.is_processed && calc.final_refund_amount != null) {
|
|
1606
|
+
return formatRefundCurrency(
|
|
1607
|
+
calc.final_refund_amount,
|
|
1608
|
+
calc.currency_code || returnOrder.currency_code
|
|
1609
|
+
);
|
|
1610
|
+
}
|
|
1611
|
+
if (calc) {
|
|
1612
|
+
return "Pending";
|
|
1613
|
+
}
|
|
1614
|
+
if (returnOrder.refund_amount == null) {
|
|
1615
|
+
return "—";
|
|
1616
|
+
}
|
|
1617
|
+
return formatRefundCurrency(
|
|
1618
|
+
Number(returnOrder.refund_amount),
|
|
1619
|
+
returnOrder.currency_code
|
|
1620
|
+
);
|
|
1621
|
+
})() }),
|
|
1622
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(returnOrder.created_at).toLocaleDateString("en-US", {
|
|
1623
|
+
year: "numeric",
|
|
1624
|
+
month: "short",
|
|
1625
|
+
day: "numeric",
|
|
1626
|
+
hour: "numeric",
|
|
1627
|
+
minute: "2-digit",
|
|
1628
|
+
hour12: true
|
|
1629
|
+
}) }),
|
|
1630
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsx(
|
|
1631
|
+
Button,
|
|
1632
|
+
{
|
|
1633
|
+
variant: "transparent",
|
|
1634
|
+
size: "small",
|
|
1635
|
+
onClick: (e) => {
|
|
1636
|
+
e.stopPropagation();
|
|
1637
|
+
navigate(`/app/orders/${returnOrder.order_id}`);
|
|
1638
|
+
},
|
|
1639
|
+
children: "Go to order"
|
|
1640
|
+
}
|
|
1641
|
+
) })
|
|
1642
|
+
]
|
|
1643
|
+
},
|
|
1644
|
+
returnOrder.id
|
|
1645
|
+
)) })
|
|
1646
|
+
] }) }),
|
|
1647
|
+
hasMore ? /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(
|
|
1648
|
+
Button,
|
|
1649
|
+
{
|
|
1650
|
+
variant: "secondary",
|
|
1651
|
+
isLoading: isFetchingMore,
|
|
1652
|
+
onClick: () => loadReturns(offset, false),
|
|
1653
|
+
children: "Load more"
|
|
1654
|
+
}
|
|
1655
|
+
) }) : null
|
|
1656
|
+
] }) });
|
|
1657
|
+
};
|
|
1658
|
+
const config$5 = defineRouteConfig({
|
|
1659
|
+
label: "Return Orders",
|
|
1660
|
+
icon: ArrowPath
|
|
1661
|
+
});
|
|
1662
|
+
const useDebounce = (value, delay) => {
|
|
1663
|
+
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
1664
|
+
useEffect(() => {
|
|
1665
|
+
const handler = setTimeout(() => setDebouncedValue(value), delay);
|
|
1666
|
+
return () => clearTimeout(handler);
|
|
1667
|
+
}, [value, delay]);
|
|
1668
|
+
return debouncedValue;
|
|
1669
|
+
};
|
|
1670
|
+
const getStatusBadgeClass$4 = (status) => {
|
|
1671
|
+
const statusLower = status.toLowerCase();
|
|
1672
|
+
if (statusLower === "requested") {
|
|
1673
|
+
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
1674
|
+
}
|
|
1675
|
+
if (statusLower === "approved") {
|
|
1676
|
+
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
1677
|
+
}
|
|
1678
|
+
if (statusLower === "rejected") {
|
|
1679
|
+
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
1680
|
+
}
|
|
1681
|
+
if (statusLower === "completed") {
|
|
1682
|
+
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1683
|
+
}
|
|
1684
|
+
if (statusLower === "cancelled") {
|
|
1685
|
+
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
1686
|
+
}
|
|
1687
|
+
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
1688
|
+
};
|
|
1689
|
+
const SwapsPage = () => {
|
|
1699
1690
|
const navigate = useNavigate();
|
|
1700
1691
|
const [items, setItems] = useState([]);
|
|
1701
1692
|
const [statusFilter, setStatusFilter] = useState("all");
|
|
@@ -1710,7 +1701,6 @@ const SwapsPage = () => {
|
|
|
1710
1701
|
const limit = 50;
|
|
1711
1702
|
const loadSwaps = useCallback(
|
|
1712
1703
|
async (nextOffset, replace = false) => {
|
|
1713
|
-
var _a;
|
|
1714
1704
|
try {
|
|
1715
1705
|
if (replace) {
|
|
1716
1706
|
setIsLoading(true);
|
|
@@ -1740,7 +1730,7 @@ const SwapsPage = () => {
|
|
|
1740
1730
|
}
|
|
1741
1731
|
const payload = await response.json();
|
|
1742
1732
|
setCount(payload.count ?? 0);
|
|
1743
|
-
setOffset(nextOffset + (
|
|
1733
|
+
setOffset(nextOffset + (payload.swaps?.length ?? 0));
|
|
1744
1734
|
setItems(
|
|
1745
1735
|
(prev) => replace ? payload.swaps ?? [] : [...prev, ...payload.swaps ?? []]
|
|
1746
1736
|
);
|
|
@@ -1907,10 +1897,9 @@ const getStatusBadgeClass$3 = (status) => {
|
|
|
1907
1897
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
1908
1898
|
};
|
|
1909
1899
|
const PaymentDetailPage = () => {
|
|
1910
|
-
var _a;
|
|
1911
1900
|
const navigate = useNavigate();
|
|
1912
1901
|
const params = useParams();
|
|
1913
|
-
const id =
|
|
1902
|
+
const id = params?.id?.trim();
|
|
1914
1903
|
const [detail, setDetail] = useState(null);
|
|
1915
1904
|
const [loading, setLoading] = useState(!!id);
|
|
1916
1905
|
const [error, setError] = useState(null);
|
|
@@ -1937,8 +1926,8 @@ const PaymentDetailPage = () => {
|
|
|
1937
1926
|
};
|
|
1938
1927
|
}, [id]);
|
|
1939
1928
|
const displayStatus = detail ? (detail.payment_id != null && detail.payment_status != null && detail.payment_status !== "" ? detail.payment_status : detail.session_status ?? "") || "—" : "";
|
|
1940
|
-
const sessionStatusRaw =
|
|
1941
|
-
const paymentStatusRaw =
|
|
1929
|
+
const sessionStatusRaw = detail?.session_status ?? "—";
|
|
1930
|
+
const paymentStatusRaw = detail?.payment_id != null ? detail?.payment_status ?? "—" : "—";
|
|
1942
1931
|
const displayAmount = detail ? `${(detail.currency_code ?? "USD").toUpperCase()} ${Number(detail.amount)}` : "";
|
|
1943
1932
|
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: [
|
|
1944
1933
|
/* @__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: [
|
|
@@ -2013,11 +2002,202 @@ const PaymentDetailPage = () => {
|
|
|
2013
2002
|
] }) : null
|
|
2014
2003
|
] }) });
|
|
2015
2004
|
};
|
|
2016
|
-
const config$3 = defineRouteConfig({
|
|
2017
|
-
label: "Payment details",
|
|
2018
|
-
icon: CreditCard
|
|
2005
|
+
const config$3 = defineRouteConfig({
|
|
2006
|
+
label: "Payment details",
|
|
2007
|
+
icon: CreditCard
|
|
2008
|
+
});
|
|
2009
|
+
const getStatusBadgeClass$2 = (status) => {
|
|
2010
|
+
const s2 = status.toLowerCase();
|
|
2011
|
+
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
2012
|
+
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
2013
|
+
if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
2014
|
+
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
2015
|
+
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
2016
|
+
};
|
|
2017
|
+
const formatAmount = (value) => {
|
|
2018
|
+
return String(value);
|
|
2019
|
+
};
|
|
2020
|
+
const RefundDetailPage = () => {
|
|
2021
|
+
const navigate = useNavigate();
|
|
2022
|
+
const params = useParams();
|
|
2023
|
+
const id = params?.id?.trim();
|
|
2024
|
+
const [detail, setDetail] = useState(null);
|
|
2025
|
+
const [loading, setLoading] = useState(!!id);
|
|
2026
|
+
const [error, setError] = useState(null);
|
|
2027
|
+
const [gatewayExpanded, setGatewayExpanded] = useState(false);
|
|
2028
|
+
useEffect(() => {
|
|
2029
|
+
if (!id) {
|
|
2030
|
+
setLoading(false);
|
|
2031
|
+
return;
|
|
2032
|
+
}
|
|
2033
|
+
let cancelled = false;
|
|
2034
|
+
setLoading(true);
|
|
2035
|
+
setError(null);
|
|
2036
|
+
fetch(`/admin/refunds/${id}`, { credentials: "include" }).then((res) => {
|
|
2037
|
+
if (!res.ok) throw new Error(res.statusText || "Failed to load");
|
|
2038
|
+
return res.json();
|
|
2039
|
+
}).then((data) => {
|
|
2040
|
+
if (!cancelled) setDetail(data);
|
|
2041
|
+
}).catch((e) => {
|
|
2042
|
+
if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
|
|
2043
|
+
}).finally(() => {
|
|
2044
|
+
if (!cancelled) setLoading(false);
|
|
2045
|
+
});
|
|
2046
|
+
return () => {
|
|
2047
|
+
cancelled = true;
|
|
2048
|
+
};
|
|
2049
|
+
}, [id]);
|
|
2050
|
+
const paymentStatus = detail?.payment?.status ?? "—";
|
|
2051
|
+
const hasGatewayData = detail?.payment?.payment_data && typeof detail.payment.payment_data === "object" && Object.keys(detail.payment.payment_data).length > 0;
|
|
2052
|
+
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: [
|
|
2053
|
+
/* @__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: [
|
|
2054
|
+
/* @__PURE__ */ jsx(Button, { variant: "transparent", size: "small", onClick: () => navigate("/refunds"), children: "← Refunds" }),
|
|
2055
|
+
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "Refund details" }),
|
|
2056
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle font-mono", children: id ?? "—" })
|
|
2057
|
+
] }) }),
|
|
2058
|
+
error ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
2059
|
+
/* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
2060
|
+
/* @__PURE__ */ jsx(Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/refunds"), children: "Back to list" })
|
|
2061
|
+
] }) : 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: [
|
|
2062
|
+
/* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2063
|
+
/* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg mb-4", children: "Refund summary" }),
|
|
2064
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
2065
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2066
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Refund ID" }),
|
|
2067
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.id })
|
|
2068
|
+
] }),
|
|
2069
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2070
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
|
|
2071
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.refund.amount) })
|
|
2072
|
+
] }),
|
|
2073
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2074
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Note" }),
|
|
2075
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.refund.note ?? "—" })
|
|
2076
|
+
] }),
|
|
2077
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2078
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Created at" }),
|
|
2079
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: new Date(detail.refund.created_at).toLocaleDateString("en-US", {
|
|
2080
|
+
year: "numeric",
|
|
2081
|
+
month: "short",
|
|
2082
|
+
day: "numeric",
|
|
2083
|
+
hour: "numeric",
|
|
2084
|
+
minute: "2-digit",
|
|
2085
|
+
hour12: true
|
|
2086
|
+
}) })
|
|
2087
|
+
] }),
|
|
2088
|
+
detail.refund.created_by ? /* @__PURE__ */ jsxs("div", { children: [
|
|
2089
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Created by" }),
|
|
2090
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.created_by })
|
|
2091
|
+
] }) : null
|
|
2092
|
+
] })
|
|
2093
|
+
] }),
|
|
2094
|
+
/* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2095
|
+
/* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg mb-4", children: "Payment summary" }),
|
|
2096
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
2097
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2098
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Payment amount" }),
|
|
2099
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.payment.payment_amount) })
|
|
2100
|
+
] }),
|
|
2101
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2102
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Captured amount" }),
|
|
2103
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.payment.captured_amount) })
|
|
2104
|
+
] }),
|
|
2105
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2106
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Refunded amount" }),
|
|
2107
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.payment.refunded_amount) })
|
|
2108
|
+
] }),
|
|
2109
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2110
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
|
|
2111
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.payment.provider_id || "—" })
|
|
2112
|
+
] }),
|
|
2113
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2114
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
|
|
2115
|
+
/* @__PURE__ */ jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsx(
|
|
2116
|
+
Badge,
|
|
2117
|
+
{
|
|
2118
|
+
size: "2xsmall",
|
|
2119
|
+
className: `uppercase ${getStatusBadgeClass$2(paymentStatus)}`,
|
|
2120
|
+
children: paymentStatus !== "—" ? paymentStatus.replace(/_/g, " ") : "—"
|
|
2121
|
+
}
|
|
2122
|
+
) })
|
|
2123
|
+
] }),
|
|
2124
|
+
detail.computed ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2125
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2126
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Full refund" }),
|
|
2127
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.computed.is_full_refund ? "Yes" : "No" })
|
|
2128
|
+
] }),
|
|
2129
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2130
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Remaining refundable" }),
|
|
2131
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.computed.remaining_refundable_amount) })
|
|
2132
|
+
] }),
|
|
2133
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2134
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Refund %" }),
|
|
2135
|
+
/* @__PURE__ */ jsxs(Text, { className: "mt-1 block", children: [
|
|
2136
|
+
detail.computed.refund_percentage.toFixed(1),
|
|
2137
|
+
"%"
|
|
2138
|
+
] })
|
|
2139
|
+
] })
|
|
2140
|
+
] }) : null
|
|
2141
|
+
] })
|
|
2142
|
+
] }),
|
|
2143
|
+
/* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2144
|
+
/* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg mb-4", children: "Order summary" }),
|
|
2145
|
+
detail.order ? /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
2146
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2147
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Order" }),
|
|
2148
|
+
/* @__PURE__ */ jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsx(
|
|
2149
|
+
Button,
|
|
2150
|
+
{
|
|
2151
|
+
variant: "transparent",
|
|
2152
|
+
size: "small",
|
|
2153
|
+
onClick: () => navigate(`/orders/${detail.order.order_id}`),
|
|
2154
|
+
children: detail.order.order_number ?? detail.order.order_id
|
|
2155
|
+
}
|
|
2156
|
+
) })
|
|
2157
|
+
] }),
|
|
2158
|
+
detail.order.total != null ? /* @__PURE__ */ jsxs("div", { children: [
|
|
2159
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Total" }),
|
|
2160
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.order.total) })
|
|
2161
|
+
] }) : null,
|
|
2162
|
+
detail.order.customer_id ? /* @__PURE__ */ jsxs("div", { children: [
|
|
2163
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Customer ID" }),
|
|
2164
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block font-mono text-sm", children: detail.order.customer_id })
|
|
2165
|
+
] }) : null,
|
|
2166
|
+
detail.order.region ? /* @__PURE__ */ jsxs("div", { children: [
|
|
2167
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Region" }),
|
|
2168
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.order.region })
|
|
2169
|
+
] }) : null,
|
|
2170
|
+
detail.order.fulfillment_status ? /* @__PURE__ */ jsxs("div", { children: [
|
|
2171
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Fulfillment status" }),
|
|
2172
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.order.fulfillment_status })
|
|
2173
|
+
] }) : null
|
|
2174
|
+
] }) : /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "No order linked to this refund." })
|
|
2175
|
+
] }),
|
|
2176
|
+
/* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2177
|
+
/* @__PURE__ */ jsxs(
|
|
2178
|
+
"button",
|
|
2179
|
+
{
|
|
2180
|
+
type: "button",
|
|
2181
|
+
className: "flex w-full items-center justify-between text-left",
|
|
2182
|
+
onClick: () => setGatewayExpanded((prev) => !prev),
|
|
2183
|
+
"aria-expanded": gatewayExpanded,
|
|
2184
|
+
"aria-label": gatewayExpanded ? "Collapse gateway data" : "Expand gateway data",
|
|
2185
|
+
children: [
|
|
2186
|
+
/* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg", children: "Gateway data" }),
|
|
2187
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: gatewayExpanded ? "Collapse" : "Expand" })
|
|
2188
|
+
]
|
|
2189
|
+
}
|
|
2190
|
+
),
|
|
2191
|
+
gatewayExpanded && /* @__PURE__ */ jsx("div", { className: "mt-4", children: hasGatewayData ? /* @__PURE__ */ 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__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "No gateway payload for this payment." }) })
|
|
2192
|
+
] })
|
|
2193
|
+
] }) : null
|
|
2194
|
+
] }) });
|
|
2195
|
+
};
|
|
2196
|
+
const config$2 = defineRouteConfig({
|
|
2197
|
+
label: "Refund details",
|
|
2198
|
+
icon: Receipt
|
|
2019
2199
|
});
|
|
2020
|
-
const getStatusBadgeClass$
|
|
2200
|
+
const getStatusBadgeClass$1 = (status) => {
|
|
2021
2201
|
const statusLower = status.toLowerCase();
|
|
2022
2202
|
if (statusLower === "requested") {
|
|
2023
2203
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
@@ -2043,7 +2223,6 @@ const getStatusBadgeClass$2 = (status) => {
|
|
|
2043
2223
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
2044
2224
|
};
|
|
2045
2225
|
const ReturnDetailPage = () => {
|
|
2046
|
-
var _a, _b, _c;
|
|
2047
2226
|
const navigate = useNavigate();
|
|
2048
2227
|
const { id } = useParams();
|
|
2049
2228
|
const [returnOrder, setReturnOrder] = useState(null);
|
|
@@ -2126,7 +2305,7 @@ const ReturnDetailPage = () => {
|
|
|
2126
2305
|
/* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => navigate("/returns"), children: "Back to list" }) })
|
|
2127
2306
|
] }) }) });
|
|
2128
2307
|
}
|
|
2129
|
-
const statusHistory =
|
|
2308
|
+
const statusHistory = returnOrder.metadata?.status_history || [];
|
|
2130
2309
|
return /* @__PURE__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxs(Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: [
|
|
2131
2310
|
/* @__PURE__ */ jsxs("header", { className: "flex flex-col gap-3", children: [
|
|
2132
2311
|
/* @__PURE__ */ jsxs(
|
|
@@ -2151,7 +2330,7 @@ const ReturnDetailPage = () => {
|
|
|
2151
2330
|
Badge,
|
|
2152
2331
|
{
|
|
2153
2332
|
size: "small",
|
|
2154
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
2333
|
+
className: `uppercase ${getStatusBadgeClass$1(returnOrder.status)}`,
|
|
2155
2334
|
children: returnOrder.status.replace(/_/g, " ")
|
|
2156
2335
|
}
|
|
2157
2336
|
)
|
|
@@ -2234,7 +2413,7 @@ const ReturnDetailPage = () => {
|
|
|
2234
2413
|
Badge,
|
|
2235
2414
|
{
|
|
2236
2415
|
size: "2xsmall",
|
|
2237
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
2416
|
+
className: `uppercase ${getStatusBadgeClass$1(entry.status)}`,
|
|
2238
2417
|
children: entry.status.replace(/_/g, " ")
|
|
2239
2418
|
}
|
|
2240
2419
|
) }),
|
|
@@ -2262,11 +2441,11 @@ const ReturnDetailPage = () => {
|
|
|
2262
2441
|
] }),
|
|
2263
2442
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
2264
2443
|
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
|
|
2265
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children:
|
|
2444
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: returnOrder.order.customer?.email || returnOrder.order.email || "—" })
|
|
2266
2445
|
] }),
|
|
2267
2446
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
2268
2447
|
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Payment method" }),
|
|
2269
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children:
|
|
2448
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: returnOrder.order.order_payment?.label || "—" })
|
|
2270
2449
|
] }),
|
|
2271
2450
|
returnOrder.order.total && /* @__PURE__ */ jsxs("div", { children: [
|
|
2272
2451
|
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
|
|
@@ -2296,202 +2475,10 @@ const ReturnDetailPage = () => {
|
|
|
2296
2475
|
updateSuccess && /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-ui-border-success bg-ui-bg-success-subtle p-4", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-success", children: "Action completed successfully" }) })
|
|
2297
2476
|
] }) });
|
|
2298
2477
|
};
|
|
2299
|
-
const config$
|
|
2478
|
+
const config$1 = defineRouteConfig({
|
|
2300
2479
|
label: "Return Order Details",
|
|
2301
2480
|
icon: CheckCircle
|
|
2302
2481
|
});
|
|
2303
|
-
const getStatusBadgeClass$1 = (status) => {
|
|
2304
|
-
const s2 = status.toLowerCase();
|
|
2305
|
-
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
2306
|
-
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
2307
|
-
if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
2308
|
-
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
2309
|
-
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
2310
|
-
};
|
|
2311
|
-
const formatAmount = (value) => {
|
|
2312
|
-
return String(value);
|
|
2313
|
-
};
|
|
2314
|
-
const RefundDetailPage = () => {
|
|
2315
|
-
var _a, _b, _c;
|
|
2316
|
-
const navigate = useNavigate();
|
|
2317
|
-
const params = useParams();
|
|
2318
|
-
const id = (_a = params == null ? void 0 : params.id) == null ? void 0 : _a.trim();
|
|
2319
|
-
const [detail, setDetail] = useState(null);
|
|
2320
|
-
const [loading, setLoading] = useState(!!id);
|
|
2321
|
-
const [error, setError] = useState(null);
|
|
2322
|
-
const [gatewayExpanded, setGatewayExpanded] = useState(false);
|
|
2323
|
-
useEffect(() => {
|
|
2324
|
-
if (!id) {
|
|
2325
|
-
setLoading(false);
|
|
2326
|
-
return;
|
|
2327
|
-
}
|
|
2328
|
-
let cancelled = false;
|
|
2329
|
-
setLoading(true);
|
|
2330
|
-
setError(null);
|
|
2331
|
-
fetch(`/admin/refunds/${id}`, { credentials: "include" }).then((res) => {
|
|
2332
|
-
if (!res.ok) throw new Error(res.statusText || "Failed to load");
|
|
2333
|
-
return res.json();
|
|
2334
|
-
}).then((data) => {
|
|
2335
|
-
if (!cancelled) setDetail(data);
|
|
2336
|
-
}).catch((e) => {
|
|
2337
|
-
if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
|
|
2338
|
-
}).finally(() => {
|
|
2339
|
-
if (!cancelled) setLoading(false);
|
|
2340
|
-
});
|
|
2341
|
-
return () => {
|
|
2342
|
-
cancelled = true;
|
|
2343
|
-
};
|
|
2344
|
-
}, [id]);
|
|
2345
|
-
const paymentStatus = ((_b = detail == null ? void 0 : detail.payment) == null ? void 0 : _b.status) ?? "—";
|
|
2346
|
-
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;
|
|
2347
|
-
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: [
|
|
2348
|
-
/* @__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: [
|
|
2349
|
-
/* @__PURE__ */ jsx(Button, { variant: "transparent", size: "small", onClick: () => navigate("/refunds"), children: "← Refunds" }),
|
|
2350
|
-
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "Refund details" }),
|
|
2351
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle font-mono", children: id ?? "—" })
|
|
2352
|
-
] }) }),
|
|
2353
|
-
error ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
2354
|
-
/* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
2355
|
-
/* @__PURE__ */ jsx(Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/refunds"), children: "Back to list" })
|
|
2356
|
-
] }) : 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: [
|
|
2357
|
-
/* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2358
|
-
/* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg mb-4", children: "Refund summary" }),
|
|
2359
|
-
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
2360
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2361
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Refund ID" }),
|
|
2362
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.id })
|
|
2363
|
-
] }),
|
|
2364
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2365
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
|
|
2366
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.refund.amount) })
|
|
2367
|
-
] }),
|
|
2368
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2369
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Note" }),
|
|
2370
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.refund.note ?? "—" })
|
|
2371
|
-
] }),
|
|
2372
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2373
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Created at" }),
|
|
2374
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: new Date(detail.refund.created_at).toLocaleDateString("en-US", {
|
|
2375
|
-
year: "numeric",
|
|
2376
|
-
month: "short",
|
|
2377
|
-
day: "numeric",
|
|
2378
|
-
hour: "numeric",
|
|
2379
|
-
minute: "2-digit",
|
|
2380
|
-
hour12: true
|
|
2381
|
-
}) })
|
|
2382
|
-
] }),
|
|
2383
|
-
detail.refund.created_by ? /* @__PURE__ */ jsxs("div", { children: [
|
|
2384
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Created by" }),
|
|
2385
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.created_by })
|
|
2386
|
-
] }) : null
|
|
2387
|
-
] })
|
|
2388
|
-
] }),
|
|
2389
|
-
/* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2390
|
-
/* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg mb-4", children: "Payment summary" }),
|
|
2391
|
-
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
2392
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2393
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Payment amount" }),
|
|
2394
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.payment.payment_amount) })
|
|
2395
|
-
] }),
|
|
2396
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2397
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Captured amount" }),
|
|
2398
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.payment.captured_amount) })
|
|
2399
|
-
] }),
|
|
2400
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2401
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Refunded amount" }),
|
|
2402
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.payment.refunded_amount) })
|
|
2403
|
-
] }),
|
|
2404
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2405
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
|
|
2406
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.payment.provider_id || "—" })
|
|
2407
|
-
] }),
|
|
2408
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2409
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
|
|
2410
|
-
/* @__PURE__ */ jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsx(
|
|
2411
|
-
Badge,
|
|
2412
|
-
{
|
|
2413
|
-
size: "2xsmall",
|
|
2414
|
-
className: `uppercase ${getStatusBadgeClass$1(paymentStatus)}`,
|
|
2415
|
-
children: paymentStatus !== "—" ? paymentStatus.replace(/_/g, " ") : "—"
|
|
2416
|
-
}
|
|
2417
|
-
) })
|
|
2418
|
-
] }),
|
|
2419
|
-
detail.computed ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2420
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2421
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Full refund" }),
|
|
2422
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.computed.is_full_refund ? "Yes" : "No" })
|
|
2423
|
-
] }),
|
|
2424
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2425
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Remaining refundable" }),
|
|
2426
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.computed.remaining_refundable_amount) })
|
|
2427
|
-
] }),
|
|
2428
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2429
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Refund %" }),
|
|
2430
|
-
/* @__PURE__ */ jsxs(Text, { className: "mt-1 block", children: [
|
|
2431
|
-
detail.computed.refund_percentage.toFixed(1),
|
|
2432
|
-
"%"
|
|
2433
|
-
] })
|
|
2434
|
-
] })
|
|
2435
|
-
] }) : null
|
|
2436
|
-
] })
|
|
2437
|
-
] }),
|
|
2438
|
-
/* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2439
|
-
/* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg mb-4", children: "Order summary" }),
|
|
2440
|
-
detail.order ? /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
2441
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2442
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Order" }),
|
|
2443
|
-
/* @__PURE__ */ jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsx(
|
|
2444
|
-
Button,
|
|
2445
|
-
{
|
|
2446
|
-
variant: "transparent",
|
|
2447
|
-
size: "small",
|
|
2448
|
-
onClick: () => navigate(`/orders/${detail.order.order_id}`),
|
|
2449
|
-
children: detail.order.order_number ?? detail.order.order_id
|
|
2450
|
-
}
|
|
2451
|
-
) })
|
|
2452
|
-
] }),
|
|
2453
|
-
detail.order.total != null ? /* @__PURE__ */ jsxs("div", { children: [
|
|
2454
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Total" }),
|
|
2455
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.order.total) })
|
|
2456
|
-
] }) : null,
|
|
2457
|
-
detail.order.customer_id ? /* @__PURE__ */ jsxs("div", { children: [
|
|
2458
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Customer ID" }),
|
|
2459
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block font-mono text-sm", children: detail.order.customer_id })
|
|
2460
|
-
] }) : null,
|
|
2461
|
-
detail.order.region ? /* @__PURE__ */ jsxs("div", { children: [
|
|
2462
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Region" }),
|
|
2463
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.order.region })
|
|
2464
|
-
] }) : null,
|
|
2465
|
-
detail.order.fulfillment_status ? /* @__PURE__ */ jsxs("div", { children: [
|
|
2466
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Fulfillment status" }),
|
|
2467
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.order.fulfillment_status })
|
|
2468
|
-
] }) : null
|
|
2469
|
-
] }) : /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "No order linked to this refund." })
|
|
2470
|
-
] }),
|
|
2471
|
-
/* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2472
|
-
/* @__PURE__ */ jsxs(
|
|
2473
|
-
"button",
|
|
2474
|
-
{
|
|
2475
|
-
type: "button",
|
|
2476
|
-
className: "flex w-full items-center justify-between text-left",
|
|
2477
|
-
onClick: () => setGatewayExpanded((prev) => !prev),
|
|
2478
|
-
"aria-expanded": gatewayExpanded,
|
|
2479
|
-
"aria-label": gatewayExpanded ? "Collapse gateway data" : "Expand gateway data",
|
|
2480
|
-
children: [
|
|
2481
|
-
/* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg", children: "Gateway data" }),
|
|
2482
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: gatewayExpanded ? "Collapse" : "Expand" })
|
|
2483
|
-
]
|
|
2484
|
-
}
|
|
2485
|
-
),
|
|
2486
|
-
gatewayExpanded && /* @__PURE__ */ jsx("div", { className: "mt-4", children: hasGatewayData ? /* @__PURE__ */ 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__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "No gateway payload for this payment." }) })
|
|
2487
|
-
] })
|
|
2488
|
-
] }) : null
|
|
2489
|
-
] }) });
|
|
2490
|
-
};
|
|
2491
|
-
const config$1 = defineRouteConfig({
|
|
2492
|
-
label: "Refund details",
|
|
2493
|
-
icon: Receipt
|
|
2494
|
-
});
|
|
2495
2482
|
const getStatusBadgeClass = (status) => {
|
|
2496
2483
|
const statusLower = status.toLowerCase();
|
|
2497
2484
|
if (statusLower === "requested") {
|
|
@@ -2515,13 +2502,12 @@ const getStatusBadgeClass = (status) => {
|
|
|
2515
2502
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
2516
2503
|
};
|
|
2517
2504
|
const SwapDetailPage = () => {
|
|
2518
|
-
var _a, _b, _c;
|
|
2519
2505
|
const navigate = useNavigate();
|
|
2520
2506
|
const { id } = useParams();
|
|
2521
2507
|
const [swap, setSwap] = useState(null);
|
|
2522
2508
|
const [order, setOrder] = useState(null);
|
|
2523
2509
|
const [isLoading, setIsLoading] = useState(true);
|
|
2524
|
-
useState(false);
|
|
2510
|
+
const [isRejecting, setIsRejecting] = useState(false);
|
|
2525
2511
|
const [isCancelling, setIsCancelling] = useState(false);
|
|
2526
2512
|
const [error, setError] = useState(null);
|
|
2527
2513
|
const [updateError, setUpdateError] = useState(null);
|
|
@@ -2592,9 +2578,9 @@ const SwapDetailPage = () => {
|
|
|
2592
2578
|
setIsCancelling(false);
|
|
2593
2579
|
}
|
|
2594
2580
|
};
|
|
2595
|
-
const isOrderExchange = Boolean(swap
|
|
2581
|
+
const isOrderExchange = Boolean(swap?.exchange_id);
|
|
2596
2582
|
const canCancelExchange = isOrderExchange && swap && !["cancelled", "canceled", "completed", "declined"].includes(
|
|
2597
|
-
|
|
2583
|
+
swap.status?.toLowerCase() ?? ""
|
|
2598
2584
|
);
|
|
2599
2585
|
if (isLoading) {
|
|
2600
2586
|
return /* @__PURE__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsx(Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading swap..." }) }) }) });
|
|
@@ -2605,7 +2591,7 @@ const SwapDetailPage = () => {
|
|
|
2605
2591
|
/* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => navigate("/swaps"), children: "Back to list" }) })
|
|
2606
2592
|
] }) }) });
|
|
2607
2593
|
}
|
|
2608
|
-
const statusHistory =
|
|
2594
|
+
const statusHistory = swap.metadata?.status_history || [];
|
|
2609
2595
|
return /* @__PURE__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxs(Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: [
|
|
2610
2596
|
/* @__PURE__ */ jsxs("header", { className: "flex flex-col gap-3", children: [
|
|
2611
2597
|
/* @__PURE__ */ jsxs(
|
|
@@ -2726,7 +2712,7 @@ const SwapDetailPage = () => {
|
|
|
2726
2712
|
] }),
|
|
2727
2713
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
2728
2714
|
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
|
|
2729
|
-
/* @__PURE__ */ jsx(Text, { className: "font-medium", children:
|
|
2715
|
+
/* @__PURE__ */ jsx(Text, { className: "font-medium", children: order.customer?.email || order.email || "—" })
|
|
2730
2716
|
] }),
|
|
2731
2717
|
order.total && /* @__PURE__ */ jsxs("div", { children: [
|
|
2732
2718
|
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
|
|
@@ -2775,98 +2761,124 @@ const i18nTranslations0 = {};
|
|
|
2775
2761
|
const widgetModule = { widgets: [
|
|
2776
2762
|
{
|
|
2777
2763
|
Component: OrderGiftItemsWidget,
|
|
2778
|
-
zone: ["order.details.side.after"]
|
|
2764
|
+
zone: ["order.details.side.after"],
|
|
2765
|
+
widgetId: "Widget-b753"
|
|
2779
2766
|
},
|
|
2780
2767
|
{
|
|
2781
2768
|
Component: OrderRefundContextWidget,
|
|
2782
|
-
zone: ["order.details.after"]
|
|
2769
|
+
zone: ["order.details.after"],
|
|
2770
|
+
widgetId: "Widget-0606"
|
|
2783
2771
|
}
|
|
2784
2772
|
] };
|
|
2785
2773
|
const routeModule = {
|
|
2786
2774
|
routes: [
|
|
2787
2775
|
{
|
|
2788
2776
|
Component: PaymentsPage,
|
|
2789
|
-
path: "/payments"
|
|
2777
|
+
path: "/payments",
|
|
2778
|
+
handle: { label: config$7.label, translationNs: config$7.translationNs }
|
|
2790
2779
|
},
|
|
2791
2780
|
{
|
|
2792
|
-
Component:
|
|
2793
|
-
path: "/
|
|
2781
|
+
Component: RefundsPage,
|
|
2782
|
+
path: "/refunds",
|
|
2783
|
+
handle: { label: config$6.label, translationNs: config$6.translationNs }
|
|
2794
2784
|
},
|
|
2795
2785
|
{
|
|
2796
|
-
Component:
|
|
2797
|
-
path: "/
|
|
2786
|
+
Component: ReturnsPage,
|
|
2787
|
+
path: "/returns",
|
|
2788
|
+
handle: { label: config$5.label, translationNs: config$5.translationNs }
|
|
2798
2789
|
},
|
|
2799
2790
|
{
|
|
2800
2791
|
Component: SwapsPage,
|
|
2801
|
-
path: "/swaps"
|
|
2792
|
+
path: "/swaps",
|
|
2793
|
+
handle: { label: config$4.label, translationNs: config$4.translationNs }
|
|
2802
2794
|
},
|
|
2803
2795
|
{
|
|
2804
2796
|
Component: PaymentDetailPage,
|
|
2805
|
-
path: "/payments/:id"
|
|
2797
|
+
path: "/payments/:id",
|
|
2798
|
+
handle: { label: config$3.label, translationNs: config$3.translationNs }
|
|
2806
2799
|
},
|
|
2807
2800
|
{
|
|
2808
|
-
Component:
|
|
2809
|
-
path: "/
|
|
2801
|
+
Component: RefundDetailPage,
|
|
2802
|
+
path: "/refunds/:id",
|
|
2803
|
+
handle: { label: config$2.label, translationNs: config$2.translationNs }
|
|
2810
2804
|
},
|
|
2811
2805
|
{
|
|
2812
|
-
Component:
|
|
2813
|
-
path: "/
|
|
2806
|
+
Component: ReturnDetailPage,
|
|
2807
|
+
path: "/returns/:id",
|
|
2808
|
+
handle: { label: config$1.label, translationNs: config$1.translationNs }
|
|
2814
2809
|
},
|
|
2815
2810
|
{
|
|
2816
2811
|
Component: SwapDetailPage,
|
|
2817
|
-
path: "/swaps/:id"
|
|
2812
|
+
path: "/swaps/:id",
|
|
2813
|
+
handle: { label: config.label, translationNs: config.translationNs }
|
|
2818
2814
|
}
|
|
2819
2815
|
]
|
|
2820
2816
|
};
|
|
2821
2817
|
const menuItemModule = {
|
|
2822
2818
|
menuItems: [
|
|
2819
|
+
{
|
|
2820
|
+
label: config$7.label,
|
|
2821
|
+
icon: config$7.icon,
|
|
2822
|
+
path: "/payments",
|
|
2823
|
+
nested: void 0,
|
|
2824
|
+
rank: void 0,
|
|
2825
|
+
translationNs: void 0
|
|
2826
|
+
},
|
|
2823
2827
|
{
|
|
2824
2828
|
label: config$6.label,
|
|
2825
2829
|
icon: config$6.icon,
|
|
2830
|
+
path: "/refunds",
|
|
2831
|
+
nested: void 0,
|
|
2832
|
+
rank: void 0,
|
|
2833
|
+
translationNs: void 0
|
|
2834
|
+
},
|
|
2835
|
+
{
|
|
2836
|
+
label: config$5.label,
|
|
2837
|
+
icon: config$5.icon,
|
|
2826
2838
|
path: "/returns",
|
|
2827
|
-
nested: void 0
|
|
2839
|
+
nested: void 0,
|
|
2840
|
+
rank: void 0,
|
|
2841
|
+
translationNs: void 0
|
|
2828
2842
|
},
|
|
2829
2843
|
{
|
|
2830
2844
|
label: config$4.label,
|
|
2831
2845
|
icon: config$4.icon,
|
|
2832
2846
|
path: "/swaps",
|
|
2833
|
-
nested: void 0
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
label: config$7.label,
|
|
2837
|
-
icon: config$7.icon,
|
|
2838
|
-
path: "/payments",
|
|
2839
|
-
nested: void 0
|
|
2847
|
+
nested: void 0,
|
|
2848
|
+
rank: void 0,
|
|
2849
|
+
translationNs: void 0
|
|
2840
2850
|
},
|
|
2841
2851
|
{
|
|
2842
|
-
label: config$
|
|
2843
|
-
icon: config$
|
|
2844
|
-
path: "/
|
|
2845
|
-
nested: void 0
|
|
2852
|
+
label: config$3.label,
|
|
2853
|
+
icon: config$3.icon,
|
|
2854
|
+
path: "/payments/:id",
|
|
2855
|
+
nested: void 0,
|
|
2856
|
+
rank: void 0,
|
|
2857
|
+
translationNs: void 0
|
|
2846
2858
|
},
|
|
2847
2859
|
{
|
|
2848
2860
|
label: config$2.label,
|
|
2849
2861
|
icon: config$2.icon,
|
|
2862
|
+
path: "/refunds/:id",
|
|
2863
|
+
nested: void 0,
|
|
2864
|
+
rank: void 0,
|
|
2865
|
+
translationNs: void 0
|
|
2866
|
+
},
|
|
2867
|
+
{
|
|
2868
|
+
label: config$1.label,
|
|
2869
|
+
icon: config$1.icon,
|
|
2850
2870
|
path: "/returns/:id",
|
|
2851
|
-
nested: void 0
|
|
2871
|
+
nested: void 0,
|
|
2872
|
+
rank: void 0,
|
|
2873
|
+
translationNs: void 0
|
|
2852
2874
|
},
|
|
2853
2875
|
{
|
|
2854
2876
|
label: config.label,
|
|
2855
2877
|
icon: config.icon,
|
|
2856
2878
|
path: "/swaps/:id",
|
|
2857
|
-
nested: void 0
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
label: config$3.label,
|
|
2861
|
-
icon: config$3.icon,
|
|
2862
|
-
path: "/payments/:id",
|
|
2863
|
-
nested: void 0
|
|
2864
|
-
},
|
|
2865
|
-
{
|
|
2866
|
-
label: config$1.label,
|
|
2867
|
-
icon: config$1.icon,
|
|
2868
|
-
path: "/refunds/:id",
|
|
2869
|
-
nested: void 0
|
|
2879
|
+
nested: void 0,
|
|
2880
|
+
rank: void 0,
|
|
2881
|
+
translationNs: void 0
|
|
2870
2882
|
}
|
|
2871
2883
|
]
|
|
2872
2884
|
};
|
|
@@ -2875,13 +2887,19 @@ const displayModule = {
|
|
|
2875
2887
|
displays: {}
|
|
2876
2888
|
};
|
|
2877
2889
|
const i18nModule = { resources: i18nTranslations0 };
|
|
2890
|
+
const cellRendererModule = {};
|
|
2891
|
+
const layoutModule = { layouts: [] };
|
|
2892
|
+
const searchEntityModule = {};
|
|
2878
2893
|
const plugin = {
|
|
2879
2894
|
widgetModule,
|
|
2880
2895
|
routeModule,
|
|
2881
2896
|
menuItemModule,
|
|
2882
2897
|
formModule,
|
|
2883
2898
|
displayModule,
|
|
2884
|
-
i18nModule
|
|
2899
|
+
i18nModule,
|
|
2900
|
+
cellRendererModule,
|
|
2901
|
+
layoutModule,
|
|
2902
|
+
searchEntityModule
|
|
2885
2903
|
};
|
|
2886
2904
|
export {
|
|
2887
2905
|
plugin as default
|