order-management 0.0.101 → 0.0.103

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