order-management 0.0.101 → 0.0.102
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 +1717 -1707
- package/.medusa/server/src/admin/index.mjs +1718 -1708
- package/.medusa/server/src/api/store/carts/[id]/pickup/route.js +113 -0
- package/.medusa/server/src/api/store/guest-orders/[id]/returns/route.js +12 -1
- package/.medusa/server/src/api/store/guest-orders/[id]/swaps/route.js +14 -2
- package/.medusa/server/src/api/store/pickup-locations/route.js +20 -0
- package/.medusa/server/src/api/store/returns/route.js +15 -3
- package/.medusa/server/src/api/store/swaps/route.js +17 -2
- package/.medusa/server/src/config.js +4 -1
- package/.medusa/server/src/helpers/pickup-locations.js +155 -0
- package/.medusa/server/src/subscribers/order-status-change.js +37 -2
- package/.medusa/server/src/utils/order-fulfillment-metadata.js +68 -0
- package/README.md +10 -1
- package/package.json +1 -1
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
|
-
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
2
|
const jsxRuntime = require("react/jsx-runtime");
|
|
6
3
|
const adminSdk = require("@medusajs/admin-sdk");
|
|
7
4
|
const react = require("react");
|
|
@@ -378,15 +375,14 @@ const s = {
|
|
|
378
375
|
const OrderGiftItemsWidget = ({ data }) => {
|
|
379
376
|
const [fetchedItems, setFetchedItems] = react.useState(null);
|
|
380
377
|
react.useEffect(() => {
|
|
381
|
-
if (!
|
|
378
|
+
if (!data?.id) return;
|
|
382
379
|
fetch(
|
|
383
380
|
`/admin/orders/${data.id}?fields=*items,items.metadata`
|
|
384
|
-
).then((r) => r.json()).then(({ order }) => setFetchedItems(
|
|
385
|
-
}, [data
|
|
386
|
-
const items = fetchedItems ??
|
|
381
|
+
).then((r) => r.json()).then(({ order }) => setFetchedItems(order?.items ?? [])).catch(() => setFetchedItems(data?.items ?? []));
|
|
382
|
+
}, [data?.id]);
|
|
383
|
+
const items = fetchedItems ?? data?.items ?? [];
|
|
387
384
|
const giftedItems = items.filter((i) => {
|
|
388
|
-
|
|
389
|
-
const flag = (_a = i.metadata) == null ? void 0 : _a.is_gift;
|
|
385
|
+
const flag = i.metadata?.is_gift;
|
|
390
386
|
return flag === "true" || flag === true;
|
|
391
387
|
});
|
|
392
388
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: s.widget, children: [
|
|
@@ -415,9 +411,9 @@ const OrderGiftItemsWidget = ({ data }) => {
|
|
|
415
411
|
),
|
|
416
412
|
giftedItems.map((item) => {
|
|
417
413
|
const meta = item.metadata;
|
|
418
|
-
const from = meta
|
|
419
|
-
const to = meta
|
|
420
|
-
const message = meta
|
|
414
|
+
const from = meta?.gift_from;
|
|
415
|
+
const to = meta?.gift_to;
|
|
416
|
+
const message = meta?.gift_message;
|
|
421
417
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: s.card, children: [
|
|
422
418
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: s.ribbon, children: [
|
|
423
419
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: s.bowCenter, children: "🎀" }),
|
|
@@ -481,7 +477,7 @@ function formatRefundCurrency(amount, currencyCode = "inr", options) {
|
|
|
481
477
|
minimumFractionDigits: 2,
|
|
482
478
|
maximumFractionDigits: 2
|
|
483
479
|
}).format(amount);
|
|
484
|
-
if (
|
|
480
|
+
if (options?.signed && amount > 0) {
|
|
485
481
|
return `−${formatted}`;
|
|
486
482
|
}
|
|
487
483
|
return formatted;
|
|
@@ -536,8 +532,7 @@ function getOrderIdFromPath() {
|
|
|
536
532
|
return m ? m[1] : void 0;
|
|
537
533
|
}
|
|
538
534
|
const OrderRefundContextWidget = (props) => {
|
|
539
|
-
|
|
540
|
-
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();
|
|
535
|
+
const orderId = props.order?.id ?? props.data?.order?.id ?? getOrderIdFromPath();
|
|
541
536
|
const [context, setContext] = react.useState(null);
|
|
542
537
|
const [loading, setLoading] = react.useState(!!orderId);
|
|
543
538
|
const [error, setError] = react.useState(null);
|
|
@@ -575,7 +570,7 @@ const OrderRefundContextWidget = (props) => {
|
|
|
575
570
|
};
|
|
576
571
|
}, [orderId]);
|
|
577
572
|
const handleMarkRefunded = async () => {
|
|
578
|
-
if (!
|
|
573
|
+
if (!context?.return_id || !context?.refund_mapping || context.refund_mapping.is_refunded || !context.can_process_refund) {
|
|
579
574
|
return;
|
|
580
575
|
}
|
|
581
576
|
setMarking(true);
|
|
@@ -592,17 +587,14 @@ const OrderRefundContextWidget = (props) => {
|
|
|
592
587
|
}
|
|
593
588
|
const data = await res.json();
|
|
594
589
|
setContext(
|
|
595
|
-
(prev) => {
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
}
|
|
604
|
-
} : prev;
|
|
605
|
-
}
|
|
590
|
+
(prev) => prev && prev.refund_mapping ? {
|
|
591
|
+
...prev,
|
|
592
|
+
can_process_refund: false,
|
|
593
|
+
refund_mapping: {
|
|
594
|
+
...prev.refund_mapping,
|
|
595
|
+
is_refunded: data.refund_payment_mapping?.is_refunded ?? true
|
|
596
|
+
}
|
|
597
|
+
} : prev
|
|
606
598
|
);
|
|
607
599
|
} catch (e) {
|
|
608
600
|
setMarkError(e instanceof Error ? e.message : "Failed to mark refunded");
|
|
@@ -611,20 +603,19 @@ const OrderRefundContextWidget = (props) => {
|
|
|
611
603
|
}
|
|
612
604
|
};
|
|
613
605
|
const handleEditClick = () => {
|
|
614
|
-
const mapping = context
|
|
615
|
-
const mode = mapping
|
|
606
|
+
const mapping = context?.refund_mapping;
|
|
607
|
+
const mode = mapping?.refund_mode;
|
|
616
608
|
setEditRefundMode(
|
|
617
609
|
mode === "offline" || mode === "online" ? mode : ""
|
|
618
610
|
);
|
|
619
|
-
setEditDetails(
|
|
620
|
-
setEditImageUrls(
|
|
611
|
+
setEditDetails(mapping?.details ?? "");
|
|
612
|
+
setEditImageUrls(mapping?.images ?? []);
|
|
621
613
|
setSaveError(null);
|
|
622
614
|
setUploadError(null);
|
|
623
615
|
setEditing(true);
|
|
624
616
|
};
|
|
625
617
|
const handleUploadImage = async (e) => {
|
|
626
|
-
|
|
627
|
-
const file = (_a2 = e.target.files) == null ? void 0 : _a2[0];
|
|
618
|
+
const file = e.target.files?.[0];
|
|
628
619
|
if (!file) return;
|
|
629
620
|
setUploading(true);
|
|
630
621
|
setUploadError(null);
|
|
@@ -641,7 +632,7 @@ const OrderRefundContextWidget = (props) => {
|
|
|
641
632
|
throw new Error(data2.message || "Upload failed");
|
|
642
633
|
}
|
|
643
634
|
const data = await res.json();
|
|
644
|
-
const url =
|
|
635
|
+
const url = data.files?.[0]?.url;
|
|
645
636
|
if (url) setEditImageUrls((prev) => [...prev, url]);
|
|
646
637
|
} catch (err) {
|
|
647
638
|
setUploadError(err instanceof Error ? err.message : "Upload failed");
|
|
@@ -654,7 +645,7 @@ const OrderRefundContextWidget = (props) => {
|
|
|
654
645
|
setEditImageUrls((prev) => prev.filter((_, i) => i !== index));
|
|
655
646
|
};
|
|
656
647
|
const handleSaveAdminFields = async () => {
|
|
657
|
-
if (!
|
|
648
|
+
if (!context?.return_id) return;
|
|
658
649
|
setSaving(true);
|
|
659
650
|
setSaveError(null);
|
|
660
651
|
try {
|
|
@@ -691,14 +682,14 @@ const OrderRefundContextWidget = (props) => {
|
|
|
691
682
|
if (error) {
|
|
692
683
|
return /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mt-6 divide-y p-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-error", children: error }) }) });
|
|
693
684
|
}
|
|
694
|
-
const hasReturn = !!
|
|
695
|
-
const hasMapping = !!
|
|
696
|
-
const canMarkRefunded = Boolean(context
|
|
697
|
-
const returnStatus =
|
|
698
|
-
const showReceiveFirstHint = hasReturn && !
|
|
699
|
-
const paymentDetail = context
|
|
700
|
-
const paymentDetails =
|
|
701
|
-
const orderPayment = context
|
|
685
|
+
const hasReturn = !!context?.return_id;
|
|
686
|
+
const hasMapping = !!context?.refund_mapping;
|
|
687
|
+
const canMarkRefunded = Boolean(context?.can_process_refund);
|
|
688
|
+
const returnStatus = context?.return_status ?? null;
|
|
689
|
+
const showReceiveFirstHint = hasReturn && !context?.refund_mapping?.is_refunded && returnStatus !== "received" && returnStatus !== "canceled";
|
|
690
|
+
const paymentDetail = context?.payment_detail;
|
|
691
|
+
const paymentDetails = context?.payment_details && context.payment_details.length > 0 ? context.payment_details : paymentDetail ? [paymentDetail] : [];
|
|
692
|
+
const orderPayment = context?.order_payment;
|
|
702
693
|
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: [
|
|
703
694
|
/* @__PURE__ */ jsxRuntime.jsxs(ui.Heading, { level: "h2", className: "flex items-center gap-2", children: [
|
|
704
695
|
/* @__PURE__ */ jsxRuntime.jsx(icons.CashSolid, { className: "text-ui-fg-subtle" }),
|
|
@@ -710,7 +701,7 @@ const OrderRefundContextWidget = (props) => {
|
|
|
710
701
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
711
702
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "text-ui-fg-subtle", children: "Return" }),
|
|
712
703
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", children: context.return_id }),
|
|
713
|
-
|
|
704
|
+
context.refund_mapping?.is_refunded ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "green", children: "Refunded" }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "orange", children: "Not refunded" })
|
|
714
705
|
] }),
|
|
715
706
|
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,
|
|
716
707
|
orderPayment && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 space-y-2 border-t border-ui-border-base pt-3", children: [
|
|
@@ -724,17 +715,17 @@ const OrderRefundContextWidget = (props) => {
|
|
|
724
715
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 space-y-2 border-t border-ui-border-base pt-3", children: [
|
|
725
716
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
726
717
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "text-ui-fg-subtle", children: "Payment method (refund destination)" }),
|
|
727
|
-
|
|
718
|
+
context.refund_mapping?.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
|
|
728
719
|
] }),
|
|
729
|
-
|
|
730
|
-
!
|
|
731
|
-
!
|
|
720
|
+
context.refund_mapping?.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." }) }),
|
|
721
|
+
!context.refund_mapping?.payment_id && 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." }) }),
|
|
722
|
+
!context.refund_mapping?.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: [
|
|
732
723
|
"Refund will go to the original payment method (",
|
|
733
724
|
orderPayment.label,
|
|
734
725
|
")."
|
|
735
726
|
] }) }),
|
|
736
|
-
!
|
|
737
|
-
!
|
|
727
|
+
!context.refund_mapping?.payment_id && !paymentDetail && (context.is_cod || 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." }) }),
|
|
728
|
+
!context.refund_mapping?.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." }) }),
|
|
738
729
|
paymentDetails.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: paymentDetails.map((detail) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
739
730
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
|
|
740
731
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { children: detail.type.toUpperCase() }),
|
|
@@ -746,7 +737,7 @@ const OrderRefundContextWidget = (props) => {
|
|
|
746
737
|
] }, `${detail.id}-${k}`)) })
|
|
747
738
|
] }, detail.id)) })
|
|
748
739
|
] }),
|
|
749
|
-
|
|
740
|
+
context?.refund_mapping && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 space-y-3 border-t border-ui-border-base pt-3", children: [
|
|
750
741
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
751
742
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "text-ui-fg-subtle", children: "Refund mode, details & images" }),
|
|
752
743
|
!editing ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -834,10 +825,7 @@ const OrderRefundContextWidget = (props) => {
|
|
|
834
825
|
variant: "secondary",
|
|
835
826
|
type: "button",
|
|
836
827
|
disabled: uploading,
|
|
837
|
-
onClick: () =>
|
|
838
|
-
var _a2;
|
|
839
|
-
return (_a2 = fileInputRef.current) == null ? void 0 : _a2.click();
|
|
840
|
-
},
|
|
828
|
+
onClick: () => fileInputRef.current?.click(),
|
|
841
829
|
children: uploading ? "Uploading…" : "Upload image"
|
|
842
830
|
}
|
|
843
831
|
),
|
|
@@ -888,7 +876,7 @@ const OrderRefundContextWidget = (props) => {
|
|
|
888
876
|
] }),
|
|
889
877
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
890
878
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", weight: "plus", className: "text-ui-fg-muted", children: "Images" }),
|
|
891
|
-
|
|
879
|
+
context.refund_mapping.images?.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 flex flex-wrap gap-2", children: context.refund_mapping.images.map((url, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
892
880
|
"a",
|
|
893
881
|
{
|
|
894
882
|
href: url,
|
|
@@ -918,10 +906,10 @@ const OrderRefundContextWidget = (props) => {
|
|
|
918
906
|
),
|
|
919
907
|
markError && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-error", children: markError })
|
|
920
908
|
] }),
|
|
921
|
-
hasMapping && !canMarkRefunded && !
|
|
909
|
+
hasMapping && !canMarkRefunded && !context.refund_mapping?.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." })
|
|
922
910
|
] }),
|
|
923
911
|
hasReturn && !hasMapping && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-4", children: [
|
|
924
|
-
|
|
912
|
+
context?.refund ? /* @__PURE__ */ jsxRuntime.jsx(RefundCalculationBlock, { refund: context.refund }) : null,
|
|
925
913
|
orderPayment && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-3 space-y-1", children: [
|
|
926
914
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "text-ui-fg-subtle", children: "Order payment method" }),
|
|
927
915
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
@@ -1359,7 +1347,7 @@ function getEntityInfo(tableName) {
|
|
|
1359
1347
|
const def = ENTITY_DEFINITIONS[tableName];
|
|
1360
1348
|
return {
|
|
1361
1349
|
tableName,
|
|
1362
|
-
label:
|
|
1350
|
+
label: def?.label ?? humanizeTableName(tableName),
|
|
1363
1351
|
category: def && CATEGORY_BY_ID.get(def.category) || SYSTEM_CATEGORY
|
|
1364
1352
|
};
|
|
1365
1353
|
}
|
|
@@ -1384,13 +1372,11 @@ function getTablesForCategory(id) {
|
|
|
1384
1372
|
}
|
|
1385
1373
|
const GROUPS = getEntitiesByCategory();
|
|
1386
1374
|
function triggerLabel(entity, category) {
|
|
1387
|
-
var _a;
|
|
1388
1375
|
if (entity) return getEntityInfo(entity).label;
|
|
1389
|
-
if (category) return `All ${
|
|
1376
|
+
if (category) return `All ${getCategory(category)?.label ?? category}`;
|
|
1390
1377
|
return "All entities";
|
|
1391
1378
|
}
|
|
1392
1379
|
const EntityPicker = ({ entity, category, onChange }) => {
|
|
1393
|
-
var _a;
|
|
1394
1380
|
const [open, setOpen] = react.useState(false);
|
|
1395
1381
|
const [search, setSearch] = react.useState("");
|
|
1396
1382
|
const searchRef = react.useRef(null);
|
|
@@ -1410,7 +1396,7 @@ const EntityPicker = ({ entity, category, onChange }) => {
|
|
|
1410
1396
|
setOpen(false);
|
|
1411
1397
|
setSearch("");
|
|
1412
1398
|
};
|
|
1413
|
-
const firstMatch =
|
|
1399
|
+
const firstMatch = filteredGroups[0]?.entities[0];
|
|
1414
1400
|
const isAll = !entity && !category;
|
|
1415
1401
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1416
1402
|
ui.Popover,
|
|
@@ -1443,9 +1429,8 @@ const EntityPicker = ({ entity, category, onChange }) => {
|
|
|
1443
1429
|
align: "start",
|
|
1444
1430
|
className: "w-[min(360px,calc(100vw-2rem))] p-0",
|
|
1445
1431
|
onOpenAutoFocus: (event) => {
|
|
1446
|
-
var _a2;
|
|
1447
1432
|
event.preventDefault();
|
|
1448
|
-
|
|
1433
|
+
searchRef.current?.focus();
|
|
1449
1434
|
},
|
|
1450
1435
|
children: [
|
|
1451
1436
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b border-ui-border-base p-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1585,7 +1570,7 @@ function formatNumber(value) {
|
|
|
1585
1570
|
return new Intl.NumberFormat().format(value);
|
|
1586
1571
|
}
|
|
1587
1572
|
function formatMoney(amount, currencyCode) {
|
|
1588
|
-
const code = currencyCode
|
|
1573
|
+
const code = currencyCode?.trim().toUpperCase();
|
|
1589
1574
|
if (code && /^[A-Z]{3}$/.test(code)) {
|
|
1590
1575
|
try {
|
|
1591
1576
|
return new Intl.NumberFormat(void 0, { style: "currency", currency: code }).format(amount);
|
|
@@ -1652,9 +1637,9 @@ const SummaryCards = ({ stats, loading, failed }) => {
|
|
|
1652
1637
|
};
|
|
1653
1638
|
const BASE = "/admin/deleted-records-audit";
|
|
1654
1639
|
class AuditApiError extends Error {
|
|
1640
|
+
status;
|
|
1655
1641
|
constructor(message, status) {
|
|
1656
1642
|
super(message);
|
|
1657
|
-
__publicField(this, "status");
|
|
1658
1643
|
this.status = status;
|
|
1659
1644
|
}
|
|
1660
1645
|
}
|
|
@@ -1719,10 +1704,7 @@ const URL_KEYS = {
|
|
|
1719
1704
|
const DATE_PRESET_VALUES = new Set(DATE_PRESETS.map((p) => p.value));
|
|
1720
1705
|
const DAY_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
|
|
1721
1706
|
function filtersFromSearchParams(params) {
|
|
1722
|
-
const read = (key) =>
|
|
1723
|
-
var _a;
|
|
1724
|
-
return ((_a = params.get(URL_KEYS[key])) == null ? void 0 : _a.trim()) ?? "";
|
|
1725
|
-
};
|
|
1707
|
+
const read = (key) => params.get(URL_KEYS[key])?.trim() ?? "";
|
|
1726
1708
|
const date = read("date");
|
|
1727
1709
|
const from = read("from");
|
|
1728
1710
|
const to = read("to");
|
|
@@ -1876,9 +1858,9 @@ const DeletedRecordsPage = () => {
|
|
|
1876
1858
|
try {
|
|
1877
1859
|
setStats(await fetchAuditStats(signal));
|
|
1878
1860
|
} catch (e) {
|
|
1879
|
-
if (!
|
|
1861
|
+
if (!signal?.aborted) setStatsFailed(true);
|
|
1880
1862
|
} finally {
|
|
1881
|
-
if (!
|
|
1863
|
+
if (!signal?.aborted) setStatsLoading(false);
|
|
1882
1864
|
}
|
|
1883
1865
|
}, []);
|
|
1884
1866
|
react.useEffect(() => {
|
|
@@ -1935,7 +1917,7 @@ const DeletedRecordsPage = () => {
|
|
|
1935
1917
|
const visible = Array.from(document.querySelectorAll(`[data-audit-row="${lastViewed}"]`)).find(
|
|
1936
1918
|
(el) => el.offsetParent !== null
|
|
1937
1919
|
);
|
|
1938
|
-
visible
|
|
1920
|
+
visible?.scrollIntoView({ block: "center" });
|
|
1939
1921
|
});
|
|
1940
1922
|
const handle = setTimeout(() => setHighlightId(null), 2500);
|
|
1941
1923
|
return () => clearTimeout(handle);
|
|
@@ -1962,8 +1944,8 @@ const DeletedRecordsPage = () => {
|
|
|
1962
1944
|
};
|
|
1963
1945
|
const refresh = () => setReloadToken((t) => t + 1);
|
|
1964
1946
|
const hasMore = items.length < count;
|
|
1965
|
-
const knownSources =
|
|
1966
|
-
const knownDeletedBy =
|
|
1947
|
+
const knownSources = stats?.sources ?? [];
|
|
1948
|
+
const knownDeletedBy = stats?.deleted_by ?? [];
|
|
1967
1949
|
const attributionMissing = !!stats && stats.total > 0 && knownSources.length === 0 && knownDeletedBy.length === 0;
|
|
1968
1950
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-3 md:p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-7xl flex-col gap-6 p-4 md:p-6", children: [
|
|
1969
1951
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-start md:justify-between", children: [
|
|
@@ -2227,7 +2209,7 @@ const ErrorState = ({ onRetry, detail }) => /* @__PURE__ */ jsxRuntime.jsxs("div
|
|
|
2227
2209
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "max-w-md font-mono text-ui-fg-muted", children: detail }),
|
|
2228
2210
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", size: "small", className: "mt-2", onClick: onRetry, children: "Try again" })
|
|
2229
2211
|
] });
|
|
2230
|
-
const config$
|
|
2212
|
+
const config$9 = adminSdk.defineRouteConfig({
|
|
2231
2213
|
label: "Deleted Records",
|
|
2232
2214
|
icon: icons.Trash
|
|
2233
2215
|
});
|
|
@@ -2427,7 +2409,7 @@ const PaymentsPage = () => {
|
|
|
2427
2409
|
) }) : null
|
|
2428
2410
|
] }) });
|
|
2429
2411
|
};
|
|
2430
|
-
const config$
|
|
2412
|
+
const config$8 = adminSdk.defineRouteConfig({
|
|
2431
2413
|
label: "Payments",
|
|
2432
2414
|
icon: icons.CreditCard
|
|
2433
2415
|
});
|
|
@@ -2440,222 +2422,275 @@ const useDebounce$2 = (value, delay) => {
|
|
|
2440
2422
|
return debouncedValue;
|
|
2441
2423
|
};
|
|
2442
2424
|
const getStatusBadgeClass$6 = (status) => {
|
|
2443
|
-
const
|
|
2444
|
-
if (
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
if (
|
|
2448
|
-
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
2449
|
-
}
|
|
2450
|
-
if (statusLower === "requires_action") {
|
|
2451
|
-
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
2452
|
-
}
|
|
2453
|
-
if (statusLower === "completed") {
|
|
2454
|
-
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
2455
|
-
}
|
|
2456
|
-
if (statusLower === "canceled") {
|
|
2457
|
-
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
2458
|
-
}
|
|
2425
|
+
const s2 = status.toLowerCase();
|
|
2426
|
+
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
2427
|
+
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
2428
|
+
if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
2429
|
+
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
2459
2430
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
2460
2431
|
};
|
|
2461
|
-
const
|
|
2432
|
+
const RefundsPage = () => {
|
|
2462
2433
|
const navigate = reactRouterDom.useNavigate();
|
|
2463
2434
|
const [items, setItems] = react.useState([]);
|
|
2464
|
-
const [
|
|
2465
|
-
const
|
|
2466
|
-
const [
|
|
2467
|
-
const
|
|
2435
|
+
const [orderIdSearch, setOrderIdSearch] = react.useState("");
|
|
2436
|
+
const debouncedOrderId = useDebounce$2(orderIdSearch, 300);
|
|
2437
|
+
const [paymentStatusFilter, setPaymentStatusFilter] = react.useState("all");
|
|
2438
|
+
const [providerSearch, setProviderSearch] = react.useState("");
|
|
2439
|
+
const debouncedProvider = useDebounce$2(providerSearch, 300);
|
|
2440
|
+
const [currencySearch, setCurrencySearch] = react.useState("");
|
|
2441
|
+
const debouncedCurrency = useDebounce$2(currencySearch, 300);
|
|
2442
|
+
const [dateFrom, setDateFrom] = react.useState("");
|
|
2443
|
+
const [dateTo, setDateTo] = react.useState("");
|
|
2444
|
+
const [amountMin, setAmountMin] = react.useState("");
|
|
2445
|
+
const [amountMax, setAmountMax] = react.useState("");
|
|
2468
2446
|
const [isLoading, setIsLoading] = react.useState(true);
|
|
2469
2447
|
const [isFetchingMore, setIsFetchingMore] = react.useState(false);
|
|
2470
2448
|
const [error, setError] = react.useState(null);
|
|
2471
2449
|
const [offset, setOffset] = react.useState(0);
|
|
2472
2450
|
const [count, setCount] = react.useState(0);
|
|
2473
2451
|
const limit = 50;
|
|
2474
|
-
const
|
|
2475
|
-
async (nextOffset, replace
|
|
2476
|
-
var _a;
|
|
2452
|
+
const loadRefunds = react.useCallback(
|
|
2453
|
+
async (nextOffset, replace) => {
|
|
2477
2454
|
try {
|
|
2478
|
-
if (replace)
|
|
2479
|
-
|
|
2480
|
-
} else {
|
|
2481
|
-
setIsFetchingMore(true);
|
|
2482
|
-
}
|
|
2455
|
+
if (replace) setIsLoading(true);
|
|
2456
|
+
else setIsFetchingMore(true);
|
|
2483
2457
|
setError(null);
|
|
2484
2458
|
const params = new URLSearchParams();
|
|
2485
2459
|
params.set("limit", String(limit));
|
|
2486
2460
|
params.set("offset", String(nextOffset));
|
|
2487
|
-
if (
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
if (
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
params.set("
|
|
2497
|
-
const response = await fetch(
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
);
|
|
2461
|
+
if (debouncedOrderId.trim()) params.set("order_id", debouncedOrderId.trim());
|
|
2462
|
+
if (paymentStatusFilter !== "all") params.set("payment_status", paymentStatusFilter);
|
|
2463
|
+
if (debouncedProvider.trim()) params.set("provider_id", debouncedProvider.trim());
|
|
2464
|
+
if (debouncedCurrency.trim()) params.set("currency_code", debouncedCurrency.trim());
|
|
2465
|
+
if (dateFrom.trim()) params.set("date_from", dateFrom.trim());
|
|
2466
|
+
if (dateTo.trim()) params.set("date_to", dateTo.trim());
|
|
2467
|
+
const min = amountMin.trim() ? Number(amountMin) : void 0;
|
|
2468
|
+
const max = amountMax.trim() ? Number(amountMax) : void 0;
|
|
2469
|
+
if (min != null && !Number.isNaN(min)) params.set("amount_min", String(min));
|
|
2470
|
+
if (max != null && !Number.isNaN(max)) params.set("amount_max", String(max));
|
|
2471
|
+
const response = await fetch(`/admin/refunds?${params.toString()}`, {
|
|
2472
|
+
credentials: "include"
|
|
2473
|
+
});
|
|
2501
2474
|
if (!response.ok) {
|
|
2502
|
-
const
|
|
2503
|
-
throw new Error(
|
|
2475
|
+
const text = await response.text();
|
|
2476
|
+
throw new Error(text || "Failed to load refunds");
|
|
2504
2477
|
}
|
|
2505
2478
|
const payload = await response.json();
|
|
2479
|
+
const list = payload.refunds ?? [];
|
|
2506
2480
|
setCount(payload.count ?? 0);
|
|
2507
|
-
setOffset(nextOffset +
|
|
2508
|
-
setItems(
|
|
2509
|
-
|
|
2510
|
-
);
|
|
2511
|
-
} catch (loadError) {
|
|
2512
|
-
const message = loadError instanceof Error ? loadError.message : "Unable to load return orders";
|
|
2513
|
-
setError(message);
|
|
2481
|
+
setOffset(nextOffset + list.length);
|
|
2482
|
+
setItems((prev) => replace ? list : [...prev, ...list]);
|
|
2483
|
+
} catch (e) {
|
|
2484
|
+
setError(e instanceof Error ? e.message : "Failed to load");
|
|
2514
2485
|
} finally {
|
|
2515
2486
|
setIsLoading(false);
|
|
2516
2487
|
setIsFetchingMore(false);
|
|
2517
2488
|
}
|
|
2518
2489
|
},
|
|
2519
|
-
[
|
|
2490
|
+
[
|
|
2491
|
+
debouncedOrderId,
|
|
2492
|
+
paymentStatusFilter,
|
|
2493
|
+
debouncedProvider,
|
|
2494
|
+
debouncedCurrency,
|
|
2495
|
+
dateFrom,
|
|
2496
|
+
dateTo,
|
|
2497
|
+
amountMin,
|
|
2498
|
+
amountMax
|
|
2499
|
+
]
|
|
2520
2500
|
);
|
|
2521
2501
|
react.useEffect(() => {
|
|
2522
|
-
void
|
|
2523
|
-
}, [
|
|
2502
|
+
void loadRefunds(0, true);
|
|
2503
|
+
}, [loadRefunds]);
|
|
2524
2504
|
const hasMore = react.useMemo(() => offset < count, [offset, count]);
|
|
2525
|
-
const
|
|
2526
|
-
const
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2505
|
+
const displayAmount = (r) => {
|
|
2506
|
+
const code = (r.currency_code ?? "USD").toUpperCase();
|
|
2507
|
+
return `${code} ${Number(r.amount)}`;
|
|
2508
|
+
};
|
|
2509
|
+
const displayStatus = (r) => {
|
|
2510
|
+
const s2 = r.payment_status ?? "";
|
|
2511
|
+
return s2 !== "" ? s2 : "—";
|
|
2512
|
+
};
|
|
2530
2513
|
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: [
|
|
2531
2514
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
2532
2515
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
2533
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "
|
|
2534
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
2516
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Refunds" }),
|
|
2517
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Refund records — amount, order, payment status" })
|
|
2535
2518
|
] }),
|
|
2536
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () =>
|
|
2519
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadRefunds(0, true), children: "Refresh" })
|
|
2537
2520
|
] }),
|
|
2538
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2521
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
2539
2522
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2540
2523
|
ui.Input,
|
|
2541
2524
|
{
|
|
2542
|
-
placeholder: "
|
|
2543
|
-
value:
|
|
2544
|
-
onChange: (
|
|
2545
|
-
className: "md:max-w-
|
|
2525
|
+
placeholder: "Order ID",
|
|
2526
|
+
value: orderIdSearch,
|
|
2527
|
+
onChange: (e) => setOrderIdSearch(e.target.value),
|
|
2528
|
+
className: "md:max-w-[180px]",
|
|
2529
|
+
"aria-label": "Filter by order ID"
|
|
2546
2530
|
}
|
|
2547
2531
|
),
|
|
2548
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2549
|
-
|
|
2550
|
-
"select",
|
|
2551
|
-
{
|
|
2552
|
-
value: createdByFilter,
|
|
2553
|
-
onChange: (event) => setCreatedByFilter(event.target.value),
|
|
2554
|
-
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",
|
|
2555
|
-
children: [
|
|
2556
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All (Created by)" }),
|
|
2557
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "customer", children: "Customer" }),
|
|
2558
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "admin", children: "Admin" })
|
|
2559
|
-
]
|
|
2560
|
-
}
|
|
2561
|
-
),
|
|
2562
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2563
|
-
"select",
|
|
2564
|
-
{
|
|
2565
|
-
value: statusFilter,
|
|
2566
|
-
onChange: (event) => setStatusFilter(event.target.value),
|
|
2567
|
-
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",
|
|
2568
|
-
children: [
|
|
2569
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All Statuses" }),
|
|
2570
|
-
availableStatuses.map((status) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
|
|
2571
|
-
]
|
|
2572
|
-
}
|
|
2573
|
-
)
|
|
2574
|
-
] })
|
|
2575
|
-
] }),
|
|
2576
|
-
error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
2577
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
2578
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2579
|
-
ui.Button,
|
|
2532
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2533
|
+
ui.Input,
|
|
2580
2534
|
{
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2535
|
+
placeholder: "Provider",
|
|
2536
|
+
value: providerSearch,
|
|
2537
|
+
onChange: (e) => setProviderSearch(e.target.value),
|
|
2538
|
+
className: "md:max-w-[140px]",
|
|
2539
|
+
"aria-label": "Filter by provider"
|
|
2584
2540
|
}
|
|
2585
|
-
)
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No return orders yet" }),
|
|
2589
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Return orders created by customers will appear here." })
|
|
2590
|
-
] }) : /* @__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: [
|
|
2591
|
-
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
2592
|
-
/* @__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" }),
|
|
2593
|
-
/* @__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" }),
|
|
2594
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Customer" }),
|
|
2595
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
|
|
2596
|
-
/* @__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" }),
|
|
2597
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
2598
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
2599
|
-
] }) }),
|
|
2600
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((returnOrder) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2601
|
-
"tr",
|
|
2541
|
+
),
|
|
2542
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2543
|
+
ui.Input,
|
|
2602
2544
|
{
|
|
2603
|
-
|
|
2604
|
-
|
|
2545
|
+
placeholder: "Currency",
|
|
2546
|
+
value: currencySearch,
|
|
2547
|
+
onChange: (e) => setCurrencySearch(e.target.value),
|
|
2548
|
+
className: "md:max-w-[100px]",
|
|
2549
|
+
"aria-label": "Filter by currency"
|
|
2550
|
+
}
|
|
2551
|
+
),
|
|
2552
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2553
|
+
"select",
|
|
2554
|
+
{
|
|
2555
|
+
value: paymentStatusFilter,
|
|
2556
|
+
onChange: (e) => setPaymentStatusFilter(e.target.value),
|
|
2557
|
+
className: "h-9 rounded-md border border-ui-border-base bg-transparent px-3 text-sm text-ui-fg-base outline-none transition focus:ring-2 focus:ring-ui-fg-interactive md:max-w-[160px]",
|
|
2558
|
+
"aria-label": "Filter by payment status",
|
|
2605
2559
|
children: [
|
|
2606
|
-
/* @__PURE__ */ jsxRuntime.jsx("
|
|
2607
|
-
/* @__PURE__ */ jsxRuntime.jsx("
|
|
2608
|
-
/* @__PURE__ */ jsxRuntime.jsx("
|
|
2609
|
-
/* @__PURE__ */ jsxRuntime.jsx("
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2560
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All statuses" }),
|
|
2561
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "pending", children: "Pending" }),
|
|
2562
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "requires_more", children: "Requires more" }),
|
|
2563
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "error", children: "Error" }),
|
|
2564
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "canceled", children: "Canceled" }),
|
|
2565
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "authorized", children: "Authorized" }),
|
|
2566
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "captured", children: "Captured" })
|
|
2567
|
+
]
|
|
2568
|
+
}
|
|
2569
|
+
),
|
|
2570
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2571
|
+
ui.Input,
|
|
2572
|
+
{
|
|
2573
|
+
type: "date",
|
|
2574
|
+
placeholder: "From",
|
|
2575
|
+
value: dateFrom,
|
|
2576
|
+
onChange: (e) => setDateFrom(e.target.value),
|
|
2577
|
+
className: "md:max-w-[140px]",
|
|
2578
|
+
"aria-label": "Date from"
|
|
2579
|
+
}
|
|
2580
|
+
),
|
|
2581
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2582
|
+
ui.Input,
|
|
2583
|
+
{
|
|
2584
|
+
type: "date",
|
|
2585
|
+
placeholder: "To",
|
|
2586
|
+
value: dateTo,
|
|
2587
|
+
onChange: (e) => setDateTo(e.target.value),
|
|
2588
|
+
className: "md:max-w-[140px]",
|
|
2589
|
+
"aria-label": "Date to"
|
|
2590
|
+
}
|
|
2591
|
+
),
|
|
2592
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2593
|
+
ui.Input,
|
|
2594
|
+
{
|
|
2595
|
+
placeholder: "Amount min",
|
|
2596
|
+
value: amountMin,
|
|
2597
|
+
onChange: (e) => setAmountMin(e.target.value),
|
|
2598
|
+
type: "number",
|
|
2599
|
+
min: 0,
|
|
2600
|
+
className: "md:max-w-[100px]",
|
|
2601
|
+
"aria-label": "Refund amount minimum"
|
|
2602
|
+
}
|
|
2603
|
+
),
|
|
2604
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2605
|
+
ui.Input,
|
|
2606
|
+
{
|
|
2607
|
+
placeholder: "Amount max",
|
|
2608
|
+
value: amountMax,
|
|
2609
|
+
onChange: (e) => setAmountMax(e.target.value),
|
|
2610
|
+
type: "number",
|
|
2611
|
+
min: 0,
|
|
2612
|
+
className: "md:max-w-[100px]",
|
|
2613
|
+
"aria-label": "Refund amount maximum"
|
|
2614
|
+
}
|
|
2615
|
+
)
|
|
2616
|
+
] }) }),
|
|
2617
|
+
error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
2618
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
2619
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => loadRefunds(0, true), children: "Try again" }) })
|
|
2620
|
+
] }) : null,
|
|
2621
|
+
isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading refunds…" }) }) : items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
|
|
2622
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No refunds yet" }),
|
|
2623
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Refund records will appear here." })
|
|
2624
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full overflow-x-auto rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full table-fixed divide-y divide-ui-border-base", style: { minWidth: 0 }, children: [
|
|
2625
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
2626
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Refund ID" }),
|
|
2627
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
|
|
2628
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Payment ID" }),
|
|
2629
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[8%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Amount" }),
|
|
2630
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[6%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Currency" }),
|
|
2631
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[10%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Provider" }),
|
|
2632
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[10%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Payment Status" }),
|
|
2633
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[14%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Note" }),
|
|
2634
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
2635
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-[8%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
2636
|
+
] }) }),
|
|
2637
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((r) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2638
|
+
"tr",
|
|
2639
|
+
{
|
|
2640
|
+
className: "cursor-pointer hover:bg-ui-bg-subtle/60",
|
|
2641
|
+
onClick: () => navigate(`/refunds/${r.refund_id}`),
|
|
2642
|
+
children: [
|
|
2643
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 font-mono text-sm text-ui-fg-base", title: r.refund_id, children: r.refund_id }),
|
|
2644
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 font-medium text-ui-fg-base", title: r.order_id ?? void 0, children: r.order_id ?? "—" }),
|
|
2645
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 font-mono text-sm text-ui-fg-subtle", title: r.payment_id, children: r.payment_id }),
|
|
2646
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle", children: displayAmount(r) }),
|
|
2647
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle uppercase", children: r.currency_code || "—" }),
|
|
2648
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle", title: r.provider_id || void 0, children: r.provider_id || "—" }),
|
|
2649
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 px-3 py-3", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2650
|
+
ui.Badge,
|
|
2646
2651
|
{
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
e.stopPropagation();
|
|
2651
|
-
navigate(`/app/orders/${returnOrder.order_id}`);
|
|
2652
|
-
},
|
|
2653
|
-
children: "Go to order"
|
|
2652
|
+
size: "2xsmall",
|
|
2653
|
+
className: `uppercase ${getStatusBadgeClass$6(displayStatus(r))}`,
|
|
2654
|
+
children: displayStatus(r) !== "—" ? displayStatus(r).replace(/_/g, " ") : "—"
|
|
2654
2655
|
}
|
|
2655
|
-
) })
|
|
2656
|
+
) }),
|
|
2657
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle", title: r.note ?? void 0, children: r.note ?? "—" }),
|
|
2658
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle text-xs", children: new Date(r.created_at).toLocaleDateString("en-US", {
|
|
2659
|
+
month: "short",
|
|
2660
|
+
day: "numeric",
|
|
2661
|
+
hour: "numeric",
|
|
2662
|
+
minute: "2-digit",
|
|
2663
|
+
hour12: true
|
|
2664
|
+
}) }),
|
|
2665
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "min-w-0 px-3 py-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-1", children: [
|
|
2666
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2667
|
+
ui.Button,
|
|
2668
|
+
{
|
|
2669
|
+
variant: "transparent",
|
|
2670
|
+
size: "small",
|
|
2671
|
+
onClick: (e) => {
|
|
2672
|
+
e.stopPropagation();
|
|
2673
|
+
navigate(`/refunds/${r.refund_id}`);
|
|
2674
|
+
},
|
|
2675
|
+
children: "Details"
|
|
2676
|
+
}
|
|
2677
|
+
),
|
|
2678
|
+
r.order_id ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2679
|
+
ui.Button,
|
|
2680
|
+
{
|
|
2681
|
+
variant: "transparent",
|
|
2682
|
+
size: "small",
|
|
2683
|
+
onClick: (e) => {
|
|
2684
|
+
e.stopPropagation();
|
|
2685
|
+
navigate(`/orders/${r.order_id}`);
|
|
2686
|
+
},
|
|
2687
|
+
children: "Order"
|
|
2688
|
+
}
|
|
2689
|
+
) : null
|
|
2690
|
+
] }) })
|
|
2656
2691
|
]
|
|
2657
2692
|
},
|
|
2658
|
-
|
|
2693
|
+
r.refund_id
|
|
2659
2694
|
)) })
|
|
2660
2695
|
] }) }),
|
|
2661
2696
|
hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2663,761 +2698,258 @@ const ReturnsPage = () => {
|
|
|
2663
2698
|
{
|
|
2664
2699
|
variant: "secondary",
|
|
2665
2700
|
isLoading: isFetchingMore,
|
|
2666
|
-
onClick: () =>
|
|
2701
|
+
onClick: () => loadRefunds(offset, false),
|
|
2667
2702
|
children: "Load more"
|
|
2668
2703
|
}
|
|
2669
2704
|
) }) : null
|
|
2670
2705
|
] }) });
|
|
2671
2706
|
};
|
|
2672
|
-
const config$
|
|
2673
|
-
label: "
|
|
2674
|
-
icon: icons.
|
|
2707
|
+
const config$7 = adminSdk.defineRouteConfig({
|
|
2708
|
+
label: "Refunds",
|
|
2709
|
+
icon: icons.Receipt
|
|
2675
2710
|
});
|
|
2676
|
-
const
|
|
2677
|
-
const
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
/access_?key/i,
|
|
2684
|
-
/(^|_)hash(ed)?($|_)/i,
|
|
2685
|
-
/(^|_)salt$/i,
|
|
2686
|
-
/^cvv$|^cvc$|security_code/i,
|
|
2687
|
-
/card_?number/i,
|
|
2688
|
-
/account_?number/i,
|
|
2689
|
-
/credential/i,
|
|
2690
|
-
/authorization/i,
|
|
2691
|
-
/recovery_?code/i,
|
|
2692
|
-
/(^|_)otp($|_)/i,
|
|
2693
|
-
/verification_?code/i,
|
|
2694
|
-
/^code_hash$/i,
|
|
2695
|
-
/webhook_?signature/i
|
|
2696
|
-
];
|
|
2697
|
-
const TABLE_SENSITIVE_KEYS = {
|
|
2698
|
-
otp_verification: /* @__PURE__ */ new Set(["code", "value"]),
|
|
2699
|
-
auth_verification: /* @__PURE__ */ new Set(["code", "value"]),
|
|
2700
|
-
auth_mfa_factor: /* @__PURE__ */ new Set(["value", "config"])
|
|
2711
|
+
const useDebounce$1 = (value, delay) => {
|
|
2712
|
+
const [debouncedValue, setDebouncedValue] = react.useState(value);
|
|
2713
|
+
react.useEffect(() => {
|
|
2714
|
+
const handler = setTimeout(() => setDebouncedValue(value), delay);
|
|
2715
|
+
return () => clearTimeout(handler);
|
|
2716
|
+
}, [value, delay]);
|
|
2717
|
+
return debouncedValue;
|
|
2701
2718
|
};
|
|
2702
|
-
const
|
|
2703
|
-
|
|
2704
|
-
"
|
|
2705
|
-
|
|
2706
|
-
"token_id",
|
|
2707
|
-
"notification_token_id"
|
|
2708
|
-
]);
|
|
2709
|
-
function isSensitiveKey(key) {
|
|
2710
|
-
const normalized = key.trim().toLowerCase();
|
|
2711
|
-
if (SAFE_KEYS.has(normalized)) return false;
|
|
2712
|
-
return SENSITIVE_KEY_PATTERNS.some((pattern) => pattern.test(normalized));
|
|
2713
|
-
}
|
|
2714
|
-
const FULLY_SECRET_TABLES = /* @__PURE__ */ new Set(["auth_mfa_recovery_code", "auth_password_reset_token"]);
|
|
2715
|
-
const ALWAYS_VISIBLE_KEYS = /* @__PURE__ */ new Set(["id", "created_at", "updated_at", "deleted_at", "expires_at", "used_at"]);
|
|
2716
|
-
function maskValue(value, ctx, depth) {
|
|
2717
|
-
var _a;
|
|
2718
|
-
if (Array.isArray(value)) return value.map((item) => maskValue(item, ctx, depth + 1));
|
|
2719
|
-
if (value !== null && typeof value === "object") {
|
|
2720
|
-
const out = {};
|
|
2721
|
-
for (const [key, inner] of Object.entries(value)) {
|
|
2722
|
-
const topLevel = depth === 0;
|
|
2723
|
-
const secret = inner !== null && inner !== void 0 && inner !== "" && (isSensitiveKey(key) || topLevel && ((_a = ctx.tableKeys) == null ? void 0 : _a.has(key.toLowerCase())) === true || topLevel && ctx.maskAll && !ALWAYS_VISIBLE_KEYS.has(key) && !key.endsWith("_id"));
|
|
2724
|
-
if (secret) {
|
|
2725
|
-
ctx.count += 1;
|
|
2726
|
-
out[key] = MASKED_VALUE;
|
|
2727
|
-
} else {
|
|
2728
|
-
out[key] = maskValue(inner, ctx, depth + 1);
|
|
2729
|
-
}
|
|
2730
|
-
}
|
|
2731
|
-
return out;
|
|
2719
|
+
const getStatusBadgeClass$5 = (status) => {
|
|
2720
|
+
const statusLower = status.toLowerCase();
|
|
2721
|
+
if (statusLower === "requested") {
|
|
2722
|
+
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
2732
2723
|
}
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
function maskSensitiveData(data, tableName) {
|
|
2736
|
-
const ctx = {
|
|
2737
|
-
count: 0,
|
|
2738
|
-
maskAll: tableName ? FULLY_SECRET_TABLES.has(tableName) : false,
|
|
2739
|
-
tableKeys: tableName ? TABLE_SENSITIVE_KEYS[tableName] : void 0
|
|
2740
|
-
};
|
|
2741
|
-
const value = maskValue(data, ctx, 0);
|
|
2742
|
-
return { value, maskedCount: ctx.count };
|
|
2743
|
-
}
|
|
2744
|
-
const AUTO_EXPAND_DEPTH = 1;
|
|
2745
|
-
const LONG_STRING = 200;
|
|
2746
|
-
const JsonViewer = ({ data }) => {
|
|
2747
|
-
const [generation, setGeneration] = react.useState(0);
|
|
2748
|
-
const [expandAll, setExpandAll] = react.useState(null);
|
|
2749
|
-
const setAll = (value) => {
|
|
2750
|
-
setExpandAll(value);
|
|
2751
|
-
setGeneration((g) => g + 1);
|
|
2752
|
-
};
|
|
2753
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
2754
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
|
|
2755
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => setAll(true), children: "Expand all" }),
|
|
2756
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => setAll(false), children: "Collapse all" })
|
|
2757
|
-
] }),
|
|
2758
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-h-[560px] overflow-auto rounded-lg border border-ui-border-base bg-ui-bg-subtle p-3 font-mono text-xs leading-5", children: /* @__PURE__ */ jsxRuntime.jsx(JsonNode, { value: data, depth: 0, forceExpand: expandAll }, generation) })
|
|
2759
|
-
] });
|
|
2760
|
-
};
|
|
2761
|
-
const JsonNode = ({ name, value, depth, forceExpand }) => {
|
|
2762
|
-
const isContainer = value !== null && typeof value === "object";
|
|
2763
|
-
const [open, setOpen] = react.useState(forceExpand ?? depth < AUTO_EXPAND_DEPTH);
|
|
2764
|
-
const label = name !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-ui-fg-subtle", children: [
|
|
2765
|
-
name,
|
|
2766
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-fg-muted", children: ": " })
|
|
2767
|
-
] }) : null;
|
|
2768
|
-
if (!isContainer) {
|
|
2769
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 items-start", style: { paddingLeft: depth ? 16 : 0 }, children: [
|
|
2770
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-4 shrink-0" }),
|
|
2771
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0 break-words [overflow-wrap:anywhere]", children: [
|
|
2772
|
-
label,
|
|
2773
|
-
/* @__PURE__ */ jsxRuntime.jsx(Primitive, { value })
|
|
2774
|
-
] })
|
|
2775
|
-
] });
|
|
2724
|
+
if (statusLower === "received") {
|
|
2725
|
+
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
2776
2726
|
}
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
const summary = Array.isArray(value) ? `${entries.length} items` : `${entries.length} keys`;
|
|
2780
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { paddingLeft: depth ? 16 : 0 }, children: [
|
|
2781
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2782
|
-
"button",
|
|
2783
|
-
{
|
|
2784
|
-
type: "button",
|
|
2785
|
-
onClick: () => setOpen((o) => !o),
|
|
2786
|
-
className: "flex items-start text-left hover:bg-ui-bg-base-hover",
|
|
2787
|
-
"aria-expanded": open,
|
|
2788
|
-
children: [
|
|
2789
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex w-4 shrink-0 items-center pt-0.5 text-ui-fg-muted", children: entries.length ? open ? /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronDownMini, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronRightMini, {}) : null }),
|
|
2790
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
2791
|
-
label,
|
|
2792
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-fg-muted", children: openBracket }),
|
|
2793
|
-
!open || entries.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2794
|
-
entries.length ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-1 italic text-ui-fg-muted", children: summary }) : null,
|
|
2795
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-fg-muted", children: closeBracket })
|
|
2796
|
-
] }) : null
|
|
2797
|
-
] })
|
|
2798
|
-
]
|
|
2799
|
-
}
|
|
2800
|
-
),
|
|
2801
|
-
open && entries.length ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2802
|
-
entries.map(([key, child]) => /* @__PURE__ */ jsxRuntime.jsx(JsonNode, { name: key, value: child, depth: depth + 1, forceExpand }, key)),
|
|
2803
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { paddingLeft: 16 }, className: "text-ui-fg-muted", children: closeBracket })
|
|
2804
|
-
] }) : null
|
|
2805
|
-
] });
|
|
2806
|
-
};
|
|
2807
|
-
const Primitive = ({ value }) => {
|
|
2808
|
-
const [showFull, setShowFull] = react.useState(false);
|
|
2809
|
-
if (value === MASKED_VALUE) {
|
|
2810
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded bg-ui-tag-orange-bg px-1 text-ui-tag-orange-text", title: "Hidden for security", children: MASKED_VALUE });
|
|
2727
|
+
if (statusLower === "requires_action") {
|
|
2728
|
+
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
2811
2729
|
}
|
|
2812
|
-
if (
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: ui.clx("text-ui-tag-green-text"), children: [
|
|
2818
|
-
'"',
|
|
2819
|
-
truncated ? `${text.slice(0, LONG_STRING)}…` : text,
|
|
2820
|
-
'"',
|
|
2821
|
-
text.length > LONG_STRING ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2822
|
-
"button",
|
|
2823
|
-
{
|
|
2824
|
-
type: "button",
|
|
2825
|
-
onClick: () => setShowFull((s2) => !s2),
|
|
2826
|
-
className: "ml-1 font-sans text-ui-fg-interactive hover:underline",
|
|
2827
|
-
children: showFull ? "show less" : `show all (${text.length} chars)`
|
|
2828
|
-
}
|
|
2829
|
-
) : null
|
|
2830
|
-
] });
|
|
2831
|
-
};
|
|
2832
|
-
const GUIDANCE = {
|
|
2833
|
-
orders: {
|
|
2834
|
-
headline: "Order data affects customers, payments and reports.",
|
|
2835
|
-
recreate: "Orders can’t be recreated identically from the admin. If this deletion was not intended, ask a developer to restore it from a database backup using the snapshot on this page.",
|
|
2836
|
-
adminSection: { label: "Go to Orders", path: "/orders" }
|
|
2837
|
-
},
|
|
2838
|
-
carts: {
|
|
2839
|
-
headline: "Carts are usually cleaned up automatically.",
|
|
2840
|
-
recreate: "No action is normally needed. Customers can simply add items to a new cart."
|
|
2841
|
-
},
|
|
2842
|
-
customers: {
|
|
2843
|
-
headline: "Customer data may be needed for orders, support and compliance.",
|
|
2844
|
-
recreate: "If it was deleted by mistake, recreate it from Customers using the values shown above. A recreated customer gets a new ID and must reset their password.",
|
|
2845
|
-
adminSection: { label: "Go to Customers", path: "/customers" }
|
|
2846
|
-
},
|
|
2847
|
-
catalog: {
|
|
2848
|
-
headline: "Catalog changes affect what customers can see and buy.",
|
|
2849
|
-
recreate: "If it was deleted by mistake, recreate it from Products using the values shown above. It will get a new ID.",
|
|
2850
|
-
adminSection: { label: "Go to Products", path: "/products" }
|
|
2851
|
-
},
|
|
2852
|
-
pricing: {
|
|
2853
|
-
headline: "Pricing and promotions affect what customers pay.",
|
|
2854
|
-
recreate: "If it was deleted by mistake, recreate it from Promotions or Price Lists using the values shown above.",
|
|
2855
|
-
adminSection: { label: "Go to Promotions", path: "/promotions" }
|
|
2856
|
-
},
|
|
2857
|
-
payments: {
|
|
2858
|
-
headline: "Payment records are financial data.",
|
|
2859
|
-
recreate: "Do not recreate payment records by hand—this can make balances inconsistent. If this deletion was not expected, escalate to a developer or your finance team."
|
|
2860
|
-
},
|
|
2861
|
-
fulfillment: {
|
|
2862
|
-
headline: "Shipping and fulfillment settings affect checkout and delivery.",
|
|
2863
|
-
recreate: "If it was deleted by mistake, recreate it from Settings → Locations & Shipping using the values shown above.",
|
|
2864
|
-
adminSection: { label: "Go to Settings", path: "/settings" }
|
|
2865
|
-
},
|
|
2866
|
-
inventory: {
|
|
2867
|
-
headline: "Inventory changes can affect stock levels and availability.",
|
|
2868
|
-
recreate: "If it was deleted by mistake, recreate it from Inventory using the values shown above and re-check stock quantities.",
|
|
2869
|
-
adminSection: { label: "Go to Inventory", path: "/inventory" }
|
|
2870
|
-
},
|
|
2871
|
-
wallet: {
|
|
2872
|
-
headline: "Wallet and credit records are financial data.",
|
|
2873
|
-
recreate: "Do not recreate balances by hand. If this deletion was not expected, escalate to a developer or your finance team so balances can be verified."
|
|
2874
|
-
},
|
|
2875
|
-
access: {
|
|
2876
|
-
headline: "Access records control who can sign in.",
|
|
2877
|
-
recreate: "Secrets such as passwords and keys can’t be restored. Re-invite the user or create a new API key if access is still needed.",
|
|
2878
|
-
adminSection: { label: "Go to Settings", path: "/settings" }
|
|
2879
|
-
},
|
|
2880
|
-
store: {
|
|
2881
|
-
headline: "Store settings affect regions, currencies and taxes.",
|
|
2882
|
-
recreate: "If it was deleted by mistake, recreate it from Settings using the values shown above.",
|
|
2883
|
-
adminSection: { label: "Go to Settings", path: "/settings" }
|
|
2884
|
-
},
|
|
2885
|
-
engagement: {
|
|
2886
|
-
headline: "Customer-generated content.",
|
|
2887
|
-
recreate: "These usually can’t be recreated on the customer’s behalf. Keep the snapshot on this page if you need a record of it."
|
|
2888
|
-
},
|
|
2889
|
-
notifications: {
|
|
2890
|
-
headline: "Notification records are usually cleaned up automatically.",
|
|
2891
|
-
recreate: "No action is normally needed."
|
|
2892
|
-
},
|
|
2893
|
-
system: {
|
|
2894
|
-
headline: "Internal system data, usually removed automatically by the platform.",
|
|
2895
|
-
recreate: "No action is normally needed. If you suspect a problem, share this page with a developer."
|
|
2730
|
+
if (statusLower === "completed") {
|
|
2731
|
+
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
2732
|
+
}
|
|
2733
|
+
if (statusLower === "canceled") {
|
|
2734
|
+
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
2896
2735
|
}
|
|
2736
|
+
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
2897
2737
|
};
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
const
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
];
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2738
|
+
const ReturnsPage = () => {
|
|
2739
|
+
const navigate = reactRouterDom.useNavigate();
|
|
2740
|
+
const [items, setItems] = react.useState([]);
|
|
2741
|
+
const [statusFilter, setStatusFilter] = react.useState("all");
|
|
2742
|
+
const [createdByFilter, setCreatedByFilter] = react.useState("all");
|
|
2743
|
+
const [searchQuery, setSearchQuery] = react.useState("");
|
|
2744
|
+
const debouncedSearchQuery = useDebounce$1(searchQuery, 300);
|
|
2745
|
+
const [isLoading, setIsLoading] = react.useState(true);
|
|
2746
|
+
const [isFetchingMore, setIsFetchingMore] = react.useState(false);
|
|
2747
|
+
const [error, setError] = react.useState(null);
|
|
2748
|
+
const [offset, setOffset] = react.useState(0);
|
|
2749
|
+
const [count, setCount] = react.useState(0);
|
|
2750
|
+
const limit = 50;
|
|
2751
|
+
const loadReturns = react.useCallback(
|
|
2752
|
+
async (nextOffset, replace = false) => {
|
|
2753
|
+
try {
|
|
2754
|
+
if (replace) {
|
|
2755
|
+
setIsLoading(true);
|
|
2756
|
+
} else {
|
|
2757
|
+
setIsFetchingMore(true);
|
|
2758
|
+
}
|
|
2759
|
+
setError(null);
|
|
2760
|
+
const params = new URLSearchParams();
|
|
2761
|
+
params.set("limit", String(limit));
|
|
2762
|
+
params.set("offset", String(nextOffset));
|
|
2763
|
+
if (statusFilter !== "all") {
|
|
2764
|
+
params.set("status", statusFilter);
|
|
2765
|
+
}
|
|
2766
|
+
if (debouncedSearchQuery.trim()) {
|
|
2767
|
+
params.set("q", debouncedSearchQuery.trim());
|
|
2768
|
+
}
|
|
2769
|
+
if (createdByFilter !== "all") {
|
|
2770
|
+
params.set("created_by", createdByFilter);
|
|
2771
|
+
}
|
|
2772
|
+
params.set("order", "created_at");
|
|
2773
|
+
const response = await fetch(
|
|
2774
|
+
`/admin/return?${params.toString()}`,
|
|
2775
|
+
{ credentials: "include" }
|
|
2776
|
+
);
|
|
2777
|
+
if (!response.ok) {
|
|
2778
|
+
const message = await response.text();
|
|
2779
|
+
throw new Error(message || "Unable to load return orders");
|
|
2780
|
+
}
|
|
2781
|
+
const payload = await response.json();
|
|
2782
|
+
setCount(payload.count ?? 0);
|
|
2783
|
+
setOffset(nextOffset + (payload.returns?.length ?? 0));
|
|
2784
|
+
setItems(
|
|
2785
|
+
(prev) => replace ? payload.returns ?? [] : [...prev, ...payload.returns ?? []]
|
|
2786
|
+
);
|
|
2787
|
+
} catch (loadError) {
|
|
2788
|
+
const message = loadError instanceof Error ? loadError.message : "Unable to load return orders";
|
|
2789
|
+
setError(message);
|
|
2790
|
+
} finally {
|
|
2791
|
+
setIsLoading(false);
|
|
2792
|
+
setIsFetchingMore(false);
|
|
2793
|
+
}
|
|
2794
|
+
},
|
|
2795
|
+
[statusFilter, createdByFilter, debouncedSearchQuery]
|
|
2917
2796
|
);
|
|
2918
|
-
return parts.length ? parts.join(" ") : void 0;
|
|
2919
|
-
};
|
|
2920
|
-
const addressLine = (row) => {
|
|
2921
|
-
const parts = [row.address_1, row.address_2, row.city, row.province, row.postal_code, row.country_code].filter((part) => typeof part === "string" && part.trim() !== "").map((part) => part.trim());
|
|
2922
|
-
return parts.length ? parts.join(", ") : void 0;
|
|
2923
|
-
};
|
|
2924
|
-
const NAME = { key: "name", label: "Name", derive: fullName };
|
|
2925
|
-
const ADDRESS = { key: "address", label: "Address", derive: addressLine };
|
|
2926
|
-
const CREATED = { key: "created_at", label: "Created", kind: "date" };
|
|
2927
|
-
const ENTITY_FIELDS = {
|
|
2928
|
-
order: [
|
|
2929
|
-
{ key: "display_id", label: "Order number" },
|
|
2930
|
-
{ key: "status", label: "Status", kind: "status" },
|
|
2931
|
-
{ key: "email", label: "Customer email" },
|
|
2932
|
-
{ key: "customer_id", label: "Customer ID", kind: "id" },
|
|
2933
|
-
{ key: "currency_code", label: "Currency" },
|
|
2934
|
-
{ key: "region_id", label: "Region ID", kind: "id" },
|
|
2935
|
-
{ key: "sales_channel_id", label: "Sales channel ID", kind: "id" },
|
|
2936
|
-
{ key: "canceled_at", label: "Canceled", kind: "date" },
|
|
2937
|
-
CREATED
|
|
2938
|
-
],
|
|
2939
|
-
order_line_item: [
|
|
2940
|
-
{ key: "title", label: "Item" },
|
|
2941
|
-
{ key: "variant_title", label: "Variant" },
|
|
2942
|
-
{ key: "variant_sku", label: "SKU" },
|
|
2943
|
-
{ key: "unit_price", label: "Unit price", kind: "money" },
|
|
2944
|
-
{ key: "product_id", label: "Product ID", kind: "id" },
|
|
2945
|
-
{ key: "variant_id", label: "Variant ID", kind: "id" },
|
|
2946
|
-
CREATED
|
|
2947
|
-
],
|
|
2948
|
-
cart_line_item: [
|
|
2949
|
-
{ key: "title", label: "Item" },
|
|
2950
|
-
{ key: "variant_sku", label: "SKU" },
|
|
2951
|
-
{ key: "quantity", label: "Quantity", kind: "number" },
|
|
2952
|
-
{ key: "unit_price", label: "Unit price", kind: "money" },
|
|
2953
|
-
{ key: "cart_id", label: "Cart ID", kind: "id" },
|
|
2954
|
-
{ key: "variant_id", label: "Variant ID", kind: "id" },
|
|
2955
|
-
CREATED
|
|
2956
|
-
],
|
|
2957
|
-
cart: [
|
|
2958
|
-
{ key: "email", label: "Email" },
|
|
2959
|
-
{ key: "customer_id", label: "Customer ID", kind: "id" },
|
|
2960
|
-
{ key: "currency_code", label: "Currency" },
|
|
2961
|
-
{ key: "region_id", label: "Region ID", kind: "id" },
|
|
2962
|
-
{ key: "completed_at", label: "Completed", kind: "date" },
|
|
2963
|
-
CREATED
|
|
2964
|
-
],
|
|
2965
|
-
customer: [
|
|
2966
|
-
NAME,
|
|
2967
|
-
{ key: "email", label: "Email" },
|
|
2968
|
-
{ key: "phone", label: "Phone" },
|
|
2969
|
-
{ key: "company_name", label: "Company" },
|
|
2970
|
-
{ key: "has_account", label: "Registered account", kind: "boolean" },
|
|
2971
|
-
CREATED
|
|
2972
|
-
],
|
|
2973
|
-
customer_address: [
|
|
2974
|
-
{ key: "address_name", label: "Label" },
|
|
2975
|
-
NAME,
|
|
2976
|
-
ADDRESS,
|
|
2977
|
-
{ key: "phone", label: "Phone" },
|
|
2978
|
-
{ key: "customer_id", label: "Customer ID", kind: "id" },
|
|
2979
|
-
{ key: "is_default_shipping", label: "Default shipping", kind: "boolean" },
|
|
2980
|
-
CREATED
|
|
2981
|
-
],
|
|
2982
|
-
order_address: [NAME, ADDRESS, { key: "phone", label: "Phone" }, CREATED],
|
|
2983
|
-
cart_address: [NAME, ADDRESS, { key: "phone", label: "Phone" }, CREATED],
|
|
2984
|
-
product: [
|
|
2985
|
-
{ key: "title", label: "Title" },
|
|
2986
|
-
{ key: "status", label: "Status", kind: "status" },
|
|
2987
|
-
{ key: "handle", label: "Handle" },
|
|
2988
|
-
{ key: "subtitle", label: "Subtitle" },
|
|
2989
|
-
{ key: "collection_id", label: "Collection ID", kind: "id" },
|
|
2990
|
-
{ key: "is_giftcard", label: "Gift card", kind: "boolean" },
|
|
2991
|
-
CREATED
|
|
2992
|
-
],
|
|
2993
|
-
product_variant: [
|
|
2994
|
-
{ key: "title", label: "Title" },
|
|
2995
|
-
{ key: "sku", label: "SKU" },
|
|
2996
|
-
{ key: "barcode", label: "Barcode" },
|
|
2997
|
-
{ key: "product_id", label: "Product ID", kind: "id" },
|
|
2998
|
-
{ key: "manage_inventory", label: "Manages inventory", kind: "boolean" },
|
|
2999
|
-
CREATED
|
|
3000
|
-
],
|
|
3001
|
-
product_category: [
|
|
3002
|
-
{ key: "name", label: "Name" },
|
|
3003
|
-
{ key: "handle", label: "Handle" },
|
|
3004
|
-
{ key: "is_active", label: "Active", kind: "boolean" },
|
|
3005
|
-
{ key: "parent_category_id", label: "Parent category ID", kind: "id" },
|
|
3006
|
-
CREATED
|
|
3007
|
-
],
|
|
3008
|
-
product_collection: [{ key: "title", label: "Title" }, { key: "handle", label: "Handle" }, CREATED],
|
|
3009
|
-
payment: [
|
|
3010
|
-
{ key: "amount", label: "Amount", kind: "money" },
|
|
3011
|
-
{ key: "currency_code", label: "Currency" },
|
|
3012
|
-
{ key: "provider_id", label: "Provider" },
|
|
3013
|
-
{ key: "captured_at", label: "Captured", kind: "date" },
|
|
3014
|
-
{ key: "canceled_at", label: "Canceled", kind: "date" },
|
|
3015
|
-
{ key: "payment_collection_id", label: "Payment collection ID", kind: "id" },
|
|
3016
|
-
CREATED
|
|
3017
|
-
],
|
|
3018
|
-
payment_session: [
|
|
3019
|
-
{ key: "amount", label: "Amount", kind: "money" },
|
|
3020
|
-
{ key: "currency_code", label: "Currency" },
|
|
3021
|
-
{ key: "provider_id", label: "Provider" },
|
|
3022
|
-
{ key: "status", label: "Status", kind: "status" },
|
|
3023
|
-
{ key: "payment_collection_id", label: "Payment collection ID", kind: "id" },
|
|
3024
|
-
CREATED
|
|
3025
|
-
],
|
|
3026
|
-
payment_collection: [
|
|
3027
|
-
{ key: "amount", label: "Amount", kind: "money" },
|
|
3028
|
-
{ key: "currency_code", label: "Currency" },
|
|
3029
|
-
{ key: "status", label: "Status", kind: "status" },
|
|
3030
|
-
CREATED
|
|
3031
|
-
],
|
|
3032
|
-
refund: [
|
|
3033
|
-
{ key: "amount", label: "Amount", kind: "money" },
|
|
3034
|
-
{ key: "payment_id", label: "Payment ID", kind: "id" },
|
|
3035
|
-
{ key: "refund_reason_id", label: "Refund reason ID", kind: "id" },
|
|
3036
|
-
{ key: "note", label: "Note" },
|
|
3037
|
-
{ key: "created_by", label: "Created by" },
|
|
3038
|
-
CREATED
|
|
3039
|
-
],
|
|
3040
|
-
return: [
|
|
3041
|
-
{ key: "display_id", label: "Return number" },
|
|
3042
|
-
{ key: "status", label: "Status", kind: "status" },
|
|
3043
|
-
{ key: "order_id", label: "Order ID", kind: "id" },
|
|
3044
|
-
{ key: "refund_amount", label: "Refund amount", kind: "money" },
|
|
3045
|
-
{ key: "received_at", label: "Received", kind: "date" },
|
|
3046
|
-
CREATED
|
|
3047
|
-
],
|
|
3048
|
-
payment_detail: [
|
|
3049
|
-
{ key: "type", label: "Method type" },
|
|
3050
|
-
{ key: "customer_id", label: "Customer ID", kind: "id" },
|
|
3051
|
-
{ key: "is_default", label: "Default method", kind: "boolean" },
|
|
3052
|
-
CREATED
|
|
3053
|
-
],
|
|
3054
|
-
user: [NAME, { key: "email", label: "Email" }, CREATED],
|
|
3055
|
-
invite: [
|
|
3056
|
-
{ key: "email", label: "Email" },
|
|
3057
|
-
{ key: "accepted", label: "Accepted", kind: "boolean" },
|
|
3058
|
-
{ key: "expires_at", label: "Expires", kind: "date" },
|
|
3059
|
-
CREATED
|
|
3060
|
-
],
|
|
3061
|
-
api_key: [
|
|
3062
|
-
{ key: "title", label: "Title" },
|
|
3063
|
-
{ key: "type", label: "Type" },
|
|
3064
|
-
{ key: "redacted", label: "Key (redacted)" },
|
|
3065
|
-
{ key: "revoked_at", label: "Revoked", kind: "date" },
|
|
3066
|
-
CREATED
|
|
3067
|
-
],
|
|
3068
|
-
promotion: [
|
|
3069
|
-
{ key: "code", label: "Promotion code" },
|
|
3070
|
-
{ key: "type", label: "Type" },
|
|
3071
|
-
{ key: "status", label: "Status", kind: "status" },
|
|
3072
|
-
{ key: "is_automatic", label: "Automatic", kind: "boolean" },
|
|
3073
|
-
CREATED
|
|
3074
|
-
],
|
|
3075
|
-
fulfillment: [
|
|
3076
|
-
{ key: "provider_id", label: "Provider" },
|
|
3077
|
-
{ key: "location_id", label: "Location ID", kind: "id" },
|
|
3078
|
-
{ key: "shipped_at", label: "Shipped", kind: "date" },
|
|
3079
|
-
{ key: "delivered_at", label: "Delivered", kind: "date" },
|
|
3080
|
-
{ key: "canceled_at", label: "Canceled", kind: "date" },
|
|
3081
|
-
CREATED
|
|
3082
|
-
],
|
|
3083
|
-
inventory_item: [
|
|
3084
|
-
{ key: "sku", label: "SKU" },
|
|
3085
|
-
{ key: "title", label: "Title" },
|
|
3086
|
-
{ key: "requires_shipping", label: "Requires shipping", kind: "boolean" },
|
|
3087
|
-
CREATED
|
|
3088
|
-
],
|
|
3089
|
-
inventory_level: [
|
|
3090
|
-
{ key: "inventory_item_id", label: "Inventory item ID", kind: "id" },
|
|
3091
|
-
{ key: "location_id", label: "Location ID", kind: "id" },
|
|
3092
|
-
{ key: "stocked_quantity", label: "Stocked", kind: "number" },
|
|
3093
|
-
{ key: "reserved_quantity", label: "Reserved", kind: "number" },
|
|
3094
|
-
CREATED
|
|
3095
|
-
],
|
|
3096
|
-
review: [
|
|
3097
|
-
{ key: "title", label: "Title" },
|
|
3098
|
-
{ key: "rating", label: "Rating", kind: "number" },
|
|
3099
|
-
{ key: "status", label: "Status", kind: "status" },
|
|
3100
|
-
{ key: "product_id", label: "Product ID", kind: "id" },
|
|
3101
|
-
{ key: "customer_id", label: "Customer ID", kind: "id" },
|
|
3102
|
-
CREATED
|
|
3103
|
-
]
|
|
3104
|
-
};
|
|
3105
|
-
const GENERIC_FIELDS = [
|
|
3106
|
-
{ key: "display_id", label: "Number" },
|
|
3107
|
-
{ key: "title", label: "Title" },
|
|
3108
|
-
{ key: "name", label: "Name" },
|
|
3109
|
-
NAME,
|
|
3110
|
-
{ key: "email", label: "Email" },
|
|
3111
|
-
{ key: "phone", label: "Phone" },
|
|
3112
|
-
{ key: "handle", label: "Handle" },
|
|
3113
|
-
{ key: "sku", label: "SKU" },
|
|
3114
|
-
{ key: "code", label: "Code" },
|
|
3115
|
-
{ key: "status", label: "Status", kind: "status" },
|
|
3116
|
-
{ key: "type", label: "Type" },
|
|
3117
|
-
{ key: "amount", label: "Amount", kind: "money" },
|
|
3118
|
-
{ key: "quantity", label: "Quantity", kind: "number" },
|
|
3119
|
-
{ key: "currency_code", label: "Currency" },
|
|
3120
|
-
{ key: "order_id", label: "Order ID", kind: "id" },
|
|
3121
|
-
{ key: "customer_id", label: "Customer ID", kind: "id" },
|
|
3122
|
-
{ key: "product_id", label: "Product ID", kind: "id" },
|
|
3123
|
-
{ key: "payment_id", label: "Payment ID", kind: "id" },
|
|
3124
|
-
{ key: "provider_id", label: "Provider" },
|
|
3125
|
-
CREATED,
|
|
3126
|
-
{ key: "updated_at", label: "Last updated", kind: "date" }
|
|
3127
|
-
];
|
|
3128
|
-
const MAX_GENERIC_FIELDS = 8;
|
|
3129
|
-
function amountOf(value) {
|
|
3130
|
-
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
3131
|
-
if (typeof value === "string" && value.trim() !== "" && Number.isFinite(Number(value))) return Number(value);
|
|
3132
|
-
if (value !== null && typeof value === "object" && "value" in value) {
|
|
3133
|
-
return amountOf(value.value);
|
|
3134
|
-
}
|
|
3135
|
-
return null;
|
|
3136
|
-
}
|
|
3137
|
-
function formatValue(raw, kind, row) {
|
|
3138
|
-
if (raw === null || raw === void 0 || raw === "") return null;
|
|
3139
|
-
if (raw === MASKED_VALUE) return { value: MASKED_VALUE, kind: "masked" };
|
|
3140
|
-
switch (kind) {
|
|
3141
|
-
case "money": {
|
|
3142
|
-
const amount = amountOf(raw);
|
|
3143
|
-
if (amount === null) return null;
|
|
3144
|
-
const currency = typeof row.currency_code === "string" ? row.currency_code : null;
|
|
3145
|
-
return { value: formatMoney(amount, currency), kind };
|
|
3146
|
-
}
|
|
3147
|
-
case "date":
|
|
3148
|
-
return typeof raw === "string" || raw instanceof Date ? { value: formatDate(raw), kind } : null;
|
|
3149
|
-
case "boolean":
|
|
3150
|
-
return { value: raw === true || raw === "true" ? "Yes" : "No", kind };
|
|
3151
|
-
case "number": {
|
|
3152
|
-
const n = amountOf(raw);
|
|
3153
|
-
return n === null ? null : { value: formatNumber(n), kind };
|
|
3154
|
-
}
|
|
3155
|
-
case "status":
|
|
3156
|
-
return { value: String(raw).replace(/_/g, " "), kind };
|
|
3157
|
-
default:
|
|
3158
|
-
if (typeof raw === "object") return null;
|
|
3159
|
-
if (typeof raw === "string" && raw.length > 160) return { value: `${raw.slice(0, 157)}…`, kind };
|
|
3160
|
-
return { value: String(raw), kind };
|
|
3161
|
-
}
|
|
3162
|
-
}
|
|
3163
|
-
function summarizeOldData(tableName, oldData) {
|
|
3164
|
-
if (!oldData) return [];
|
|
3165
|
-
const { value: row } = maskSensitiveData(oldData, tableName);
|
|
3166
|
-
const specific = ENTITY_FIELDS[tableName];
|
|
3167
|
-
const specs = specific ?? GENERIC_FIELDS;
|
|
3168
|
-
const fields = [];
|
|
3169
|
-
const seenLabels = /* @__PURE__ */ new Set();
|
|
3170
|
-
for (const spec of specs) {
|
|
3171
|
-
const raw = spec.derive ? spec.derive(row) : row[spec.key];
|
|
3172
|
-
const formatted = formatValue(raw, spec.kind ?? "text", row);
|
|
3173
|
-
if (!formatted || seenLabels.has(spec.label)) continue;
|
|
3174
|
-
seenLabels.add(spec.label);
|
|
3175
|
-
const value = spec.key === "currency_code" ? formatted.value.toUpperCase() : formatted.value;
|
|
3176
|
-
fields.push({ key: spec.key, label: spec.label, value, kind: formatted.kind });
|
|
3177
|
-
if (!specific && fields.length >= MAX_GENERIC_FIELDS) break;
|
|
3178
|
-
}
|
|
3179
|
-
return fields;
|
|
3180
|
-
}
|
|
3181
|
-
function readLastListSearch() {
|
|
3182
|
-
try {
|
|
3183
|
-
return window.sessionStorage.getItem(LAST_LIST_URL_KEY) ?? "";
|
|
3184
|
-
} catch {
|
|
3185
|
-
return "";
|
|
3186
|
-
}
|
|
3187
|
-
}
|
|
3188
|
-
const DeletedRecordDetailPage = () => {
|
|
3189
|
-
var _a;
|
|
3190
|
-
const navigate = reactRouterDom.useNavigate();
|
|
3191
|
-
const location = reactRouterDom.useLocation();
|
|
3192
|
-
const { id = "" } = reactRouterDom.useParams();
|
|
3193
|
-
const [state, setState] = react.useState({ status: "loading" });
|
|
3194
|
-
const [reloadToken, setReloadToken] = react.useState(0);
|
|
3195
|
-
const cameFromList = ((_a = location.state) == null ? void 0 : _a.fromList) === true;
|
|
3196
|
-
const goBack = () => {
|
|
3197
|
-
if (cameFromList) navigate(-1);
|
|
3198
|
-
else navigate(`/deleted-records-audit${readLastListSearch()}`);
|
|
3199
|
-
};
|
|
3200
2797
|
react.useEffect(() => {
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
return () => controller.abort();
|
|
3212
|
-
}, [id, reloadToken]);
|
|
3213
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-3 md:p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-4 md:p-6", children: [
|
|
3214
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: "transparent", size: "small", onClick: goBack, className: "-ml-2", children: [
|
|
3215
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, {}),
|
|
3216
|
-
"Back to Deleted Records"
|
|
3217
|
-
] }) }),
|
|
3218
|
-
state.status === "loading" ? /* @__PURE__ */ jsxRuntime.jsx(DetailSkeleton, {}) : state.status === "error" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3219
|
-
DetailError,
|
|
3220
|
-
{
|
|
3221
|
-
notFound: state.notFound,
|
|
3222
|
-
message: state.message,
|
|
3223
|
-
onRetry: () => setReloadToken((t) => t + 1),
|
|
3224
|
-
onBack: goBack
|
|
3225
|
-
}
|
|
3226
|
-
) : /* @__PURE__ */ jsxRuntime.jsx(DetailContent, { audit: state.audit })
|
|
3227
|
-
] }) });
|
|
3228
|
-
};
|
|
3229
|
-
const DetailContent = ({ audit }) => {
|
|
3230
|
-
const navigate = reactRouterDom.useNavigate();
|
|
3231
|
-
const entity = getEntityInfo(audit.table_name);
|
|
3232
|
-
const source = describeSource(audit.source);
|
|
3233
|
-
const summary = react.useMemo(() => summarizeOldData(audit.table_name, audit.old_data), [audit]);
|
|
3234
|
-
const masked = react.useMemo(() => maskSensitiveData(audit.old_data, audit.table_name), [audit]);
|
|
3235
|
-
const guidance = getNextSteps(entity.category.id);
|
|
3236
|
-
const related = getRelatedLinks(audit.table_name, audit.old_data);
|
|
3237
|
-
const [showRaw, setShowRaw] = react.useState(false);
|
|
3238
|
-
const copyJson = async () => {
|
|
3239
|
-
try {
|
|
3240
|
-
await navigator.clipboard.writeText(JSON.stringify(masked.value, null, 2));
|
|
3241
|
-
ui.toast.success("Record data copied", {
|
|
3242
|
-
description: masked.maskedCount ? "Sensitive values were left hidden." : void 0
|
|
3243
|
-
});
|
|
3244
|
-
} catch {
|
|
3245
|
-
ui.toast.error("Couldn’t copy to clipboard");
|
|
3246
|
-
}
|
|
3247
|
-
};
|
|
3248
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3249
|
-
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
|
|
3250
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
3251
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { size: "small", color: "red", children: [
|
|
3252
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.Trash, {}),
|
|
3253
|
-
"Deleted"
|
|
3254
|
-
] }),
|
|
3255
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: entity.category.label })
|
|
3256
|
-
] }),
|
|
3257
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Heading, { level: "h1", children: [
|
|
3258
|
-
"Deleted ",
|
|
3259
|
-
entity.label
|
|
3260
|
-
] }),
|
|
2798
|
+
void loadReturns(0, true);
|
|
2799
|
+
}, [statusFilter, createdByFilter, debouncedSearchQuery, loadReturns]);
|
|
2800
|
+
const hasMore = react.useMemo(() => offset < count, [offset, count]);
|
|
2801
|
+
const availableStatuses = react.useMemo(() => {
|
|
2802
|
+
const statuses = /* @__PURE__ */ new Set();
|
|
2803
|
+
items.forEach((item) => statuses.add(item.status));
|
|
2804
|
+
return Array.from(statuses).sort();
|
|
2805
|
+
}, [items]);
|
|
2806
|
+
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: [
|
|
2807
|
+
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
3261
2808
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
3262
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3263
|
-
/* @__PURE__ */ jsxRuntime.
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
] })
|
|
3267
|
-
] })
|
|
2809
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Return Orders" }),
|
|
2810
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer return orders" })
|
|
2811
|
+
] }),
|
|
2812
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadReturns(0, true), children: "Refresh" })
|
|
3268
2813
|
] }),
|
|
3269
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex
|
|
3270
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
2814
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
2815
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2816
|
+
ui.Input,
|
|
2817
|
+
{
|
|
2818
|
+
placeholder: "Search by return ID, order ID, or customer email",
|
|
2819
|
+
value: searchQuery,
|
|
2820
|
+
onChange: (event) => setSearchQuery(event.target.value),
|
|
2821
|
+
className: "md:max-w-sm"
|
|
2822
|
+
}
|
|
2823
|
+
),
|
|
2824
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
|
|
2825
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2826
|
+
"select",
|
|
2827
|
+
{
|
|
2828
|
+
value: createdByFilter,
|
|
2829
|
+
onChange: (event) => setCreatedByFilter(event.target.value),
|
|
2830
|
+
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",
|
|
2831
|
+
children: [
|
|
2832
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All (Created by)" }),
|
|
2833
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "customer", children: "Customer" }),
|
|
2834
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "admin", children: "Admin" })
|
|
2835
|
+
]
|
|
2836
|
+
}
|
|
2837
|
+
),
|
|
2838
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2839
|
+
"select",
|
|
2840
|
+
{
|
|
2841
|
+
value: statusFilter,
|
|
2842
|
+
onChange: (event) => setStatusFilter(event.target.value),
|
|
2843
|
+
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",
|
|
2844
|
+
children: [
|
|
2845
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All Statuses" }),
|
|
2846
|
+
availableStatuses.map((status) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
|
|
2847
|
+
]
|
|
2848
|
+
}
|
|
2849
|
+
)
|
|
3274
2850
|
] })
|
|
3275
2851
|
] }),
|
|
3276
|
-
|
|
3277
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
2852
|
+
error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
2853
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
2854
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2855
|
+
ui.Button,
|
|
2856
|
+
{
|
|
2857
|
+
variant: "secondary",
|
|
2858
|
+
onClick: () => loadReturns(0, true),
|
|
2859
|
+
children: "Try again"
|
|
2860
|
+
}
|
|
2861
|
+
) })
|
|
2862
|
+
] }) : null,
|
|
2863
|
+
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: [
|
|
2864
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No return orders yet" }),
|
|
2865
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Return orders created by customers will appear here." })
|
|
2866
|
+
] }) : /* @__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: [
|
|
2867
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
2868
|
+
/* @__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" }),
|
|
2869
|
+
/* @__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" }),
|
|
2870
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Customer" }),
|
|
2871
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
|
|
2872
|
+
/* @__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" }),
|
|
2873
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
2874
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
3283
2875
|
] }) }),
|
|
3284
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3285
|
-
|
|
3286
|
-
|
|
2876
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((returnOrder) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2877
|
+
"tr",
|
|
2878
|
+
{
|
|
2879
|
+
className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
|
|
2880
|
+
onClick: () => navigate(`/returns/${returnOrder.id}`),
|
|
2881
|
+
children: [
|
|
2882
|
+
/* @__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 }) }) }),
|
|
2883
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.order_id }),
|
|
2884
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.customer_email || returnOrder.order_email || "—" }),
|
|
2885
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2886
|
+
ui.Badge,
|
|
2887
|
+
{
|
|
2888
|
+
size: "2xsmall",
|
|
2889
|
+
className: `uppercase ${getStatusBadgeClass$5(returnOrder.status)}`,
|
|
2890
|
+
children: returnOrder.status.replace(/_/g, " ")
|
|
2891
|
+
}
|
|
2892
|
+
) }),
|
|
2893
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
|
|
2894
|
+
const calc = returnOrder.refund;
|
|
2895
|
+
if (calc?.is_processed && calc.final_refund_amount != null) {
|
|
2896
|
+
return formatRefundCurrency(
|
|
2897
|
+
calc.final_refund_amount,
|
|
2898
|
+
calc.currency_code || returnOrder.currency_code
|
|
2899
|
+
);
|
|
2900
|
+
}
|
|
2901
|
+
if (calc) {
|
|
2902
|
+
return "Pending";
|
|
2903
|
+
}
|
|
2904
|
+
if (returnOrder.refund_amount == null) {
|
|
2905
|
+
return "—";
|
|
2906
|
+
}
|
|
2907
|
+
return formatRefundCurrency(
|
|
2908
|
+
Number(returnOrder.refund_amount),
|
|
2909
|
+
returnOrder.currency_code
|
|
2910
|
+
);
|
|
2911
|
+
})() }),
|
|
2912
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(returnOrder.created_at).toLocaleDateString("en-US", {
|
|
2913
|
+
year: "numeric",
|
|
2914
|
+
month: "short",
|
|
2915
|
+
day: "numeric",
|
|
2916
|
+
hour: "numeric",
|
|
2917
|
+
minute: "2-digit",
|
|
2918
|
+
hour12: true
|
|
2919
|
+
}) }),
|
|
2920
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2921
|
+
ui.Button,
|
|
2922
|
+
{
|
|
2923
|
+
variant: "transparent",
|
|
2924
|
+
size: "small",
|
|
2925
|
+
onClick: (e) => {
|
|
2926
|
+
e.stopPropagation();
|
|
2927
|
+
navigate(`/app/orders/${returnOrder.order_id}`);
|
|
2928
|
+
},
|
|
2929
|
+
children: "Go to order"
|
|
2930
|
+
}
|
|
2931
|
+
) })
|
|
2932
|
+
]
|
|
2933
|
+
},
|
|
2934
|
+
returnOrder.id
|
|
2935
|
+
)) })
|
|
3287
2936
|
] }) }),
|
|
3288
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3289
|
-
|
|
3290
|
-
{
|
|
3291
|
-
title: "Record summary",
|
|
3292
|
-
description: `Key details of this ${entity.label.toLowerCase()} at the moment it was deleted.`,
|
|
3293
|
-
children: summary.length ? /* @__PURE__ */ jsxRuntime.jsx("dl", { className: "grid grid-cols-1 gap-x-6 gap-y-4 sm:grid-cols-2", children: summary.map((field) => /* @__PURE__ */ jsxRuntime.jsx(Field, { label: field.label, children: field.kind === "id" ? /* @__PURE__ */ jsxRuntime.jsx(CopyableId, { value: field.value }) : field.kind === "status" ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { size: "2xsmall", color: "grey", className: "capitalize", children: field.value }) : field.kind === "masked" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-muted", children: "Hidden for security" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "break-words text-sm text-ui-fg-base", children: field.value }) }, field.label)) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No key details could be extracted for this record type. See the original record data below." })
|
|
3294
|
-
}
|
|
3295
|
-
),
|
|
3296
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3297
|
-
Section,
|
|
2937
|
+
hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2938
|
+
ui.Button,
|
|
3298
2939
|
{
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
"Copy JSON"
|
|
3304
|
-
] }) : null,
|
|
3305
|
-
children: audit.old_data ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
3306
|
-
masked.maskedCount > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
3307
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.ShieldCheck, { className: "shrink-0 text-ui-fg-muted" }),
|
|
3308
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
|
|
3309
|
-
masked.maskedCount,
|
|
3310
|
-
" sensitive ",
|
|
3311
|
-
masked.maskedCount === 1 ? "value is" : "values are",
|
|
3312
|
-
" hidden for security (passwords, tokens, card or account numbers)."
|
|
3313
|
-
] })
|
|
3314
|
-
] }) : null,
|
|
3315
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: "secondary", size: "small", onClick: () => setShowRaw((s2) => !s2), "aria-expanded": showRaw, children: [
|
|
3316
|
-
showRaw ? /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronDownMini, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronRightMini, {}),
|
|
3317
|
-
showRaw ? "Hide full record" : "View full record"
|
|
3318
|
-
] }) }),
|
|
3319
|
-
showRaw ? /* @__PURE__ */ jsxRuntime.jsx(JsonViewer, { data: masked.value }) : null
|
|
3320
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No data was captured for this deletion." })
|
|
2940
|
+
variant: "secondary",
|
|
2941
|
+
isLoading: isFetchingMore,
|
|
2942
|
+
onClick: () => loadReturns(offset, false),
|
|
2943
|
+
children: "Load more"
|
|
3321
2944
|
}
|
|
3322
|
-
)
|
|
3323
|
-
|
|
3324
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-base", children: [
|
|
3325
|
-
"This record was permanently deleted. ",
|
|
3326
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Automatic restoration is not available" }),
|
|
3327
|
-
" ",
|
|
3328
|
-
"from this screen."
|
|
3329
|
-
] }),
|
|
3330
|
-
/* @__PURE__ */ jsxRuntime.jsxs("ol", { className: "flex list-decimal flex-col gap-3 pl-5 text-sm text-ui-fg-subtle marker:text-ui-fg-muted", children: [
|
|
3331
|
-
/* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
|
|
3332
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-ui-fg-base", children: "Check whether this was expected." }),
|
|
3333
|
-
" ",
|
|
3334
|
-
audit.deleted_by || source.kind !== "unknown" ? "Confirm with the person or system shown above." : `Who deleted it wasn’t recorded—check with your team or integrations active around ${formatExactDateTime(audit.occurred_at)}.`,
|
|
3335
|
-
" ",
|
|
3336
|
-
guidance.headline
|
|
3337
|
-
] }),
|
|
3338
|
-
/* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
|
|
3339
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-ui-fg-base", children: "If it needs to come back:" }),
|
|
3340
|
-
" ",
|
|
3341
|
-
guidance.recreate
|
|
3342
|
-
] }),
|
|
3343
|
-
/* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
|
|
3344
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-ui-fg-base", children: "Need the details?" }),
|
|
3345
|
-
" Use “View full record” above to see or copy everything that was stored. Sensitive values stay hidden."
|
|
3346
|
-
] })
|
|
3347
|
-
] }),
|
|
3348
|
-
guidance.adminSection || related.length ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
|
|
3349
|
-
guidance.adminSection ? /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", size: "small", onClick: () => navigate(guidance.adminSection.path), children: guidance.adminSection.label }) : null,
|
|
3350
|
-
related.map((link) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3351
|
-
ui.Button,
|
|
3352
|
-
{
|
|
3353
|
-
variant: "transparent",
|
|
3354
|
-
size: "small",
|
|
3355
|
-
onClick: () => navigate(link.path),
|
|
3356
|
-
title: `Opens ${link.label.toLowerCase()} ${link.id} if it still exists`,
|
|
3357
|
-
children: [
|
|
3358
|
-
"Open related ",
|
|
3359
|
-
link.label.toLowerCase(),
|
|
3360
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.ChevronRightMini, {})
|
|
3361
|
-
]
|
|
3362
|
-
},
|
|
3363
|
-
link.path
|
|
3364
|
-
))
|
|
3365
|
-
] }) : null,
|
|
3366
|
-
related.length ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: "Related records open only if they haven’t been deleted too." }) : null
|
|
3367
|
-
] }) })
|
|
3368
|
-
] });
|
|
2945
|
+
) }) : null
|
|
2946
|
+
] }) });
|
|
3369
2947
|
};
|
|
3370
|
-
const
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
}) => /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "flex flex-col gap-4 rounded-lg border border-ui-border-base p-5", children: [
|
|
3376
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-start justify-between gap-2", children: [
|
|
3377
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [
|
|
3378
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: title }),
|
|
3379
|
-
description ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: description }) : null
|
|
3380
|
-
] }),
|
|
3381
|
-
actions
|
|
3382
|
-
] }),
|
|
3383
|
-
children
|
|
3384
|
-
] });
|
|
3385
|
-
const Field = ({ label, children }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-col gap-1", children: [
|
|
3386
|
-
/* @__PURE__ */ jsxRuntime.jsx("dt", { className: "text-xs font-medium uppercase tracking-wide text-ui-fg-muted", children: label }),
|
|
3387
|
-
/* @__PURE__ */ jsxRuntime.jsx("dd", { className: "min-w-0", children })
|
|
3388
|
-
] });
|
|
3389
|
-
const DetailSkeleton = () => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", "aria-busy": "true", children: [
|
|
3390
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
3391
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-5 w-24 rounded-full" }),
|
|
3392
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-8 w-64" }),
|
|
3393
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-4 w-48" })
|
|
3394
|
-
] }),
|
|
3395
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-14 w-full" }),
|
|
3396
|
-
Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4 rounded-lg border border-ui-border-base p-5", children: [
|
|
3397
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-5 w-40" }),
|
|
3398
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: Array.from({ length: 4 }).map((__, j) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
3399
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-3 w-20" }),
|
|
3400
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-4 w-36" })
|
|
3401
|
-
] }, j)) })
|
|
3402
|
-
] }, i))
|
|
3403
|
-
] });
|
|
3404
|
-
const DetailError = ({
|
|
3405
|
-
notFound,
|
|
3406
|
-
message,
|
|
3407
|
-
onRetry,
|
|
3408
|
-
onBack
|
|
3409
|
-
}) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-2 rounded-lg border border-ui-border-base px-6 py-12 text-center", children: [
|
|
3410
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.ExclamationCircle, { className: ui.clx(notFound ? "text-ui-fg-muted" : "text-ui-fg-error") }),
|
|
3411
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", children: notFound ? "Audit entry not found" : "Unable to load this deleted record" }),
|
|
3412
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "max-w-md text-ui-fg-subtle", children: notFound ? "This audit entry doesn’t exist. The link may be incorrect." : "We couldn’t retrieve the audit entry right now. Check your connection and try again." }),
|
|
3413
|
-
!notFound ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "max-w-md font-mono text-ui-fg-muted", children: message }) : null,
|
|
3414
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 flex gap-2", children: [
|
|
3415
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", size: "small", onClick: onBack, children: "Back to Deleted Records" }),
|
|
3416
|
-
!notFound ? /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", size: "small", onClick: onRetry, children: "Try again" }) : null
|
|
3417
|
-
] })
|
|
3418
|
-
] });
|
|
3419
|
-
adminSdk.defineRouteConfig({});
|
|
3420
|
-
const useDebounce$1 = (value, delay) => {
|
|
2948
|
+
const config$6 = adminSdk.defineRouteConfig({
|
|
2949
|
+
label: "Return Orders",
|
|
2950
|
+
icon: icons.ArrowPath
|
|
2951
|
+
});
|
|
2952
|
+
const useDebounce = (value, delay) => {
|
|
3421
2953
|
const [debouncedValue, setDebouncedValue] = react.useState(value);
|
|
3422
2954
|
react.useEffect(() => {
|
|
3423
2955
|
const handler = setTimeout(() => setDebouncedValue(value), delay);
|
|
@@ -3425,7 +2957,7 @@ const useDebounce$1 = (value, delay) => {
|
|
|
3425
2957
|
}, [value, delay]);
|
|
3426
2958
|
return debouncedValue;
|
|
3427
2959
|
};
|
|
3428
|
-
const getStatusBadgeClass$
|
|
2960
|
+
const getStatusBadgeClass$4 = (status) => {
|
|
3429
2961
|
const statusLower = status.toLowerCase();
|
|
3430
2962
|
if (statusLower === "requested") {
|
|
3431
2963
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
@@ -3450,7 +2982,7 @@ const SwapsPage = () => {
|
|
|
3450
2982
|
const [statusFilter, setStatusFilter] = react.useState("all");
|
|
3451
2983
|
const [createdByFilter, setCreatedByFilter] = react.useState("all");
|
|
3452
2984
|
const [searchQuery, setSearchQuery] = react.useState("");
|
|
3453
|
-
const debouncedSearchQuery = useDebounce
|
|
2985
|
+
const debouncedSearchQuery = useDebounce(searchQuery, 300);
|
|
3454
2986
|
const [isLoading, setIsLoading] = react.useState(true);
|
|
3455
2987
|
const [isFetchingMore, setIsFetchingMore] = react.useState(false);
|
|
3456
2988
|
const [error, setError] = react.useState(null);
|
|
@@ -3459,7 +2991,6 @@ const SwapsPage = () => {
|
|
|
3459
2991
|
const limit = 50;
|
|
3460
2992
|
const loadSwaps = react.useCallback(
|
|
3461
2993
|
async (nextOffset, replace = false) => {
|
|
3462
|
-
var _a;
|
|
3463
2994
|
try {
|
|
3464
2995
|
if (replace) {
|
|
3465
2996
|
setIsLoading(true);
|
|
@@ -3489,7 +3020,7 @@ const SwapsPage = () => {
|
|
|
3489
3020
|
}
|
|
3490
3021
|
const payload = await response.json();
|
|
3491
3022
|
setCount(payload.count ?? 0);
|
|
3492
|
-
setOffset(nextOffset + (
|
|
3023
|
+
setOffset(nextOffset + (payload.swaps?.length ?? 0));
|
|
3493
3024
|
setItems(
|
|
3494
3025
|
(prev) => replace ? payload.swaps ?? [] : [...prev, ...payload.swaps ?? []]
|
|
3495
3026
|
);
|
|
@@ -3593,7 +3124,7 @@ const SwapsPage = () => {
|
|
|
3593
3124
|
ui.Badge,
|
|
3594
3125
|
{
|
|
3595
3126
|
size: "2xsmall",
|
|
3596
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
3127
|
+
className: `uppercase ${getStatusBadgeClass$4(swap.status)}`,
|
|
3597
3128
|
children: swap.status.replace(/_/g, " ")
|
|
3598
3129
|
}
|
|
3599
3130
|
) }),
|
|
@@ -3647,301 +3178,748 @@ const config$5 = adminSdk.defineRouteConfig({
|
|
|
3647
3178
|
label: "Exchanges",
|
|
3648
3179
|
icon: icons.ArrowPath
|
|
3649
3180
|
});
|
|
3650
|
-
const
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3181
|
+
const MASKED_VALUE = "••••••••••••";
|
|
3182
|
+
const SENSITIVE_KEY_PATTERNS = [
|
|
3183
|
+
/password|passwd|passphrase/i,
|
|
3184
|
+
/secret/i,
|
|
3185
|
+
/token/i,
|
|
3186
|
+
/api_?key$/i,
|
|
3187
|
+
/private_?key/i,
|
|
3188
|
+
/access_?key/i,
|
|
3189
|
+
/(^|_)hash(ed)?($|_)/i,
|
|
3190
|
+
/(^|_)salt$/i,
|
|
3191
|
+
/^cvv$|^cvc$|security_code/i,
|
|
3192
|
+
/card_?number/i,
|
|
3193
|
+
/account_?number/i,
|
|
3194
|
+
/credential/i,
|
|
3195
|
+
/authorization/i,
|
|
3196
|
+
/recovery_?code/i,
|
|
3197
|
+
/(^|_)otp($|_)/i,
|
|
3198
|
+
/verification_?code/i,
|
|
3199
|
+
/^code_hash$/i,
|
|
3200
|
+
/webhook_?signature/i
|
|
3201
|
+
];
|
|
3202
|
+
const TABLE_SENSITIVE_KEYS = {
|
|
3203
|
+
otp_verification: /* @__PURE__ */ new Set(["code", "value"]),
|
|
3204
|
+
auth_verification: /* @__PURE__ */ new Set(["code", "value"]),
|
|
3205
|
+
auth_mfa_factor: /* @__PURE__ */ new Set(["value", "config"])
|
|
3665
3206
|
};
|
|
3666
|
-
const
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
const
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
const params = new URLSearchParams();
|
|
3693
|
-
params.set("limit", String(limit));
|
|
3694
|
-
params.set("offset", String(nextOffset));
|
|
3695
|
-
if (debouncedOrderId.trim()) params.set("order_id", debouncedOrderId.trim());
|
|
3696
|
-
if (paymentStatusFilter !== "all") params.set("payment_status", paymentStatusFilter);
|
|
3697
|
-
if (debouncedProvider.trim()) params.set("provider_id", debouncedProvider.trim());
|
|
3698
|
-
if (debouncedCurrency.trim()) params.set("currency_code", debouncedCurrency.trim());
|
|
3699
|
-
if (dateFrom.trim()) params.set("date_from", dateFrom.trim());
|
|
3700
|
-
if (dateTo.trim()) params.set("date_to", dateTo.trim());
|
|
3701
|
-
const min = amountMin.trim() ? Number(amountMin) : void 0;
|
|
3702
|
-
const max = amountMax.trim() ? Number(amountMax) : void 0;
|
|
3703
|
-
if (min != null && !Number.isNaN(min)) params.set("amount_min", String(min));
|
|
3704
|
-
if (max != null && !Number.isNaN(max)) params.set("amount_max", String(max));
|
|
3705
|
-
const response = await fetch(`/admin/refunds?${params.toString()}`, {
|
|
3706
|
-
credentials: "include"
|
|
3707
|
-
});
|
|
3708
|
-
if (!response.ok) {
|
|
3709
|
-
const text = await response.text();
|
|
3710
|
-
throw new Error(text || "Failed to load refunds");
|
|
3711
|
-
}
|
|
3712
|
-
const payload = await response.json();
|
|
3713
|
-
const list = payload.refunds ?? [];
|
|
3714
|
-
setCount(payload.count ?? 0);
|
|
3715
|
-
setOffset(nextOffset + list.length);
|
|
3716
|
-
setItems((prev) => replace ? list : [...prev, ...list]);
|
|
3717
|
-
} catch (e) {
|
|
3718
|
-
setError(e instanceof Error ? e.message : "Failed to load");
|
|
3719
|
-
} finally {
|
|
3720
|
-
setIsLoading(false);
|
|
3721
|
-
setIsFetchingMore(false);
|
|
3207
|
+
const SAFE_KEYS = /* @__PURE__ */ new Set([
|
|
3208
|
+
"token_type",
|
|
3209
|
+
"redacted",
|
|
3210
|
+
"api_key_id",
|
|
3211
|
+
"token_id",
|
|
3212
|
+
"notification_token_id"
|
|
3213
|
+
]);
|
|
3214
|
+
function isSensitiveKey(key) {
|
|
3215
|
+
const normalized = key.trim().toLowerCase();
|
|
3216
|
+
if (SAFE_KEYS.has(normalized)) return false;
|
|
3217
|
+
return SENSITIVE_KEY_PATTERNS.some((pattern) => pattern.test(normalized));
|
|
3218
|
+
}
|
|
3219
|
+
const FULLY_SECRET_TABLES = /* @__PURE__ */ new Set(["auth_mfa_recovery_code", "auth_password_reset_token"]);
|
|
3220
|
+
const ALWAYS_VISIBLE_KEYS = /* @__PURE__ */ new Set(["id", "created_at", "updated_at", "deleted_at", "expires_at", "used_at"]);
|
|
3221
|
+
function maskValue(value, ctx, depth) {
|
|
3222
|
+
if (Array.isArray(value)) return value.map((item) => maskValue(item, ctx, depth + 1));
|
|
3223
|
+
if (value !== null && typeof value === "object") {
|
|
3224
|
+
const out = {};
|
|
3225
|
+
for (const [key, inner] of Object.entries(value)) {
|
|
3226
|
+
const topLevel = depth === 0;
|
|
3227
|
+
const secret = inner !== null && inner !== void 0 && inner !== "" && (isSensitiveKey(key) || topLevel && ctx.tableKeys?.has(key.toLowerCase()) === true || topLevel && ctx.maskAll && !ALWAYS_VISIBLE_KEYS.has(key) && !key.endsWith("_id"));
|
|
3228
|
+
if (secret) {
|
|
3229
|
+
ctx.count += 1;
|
|
3230
|
+
out[key] = MASKED_VALUE;
|
|
3231
|
+
} else {
|
|
3232
|
+
out[key] = maskValue(inner, ctx, depth + 1);
|
|
3722
3233
|
}
|
|
3723
|
-
}
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
]
|
|
3734
|
-
);
|
|
3735
|
-
react.useEffect(() => {
|
|
3736
|
-
void loadRefunds(0, true);
|
|
3737
|
-
}, [loadRefunds]);
|
|
3738
|
-
const hasMore = react.useMemo(() => offset < count, [offset, count]);
|
|
3739
|
-
const displayAmount = (r) => {
|
|
3740
|
-
const code = (r.currency_code ?? "USD").toUpperCase();
|
|
3741
|
-
return `${code} ${Number(r.amount)}`;
|
|
3234
|
+
}
|
|
3235
|
+
return out;
|
|
3236
|
+
}
|
|
3237
|
+
return value;
|
|
3238
|
+
}
|
|
3239
|
+
function maskSensitiveData(data, tableName) {
|
|
3240
|
+
const ctx = {
|
|
3241
|
+
count: 0,
|
|
3242
|
+
maskAll: tableName ? FULLY_SECRET_TABLES.has(tableName) : false,
|
|
3243
|
+
tableKeys: tableName ? TABLE_SENSITIVE_KEYS[tableName] : void 0
|
|
3742
3244
|
};
|
|
3743
|
-
const
|
|
3744
|
-
|
|
3745
|
-
|
|
3245
|
+
const value = maskValue(data, ctx, 0);
|
|
3246
|
+
return { value, maskedCount: ctx.count };
|
|
3247
|
+
}
|
|
3248
|
+
const AUTO_EXPAND_DEPTH = 1;
|
|
3249
|
+
const LONG_STRING = 200;
|
|
3250
|
+
const JsonViewer = ({ data }) => {
|
|
3251
|
+
const [generation, setGeneration] = react.useState(0);
|
|
3252
|
+
const [expandAll, setExpandAll] = react.useState(null);
|
|
3253
|
+
const setAll = (value) => {
|
|
3254
|
+
setExpandAll(value);
|
|
3255
|
+
setGeneration((g) => g + 1);
|
|
3746
3256
|
};
|
|
3747
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
3748
|
-
/* @__PURE__ */ jsxRuntime.jsxs("
|
|
3749
|
-
/* @__PURE__ */ jsxRuntime.
|
|
3750
|
-
|
|
3751
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Refund records — amount, order, payment status" })
|
|
3752
|
-
] }),
|
|
3753
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadRefunds(0, true), children: "Refresh" })
|
|
3257
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
3258
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
|
|
3259
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => setAll(true), children: "Expand all" }),
|
|
3260
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => setAll(false), children: "Collapse all" })
|
|
3754
3261
|
] }),
|
|
3755
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
}
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3262
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-h-[560px] overflow-auto rounded-lg border border-ui-border-base bg-ui-bg-subtle p-3 font-mono text-xs leading-5", children: /* @__PURE__ */ jsxRuntime.jsx(JsonNode, { value: data, depth: 0, forceExpand: expandAll }, generation) })
|
|
3263
|
+
] });
|
|
3264
|
+
};
|
|
3265
|
+
const JsonNode = ({ name, value, depth, forceExpand }) => {
|
|
3266
|
+
const isContainer = value !== null && typeof value === "object";
|
|
3267
|
+
const [open, setOpen] = react.useState(forceExpand ?? depth < AUTO_EXPAND_DEPTH);
|
|
3268
|
+
const label = name !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-ui-fg-subtle", children: [
|
|
3269
|
+
name,
|
|
3270
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-fg-muted", children: ": " })
|
|
3271
|
+
] }) : null;
|
|
3272
|
+
if (!isContainer) {
|
|
3273
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 items-start", style: { paddingLeft: depth ? 16 : 0 }, children: [
|
|
3274
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-4 shrink-0" }),
|
|
3275
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0 break-words [overflow-wrap:anywhere]", children: [
|
|
3276
|
+
label,
|
|
3277
|
+
/* @__PURE__ */ jsxRuntime.jsx(Primitive, { value })
|
|
3278
|
+
] })
|
|
3279
|
+
] });
|
|
3280
|
+
}
|
|
3281
|
+
const entries = Array.isArray(value) ? value.map((v, i) => [String(i), v]) : Object.entries(value);
|
|
3282
|
+
const [openBracket, closeBracket] = Array.isArray(value) ? ["[", "]"] : ["{", "}"];
|
|
3283
|
+
const summary = Array.isArray(value) ? `${entries.length} items` : `${entries.length} keys`;
|
|
3284
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { paddingLeft: depth ? 16 : 0 }, children: [
|
|
3285
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3286
|
+
"button",
|
|
3287
|
+
{
|
|
3288
|
+
type: "button",
|
|
3289
|
+
onClick: () => setOpen((o) => !o),
|
|
3290
|
+
className: "flex items-start text-left hover:bg-ui-bg-base-hover",
|
|
3291
|
+
"aria-expanded": open,
|
|
3292
|
+
children: [
|
|
3293
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex w-4 shrink-0 items-center pt-0.5 text-ui-fg-muted", children: entries.length ? open ? /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronDownMini, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronRightMini, {}) : null }),
|
|
3294
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
3295
|
+
label,
|
|
3296
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-fg-muted", children: openBracket }),
|
|
3297
|
+
!open || entries.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3298
|
+
entries.length ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-1 italic text-ui-fg-muted", children: summary }) : null,
|
|
3299
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-fg-muted", children: closeBracket })
|
|
3300
|
+
] }) : null
|
|
3301
|
+
] })
|
|
3302
|
+
]
|
|
3303
|
+
}
|
|
3304
|
+
),
|
|
3305
|
+
open && entries.length ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3306
|
+
entries.map(([key, child]) => /* @__PURE__ */ jsxRuntime.jsx(JsonNode, { name: key, value: child, depth: depth + 1, forceExpand }, key)),
|
|
3307
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { paddingLeft: 16 }, className: "text-ui-fg-muted", children: closeBracket })
|
|
3308
|
+
] }) : null
|
|
3309
|
+
] });
|
|
3310
|
+
};
|
|
3311
|
+
const Primitive = ({ value }) => {
|
|
3312
|
+
const [showFull, setShowFull] = react.useState(false);
|
|
3313
|
+
if (value === MASKED_VALUE) {
|
|
3314
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded bg-ui-tag-orange-bg px-1 text-ui-tag-orange-text", title: "Hidden for security", children: MASKED_VALUE });
|
|
3315
|
+
}
|
|
3316
|
+
if (value === null || value === void 0) return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-fg-muted", children: "null" });
|
|
3317
|
+
if (typeof value === "boolean") return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-tag-purple-text", children: String(value) });
|
|
3318
|
+
if (typeof value === "number") return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-tag-blue-text", children: value });
|
|
3319
|
+
const text = String(value);
|
|
3320
|
+
const truncated = !showFull && text.length > LONG_STRING;
|
|
3321
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: ui.clx("text-ui-tag-green-text"), children: [
|
|
3322
|
+
'"',
|
|
3323
|
+
truncated ? `${text.slice(0, LONG_STRING)}…` : text,
|
|
3324
|
+
'"',
|
|
3325
|
+
text.length > LONG_STRING ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3326
|
+
"button",
|
|
3327
|
+
{
|
|
3328
|
+
type: "button",
|
|
3329
|
+
onClick: () => setShowFull((s2) => !s2),
|
|
3330
|
+
className: "ml-1 font-sans text-ui-fg-interactive hover:underline",
|
|
3331
|
+
children: showFull ? "show less" : `show all (${text.length} chars)`
|
|
3332
|
+
}
|
|
3333
|
+
) : null
|
|
3334
|
+
] });
|
|
3335
|
+
};
|
|
3336
|
+
const GUIDANCE = {
|
|
3337
|
+
orders: {
|
|
3338
|
+
headline: "Order data affects customers, payments and reports.",
|
|
3339
|
+
recreate: "Orders can’t be recreated identically from the admin. If this deletion was not intended, ask a developer to restore it from a database backup using the snapshot on this page.",
|
|
3340
|
+
adminSection: { label: "Go to Orders", path: "/orders" }
|
|
3341
|
+
},
|
|
3342
|
+
carts: {
|
|
3343
|
+
headline: "Carts are usually cleaned up automatically.",
|
|
3344
|
+
recreate: "No action is normally needed. Customers can simply add items to a new cart."
|
|
3345
|
+
},
|
|
3346
|
+
customers: {
|
|
3347
|
+
headline: "Customer data may be needed for orders, support and compliance.",
|
|
3348
|
+
recreate: "If it was deleted by mistake, recreate it from Customers using the values shown above. A recreated customer gets a new ID and must reset their password.",
|
|
3349
|
+
adminSection: { label: "Go to Customers", path: "/customers" }
|
|
3350
|
+
},
|
|
3351
|
+
catalog: {
|
|
3352
|
+
headline: "Catalog changes affect what customers can see and buy.",
|
|
3353
|
+
recreate: "If it was deleted by mistake, recreate it from Products using the values shown above. It will get a new ID.",
|
|
3354
|
+
adminSection: { label: "Go to Products", path: "/products" }
|
|
3355
|
+
},
|
|
3356
|
+
pricing: {
|
|
3357
|
+
headline: "Pricing and promotions affect what customers pay.",
|
|
3358
|
+
recreate: "If it was deleted by mistake, recreate it from Promotions or Price Lists using the values shown above.",
|
|
3359
|
+
adminSection: { label: "Go to Promotions", path: "/promotions" }
|
|
3360
|
+
},
|
|
3361
|
+
payments: {
|
|
3362
|
+
headline: "Payment records are financial data.",
|
|
3363
|
+
recreate: "Do not recreate payment records by hand—this can make balances inconsistent. If this deletion was not expected, escalate to a developer or your finance team."
|
|
3364
|
+
},
|
|
3365
|
+
fulfillment: {
|
|
3366
|
+
headline: "Shipping and fulfillment settings affect checkout and delivery.",
|
|
3367
|
+
recreate: "If it was deleted by mistake, recreate it from Settings → Locations & Shipping using the values shown above.",
|
|
3368
|
+
adminSection: { label: "Go to Settings", path: "/settings" }
|
|
3369
|
+
},
|
|
3370
|
+
inventory: {
|
|
3371
|
+
headline: "Inventory changes can affect stock levels and availability.",
|
|
3372
|
+
recreate: "If it was deleted by mistake, recreate it from Inventory using the values shown above and re-check stock quantities.",
|
|
3373
|
+
adminSection: { label: "Go to Inventory", path: "/inventory" }
|
|
3374
|
+
},
|
|
3375
|
+
wallet: {
|
|
3376
|
+
headline: "Wallet and credit records are financial data.",
|
|
3377
|
+
recreate: "Do not recreate balances by hand. If this deletion was not expected, escalate to a developer or your finance team so balances can be verified."
|
|
3378
|
+
},
|
|
3379
|
+
access: {
|
|
3380
|
+
headline: "Access records control who can sign in.",
|
|
3381
|
+
recreate: "Secrets such as passwords and keys can’t be restored. Re-invite the user or create a new API key if access is still needed.",
|
|
3382
|
+
adminSection: { label: "Go to Settings", path: "/settings" }
|
|
3383
|
+
},
|
|
3384
|
+
store: {
|
|
3385
|
+
headline: "Store settings affect regions, currencies and taxes.",
|
|
3386
|
+
recreate: "If it was deleted by mistake, recreate it from Settings using the values shown above.",
|
|
3387
|
+
adminSection: { label: "Go to Settings", path: "/settings" }
|
|
3388
|
+
},
|
|
3389
|
+
engagement: {
|
|
3390
|
+
headline: "Customer-generated content.",
|
|
3391
|
+
recreate: "These usually can’t be recreated on the customer’s behalf. Keep the snapshot on this page if you need a record of it."
|
|
3392
|
+
},
|
|
3393
|
+
notifications: {
|
|
3394
|
+
headline: "Notification records are usually cleaned up automatically.",
|
|
3395
|
+
recreate: "No action is normally needed."
|
|
3396
|
+
},
|
|
3397
|
+
system: {
|
|
3398
|
+
headline: "Internal system data, usually removed automatically by the platform.",
|
|
3399
|
+
recreate: "No action is normally needed. If you suspect a problem, share this page with a developer."
|
|
3400
|
+
}
|
|
3401
|
+
};
|
|
3402
|
+
function getNextSteps(category) {
|
|
3403
|
+
return GUIDANCE[category];
|
|
3404
|
+
}
|
|
3405
|
+
const RELATED_LINKS = [
|
|
3406
|
+
{ key: "order_id", label: "Order", path: (id) => `/orders/${id}`, selfTables: ["order"] },
|
|
3407
|
+
{ key: "customer_id", label: "Customer", path: (id) => `/customers/${id}`, selfTables: ["customer"] },
|
|
3408
|
+
{ key: "product_id", label: "Product", path: (id) => `/products/${id}`, selfTables: ["product"] }
|
|
3409
|
+
];
|
|
3410
|
+
function getRelatedLinks(tableName, oldData) {
|
|
3411
|
+
if (!oldData) return [];
|
|
3412
|
+
return RELATED_LINKS.flatMap((link) => {
|
|
3413
|
+
const id = oldData[link.key];
|
|
3414
|
+
if (link.selfTables.includes(tableName) || typeof id !== "string" || !id.trim()) return [];
|
|
3415
|
+
return [{ label: link.label, id, path: link.path(id) }];
|
|
3416
|
+
});
|
|
3417
|
+
}
|
|
3418
|
+
const fullName = (row) => {
|
|
3419
|
+
const parts = [row.first_name, row.last_name].filter(
|
|
3420
|
+
(part) => typeof part === "string" && part.trim() !== ""
|
|
3421
|
+
);
|
|
3422
|
+
return parts.length ? parts.join(" ") : void 0;
|
|
3423
|
+
};
|
|
3424
|
+
const addressLine = (row) => {
|
|
3425
|
+
const parts = [row.address_1, row.address_2, row.city, row.province, row.postal_code, row.country_code].filter((part) => typeof part === "string" && part.trim() !== "").map((part) => part.trim());
|
|
3426
|
+
return parts.length ? parts.join(", ") : void 0;
|
|
3427
|
+
};
|
|
3428
|
+
const NAME = { key: "name", label: "Name", derive: fullName };
|
|
3429
|
+
const ADDRESS = { key: "address", label: "Address", derive: addressLine };
|
|
3430
|
+
const CREATED = { key: "created_at", label: "Created", kind: "date" };
|
|
3431
|
+
const ENTITY_FIELDS = {
|
|
3432
|
+
order: [
|
|
3433
|
+
{ key: "display_id", label: "Order number" },
|
|
3434
|
+
{ key: "status", label: "Status", kind: "status" },
|
|
3435
|
+
{ key: "email", label: "Customer email" },
|
|
3436
|
+
{ key: "customer_id", label: "Customer ID", kind: "id" },
|
|
3437
|
+
{ key: "currency_code", label: "Currency" },
|
|
3438
|
+
{ key: "region_id", label: "Region ID", kind: "id" },
|
|
3439
|
+
{ key: "sales_channel_id", label: "Sales channel ID", kind: "id" },
|
|
3440
|
+
{ key: "canceled_at", label: "Canceled", kind: "date" },
|
|
3441
|
+
CREATED
|
|
3442
|
+
],
|
|
3443
|
+
order_line_item: [
|
|
3444
|
+
{ key: "title", label: "Item" },
|
|
3445
|
+
{ key: "variant_title", label: "Variant" },
|
|
3446
|
+
{ key: "variant_sku", label: "SKU" },
|
|
3447
|
+
{ key: "unit_price", label: "Unit price", kind: "money" },
|
|
3448
|
+
{ key: "product_id", label: "Product ID", kind: "id" },
|
|
3449
|
+
{ key: "variant_id", label: "Variant ID", kind: "id" },
|
|
3450
|
+
CREATED
|
|
3451
|
+
],
|
|
3452
|
+
cart_line_item: [
|
|
3453
|
+
{ key: "title", label: "Item" },
|
|
3454
|
+
{ key: "variant_sku", label: "SKU" },
|
|
3455
|
+
{ key: "quantity", label: "Quantity", kind: "number" },
|
|
3456
|
+
{ key: "unit_price", label: "Unit price", kind: "money" },
|
|
3457
|
+
{ key: "cart_id", label: "Cart ID", kind: "id" },
|
|
3458
|
+
{ key: "variant_id", label: "Variant ID", kind: "id" },
|
|
3459
|
+
CREATED
|
|
3460
|
+
],
|
|
3461
|
+
cart: [
|
|
3462
|
+
{ key: "email", label: "Email" },
|
|
3463
|
+
{ key: "customer_id", label: "Customer ID", kind: "id" },
|
|
3464
|
+
{ key: "currency_code", label: "Currency" },
|
|
3465
|
+
{ key: "region_id", label: "Region ID", kind: "id" },
|
|
3466
|
+
{ key: "completed_at", label: "Completed", kind: "date" },
|
|
3467
|
+
CREATED
|
|
3468
|
+
],
|
|
3469
|
+
customer: [
|
|
3470
|
+
NAME,
|
|
3471
|
+
{ key: "email", label: "Email" },
|
|
3472
|
+
{ key: "phone", label: "Phone" },
|
|
3473
|
+
{ key: "company_name", label: "Company" },
|
|
3474
|
+
{ key: "has_account", label: "Registered account", kind: "boolean" },
|
|
3475
|
+
CREATED
|
|
3476
|
+
],
|
|
3477
|
+
customer_address: [
|
|
3478
|
+
{ key: "address_name", label: "Label" },
|
|
3479
|
+
NAME,
|
|
3480
|
+
ADDRESS,
|
|
3481
|
+
{ key: "phone", label: "Phone" },
|
|
3482
|
+
{ key: "customer_id", label: "Customer ID", kind: "id" },
|
|
3483
|
+
{ key: "is_default_shipping", label: "Default shipping", kind: "boolean" },
|
|
3484
|
+
CREATED
|
|
3485
|
+
],
|
|
3486
|
+
order_address: [NAME, ADDRESS, { key: "phone", label: "Phone" }, CREATED],
|
|
3487
|
+
cart_address: [NAME, ADDRESS, { key: "phone", label: "Phone" }, CREATED],
|
|
3488
|
+
product: [
|
|
3489
|
+
{ key: "title", label: "Title" },
|
|
3490
|
+
{ key: "status", label: "Status", kind: "status" },
|
|
3491
|
+
{ key: "handle", label: "Handle" },
|
|
3492
|
+
{ key: "subtitle", label: "Subtitle" },
|
|
3493
|
+
{ key: "collection_id", label: "Collection ID", kind: "id" },
|
|
3494
|
+
{ key: "is_giftcard", label: "Gift card", kind: "boolean" },
|
|
3495
|
+
CREATED
|
|
3496
|
+
],
|
|
3497
|
+
product_variant: [
|
|
3498
|
+
{ key: "title", label: "Title" },
|
|
3499
|
+
{ key: "sku", label: "SKU" },
|
|
3500
|
+
{ key: "barcode", label: "Barcode" },
|
|
3501
|
+
{ key: "product_id", label: "Product ID", kind: "id" },
|
|
3502
|
+
{ key: "manage_inventory", label: "Manages inventory", kind: "boolean" },
|
|
3503
|
+
CREATED
|
|
3504
|
+
],
|
|
3505
|
+
product_category: [
|
|
3506
|
+
{ key: "name", label: "Name" },
|
|
3507
|
+
{ key: "handle", label: "Handle" },
|
|
3508
|
+
{ key: "is_active", label: "Active", kind: "boolean" },
|
|
3509
|
+
{ key: "parent_category_id", label: "Parent category ID", kind: "id" },
|
|
3510
|
+
CREATED
|
|
3511
|
+
],
|
|
3512
|
+
product_collection: [{ key: "title", label: "Title" }, { key: "handle", label: "Handle" }, CREATED],
|
|
3513
|
+
payment: [
|
|
3514
|
+
{ key: "amount", label: "Amount", kind: "money" },
|
|
3515
|
+
{ key: "currency_code", label: "Currency" },
|
|
3516
|
+
{ key: "provider_id", label: "Provider" },
|
|
3517
|
+
{ key: "captured_at", label: "Captured", kind: "date" },
|
|
3518
|
+
{ key: "canceled_at", label: "Canceled", kind: "date" },
|
|
3519
|
+
{ key: "payment_collection_id", label: "Payment collection ID", kind: "id" },
|
|
3520
|
+
CREATED
|
|
3521
|
+
],
|
|
3522
|
+
payment_session: [
|
|
3523
|
+
{ key: "amount", label: "Amount", kind: "money" },
|
|
3524
|
+
{ key: "currency_code", label: "Currency" },
|
|
3525
|
+
{ key: "provider_id", label: "Provider" },
|
|
3526
|
+
{ key: "status", label: "Status", kind: "status" },
|
|
3527
|
+
{ key: "payment_collection_id", label: "Payment collection ID", kind: "id" },
|
|
3528
|
+
CREATED
|
|
3529
|
+
],
|
|
3530
|
+
payment_collection: [
|
|
3531
|
+
{ key: "amount", label: "Amount", kind: "money" },
|
|
3532
|
+
{ key: "currency_code", label: "Currency" },
|
|
3533
|
+
{ key: "status", label: "Status", kind: "status" },
|
|
3534
|
+
CREATED
|
|
3535
|
+
],
|
|
3536
|
+
refund: [
|
|
3537
|
+
{ key: "amount", label: "Amount", kind: "money" },
|
|
3538
|
+
{ key: "payment_id", label: "Payment ID", kind: "id" },
|
|
3539
|
+
{ key: "refund_reason_id", label: "Refund reason ID", kind: "id" },
|
|
3540
|
+
{ key: "note", label: "Note" },
|
|
3541
|
+
{ key: "created_by", label: "Created by" },
|
|
3542
|
+
CREATED
|
|
3543
|
+
],
|
|
3544
|
+
return: [
|
|
3545
|
+
{ key: "display_id", label: "Return number" },
|
|
3546
|
+
{ key: "status", label: "Status", kind: "status" },
|
|
3547
|
+
{ key: "order_id", label: "Order ID", kind: "id" },
|
|
3548
|
+
{ key: "refund_amount", label: "Refund amount", kind: "money" },
|
|
3549
|
+
{ key: "received_at", label: "Received", kind: "date" },
|
|
3550
|
+
CREATED
|
|
3551
|
+
],
|
|
3552
|
+
payment_detail: [
|
|
3553
|
+
{ key: "type", label: "Method type" },
|
|
3554
|
+
{ key: "customer_id", label: "Customer ID", kind: "id" },
|
|
3555
|
+
{ key: "is_default", label: "Default method", kind: "boolean" },
|
|
3556
|
+
CREATED
|
|
3557
|
+
],
|
|
3558
|
+
user: [NAME, { key: "email", label: "Email" }, CREATED],
|
|
3559
|
+
invite: [
|
|
3560
|
+
{ key: "email", label: "Email" },
|
|
3561
|
+
{ key: "accepted", label: "Accepted", kind: "boolean" },
|
|
3562
|
+
{ key: "expires_at", label: "Expires", kind: "date" },
|
|
3563
|
+
CREATED
|
|
3564
|
+
],
|
|
3565
|
+
api_key: [
|
|
3566
|
+
{ key: "title", label: "Title" },
|
|
3567
|
+
{ key: "type", label: "Type" },
|
|
3568
|
+
{ key: "redacted", label: "Key (redacted)" },
|
|
3569
|
+
{ key: "revoked_at", label: "Revoked", kind: "date" },
|
|
3570
|
+
CREATED
|
|
3571
|
+
],
|
|
3572
|
+
promotion: [
|
|
3573
|
+
{ key: "code", label: "Promotion code" },
|
|
3574
|
+
{ key: "type", label: "Type" },
|
|
3575
|
+
{ key: "status", label: "Status", kind: "status" },
|
|
3576
|
+
{ key: "is_automatic", label: "Automatic", kind: "boolean" },
|
|
3577
|
+
CREATED
|
|
3578
|
+
],
|
|
3579
|
+
fulfillment: [
|
|
3580
|
+
{ key: "provider_id", label: "Provider" },
|
|
3581
|
+
{ key: "location_id", label: "Location ID", kind: "id" },
|
|
3582
|
+
{ key: "shipped_at", label: "Shipped", kind: "date" },
|
|
3583
|
+
{ key: "delivered_at", label: "Delivered", kind: "date" },
|
|
3584
|
+
{ key: "canceled_at", label: "Canceled", kind: "date" },
|
|
3585
|
+
CREATED
|
|
3586
|
+
],
|
|
3587
|
+
inventory_item: [
|
|
3588
|
+
{ key: "sku", label: "SKU" },
|
|
3589
|
+
{ key: "title", label: "Title" },
|
|
3590
|
+
{ key: "requires_shipping", label: "Requires shipping", kind: "boolean" },
|
|
3591
|
+
CREATED
|
|
3592
|
+
],
|
|
3593
|
+
inventory_level: [
|
|
3594
|
+
{ key: "inventory_item_id", label: "Inventory item ID", kind: "id" },
|
|
3595
|
+
{ key: "location_id", label: "Location ID", kind: "id" },
|
|
3596
|
+
{ key: "stocked_quantity", label: "Stocked", kind: "number" },
|
|
3597
|
+
{ key: "reserved_quantity", label: "Reserved", kind: "number" },
|
|
3598
|
+
CREATED
|
|
3599
|
+
],
|
|
3600
|
+
review: [
|
|
3601
|
+
{ key: "title", label: "Title" },
|
|
3602
|
+
{ key: "rating", label: "Rating", kind: "number" },
|
|
3603
|
+
{ key: "status", label: "Status", kind: "status" },
|
|
3604
|
+
{ key: "product_id", label: "Product ID", kind: "id" },
|
|
3605
|
+
{ key: "customer_id", label: "Customer ID", kind: "id" },
|
|
3606
|
+
CREATED
|
|
3607
|
+
]
|
|
3608
|
+
};
|
|
3609
|
+
const GENERIC_FIELDS = [
|
|
3610
|
+
{ key: "display_id", label: "Number" },
|
|
3611
|
+
{ key: "title", label: "Title" },
|
|
3612
|
+
{ key: "name", label: "Name" },
|
|
3613
|
+
NAME,
|
|
3614
|
+
{ key: "email", label: "Email" },
|
|
3615
|
+
{ key: "phone", label: "Phone" },
|
|
3616
|
+
{ key: "handle", label: "Handle" },
|
|
3617
|
+
{ key: "sku", label: "SKU" },
|
|
3618
|
+
{ key: "code", label: "Code" },
|
|
3619
|
+
{ key: "status", label: "Status", kind: "status" },
|
|
3620
|
+
{ key: "type", label: "Type" },
|
|
3621
|
+
{ key: "amount", label: "Amount", kind: "money" },
|
|
3622
|
+
{ key: "quantity", label: "Quantity", kind: "number" },
|
|
3623
|
+
{ key: "currency_code", label: "Currency" },
|
|
3624
|
+
{ key: "order_id", label: "Order ID", kind: "id" },
|
|
3625
|
+
{ key: "customer_id", label: "Customer ID", kind: "id" },
|
|
3626
|
+
{ key: "product_id", label: "Product ID", kind: "id" },
|
|
3627
|
+
{ key: "payment_id", label: "Payment ID", kind: "id" },
|
|
3628
|
+
{ key: "provider_id", label: "Provider" },
|
|
3629
|
+
CREATED,
|
|
3630
|
+
{ key: "updated_at", label: "Last updated", kind: "date" }
|
|
3631
|
+
];
|
|
3632
|
+
const MAX_GENERIC_FIELDS = 8;
|
|
3633
|
+
function amountOf(value) {
|
|
3634
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
3635
|
+
if (typeof value === "string" && value.trim() !== "" && Number.isFinite(Number(value))) return Number(value);
|
|
3636
|
+
if (value !== null && typeof value === "object" && "value" in value) {
|
|
3637
|
+
return amountOf(value.value);
|
|
3638
|
+
}
|
|
3639
|
+
return null;
|
|
3640
|
+
}
|
|
3641
|
+
function formatValue(raw, kind, row) {
|
|
3642
|
+
if (raw === null || raw === void 0 || raw === "") return null;
|
|
3643
|
+
if (raw === MASKED_VALUE) return { value: MASKED_VALUE, kind: "masked" };
|
|
3644
|
+
switch (kind) {
|
|
3645
|
+
case "money": {
|
|
3646
|
+
const amount = amountOf(raw);
|
|
3647
|
+
if (amount === null) return null;
|
|
3648
|
+
const currency = typeof row.currency_code === "string" ? row.currency_code : null;
|
|
3649
|
+
return { value: formatMoney(amount, currency), kind };
|
|
3650
|
+
}
|
|
3651
|
+
case "date":
|
|
3652
|
+
return typeof raw === "string" || raw instanceof Date ? { value: formatDate(raw), kind } : null;
|
|
3653
|
+
case "boolean":
|
|
3654
|
+
return { value: raw === true || raw === "true" ? "Yes" : "No", kind };
|
|
3655
|
+
case "number": {
|
|
3656
|
+
const n = amountOf(raw);
|
|
3657
|
+
return n === null ? null : { value: formatNumber(n), kind };
|
|
3658
|
+
}
|
|
3659
|
+
case "status":
|
|
3660
|
+
return { value: String(raw).replace(/_/g, " "), kind };
|
|
3661
|
+
default:
|
|
3662
|
+
if (typeof raw === "object") return null;
|
|
3663
|
+
if (typeof raw === "string" && raw.length > 160) return { value: `${raw.slice(0, 157)}…`, kind };
|
|
3664
|
+
return { value: String(raw), kind };
|
|
3665
|
+
}
|
|
3666
|
+
}
|
|
3667
|
+
function summarizeOldData(tableName, oldData) {
|
|
3668
|
+
if (!oldData) return [];
|
|
3669
|
+
const { value: row } = maskSensitiveData(oldData, tableName);
|
|
3670
|
+
const specific = ENTITY_FIELDS[tableName];
|
|
3671
|
+
const specs = specific ?? GENERIC_FIELDS;
|
|
3672
|
+
const fields = [];
|
|
3673
|
+
const seenLabels = /* @__PURE__ */ new Set();
|
|
3674
|
+
for (const spec of specs) {
|
|
3675
|
+
const raw = spec.derive ? spec.derive(row) : row[spec.key];
|
|
3676
|
+
const formatted = formatValue(raw, spec.kind ?? "text", row);
|
|
3677
|
+
if (!formatted || seenLabels.has(spec.label)) continue;
|
|
3678
|
+
seenLabels.add(spec.label);
|
|
3679
|
+
const value = spec.key === "currency_code" ? formatted.value.toUpperCase() : formatted.value;
|
|
3680
|
+
fields.push({ key: spec.key, label: spec.label, value, kind: formatted.kind });
|
|
3681
|
+
if (!specific && fields.length >= MAX_GENERIC_FIELDS) break;
|
|
3682
|
+
}
|
|
3683
|
+
return fields;
|
|
3684
|
+
}
|
|
3685
|
+
function readLastListSearch() {
|
|
3686
|
+
try {
|
|
3687
|
+
return window.sessionStorage.getItem(LAST_LIST_URL_KEY) ?? "";
|
|
3688
|
+
} catch {
|
|
3689
|
+
return "";
|
|
3690
|
+
}
|
|
3691
|
+
}
|
|
3692
|
+
const DeletedRecordDetailPage = () => {
|
|
3693
|
+
const navigate = reactRouterDom.useNavigate();
|
|
3694
|
+
const location = reactRouterDom.useLocation();
|
|
3695
|
+
const { id = "" } = reactRouterDom.useParams();
|
|
3696
|
+
const [state, setState] = react.useState({ status: "loading" });
|
|
3697
|
+
const [reloadToken, setReloadToken] = react.useState(0);
|
|
3698
|
+
const cameFromList = location.state?.fromList === true;
|
|
3699
|
+
const goBack = () => {
|
|
3700
|
+
if (cameFromList) navigate(-1);
|
|
3701
|
+
else navigate(`/deleted-records-audit${readLastListSearch()}`);
|
|
3702
|
+
};
|
|
3703
|
+
react.useEffect(() => {
|
|
3704
|
+
const controller = new AbortController();
|
|
3705
|
+
setState({ status: "loading" });
|
|
3706
|
+
fetchAuditDetail(id, controller.signal).then((audit) => setState({ status: "ready", audit })).catch((e) => {
|
|
3707
|
+
if (controller.signal.aborted) return;
|
|
3708
|
+
setState({
|
|
3709
|
+
status: "error",
|
|
3710
|
+
message: e instanceof Error ? e.message : "Unknown error",
|
|
3711
|
+
notFound: e instanceof AuditApiError && e.status === 404
|
|
3712
|
+
});
|
|
3713
|
+
});
|
|
3714
|
+
return () => controller.abort();
|
|
3715
|
+
}, [id, reloadToken]);
|
|
3716
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-3 md:p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-4 md:p-6", children: [
|
|
3717
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: "transparent", size: "small", onClick: goBack, className: "-ml-2", children: [
|
|
3718
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, {}),
|
|
3719
|
+
"Back to Deleted Records"
|
|
3929
3720
|
] }) }),
|
|
3930
|
-
|
|
3931
|
-
|
|
3721
|
+
state.status === "loading" ? /* @__PURE__ */ jsxRuntime.jsx(DetailSkeleton, {}) : state.status === "error" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3722
|
+
DetailError,
|
|
3932
3723
|
{
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3724
|
+
notFound: state.notFound,
|
|
3725
|
+
message: state.message,
|
|
3726
|
+
onRetry: () => setReloadToken((t) => t + 1),
|
|
3727
|
+
onBack: goBack
|
|
3937
3728
|
}
|
|
3938
|
-
)
|
|
3729
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(DetailContent, { audit: state.audit })
|
|
3939
3730
|
] }) });
|
|
3940
3731
|
};
|
|
3941
|
-
const
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3732
|
+
const DetailContent = ({ audit }) => {
|
|
3733
|
+
const navigate = reactRouterDom.useNavigate();
|
|
3734
|
+
const entity = getEntityInfo(audit.table_name);
|
|
3735
|
+
const source = describeSource(audit.source);
|
|
3736
|
+
const summary = react.useMemo(() => summarizeOldData(audit.table_name, audit.old_data), [audit]);
|
|
3737
|
+
const masked = react.useMemo(() => maskSensitiveData(audit.old_data, audit.table_name), [audit]);
|
|
3738
|
+
const guidance = getNextSteps(entity.category.id);
|
|
3739
|
+
const related = getRelatedLinks(audit.table_name, audit.old_data);
|
|
3740
|
+
const [showRaw, setShowRaw] = react.useState(false);
|
|
3741
|
+
const copyJson = async () => {
|
|
3742
|
+
try {
|
|
3743
|
+
await navigator.clipboard.writeText(JSON.stringify(masked.value, null, 2));
|
|
3744
|
+
ui.toast.success("Record data copied", {
|
|
3745
|
+
description: masked.maskedCount ? "Sensitive values were left hidden." : void 0
|
|
3746
|
+
});
|
|
3747
|
+
} catch {
|
|
3748
|
+
ui.toast.error("Couldn’t copy to clipboard");
|
|
3749
|
+
}
|
|
3750
|
+
};
|
|
3751
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3752
|
+
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
|
|
3753
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
3754
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { size: "small", color: "red", children: [
|
|
3755
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.Trash, {}),
|
|
3756
|
+
"Deleted"
|
|
3757
|
+
] }),
|
|
3758
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: entity.category.label })
|
|
3759
|
+
] }),
|
|
3760
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Heading, { level: "h1", children: [
|
|
3761
|
+
"Deleted ",
|
|
3762
|
+
entity.label
|
|
3763
|
+
] }),
|
|
3764
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
3765
|
+
/* @__PURE__ */ jsxRuntime.jsx(CopyableId, { value: audit.record_id, emptyLabel: "This record type has no ID column", className: "text-sm" }),
|
|
3766
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: [
|
|
3767
|
+
"Database table: ",
|
|
3768
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono", children: audit.table_name })
|
|
3769
|
+
] })
|
|
3770
|
+
] })
|
|
3771
|
+
] }),
|
|
3772
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3 rounded-lg border border-ui-tag-orange-border bg-ui-tag-orange-bg px-4 py-3", children: [
|
|
3773
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.InformationCircle, { className: "mt-0.5 shrink-0 text-ui-tag-orange-icon" }),
|
|
3774
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-tag-orange-text", children: [
|
|
3775
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "This is a historical snapshot" }),
|
|
3776
|
+
" captured immediately before deletion. The record no longer exists in the database, so changes elsewhere in the admin are not reflected here."
|
|
3777
|
+
] })
|
|
3778
|
+
] }),
|
|
3779
|
+
/* @__PURE__ */ jsxRuntime.jsx(Section, { title: "Deletion information", children: /* @__PURE__ */ jsxRuntime.jsxs("dl", { className: "grid grid-cols-1 gap-x-6 gap-y-4 sm:grid-cols-2", children: [
|
|
3780
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Deleted", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
|
|
3781
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: formatExactDateTime(audit.occurred_at) }),
|
|
3782
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1 text-xs text-ui-fg-muted", children: [
|
|
3783
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.ClockSolid, { className: "size-3" }),
|
|
3784
|
+
formatRelativeTime(audit.occurred_at)
|
|
3785
|
+
] })
|
|
3786
|
+
] }) }),
|
|
3787
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Deleted by", children: audit.deleted_by ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "break-all text-sm text-ui-fg-base", children: audit.deleted_by }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-muted", children: "Not recorded" }) }),
|
|
3788
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Source", children: source.kind === "unknown" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-muted", children: "Unknown" }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { size: "small", color: sourceBadgeColor(source.kind), children: source.label }) }),
|
|
3789
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Action", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Permanently deleted" }) })
|
|
3790
|
+
] }) }),
|
|
3791
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3792
|
+
Section,
|
|
3793
|
+
{
|
|
3794
|
+
title: "Record summary",
|
|
3795
|
+
description: `Key details of this ${entity.label.toLowerCase()} at the moment it was deleted.`,
|
|
3796
|
+
children: summary.length ? /* @__PURE__ */ jsxRuntime.jsx("dl", { className: "grid grid-cols-1 gap-x-6 gap-y-4 sm:grid-cols-2", children: summary.map((field) => /* @__PURE__ */ jsxRuntime.jsx(Field, { label: field.label, children: field.kind === "id" ? /* @__PURE__ */ jsxRuntime.jsx(CopyableId, { value: field.value }) : field.kind === "status" ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { size: "2xsmall", color: "grey", className: "capitalize", children: field.value }) : field.kind === "masked" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-muted", children: "Hidden for security" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "break-words text-sm text-ui-fg-base", children: field.value }) }, field.label)) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No key details could be extracted for this record type. See the original record data below." })
|
|
3797
|
+
}
|
|
3798
|
+
),
|
|
3799
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3800
|
+
Section,
|
|
3801
|
+
{
|
|
3802
|
+
title: "Original record data",
|
|
3803
|
+
description: "The complete data captured before deletion.",
|
|
3804
|
+
actions: showRaw && audit.old_data ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: "secondary", size: "small", onClick: copyJson, children: [
|
|
3805
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.SquareTwoStack, {}),
|
|
3806
|
+
"Copy JSON"
|
|
3807
|
+
] }) : null,
|
|
3808
|
+
children: audit.old_data ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
3809
|
+
masked.maskedCount > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
3810
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.ShieldCheck, { className: "shrink-0 text-ui-fg-muted" }),
|
|
3811
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
|
|
3812
|
+
masked.maskedCount,
|
|
3813
|
+
" sensitive ",
|
|
3814
|
+
masked.maskedCount === 1 ? "value is" : "values are",
|
|
3815
|
+
" hidden for security (passwords, tokens, card or account numbers)."
|
|
3816
|
+
] })
|
|
3817
|
+
] }) : null,
|
|
3818
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: "secondary", size: "small", onClick: () => setShowRaw((s2) => !s2), "aria-expanded": showRaw, children: [
|
|
3819
|
+
showRaw ? /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronDownMini, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronRightMini, {}),
|
|
3820
|
+
showRaw ? "Hide full record" : "View full record"
|
|
3821
|
+
] }) }),
|
|
3822
|
+
showRaw ? /* @__PURE__ */ jsxRuntime.jsx(JsonViewer, { data: masked.value }) : null
|
|
3823
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No data was captured for this deletion." })
|
|
3824
|
+
}
|
|
3825
|
+
),
|
|
3826
|
+
/* @__PURE__ */ jsxRuntime.jsx(Section, { title: "What you can do now", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
3827
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-base", children: [
|
|
3828
|
+
"This record was permanently deleted. ",
|
|
3829
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Automatic restoration is not available" }),
|
|
3830
|
+
" ",
|
|
3831
|
+
"from this screen."
|
|
3832
|
+
] }),
|
|
3833
|
+
/* @__PURE__ */ jsxRuntime.jsxs("ol", { className: "flex list-decimal flex-col gap-3 pl-5 text-sm text-ui-fg-subtle marker:text-ui-fg-muted", children: [
|
|
3834
|
+
/* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
|
|
3835
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-ui-fg-base", children: "Check whether this was expected." }),
|
|
3836
|
+
" ",
|
|
3837
|
+
audit.deleted_by || source.kind !== "unknown" ? "Confirm with the person or system shown above." : `Who deleted it wasn’t recorded—check with your team or integrations active around ${formatExactDateTime(audit.occurred_at)}.`,
|
|
3838
|
+
" ",
|
|
3839
|
+
guidance.headline
|
|
3840
|
+
] }),
|
|
3841
|
+
/* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
|
|
3842
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-ui-fg-base", children: "If it needs to come back:" }),
|
|
3843
|
+
" ",
|
|
3844
|
+
guidance.recreate
|
|
3845
|
+
] }),
|
|
3846
|
+
/* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
|
|
3847
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-ui-fg-base", children: "Need the details?" }),
|
|
3848
|
+
" Use “View full record” above to see or copy everything that was stored. Sensitive values stay hidden."
|
|
3849
|
+
] })
|
|
3850
|
+
] }),
|
|
3851
|
+
guidance.adminSection || related.length ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
|
|
3852
|
+
guidance.adminSection ? /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", size: "small", onClick: () => navigate(guidance.adminSection.path), children: guidance.adminSection.label }) : null,
|
|
3853
|
+
related.map((link) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3854
|
+
ui.Button,
|
|
3855
|
+
{
|
|
3856
|
+
variant: "transparent",
|
|
3857
|
+
size: "small",
|
|
3858
|
+
onClick: () => navigate(link.path),
|
|
3859
|
+
title: `Opens ${link.label.toLowerCase()} ${link.id} if it still exists`,
|
|
3860
|
+
children: [
|
|
3861
|
+
"Open related ",
|
|
3862
|
+
link.label.toLowerCase(),
|
|
3863
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.ChevronRightMini, {})
|
|
3864
|
+
]
|
|
3865
|
+
},
|
|
3866
|
+
link.path
|
|
3867
|
+
))
|
|
3868
|
+
] }) : null,
|
|
3869
|
+
related.length ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: "Related records open only if they haven’t been deleted too." }) : null
|
|
3870
|
+
] }) })
|
|
3871
|
+
] });
|
|
3872
|
+
};
|
|
3873
|
+
const Section = ({
|
|
3874
|
+
title,
|
|
3875
|
+
description,
|
|
3876
|
+
actions,
|
|
3877
|
+
children
|
|
3878
|
+
}) => /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "flex flex-col gap-4 rounded-lg border border-ui-border-base p-5", children: [
|
|
3879
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-start justify-between gap-2", children: [
|
|
3880
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [
|
|
3881
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: title }),
|
|
3882
|
+
description ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: description }) : null
|
|
3883
|
+
] }),
|
|
3884
|
+
actions
|
|
3885
|
+
] }),
|
|
3886
|
+
children
|
|
3887
|
+
] });
|
|
3888
|
+
const Field = ({ label, children }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-col gap-1", children: [
|
|
3889
|
+
/* @__PURE__ */ jsxRuntime.jsx("dt", { className: "text-xs font-medium uppercase tracking-wide text-ui-fg-muted", children: label }),
|
|
3890
|
+
/* @__PURE__ */ jsxRuntime.jsx("dd", { className: "min-w-0", children })
|
|
3891
|
+
] });
|
|
3892
|
+
const DetailSkeleton = () => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", "aria-busy": "true", children: [
|
|
3893
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
3894
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-5 w-24 rounded-full" }),
|
|
3895
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-8 w-64" }),
|
|
3896
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-4 w-48" })
|
|
3897
|
+
] }),
|
|
3898
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-14 w-full" }),
|
|
3899
|
+
Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4 rounded-lg border border-ui-border-base p-5", children: [
|
|
3900
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-5 w-40" }),
|
|
3901
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: Array.from({ length: 4 }).map((__, j) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
3902
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-3 w-20" }),
|
|
3903
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-4 w-36" })
|
|
3904
|
+
] }, j)) })
|
|
3905
|
+
] }, i))
|
|
3906
|
+
] });
|
|
3907
|
+
const DetailError = ({
|
|
3908
|
+
notFound,
|
|
3909
|
+
message,
|
|
3910
|
+
onRetry,
|
|
3911
|
+
onBack
|
|
3912
|
+
}) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-2 rounded-lg border border-ui-border-base px-6 py-12 text-center", children: [
|
|
3913
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.ExclamationCircle, { className: ui.clx(notFound ? "text-ui-fg-muted" : "text-ui-fg-error") }),
|
|
3914
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", children: notFound ? "Audit entry not found" : "Unable to load this deleted record" }),
|
|
3915
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "max-w-md text-ui-fg-subtle", children: notFound ? "This audit entry doesn’t exist. The link may be incorrect." : "We couldn’t retrieve the audit entry right now. Check your connection and try again." }),
|
|
3916
|
+
!notFound ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "max-w-md font-mono text-ui-fg-muted", children: message }) : null,
|
|
3917
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 flex gap-2", children: [
|
|
3918
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", size: "small", onClick: onBack, children: "Back to Deleted Records" }),
|
|
3919
|
+
!notFound ? /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", size: "small", onClick: onRetry, children: "Try again" }) : null
|
|
3920
|
+
] })
|
|
3921
|
+
] });
|
|
3922
|
+
const config$4 = adminSdk.defineRouteConfig({});
|
|
3945
3923
|
const getStatusBadgeClass$3 = (status) => {
|
|
3946
3924
|
const s2 = status.toLowerCase();
|
|
3947
3925
|
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
@@ -3951,10 +3929,9 @@ const getStatusBadgeClass$3 = (status) => {
|
|
|
3951
3929
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
3952
3930
|
};
|
|
3953
3931
|
const PaymentDetailPage = () => {
|
|
3954
|
-
var _a;
|
|
3955
3932
|
const navigate = reactRouterDom.useNavigate();
|
|
3956
3933
|
const params = reactRouterDom.useParams();
|
|
3957
|
-
const id =
|
|
3934
|
+
const id = params?.id?.trim();
|
|
3958
3935
|
const [detail, setDetail] = react.useState(null);
|
|
3959
3936
|
const [loading, setLoading] = react.useState(!!id);
|
|
3960
3937
|
const [error, setError] = react.useState(null);
|
|
@@ -3981,8 +3958,8 @@ const PaymentDetailPage = () => {
|
|
|
3981
3958
|
};
|
|
3982
3959
|
}, [id]);
|
|
3983
3960
|
const displayStatus = detail ? (detail.payment_id != null && detail.payment_status != null && detail.payment_status !== "" ? detail.payment_status : detail.session_status ?? "") || "—" : "";
|
|
3984
|
-
const sessionStatusRaw =
|
|
3985
|
-
const paymentStatusRaw =
|
|
3961
|
+
const sessionStatusRaw = detail?.session_status ?? "—";
|
|
3962
|
+
const paymentStatusRaw = detail?.payment_id != null ? detail?.payment_status ?? "—" : "—";
|
|
3986
3963
|
const displayAmount = detail ? `${(detail.currency_code ?? "USD").toUpperCase()} ${Number(detail.amount)}` : "";
|
|
3987
3964
|
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: [
|
|
3988
3965
|
/* @__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: [
|
|
@@ -4049,19 +4026,210 @@ const PaymentDetailPage = () => {
|
|
|
4049
4026
|
hour12: true
|
|
4050
4027
|
}) })
|
|
4051
4028
|
] })
|
|
4052
|
-
] }) }),
|
|
4053
|
-
Object.keys(detail.data ?? {}).length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
4054
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Provider data" }),
|
|
4055
|
-
/* @__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) })
|
|
4056
|
-
] }) : /* @__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." }) })
|
|
4029
|
+
] }) }),
|
|
4030
|
+
Object.keys(detail.data ?? {}).length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
4031
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Provider data" }),
|
|
4032
|
+
/* @__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) })
|
|
4033
|
+
] }) : /* @__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." }) })
|
|
4034
|
+
] }) : null
|
|
4035
|
+
] }) });
|
|
4036
|
+
};
|
|
4037
|
+
const config$3 = adminSdk.defineRouteConfig({
|
|
4038
|
+
label: "Payment details",
|
|
4039
|
+
icon: icons.CreditCard
|
|
4040
|
+
});
|
|
4041
|
+
const getStatusBadgeClass$2 = (status) => {
|
|
4042
|
+
const s2 = status.toLowerCase();
|
|
4043
|
+
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
4044
|
+
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
4045
|
+
if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
4046
|
+
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
4047
|
+
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
4048
|
+
};
|
|
4049
|
+
const formatAmount = (value) => {
|
|
4050
|
+
return String(value);
|
|
4051
|
+
};
|
|
4052
|
+
const RefundDetailPage = () => {
|
|
4053
|
+
const navigate = reactRouterDom.useNavigate();
|
|
4054
|
+
const params = reactRouterDom.useParams();
|
|
4055
|
+
const id = params?.id?.trim();
|
|
4056
|
+
const [detail, setDetail] = react.useState(null);
|
|
4057
|
+
const [loading, setLoading] = react.useState(!!id);
|
|
4058
|
+
const [error, setError] = react.useState(null);
|
|
4059
|
+
const [gatewayExpanded, setGatewayExpanded] = react.useState(false);
|
|
4060
|
+
react.useEffect(() => {
|
|
4061
|
+
if (!id) {
|
|
4062
|
+
setLoading(false);
|
|
4063
|
+
return;
|
|
4064
|
+
}
|
|
4065
|
+
let cancelled = false;
|
|
4066
|
+
setLoading(true);
|
|
4067
|
+
setError(null);
|
|
4068
|
+
fetch(`/admin/refunds/${id}`, { credentials: "include" }).then((res) => {
|
|
4069
|
+
if (!res.ok) throw new Error(res.statusText || "Failed to load");
|
|
4070
|
+
return res.json();
|
|
4071
|
+
}).then((data) => {
|
|
4072
|
+
if (!cancelled) setDetail(data);
|
|
4073
|
+
}).catch((e) => {
|
|
4074
|
+
if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
|
|
4075
|
+
}).finally(() => {
|
|
4076
|
+
if (!cancelled) setLoading(false);
|
|
4077
|
+
});
|
|
4078
|
+
return () => {
|
|
4079
|
+
cancelled = true;
|
|
4080
|
+
};
|
|
4081
|
+
}, [id]);
|
|
4082
|
+
const paymentStatus = detail?.payment?.status ?? "—";
|
|
4083
|
+
const hasGatewayData = detail?.payment?.payment_data && typeof detail.payment.payment_data === "object" && Object.keys(detail.payment.payment_data).length > 0;
|
|
4084
|
+
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: [
|
|
4085
|
+
/* @__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: [
|
|
4086
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => navigate("/refunds"), children: "← Refunds" }),
|
|
4087
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Refund details" }),
|
|
4088
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle font-mono", children: id ?? "—" })
|
|
4089
|
+
] }) }),
|
|
4090
|
+
error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
4091
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
4092
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/refunds"), children: "Back to list" })
|
|
4093
|
+
] }) : 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: [
|
|
4094
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
4095
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Refund summary" }),
|
|
4096
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
4097
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4098
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refund ID" }),
|
|
4099
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.id })
|
|
4100
|
+
] }),
|
|
4101
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4102
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
|
|
4103
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.refund.amount) })
|
|
4104
|
+
] }),
|
|
4105
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4106
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Note" }),
|
|
4107
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.refund.note ?? "—" })
|
|
4108
|
+
] }),
|
|
4109
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4110
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created at" }),
|
|
4111
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: new Date(detail.refund.created_at).toLocaleDateString("en-US", {
|
|
4112
|
+
year: "numeric",
|
|
4113
|
+
month: "short",
|
|
4114
|
+
day: "numeric",
|
|
4115
|
+
hour: "numeric",
|
|
4116
|
+
minute: "2-digit",
|
|
4117
|
+
hour12: true
|
|
4118
|
+
}) })
|
|
4119
|
+
] }),
|
|
4120
|
+
detail.refund.created_by ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4121
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created by" }),
|
|
4122
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.created_by })
|
|
4123
|
+
] }) : null
|
|
4124
|
+
] })
|
|
4125
|
+
] }),
|
|
4126
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
4127
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Payment summary" }),
|
|
4128
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
4129
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4130
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Payment amount" }),
|
|
4131
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.payment_amount) })
|
|
4132
|
+
] }),
|
|
4133
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4134
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Captured amount" }),
|
|
4135
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.captured_amount) })
|
|
4136
|
+
] }),
|
|
4137
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4138
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refunded amount" }),
|
|
4139
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.refunded_amount) })
|
|
4140
|
+
] }),
|
|
4141
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4142
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
|
|
4143
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.payment.provider_id || "—" })
|
|
4144
|
+
] }),
|
|
4145
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4146
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
|
|
4147
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4148
|
+
ui.Badge,
|
|
4149
|
+
{
|
|
4150
|
+
size: "2xsmall",
|
|
4151
|
+
className: `uppercase ${getStatusBadgeClass$2(paymentStatus)}`,
|
|
4152
|
+
children: paymentStatus !== "—" ? paymentStatus.replace(/_/g, " ") : "—"
|
|
4153
|
+
}
|
|
4154
|
+
) })
|
|
4155
|
+
] }),
|
|
4156
|
+
detail.computed ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4157
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4158
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Full refund" }),
|
|
4159
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.computed.is_full_refund ? "Yes" : "No" })
|
|
4160
|
+
] }),
|
|
4161
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4162
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Remaining refundable" }),
|
|
4163
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.computed.remaining_refundable_amount) })
|
|
4164
|
+
] }),
|
|
4165
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4166
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refund %" }),
|
|
4167
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "mt-1 block", children: [
|
|
4168
|
+
detail.computed.refund_percentage.toFixed(1),
|
|
4169
|
+
"%"
|
|
4170
|
+
] })
|
|
4171
|
+
] })
|
|
4172
|
+
] }) : null
|
|
4173
|
+
] })
|
|
4174
|
+
] }),
|
|
4175
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
4176
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Order summary" }),
|
|
4177
|
+
detail.order ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
4178
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4179
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Order" }),
|
|
4180
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4181
|
+
ui.Button,
|
|
4182
|
+
{
|
|
4183
|
+
variant: "transparent",
|
|
4184
|
+
size: "small",
|
|
4185
|
+
onClick: () => navigate(`/orders/${detail.order.order_id}`),
|
|
4186
|
+
children: detail.order.order_number ?? detail.order.order_id
|
|
4187
|
+
}
|
|
4188
|
+
) })
|
|
4189
|
+
] }),
|
|
4190
|
+
detail.order.total != null ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4191
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Total" }),
|
|
4192
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.order.total) })
|
|
4193
|
+
] }) : null,
|
|
4194
|
+
detail.order.customer_id ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4195
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Customer ID" }),
|
|
4196
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.order.customer_id })
|
|
4197
|
+
] }) : null,
|
|
4198
|
+
detail.order.region ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4199
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Region" }),
|
|
4200
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.region })
|
|
4201
|
+
] }) : null,
|
|
4202
|
+
detail.order.fulfillment_status ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4203
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Fulfillment status" }),
|
|
4204
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.fulfillment_status })
|
|
4205
|
+
] }) : null
|
|
4206
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No order linked to this refund." })
|
|
4207
|
+
] }),
|
|
4208
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
4209
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4210
|
+
"button",
|
|
4211
|
+
{
|
|
4212
|
+
type: "button",
|
|
4213
|
+
className: "flex w-full items-center justify-between text-left",
|
|
4214
|
+
onClick: () => setGatewayExpanded((prev) => !prev),
|
|
4215
|
+
"aria-expanded": gatewayExpanded,
|
|
4216
|
+
"aria-label": gatewayExpanded ? "Collapse gateway data" : "Expand gateway data",
|
|
4217
|
+
children: [
|
|
4218
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg", children: "Gateway data" }),
|
|
4219
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: gatewayExpanded ? "Collapse" : "Expand" })
|
|
4220
|
+
]
|
|
4221
|
+
}
|
|
4222
|
+
),
|
|
4223
|
+
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." }) })
|
|
4224
|
+
] })
|
|
4057
4225
|
] }) : null
|
|
4058
4226
|
] }) });
|
|
4059
4227
|
};
|
|
4060
|
-
const config$
|
|
4061
|
-
label: "
|
|
4062
|
-
icon: icons.
|
|
4228
|
+
const config$2 = adminSdk.defineRouteConfig({
|
|
4229
|
+
label: "Refund details",
|
|
4230
|
+
icon: icons.Receipt
|
|
4063
4231
|
});
|
|
4064
|
-
const getStatusBadgeClass$
|
|
4232
|
+
const getStatusBadgeClass$1 = (status) => {
|
|
4065
4233
|
const statusLower = status.toLowerCase();
|
|
4066
4234
|
if (statusLower === "requested") {
|
|
4067
4235
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
@@ -4072,109 +4240,104 @@ const getStatusBadgeClass$2 = (status) => {
|
|
|
4072
4240
|
if (statusLower === "rejected") {
|
|
4073
4241
|
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
4074
4242
|
}
|
|
4243
|
+
if (statusLower === "received") {
|
|
4244
|
+
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
4245
|
+
}
|
|
4246
|
+
if (statusLower === "refunded") {
|
|
4247
|
+
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
4248
|
+
}
|
|
4075
4249
|
if (statusLower === "completed") {
|
|
4076
4250
|
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
4077
4251
|
}
|
|
4078
|
-
if (statusLower === "cancelled"
|
|
4252
|
+
if (statusLower === "cancelled") {
|
|
4079
4253
|
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
4080
4254
|
}
|
|
4081
|
-
if (statusLower === "pending") {
|
|
4082
|
-
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
4083
|
-
}
|
|
4084
4255
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
4085
4256
|
};
|
|
4086
|
-
const
|
|
4087
|
-
var _a, _b, _c;
|
|
4257
|
+
const ReturnDetailPage = () => {
|
|
4088
4258
|
const navigate = reactRouterDom.useNavigate();
|
|
4089
4259
|
const { id } = reactRouterDom.useParams();
|
|
4090
|
-
const [
|
|
4091
|
-
const [order, setOrder] = react.useState(null);
|
|
4260
|
+
const [returnOrder, setReturnOrder] = react.useState(null);
|
|
4092
4261
|
const [isLoading, setIsLoading] = react.useState(true);
|
|
4093
|
-
react.useState(false);
|
|
4094
|
-
const [isCancelling, setIsCancelling] = react.useState(false);
|
|
4262
|
+
const [isRejecting, setIsRejecting] = react.useState(false);
|
|
4095
4263
|
const [error, setError] = react.useState(null);
|
|
4096
4264
|
const [updateError, setUpdateError] = react.useState(null);
|
|
4097
4265
|
const [updateSuccess, setUpdateSuccess] = react.useState(false);
|
|
4098
4266
|
react.useEffect(() => {
|
|
4099
4267
|
if (!id) {
|
|
4100
|
-
navigate("/
|
|
4268
|
+
navigate("/returns");
|
|
4101
4269
|
return;
|
|
4102
4270
|
}
|
|
4103
|
-
const
|
|
4271
|
+
const loadReturn = async () => {
|
|
4104
4272
|
try {
|
|
4105
4273
|
setIsLoading(true);
|
|
4106
4274
|
setError(null);
|
|
4107
|
-
const response = await fetch(`/admin/
|
|
4275
|
+
const response = await fetch(`/admin/return/${id}`, {
|
|
4108
4276
|
credentials: "include"
|
|
4109
4277
|
});
|
|
4110
4278
|
if (!response.ok) {
|
|
4111
4279
|
const message = await response.text();
|
|
4112
|
-
throw new Error(message || "Unable to load
|
|
4280
|
+
throw new Error(message || "Unable to load return order");
|
|
4113
4281
|
}
|
|
4114
4282
|
const payload = await response.json();
|
|
4115
|
-
|
|
4116
|
-
setOrder(payload.order || null);
|
|
4283
|
+
setReturnOrder(payload.return);
|
|
4117
4284
|
} catch (loadError) {
|
|
4118
|
-
const message = loadError instanceof Error ? loadError.message : "Unable to load
|
|
4285
|
+
const message = loadError instanceof Error ? loadError.message : "Unable to load return order";
|
|
4119
4286
|
setError(message);
|
|
4120
4287
|
} finally {
|
|
4121
4288
|
setIsLoading(false);
|
|
4122
4289
|
}
|
|
4123
4290
|
};
|
|
4124
|
-
void
|
|
4291
|
+
void loadReturn();
|
|
4125
4292
|
}, [id, navigate]);
|
|
4126
|
-
const
|
|
4293
|
+
const handleReject = async () => {
|
|
4127
4294
|
if (!id) {
|
|
4128
4295
|
return;
|
|
4129
4296
|
}
|
|
4130
4297
|
try {
|
|
4131
|
-
|
|
4298
|
+
setIsRejecting(true);
|
|
4132
4299
|
setUpdateError(null);
|
|
4133
4300
|
setUpdateSuccess(false);
|
|
4134
|
-
const response = await fetch(`/admin/
|
|
4301
|
+
const response = await fetch(`/admin/return/${id}/reject`, {
|
|
4135
4302
|
method: "POST",
|
|
4136
4303
|
headers: {
|
|
4137
4304
|
"Content-Type": "application/json"
|
|
4138
4305
|
},
|
|
4139
|
-
credentials: "include"
|
|
4306
|
+
credentials: "include",
|
|
4307
|
+
body: JSON.stringify({ reason: "Rejected by admin" })
|
|
4140
4308
|
});
|
|
4141
4309
|
if (!response.ok) {
|
|
4142
4310
|
const message = await response.text();
|
|
4143
|
-
throw new Error(message || "Unable to
|
|
4311
|
+
throw new Error(message || "Unable to reject return");
|
|
4144
4312
|
}
|
|
4145
4313
|
const payload = await response.json();
|
|
4146
|
-
|
|
4314
|
+
setReturnOrder(payload.return);
|
|
4147
4315
|
setUpdateSuccess(true);
|
|
4148
4316
|
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
4149
|
-
const detailResponse = await fetch(`/admin/
|
|
4317
|
+
const detailResponse = await fetch(`/admin/return/${id}`, {
|
|
4150
4318
|
credentials: "include"
|
|
4151
4319
|
});
|
|
4152
4320
|
if (detailResponse.ok) {
|
|
4153
4321
|
const detailPayload = await detailResponse.json();
|
|
4154
|
-
|
|
4155
|
-
setOrder(detailPayload.order || null);
|
|
4322
|
+
setReturnOrder(detailPayload.return);
|
|
4156
4323
|
}
|
|
4157
|
-
} catch (
|
|
4158
|
-
const message =
|
|
4324
|
+
} catch (updateErr) {
|
|
4325
|
+
const message = updateErr instanceof Error ? updateErr.message : "Unable to reject return";
|
|
4159
4326
|
setUpdateError(message);
|
|
4160
4327
|
} finally {
|
|
4161
|
-
|
|
4328
|
+
setIsRejecting(false);
|
|
4162
4329
|
}
|
|
4163
4330
|
};
|
|
4164
|
-
const isOrderExchange = Boolean(swap == null ? void 0 : swap.exchange_id);
|
|
4165
|
-
const canCancelExchange = isOrderExchange && swap && !["cancelled", "canceled", "completed", "declined"].includes(
|
|
4166
|
-
((_a = swap.status) == null ? void 0 : _a.toLowerCase()) ?? ""
|
|
4167
|
-
);
|
|
4168
4331
|
if (isLoading) {
|
|
4169
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading
|
|
4332
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading return order..." }) }) }) });
|
|
4170
4333
|
}
|
|
4171
|
-
if (error || !
|
|
4334
|
+
if (error || !returnOrder) {
|
|
4172
4335
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
4173
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "
|
|
4174
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/
|
|
4336
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "Return order not found" }),
|
|
4337
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/returns"), children: "Back to list" }) })
|
|
4175
4338
|
] }) }) });
|
|
4176
4339
|
}
|
|
4177
|
-
const statusHistory =
|
|
4340
|
+
const statusHistory = returnOrder.metadata?.status_history || [];
|
|
4178
4341
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: [
|
|
4179
4342
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
|
|
4180
4343
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -4182,7 +4345,7 @@ const SwapDetailPage = () => {
|
|
|
4182
4345
|
{
|
|
4183
4346
|
variant: "transparent",
|
|
4184
4347
|
size: "small",
|
|
4185
|
-
onClick: () => navigate("/
|
|
4348
|
+
onClick: () => navigate("/returns"),
|
|
4186
4349
|
className: "w-fit",
|
|
4187
4350
|
children: [
|
|
4188
4351
|
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, { className: "mr-2" }),
|
|
@@ -4192,67 +4355,82 @@ const SwapDetailPage = () => {
|
|
|
4192
4355
|
),
|
|
4193
4356
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 md:flex-row md:items-center md:justify-between", children: [
|
|
4194
4357
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
4195
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "
|
|
4196
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children:
|
|
4358
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Return Order Details" }),
|
|
4359
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: returnOrder.id })
|
|
4197
4360
|
] }),
|
|
4198
4361
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4199
4362
|
ui.Badge,
|
|
4200
4363
|
{
|
|
4201
4364
|
size: "small",
|
|
4202
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
4203
|
-
children:
|
|
4365
|
+
className: `uppercase ${getStatusBadgeClass$1(returnOrder.status)}`,
|
|
4366
|
+
children: returnOrder.status.replace(/_/g, " ")
|
|
4204
4367
|
}
|
|
4205
4368
|
)
|
|
4206
4369
|
] })
|
|
4207
4370
|
] }),
|
|
4208
|
-
|
|
4371
|
+
returnOrder.status === "requested" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
4209
4372
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4210
4373
|
ui.Button,
|
|
4211
4374
|
{
|
|
4212
4375
|
variant: "danger",
|
|
4213
|
-
onClick:
|
|
4214
|
-
disabled:
|
|
4215
|
-
isLoading:
|
|
4216
|
-
children: "Cancel
|
|
4376
|
+
onClick: handleReject,
|
|
4377
|
+
disabled: isRejecting,
|
|
4378
|
+
isLoading: isRejecting,
|
|
4379
|
+
children: "Reject (Cancel) Return"
|
|
4217
4380
|
}
|
|
4218
4381
|
) }),
|
|
4219
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children:
|
|
4382
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: 'Cancel this return request. Use "Mark as received" when items are received.' })
|
|
4383
|
+
] }),
|
|
4384
|
+
returnOrder.refund ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: /* @__PURE__ */ jsxRuntime.jsx(RefundCalculationBlock, { refund: returnOrder.refund }) }) : null,
|
|
4385
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
4386
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Information" }),
|
|
4387
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
4388
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4389
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Return ID" }),
|
|
4390
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.id })
|
|
4391
|
+
] }),
|
|
4392
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4393
|
+
ui.Button,
|
|
4394
|
+
{
|
|
4395
|
+
variant: "secondary",
|
|
4396
|
+
onClick: () => {
|
|
4397
|
+
window.open(
|
|
4398
|
+
`/app/orders/${returnOrder.order_id}`,
|
|
4399
|
+
"_blank"
|
|
4400
|
+
);
|
|
4401
|
+
},
|
|
4402
|
+
children: "View order"
|
|
4403
|
+
}
|
|
4404
|
+
) })
|
|
4405
|
+
] })
|
|
4220
4406
|
] }),
|
|
4221
4407
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
|
|
4222
4408
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
4223
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "
|
|
4409
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Details" }),
|
|
4224
4410
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
4225
4411
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4226
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
4227
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
4412
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Return ID" }),
|
|
4413
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.id })
|
|
4228
4414
|
] }),
|
|
4229
4415
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4230
4416
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Status" }),
|
|
4231
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
4232
|
-
] }),
|
|
4233
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4234
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Difference Due" }),
|
|
4235
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.difference_due != null ? `${swap.currency_code || "$"}${(Number(swap.difference_due) / 100).toFixed(2)}` : "—" })
|
|
4417
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.status })
|
|
4236
4418
|
] }),
|
|
4237
|
-
|
|
4419
|
+
returnOrder.reason && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4238
4420
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Reason" }),
|
|
4239
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
4421
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.reason })
|
|
4240
4422
|
] }),
|
|
4241
|
-
|
|
4423
|
+
returnOrder.note && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4242
4424
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Note" }),
|
|
4243
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
4425
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.note })
|
|
4244
4426
|
] }),
|
|
4245
4427
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4246
4428
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Created" }),
|
|
4247
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(
|
|
4429
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(returnOrder.created_at).toLocaleString() })
|
|
4248
4430
|
] }),
|
|
4249
4431
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4250
4432
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Last Updated" }),
|
|
4251
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(
|
|
4252
|
-
] }),
|
|
4253
|
-
swap.exchange_id && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4254
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
|
|
4255
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.exchange_id })
|
|
4433
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(returnOrder.updated_at).toLocaleString() })
|
|
4256
4434
|
] })
|
|
4257
4435
|
] })
|
|
4258
4436
|
] }),
|
|
@@ -4267,7 +4445,7 @@ const SwapDetailPage = () => {
|
|
|
4267
4445
|
ui.Badge,
|
|
4268
4446
|
{
|
|
4269
4447
|
size: "2xsmall",
|
|
4270
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
4448
|
+
className: `uppercase ${getStatusBadgeClass$1(entry.status)}`,
|
|
4271
4449
|
children: entry.status.replace(/_/g, " ")
|
|
4272
4450
|
}
|
|
4273
4451
|
) }),
|
|
@@ -4282,31 +4460,35 @@ const SwapDetailPage = () => {
|
|
|
4282
4460
|
)) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No status history available" })
|
|
4283
4461
|
] })
|
|
4284
4462
|
] }),
|
|
4285
|
-
order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
4463
|
+
returnOrder.order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
4286
4464
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Related Order Information" }),
|
|
4287
4465
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
4288
4466
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4289
4467
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order ID" }),
|
|
4290
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.id })
|
|
4468
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.id })
|
|
4291
4469
|
] }),
|
|
4292
4470
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4293
4471
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Status" }),
|
|
4294
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.status || "—" })
|
|
4472
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.status || "—" })
|
|
4295
4473
|
] }),
|
|
4296
4474
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4297
4475
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
|
|
4298
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
4476
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.customer?.email || returnOrder.order.email || "—" })
|
|
4299
4477
|
] }),
|
|
4300
|
-
|
|
4478
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4479
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Payment method" }),
|
|
4480
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.order_payment?.label || "—" })
|
|
4481
|
+
] }),
|
|
4482
|
+
returnOrder.order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4301
4483
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
|
|
4302
4484
|
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "font-medium", children: [
|
|
4303
|
-
order.currency_code || "$",
|
|
4304
|
-
(Number(order.total) / 100).toFixed(2)
|
|
4485
|
+
returnOrder.order.currency_code || "$",
|
|
4486
|
+
(Number(returnOrder.order.total) / 100).toFixed(2)
|
|
4305
4487
|
] })
|
|
4306
4488
|
] })
|
|
4307
4489
|
] })
|
|
4308
4490
|
] }),
|
|
4309
|
-
|
|
4491
|
+
returnOrder.return_items && returnOrder.return_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
4310
4492
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Items" }),
|
|
4311
4493
|
/* @__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: [
|
|
4312
4494
|
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
@@ -4314,33 +4496,22 @@ const SwapDetailPage = () => {
|
|
|
4314
4496
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" }),
|
|
4315
4497
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Reason" })
|
|
4316
4498
|
] }) }),
|
|
4317
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children:
|
|
4499
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: returnOrder.return_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
4318
4500
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.id }),
|
|
4319
4501
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity }),
|
|
4320
4502
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.reason || "—" })
|
|
4321
4503
|
] }, item.id || index)) })
|
|
4322
4504
|
] }) })
|
|
4323
4505
|
] }),
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
/* @__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: [
|
|
4327
|
-
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
4328
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Variant ID" }),
|
|
4329
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" })
|
|
4330
|
-
] }) }),
|
|
4331
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.new_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
4332
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.variant_id }),
|
|
4333
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity })
|
|
4334
|
-
] }, item.variant_id || index)) })
|
|
4335
|
-
] }) })
|
|
4336
|
-
] })
|
|
4506
|
+
updateError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-ui-border-error bg-ui-bg-error-subtle p-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-error", children: updateError }) }),
|
|
4507
|
+
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" }) })
|
|
4337
4508
|
] }) });
|
|
4338
4509
|
};
|
|
4339
|
-
const config$
|
|
4340
|
-
label: "
|
|
4341
|
-
icon: icons.
|
|
4510
|
+
const config$1 = adminSdk.defineRouteConfig({
|
|
4511
|
+
label: "Return Order Details",
|
|
4512
|
+
icon: icons.CheckCircle
|
|
4342
4513
|
});
|
|
4343
|
-
const getStatusBadgeClass
|
|
4514
|
+
const getStatusBadgeClass = (status) => {
|
|
4344
4515
|
const statusLower = status.toLowerCase();
|
|
4345
4516
|
if (statusLower === "requested") {
|
|
4346
4517
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
@@ -4351,105 +4522,108 @@ const getStatusBadgeClass$1 = (status) => {
|
|
|
4351
4522
|
if (statusLower === "rejected") {
|
|
4352
4523
|
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
4353
4524
|
}
|
|
4354
|
-
if (statusLower === "received") {
|
|
4355
|
-
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
4356
|
-
}
|
|
4357
|
-
if (statusLower === "refunded") {
|
|
4358
|
-
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
4359
|
-
}
|
|
4360
4525
|
if (statusLower === "completed") {
|
|
4361
4526
|
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
4362
4527
|
}
|
|
4363
|
-
if (statusLower === "cancelled") {
|
|
4528
|
+
if (statusLower === "cancelled" || statusLower === "canceled") {
|
|
4364
4529
|
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
4365
4530
|
}
|
|
4531
|
+
if (statusLower === "pending") {
|
|
4532
|
+
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
4533
|
+
}
|
|
4366
4534
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
4367
4535
|
};
|
|
4368
|
-
const
|
|
4369
|
-
var _a, _b, _c;
|
|
4536
|
+
const SwapDetailPage = () => {
|
|
4370
4537
|
const navigate = reactRouterDom.useNavigate();
|
|
4371
4538
|
const { id } = reactRouterDom.useParams();
|
|
4372
|
-
const [
|
|
4539
|
+
const [swap, setSwap] = react.useState(null);
|
|
4540
|
+
const [order, setOrder] = react.useState(null);
|
|
4373
4541
|
const [isLoading, setIsLoading] = react.useState(true);
|
|
4374
4542
|
const [isRejecting, setIsRejecting] = react.useState(false);
|
|
4543
|
+
const [isCancelling, setIsCancelling] = react.useState(false);
|
|
4375
4544
|
const [error, setError] = react.useState(null);
|
|
4376
4545
|
const [updateError, setUpdateError] = react.useState(null);
|
|
4377
4546
|
const [updateSuccess, setUpdateSuccess] = react.useState(false);
|
|
4378
4547
|
react.useEffect(() => {
|
|
4379
4548
|
if (!id) {
|
|
4380
|
-
navigate("/
|
|
4549
|
+
navigate("/swaps");
|
|
4381
4550
|
return;
|
|
4382
4551
|
}
|
|
4383
|
-
const
|
|
4552
|
+
const loadSwap = async () => {
|
|
4384
4553
|
try {
|
|
4385
4554
|
setIsLoading(true);
|
|
4386
4555
|
setError(null);
|
|
4387
|
-
const response = await fetch(`/admin/
|
|
4556
|
+
const response = await fetch(`/admin/swaps/${id}`, {
|
|
4388
4557
|
credentials: "include"
|
|
4389
4558
|
});
|
|
4390
4559
|
if (!response.ok) {
|
|
4391
4560
|
const message = await response.text();
|
|
4392
|
-
throw new Error(message || "Unable to load
|
|
4561
|
+
throw new Error(message || "Unable to load swap");
|
|
4393
4562
|
}
|
|
4394
4563
|
const payload = await response.json();
|
|
4395
|
-
|
|
4564
|
+
setSwap(payload.swap);
|
|
4565
|
+
setOrder(payload.order || null);
|
|
4396
4566
|
} catch (loadError) {
|
|
4397
|
-
const message = loadError instanceof Error ? loadError.message : "Unable to load
|
|
4567
|
+
const message = loadError instanceof Error ? loadError.message : "Unable to load swap";
|
|
4398
4568
|
setError(message);
|
|
4399
4569
|
} finally {
|
|
4400
4570
|
setIsLoading(false);
|
|
4401
4571
|
}
|
|
4402
4572
|
};
|
|
4403
|
-
void
|
|
4573
|
+
void loadSwap();
|
|
4404
4574
|
}, [id, navigate]);
|
|
4405
|
-
const
|
|
4575
|
+
const handleCancelExchange = async () => {
|
|
4406
4576
|
if (!id) {
|
|
4407
4577
|
return;
|
|
4408
4578
|
}
|
|
4409
4579
|
try {
|
|
4410
|
-
|
|
4580
|
+
setIsCancelling(true);
|
|
4411
4581
|
setUpdateError(null);
|
|
4412
4582
|
setUpdateSuccess(false);
|
|
4413
|
-
const response = await fetch(`/admin/
|
|
4583
|
+
const response = await fetch(`/admin/swaps/${id}/cancel`, {
|
|
4414
4584
|
method: "POST",
|
|
4415
4585
|
headers: {
|
|
4416
4586
|
"Content-Type": "application/json"
|
|
4417
4587
|
},
|
|
4418
|
-
credentials: "include"
|
|
4419
|
-
body: JSON.stringify({ reason: "Rejected by admin" })
|
|
4588
|
+
credentials: "include"
|
|
4420
4589
|
});
|
|
4421
4590
|
if (!response.ok) {
|
|
4422
4591
|
const message = await response.text();
|
|
4423
|
-
throw new Error(message || "Unable to
|
|
4592
|
+
throw new Error(message || "Unable to cancel exchange");
|
|
4424
4593
|
}
|
|
4425
4594
|
const payload = await response.json();
|
|
4426
|
-
|
|
4595
|
+
setSwap(payload.swap);
|
|
4427
4596
|
setUpdateSuccess(true);
|
|
4428
4597
|
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
4429
|
-
const detailResponse = await fetch(`/admin/
|
|
4598
|
+
const detailResponse = await fetch(`/admin/swaps/${id}`, {
|
|
4430
4599
|
credentials: "include"
|
|
4431
4600
|
});
|
|
4432
4601
|
if (detailResponse.ok) {
|
|
4433
4602
|
const detailPayload = await detailResponse.json();
|
|
4434
|
-
|
|
4603
|
+
setSwap(detailPayload.swap);
|
|
4604
|
+
setOrder(detailPayload.order || null);
|
|
4435
4605
|
}
|
|
4436
|
-
} catch (
|
|
4437
|
-
const message =
|
|
4606
|
+
} catch (cancelErr) {
|
|
4607
|
+
const message = cancelErr instanceof Error ? cancelErr.message : "Unable to cancel exchange";
|
|
4438
4608
|
setUpdateError(message);
|
|
4439
4609
|
} finally {
|
|
4440
|
-
|
|
4610
|
+
setIsCancelling(false);
|
|
4441
4611
|
}
|
|
4442
4612
|
};
|
|
4613
|
+
const isOrderExchange = Boolean(swap?.exchange_id);
|
|
4614
|
+
const canCancelExchange = isOrderExchange && swap && !["cancelled", "canceled", "completed", "declined"].includes(
|
|
4615
|
+
swap.status?.toLowerCase() ?? ""
|
|
4616
|
+
);
|
|
4443
4617
|
if (isLoading) {
|
|
4444
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading
|
|
4618
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading swap..." }) }) }) });
|
|
4445
4619
|
}
|
|
4446
|
-
if (error || !
|
|
4620
|
+
if (error || !swap) {
|
|
4447
4621
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
4448
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "
|
|
4449
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/
|
|
4622
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "Swap not found" }),
|
|
4623
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/swaps"), children: "Back to list" }) })
|
|
4450
4624
|
] }) }) });
|
|
4451
4625
|
}
|
|
4452
|
-
const statusHistory =
|
|
4626
|
+
const statusHistory = swap.metadata?.status_history || [];
|
|
4453
4627
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: [
|
|
4454
4628
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
|
|
4455
4629
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -4457,7 +4631,7 @@ const ReturnDetailPage = () => {
|
|
|
4457
4631
|
{
|
|
4458
4632
|
variant: "transparent",
|
|
4459
4633
|
size: "small",
|
|
4460
|
-
onClick: () => navigate("/
|
|
4634
|
+
onClick: () => navigate("/swaps"),
|
|
4461
4635
|
className: "w-fit",
|
|
4462
4636
|
children: [
|
|
4463
4637
|
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, { className: "mr-2" }),
|
|
@@ -4467,82 +4641,67 @@ const ReturnDetailPage = () => {
|
|
|
4467
4641
|
),
|
|
4468
4642
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 md:flex-row md:items-center md:justify-between", children: [
|
|
4469
4643
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
4470
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "
|
|
4471
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children:
|
|
4644
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Exchange Details" }),
|
|
4645
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: swap.id })
|
|
4472
4646
|
] }),
|
|
4473
4647
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4474
4648
|
ui.Badge,
|
|
4475
4649
|
{
|
|
4476
4650
|
size: "small",
|
|
4477
|
-
className: `uppercase ${getStatusBadgeClass
|
|
4478
|
-
children:
|
|
4651
|
+
className: `uppercase ${getStatusBadgeClass(swap.status)}`,
|
|
4652
|
+
children: swap.status.replace(/_/g, " ")
|
|
4479
4653
|
}
|
|
4480
4654
|
)
|
|
4481
4655
|
] })
|
|
4482
4656
|
] }),
|
|
4483
|
-
|
|
4657
|
+
canCancelExchange && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
4484
4658
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4485
4659
|
ui.Button,
|
|
4486
4660
|
{
|
|
4487
4661
|
variant: "danger",
|
|
4488
|
-
onClick:
|
|
4489
|
-
disabled:
|
|
4490
|
-
isLoading:
|
|
4491
|
-
children: "
|
|
4662
|
+
onClick: handleCancelExchange,
|
|
4663
|
+
disabled: isCancelling,
|
|
4664
|
+
isLoading: isCancelling,
|
|
4665
|
+
children: "Cancel Exchange"
|
|
4492
4666
|
}
|
|
4493
4667
|
) }),
|
|
4494
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children:
|
|
4495
|
-
] }),
|
|
4496
|
-
returnOrder.refund ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: /* @__PURE__ */ jsxRuntime.jsx(RefundCalculationBlock, { refund: returnOrder.refund }) }) : null,
|
|
4497
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
4498
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Information" }),
|
|
4499
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
4500
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4501
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Return ID" }),
|
|
4502
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.id })
|
|
4503
|
-
] }),
|
|
4504
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4505
|
-
ui.Button,
|
|
4506
|
-
{
|
|
4507
|
-
variant: "secondary",
|
|
4508
|
-
onClick: () => {
|
|
4509
|
-
window.open(
|
|
4510
|
-
`/app/orders/${returnOrder.order_id}`,
|
|
4511
|
-
"_blank"
|
|
4512
|
-
);
|
|
4513
|
-
},
|
|
4514
|
-
children: "View order"
|
|
4515
|
-
}
|
|
4516
|
-
) })
|
|
4517
|
-
] })
|
|
4668
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "This will cancel the exchange request. The order will remain unchanged." })
|
|
4518
4669
|
] }),
|
|
4519
4670
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
|
|
4520
4671
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
4521
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "
|
|
4672
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Exchange Information" }),
|
|
4522
4673
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
4523
4674
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4524
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
4525
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
4675
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
|
|
4676
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.id })
|
|
4526
4677
|
] }),
|
|
4527
4678
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4528
4679
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Status" }),
|
|
4529
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
4680
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.status })
|
|
4530
4681
|
] }),
|
|
4531
|
-
|
|
4682
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4683
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Difference Due" }),
|
|
4684
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.difference_due != null ? `${swap.currency_code || "$"}${(Number(swap.difference_due) / 100).toFixed(2)}` : "—" })
|
|
4685
|
+
] }),
|
|
4686
|
+
swap.reason && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4532
4687
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Reason" }),
|
|
4533
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
4688
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.reason })
|
|
4534
4689
|
] }),
|
|
4535
|
-
|
|
4690
|
+
swap.note && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4536
4691
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Note" }),
|
|
4537
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
4692
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.note })
|
|
4538
4693
|
] }),
|
|
4539
4694
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4540
4695
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Created" }),
|
|
4541
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(
|
|
4696
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(swap.created_at).toLocaleString() })
|
|
4542
4697
|
] }),
|
|
4543
4698
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4544
4699
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Last Updated" }),
|
|
4545
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(
|
|
4700
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(swap.updated_at).toLocaleString() })
|
|
4701
|
+
] }),
|
|
4702
|
+
swap.exchange_id && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4703
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
|
|
4704
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.exchange_id })
|
|
4546
4705
|
] })
|
|
4547
4706
|
] })
|
|
4548
4707
|
] }),
|
|
@@ -4557,7 +4716,7 @@ const ReturnDetailPage = () => {
|
|
|
4557
4716
|
ui.Badge,
|
|
4558
4717
|
{
|
|
4559
4718
|
size: "2xsmall",
|
|
4560
|
-
className: `uppercase ${getStatusBadgeClass
|
|
4719
|
+
className: `uppercase ${getStatusBadgeClass(entry.status)}`,
|
|
4561
4720
|
children: entry.status.replace(/_/g, " ")
|
|
4562
4721
|
}
|
|
4563
4722
|
) }),
|
|
@@ -4572,35 +4731,31 @@ const ReturnDetailPage = () => {
|
|
|
4572
4731
|
)) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No status history available" })
|
|
4573
4732
|
] })
|
|
4574
4733
|
] }),
|
|
4575
|
-
|
|
4734
|
+
order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
4576
4735
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Related Order Information" }),
|
|
4577
4736
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
4578
4737
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4579
4738
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order ID" }),
|
|
4580
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
4739
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.id })
|
|
4581
4740
|
] }),
|
|
4582
4741
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4583
4742
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Status" }),
|
|
4584
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
4743
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.status || "—" })
|
|
4585
4744
|
] }),
|
|
4586
4745
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4587
4746
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
|
|
4588
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
4747
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.customer?.email || order.email || "—" })
|
|
4589
4748
|
] }),
|
|
4590
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4591
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Payment method" }),
|
|
4592
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_c = returnOrder.order.order_payment) == null ? void 0 : _c.label) || "—" })
|
|
4593
|
-
] }),
|
|
4594
|
-
returnOrder.order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4749
|
+
order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4595
4750
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
|
|
4596
4751
|
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "font-medium", children: [
|
|
4597
|
-
|
|
4598
|
-
(Number(
|
|
4752
|
+
order.currency_code || "$",
|
|
4753
|
+
(Number(order.total) / 100).toFixed(2)
|
|
4599
4754
|
] })
|
|
4600
4755
|
] })
|
|
4601
4756
|
] })
|
|
4602
4757
|
] }),
|
|
4603
|
-
|
|
4758
|
+
swap.return_items && swap.return_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
4604
4759
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Items" }),
|
|
4605
4760
|
/* @__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: [
|
|
4606
4761
|
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
@@ -4608,323 +4763,172 @@ const ReturnDetailPage = () => {
|
|
|
4608
4763
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" }),
|
|
4609
4764
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Reason" })
|
|
4610
4765
|
] }) }),
|
|
4611
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children:
|
|
4766
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.return_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
4612
4767
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.id }),
|
|
4613
4768
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity }),
|
|
4614
4769
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.reason || "—" })
|
|
4615
4770
|
] }, item.id || index)) })
|
|
4616
4771
|
] }) })
|
|
4617
4772
|
] }),
|
|
4618
|
-
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
|
|
4622
|
-
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
|
|
4626
|
-
|
|
4627
|
-
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
4632
|
-
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
4633
|
-
};
|
|
4634
|
-
const formatAmount = (value) => {
|
|
4635
|
-
return String(value);
|
|
4636
|
-
};
|
|
4637
|
-
const RefundDetailPage = () => {
|
|
4638
|
-
var _a, _b, _c;
|
|
4639
|
-
const navigate = reactRouterDom.useNavigate();
|
|
4640
|
-
const params = reactRouterDom.useParams();
|
|
4641
|
-
const id = (_a = params == null ? void 0 : params.id) == null ? void 0 : _a.trim();
|
|
4642
|
-
const [detail, setDetail] = react.useState(null);
|
|
4643
|
-
const [loading, setLoading] = react.useState(!!id);
|
|
4644
|
-
const [error, setError] = react.useState(null);
|
|
4645
|
-
const [gatewayExpanded, setGatewayExpanded] = react.useState(false);
|
|
4646
|
-
react.useEffect(() => {
|
|
4647
|
-
if (!id) {
|
|
4648
|
-
setLoading(false);
|
|
4649
|
-
return;
|
|
4650
|
-
}
|
|
4651
|
-
let cancelled = false;
|
|
4652
|
-
setLoading(true);
|
|
4653
|
-
setError(null);
|
|
4654
|
-
fetch(`/admin/refunds/${id}`, { credentials: "include" }).then((res) => {
|
|
4655
|
-
if (!res.ok) throw new Error(res.statusText || "Failed to load");
|
|
4656
|
-
return res.json();
|
|
4657
|
-
}).then((data) => {
|
|
4658
|
-
if (!cancelled) setDetail(data);
|
|
4659
|
-
}).catch((e) => {
|
|
4660
|
-
if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
|
|
4661
|
-
}).finally(() => {
|
|
4662
|
-
if (!cancelled) setLoading(false);
|
|
4663
|
-
});
|
|
4664
|
-
return () => {
|
|
4665
|
-
cancelled = true;
|
|
4666
|
-
};
|
|
4667
|
-
}, [id]);
|
|
4668
|
-
const paymentStatus = ((_b = detail == null ? void 0 : detail.payment) == null ? void 0 : _b.status) ?? "—";
|
|
4669
|
-
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;
|
|
4670
|
-
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: [
|
|
4671
|
-
/* @__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: [
|
|
4672
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => navigate("/refunds"), children: "← Refunds" }),
|
|
4673
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Refund details" }),
|
|
4674
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle font-mono", children: id ?? "—" })
|
|
4675
|
-
] }) }),
|
|
4676
|
-
error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
4677
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
4678
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/refunds"), children: "Back to list" })
|
|
4679
|
-
] }) : 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: [
|
|
4680
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
4681
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Refund summary" }),
|
|
4682
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
4683
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4684
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refund ID" }),
|
|
4685
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.id })
|
|
4686
|
-
] }),
|
|
4687
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4688
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
|
|
4689
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.refund.amount) })
|
|
4690
|
-
] }),
|
|
4691
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4692
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Note" }),
|
|
4693
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.refund.note ?? "—" })
|
|
4694
|
-
] }),
|
|
4695
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4696
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created at" }),
|
|
4697
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: new Date(detail.refund.created_at).toLocaleDateString("en-US", {
|
|
4698
|
-
year: "numeric",
|
|
4699
|
-
month: "short",
|
|
4700
|
-
day: "numeric",
|
|
4701
|
-
hour: "numeric",
|
|
4702
|
-
minute: "2-digit",
|
|
4703
|
-
hour12: true
|
|
4704
|
-
}) })
|
|
4705
|
-
] }),
|
|
4706
|
-
detail.refund.created_by ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4707
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created by" }),
|
|
4708
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.created_by })
|
|
4709
|
-
] }) : null
|
|
4710
|
-
] })
|
|
4711
|
-
] }),
|
|
4712
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
4713
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Payment summary" }),
|
|
4714
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
4715
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4716
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Payment amount" }),
|
|
4717
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.payment_amount) })
|
|
4718
|
-
] }),
|
|
4719
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4720
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Captured amount" }),
|
|
4721
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.captured_amount) })
|
|
4722
|
-
] }),
|
|
4723
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4724
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refunded amount" }),
|
|
4725
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.payment.refunded_amount) })
|
|
4726
|
-
] }),
|
|
4727
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4728
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
|
|
4729
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.payment.provider_id || "—" })
|
|
4730
|
-
] }),
|
|
4731
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4732
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
|
|
4733
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4734
|
-
ui.Badge,
|
|
4735
|
-
{
|
|
4736
|
-
size: "2xsmall",
|
|
4737
|
-
className: `uppercase ${getStatusBadgeClass(paymentStatus)}`,
|
|
4738
|
-
children: paymentStatus !== "—" ? paymentStatus.replace(/_/g, " ") : "—"
|
|
4739
|
-
}
|
|
4740
|
-
) })
|
|
4741
|
-
] }),
|
|
4742
|
-
detail.computed ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4743
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4744
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Full refund" }),
|
|
4745
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.computed.is_full_refund ? "Yes" : "No" })
|
|
4746
|
-
] }),
|
|
4747
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4748
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Remaining refundable" }),
|
|
4749
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.computed.remaining_refundable_amount) })
|
|
4750
|
-
] }),
|
|
4751
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4752
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Refund %" }),
|
|
4753
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "mt-1 block", children: [
|
|
4754
|
-
detail.computed.refund_percentage.toFixed(1),
|
|
4755
|
-
"%"
|
|
4756
|
-
] })
|
|
4757
|
-
] })
|
|
4758
|
-
] }) : null
|
|
4759
|
-
] })
|
|
4760
|
-
] }),
|
|
4761
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
4762
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Order summary" }),
|
|
4763
|
-
detail.order ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
4764
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4765
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Order" }),
|
|
4766
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4767
|
-
ui.Button,
|
|
4768
|
-
{
|
|
4769
|
-
variant: "transparent",
|
|
4770
|
-
size: "small",
|
|
4771
|
-
onClick: () => navigate(`/orders/${detail.order.order_id}`),
|
|
4772
|
-
children: detail.order.order_number ?? detail.order.order_id
|
|
4773
|
-
}
|
|
4774
|
-
) })
|
|
4775
|
-
] }),
|
|
4776
|
-
detail.order.total != null ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4777
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Total" }),
|
|
4778
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: formatAmount(detail.order.total) })
|
|
4779
|
-
] }) : null,
|
|
4780
|
-
detail.order.customer_id ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4781
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Customer ID" }),
|
|
4782
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block font-mono text-sm", children: detail.order.customer_id })
|
|
4783
|
-
] }) : null,
|
|
4784
|
-
detail.order.region ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4785
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Region" }),
|
|
4786
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.region })
|
|
4787
|
-
] }) : null,
|
|
4788
|
-
detail.order.fulfillment_status ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4789
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Fulfillment status" }),
|
|
4790
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.order.fulfillment_status })
|
|
4791
|
-
] }) : null
|
|
4792
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No order linked to this refund." })
|
|
4793
|
-
] }),
|
|
4794
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
4795
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4796
|
-
"button",
|
|
4797
|
-
{
|
|
4798
|
-
type: "button",
|
|
4799
|
-
className: "flex w-full items-center justify-between text-left",
|
|
4800
|
-
onClick: () => setGatewayExpanded((prev) => !prev),
|
|
4801
|
-
"aria-expanded": gatewayExpanded,
|
|
4802
|
-
"aria-label": gatewayExpanded ? "Collapse gateway data" : "Expand gateway data",
|
|
4803
|
-
children: [
|
|
4804
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg", children: "Gateway data" }),
|
|
4805
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: gatewayExpanded ? "Collapse" : "Expand" })
|
|
4806
|
-
]
|
|
4807
|
-
}
|
|
4808
|
-
),
|
|
4809
|
-
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." }) })
|
|
4810
|
-
] })
|
|
4811
|
-
] }) : null
|
|
4773
|
+
swap.new_items && swap.new_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
4774
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "New Items" }),
|
|
4775
|
+
/* @__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: [
|
|
4776
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
4777
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Variant ID" }),
|
|
4778
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" })
|
|
4779
|
+
] }) }),
|
|
4780
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.new_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
4781
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.variant_id }),
|
|
4782
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity })
|
|
4783
|
+
] }, item.variant_id || index)) })
|
|
4784
|
+
] }) })
|
|
4785
|
+
] })
|
|
4812
4786
|
] }) });
|
|
4813
4787
|
};
|
|
4814
4788
|
const config = adminSdk.defineRouteConfig({
|
|
4815
|
-
label: "
|
|
4816
|
-
icon: icons.
|
|
4789
|
+
label: "Swap Details",
|
|
4790
|
+
icon: icons.ArrowPath
|
|
4817
4791
|
});
|
|
4818
4792
|
const i18nTranslations0 = {};
|
|
4819
4793
|
const widgetModule = { widgets: [
|
|
4820
4794
|
{
|
|
4821
4795
|
Component: OrderGiftItemsWidget,
|
|
4822
|
-
zone: ["order.details.side.after"]
|
|
4796
|
+
zone: ["order.details.side.after"],
|
|
4797
|
+
widgetId: "Widget-b753"
|
|
4823
4798
|
},
|
|
4824
4799
|
{
|
|
4825
4800
|
Component: OrderRefundContextWidget,
|
|
4826
|
-
zone: ["order.details.after"]
|
|
4801
|
+
zone: ["order.details.after"],
|
|
4802
|
+
widgetId: "Widget-0606"
|
|
4827
4803
|
}
|
|
4828
4804
|
] };
|
|
4829
4805
|
const routeModule = {
|
|
4830
4806
|
routes: [
|
|
4831
4807
|
{
|
|
4832
4808
|
Component: DeletedRecordsPage,
|
|
4833
|
-
path: "/deleted-records-audit"
|
|
4809
|
+
path: "/deleted-records-audit",
|
|
4810
|
+
handle: { label: config$9.label, translationNs: config$9.translationNs }
|
|
4834
4811
|
},
|
|
4835
4812
|
{
|
|
4836
4813
|
Component: PaymentsPage,
|
|
4837
|
-
path: "/payments"
|
|
4814
|
+
path: "/payments",
|
|
4815
|
+
handle: { label: config$8.label, translationNs: config$8.translationNs }
|
|
4838
4816
|
},
|
|
4839
4817
|
{
|
|
4840
|
-
Component:
|
|
4841
|
-
path: "/
|
|
4818
|
+
Component: RefundsPage,
|
|
4819
|
+
path: "/refunds",
|
|
4820
|
+
handle: { label: config$7.label, translationNs: config$7.translationNs }
|
|
4842
4821
|
},
|
|
4843
4822
|
{
|
|
4844
|
-
Component:
|
|
4845
|
-
path: "/
|
|
4823
|
+
Component: ReturnsPage,
|
|
4824
|
+
path: "/returns",
|
|
4825
|
+
handle: { label: config$6.label, translationNs: config$6.translationNs }
|
|
4846
4826
|
},
|
|
4847
4827
|
{
|
|
4848
4828
|
Component: SwapsPage,
|
|
4849
|
-
path: "/swaps"
|
|
4829
|
+
path: "/swaps",
|
|
4830
|
+
handle: { label: config$5.label, translationNs: config$5.translationNs }
|
|
4850
4831
|
},
|
|
4851
4832
|
{
|
|
4852
|
-
Component:
|
|
4853
|
-
path: "/
|
|
4833
|
+
Component: DeletedRecordDetailPage,
|
|
4834
|
+
path: "/deleted-records-audit/:id",
|
|
4835
|
+
handle: { label: config$4.label, translationNs: config$4.translationNs }
|
|
4854
4836
|
},
|
|
4855
4837
|
{
|
|
4856
4838
|
Component: PaymentDetailPage,
|
|
4857
|
-
path: "/payments/:id"
|
|
4839
|
+
path: "/payments/:id",
|
|
4840
|
+
handle: { label: config$3.label, translationNs: config$3.translationNs }
|
|
4858
4841
|
},
|
|
4859
4842
|
{
|
|
4860
|
-
Component:
|
|
4861
|
-
path: "/
|
|
4843
|
+
Component: RefundDetailPage,
|
|
4844
|
+
path: "/refunds/:id",
|
|
4845
|
+
handle: { label: config$2.label, translationNs: config$2.translationNs }
|
|
4862
4846
|
},
|
|
4863
4847
|
{
|
|
4864
4848
|
Component: ReturnDetailPage,
|
|
4865
|
-
path: "/returns/:id"
|
|
4849
|
+
path: "/returns/:id",
|
|
4850
|
+
handle: { label: config$1.label, translationNs: config$1.translationNs }
|
|
4866
4851
|
},
|
|
4867
4852
|
{
|
|
4868
|
-
Component:
|
|
4869
|
-
path: "/
|
|
4853
|
+
Component: SwapDetailPage,
|
|
4854
|
+
path: "/swaps/:id",
|
|
4855
|
+
handle: { label: config.label, translationNs: config.translationNs }
|
|
4870
4856
|
}
|
|
4871
4857
|
]
|
|
4872
4858
|
};
|
|
4873
4859
|
const menuItemModule = {
|
|
4874
4860
|
menuItems: [
|
|
4861
|
+
{
|
|
4862
|
+
label: config$9.label,
|
|
4863
|
+
icon: config$9.icon,
|
|
4864
|
+
path: "/deleted-records-audit",
|
|
4865
|
+
nested: void 0,
|
|
4866
|
+
rank: void 0,
|
|
4867
|
+
translationNs: void 0
|
|
4868
|
+
},
|
|
4875
4869
|
{
|
|
4876
4870
|
label: config$8.label,
|
|
4877
4871
|
icon: config$8.icon,
|
|
4878
|
-
path: "/
|
|
4879
|
-
nested: void 0
|
|
4872
|
+
path: "/payments",
|
|
4873
|
+
nested: void 0,
|
|
4874
|
+
rank: void 0,
|
|
4875
|
+
translationNs: void 0
|
|
4880
4876
|
},
|
|
4881
4877
|
{
|
|
4882
4878
|
label: config$7.label,
|
|
4883
4879
|
icon: config$7.icon,
|
|
4884
|
-
path: "/
|
|
4885
|
-
nested: void 0
|
|
4880
|
+
path: "/refunds",
|
|
4881
|
+
nested: void 0,
|
|
4882
|
+
rank: void 0,
|
|
4883
|
+
translationNs: void 0
|
|
4886
4884
|
},
|
|
4887
4885
|
{
|
|
4888
4886
|
label: config$6.label,
|
|
4889
4887
|
icon: config$6.icon,
|
|
4890
4888
|
path: "/returns",
|
|
4891
|
-
nested: void 0
|
|
4889
|
+
nested: void 0,
|
|
4890
|
+
rank: void 0,
|
|
4891
|
+
translationNs: void 0
|
|
4892
4892
|
},
|
|
4893
4893
|
{
|
|
4894
4894
|
label: config$5.label,
|
|
4895
4895
|
icon: config$5.icon,
|
|
4896
4896
|
path: "/swaps",
|
|
4897
|
-
nested: void 0
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
label: config$4.label,
|
|
4901
|
-
icon: config$4.icon,
|
|
4902
|
-
path: "/refunds",
|
|
4903
|
-
nested: void 0
|
|
4897
|
+
nested: void 0,
|
|
4898
|
+
rank: void 0,
|
|
4899
|
+
translationNs: void 0
|
|
4904
4900
|
},
|
|
4905
4901
|
{
|
|
4906
4902
|
label: config$3.label,
|
|
4907
4903
|
icon: config$3.icon,
|
|
4908
4904
|
path: "/payments/:id",
|
|
4909
|
-
nested: void 0
|
|
4905
|
+
nested: void 0,
|
|
4906
|
+
rank: void 0,
|
|
4907
|
+
translationNs: void 0
|
|
4908
|
+
},
|
|
4909
|
+
{
|
|
4910
|
+
label: config$2.label,
|
|
4911
|
+
icon: config$2.icon,
|
|
4912
|
+
path: "/refunds/:id",
|
|
4913
|
+
nested: void 0,
|
|
4914
|
+
rank: void 0,
|
|
4915
|
+
translationNs: void 0
|
|
4910
4916
|
},
|
|
4911
4917
|
{
|
|
4912
4918
|
label: config$1.label,
|
|
4913
4919
|
icon: config$1.icon,
|
|
4914
4920
|
path: "/returns/:id",
|
|
4915
|
-
nested: void 0
|
|
4916
|
-
|
|
4917
|
-
|
|
4918
|
-
label: config$2.label,
|
|
4919
|
-
icon: config$2.icon,
|
|
4920
|
-
path: "/swaps/:id",
|
|
4921
|
-
nested: void 0
|
|
4921
|
+
nested: void 0,
|
|
4922
|
+
rank: void 0,
|
|
4923
|
+
translationNs: void 0
|
|
4922
4924
|
},
|
|
4923
4925
|
{
|
|
4924
4926
|
label: config.label,
|
|
4925
4927
|
icon: config.icon,
|
|
4926
|
-
path: "/
|
|
4927
|
-
nested: void 0
|
|
4928
|
+
path: "/swaps/:id",
|
|
4929
|
+
nested: void 0,
|
|
4930
|
+
rank: void 0,
|
|
4931
|
+
translationNs: void 0
|
|
4928
4932
|
}
|
|
4929
4933
|
]
|
|
4930
4934
|
};
|
|
@@ -4933,12 +4937,18 @@ const displayModule = {
|
|
|
4933
4937
|
displays: {}
|
|
4934
4938
|
};
|
|
4935
4939
|
const i18nModule = { resources: i18nTranslations0 };
|
|
4940
|
+
const cellRendererModule = {};
|
|
4941
|
+
const layoutModule = { layouts: [] };
|
|
4942
|
+
const searchEntityModule = {};
|
|
4936
4943
|
const plugin = {
|
|
4937
4944
|
widgetModule,
|
|
4938
4945
|
routeModule,
|
|
4939
4946
|
menuItemModule,
|
|
4940
4947
|
formModule,
|
|
4941
4948
|
displayModule,
|
|
4942
|
-
i18nModule
|
|
4949
|
+
i18nModule,
|
|
4950
|
+
cellRendererModule,
|
|
4951
|
+
layoutModule,
|
|
4952
|
+
searchEntityModule
|
|
4943
4953
|
};
|
|
4944
4954
|
module.exports = plugin;
|