@odla-ai/chapter 0.58.1 → 0.59.1

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.
@@ -4,7 +4,7 @@ import {
4
4
  DEFAULT_CHAPTER_COPY,
5
5
  formatChapterCopy,
6
6
  useChapterCopy
7
- } from "./chunk-FHKZVF5G.js";
7
+ } from "./chunk-GADLTNJF.js";
8
8
 
9
9
  // src/ui/admin.tsx
10
10
  import { useEffect as useEffect12, useMemo as useMemo3, useRef as useRef3, useState as useState27 } from "preact/hooks";
@@ -773,7 +773,7 @@ function SeatPanel(props) {
773
773
  setBusy(false);
774
774
  }
775
775
  };
776
- const money5 = new Intl.NumberFormat("en-US", { style: "currency", currency: data.currency }).format(data.amountCents / 100);
776
+ const money6 = new Intl.NumberFormat("en-US", { style: "currency", currency: data.currency }).format(data.amountCents / 100);
777
777
  const refund = async () => {
778
778
  setBusy(true);
779
779
  setNote(null);
@@ -807,7 +807,7 @@ function SeatPanel(props) {
807
807
  seat.invitationHeld ? " (invitation waits for the purchaser's approval)" : ""
808
808
  ] }),
809
809
  /* @__PURE__ */ jsxs7("p", { className: "muted", style: { margin: 0 }, children: [
810
- data.amountCents === 0 ? "Included with the membership; nothing was charged." : `${money5} paid in full.`,
810
+ data.amountCents === 0 ? "Included with the membership; nothing was charged." : `${money6} paid in full.`,
811
811
  " The seat waits for its recipient and is never refunded automatically."
812
812
  ] }),
813
813
  data.refundable || data.regiftable ? /* @__PURE__ */ jsxs7("div", { style: { display: "flex", gap: 8 }, children: [
@@ -1944,7 +1944,7 @@ function RecordsExplorer(props) {
1944
1944
  `/api/admin/network/records?${query}`
1945
1945
  );
1946
1946
  const selected = page.data?.records.find((record) => record.id === ctx.route.recordId);
1947
- const columns3 = useMemo(() => [
1947
+ const columns4 = useMemo(() => [
1948
1948
  {
1949
1949
  key: "name",
1950
1950
  header: "Name",
@@ -1988,7 +1988,7 @@ function RecordsExplorer(props) {
1988
1988
  ctx.navigate({ recordId: null, detailTab: null });
1989
1989
  },
1990
1990
  rows: page.data?.records ?? [],
1991
- columns: columns3,
1991
+ columns: columns4,
1992
1992
  rowKey: (record) => record.id,
1993
1993
  loading: page.loading,
1994
1994
  emptyState: page.error ? `Could not load records: ${page.error}` : "No records found.",
@@ -3585,14 +3585,103 @@ function NetworkSeatBilling(props) {
3585
3585
  ] });
3586
3586
  }
3587
3587
 
3588
- // src/ui/membership-policy-versions.tsx
3589
- import { Button as Button20, DataTable as DataTable5 } from "@odla-ai/ui/components";
3588
+ // src/ui/membership-disputes.tsx
3590
3589
  import { useState as useState31 } from "preact/hooks";
3591
- import { Fragment as Fragment15, jsx as jsx38, jsxs as jsxs34 } from "preact/jsx-runtime";
3590
+ import { Button as Button20, DataTable as DataTable5 } from "@odla-ai/ui/components";
3591
+ import { jsx as jsx38, jsxs as jsxs34 } from "preact/jsx-runtime";
3592
+ var money4 = (row, cents) => new Intl.NumberFormat("en-US", { style: "currency", currency: row.currency }).format(cents / 100);
3593
+ var day = (at) => at ? new Date(at).toLocaleDateString() : "\u2014";
3594
+ var DISPUTE_STATUS_WORDS = {
3595
+ warning_needs_response: "inquiry, response needed",
3596
+ warning_under_review: "inquiry under review",
3597
+ warning_closed: "inquiry closed",
3598
+ needs_response: "open, response needed",
3599
+ under_review: "under review",
3600
+ won: "won",
3601
+ lost: "lost",
3602
+ recharged: "re-charged"
3603
+ };
3604
+ var columns3 = (begin, busy) => [
3605
+ { key: "member", header: "Member", cell: (row) => row.kind === "seat" ? /* @__PURE__ */ jsxs34("span", { children: [
3606
+ "Seat for ",
3607
+ row.recipientName ?? "the named recipient",
3608
+ " \xB7 ",
3609
+ /* @__PURE__ */ jsx38("code", { children: row.applicationId })
3610
+ ] }) : /* @__PURE__ */ jsxs34("span", { children: [
3611
+ row.memberNumber ? `#${row.memberNumber} \xB7 ` : "",
3612
+ /* @__PURE__ */ jsx38("code", { children: row.applicationId })
3613
+ ] }) },
3614
+ { key: "chapter", header: "Chapter / runtime", cell: (row) => `${row.chapterId} / ${row.runtime}` },
3615
+ { key: "status", header: "Record", cell: (row) => row.status === "payment_disputed" ? `${row.kind === "seat" ? "seat" : "membership"} suspended by dispute` : row.status },
3616
+ { key: "dispute", header: "Dispute", cell: (row) => /* @__PURE__ */ jsxs34("span", { children: [
3617
+ DISPUTE_STATUS_WORDS[row.disputeStatus] ?? row.disputeStatus,
3618
+ row.disputeReason ? ` \xB7 ${row.disputeReason}` : ""
3619
+ ] }) },
3620
+ { key: "amount", header: "Amount", cell: (row) => money4(row, row.disputeAmountCents ?? row.amountCents) },
3621
+ { key: "opened", header: "Opened", cell: (row) => day(row.disputedAt) },
3622
+ { key: "closed", header: "Closed", cell: (row) => day(row.disputeClosedAt) },
3623
+ { key: "recharge", header: "Re-charge", cell: (row) => row.rechargePaymentIntentId ? /* @__PURE__ */ jsxs34("span", { children: [
3624
+ day(row.rechargedAt),
3625
+ " \xB7 ",
3626
+ /* @__PURE__ */ jsx38("code", { children: row.rechargePaymentIntentId })
3627
+ ] }) : row.status === "payment_disputed" && row.disputeStatus === "lost" ? /* @__PURE__ */ jsx38(Button20, { mini: true, disabled: busy !== null, onClick: () => begin(row), children: busy === row.id ? "Charging\u2026" : "Charge again" }) : row.status === "payment_disputed" ? "Respond to the dispute in Stripe" : "\u2014" }
3628
+ ];
3629
+ function MembershipDisputes(props) {
3630
+ const { data, loading, error, refresh } = useAdminResource(props.getToken, "/api/admin/membership-disputes");
3631
+ const [busy, setBusy] = useState31(null);
3632
+ const [confirming, setConfirming] = useState31(null);
3633
+ const [note, setNote] = useState31(null);
3634
+ const recharge = async (row) => {
3635
+ setBusy(row.id);
3636
+ setNote(null);
3637
+ setConfirming(null);
3638
+ try {
3639
+ const receipt = await adminFetch(
3640
+ props.getToken,
3641
+ `/api/admin/membership-disputes/${encodeURIComponent(row.id)}/recharge`,
3642
+ { method: "POST" }
3643
+ );
3644
+ const what = row.kind === "seat" ? `the seat for ${row.recipientName ?? "the recipient"}` : `membership ${row.applicationId}`;
3645
+ setNote(receipt.replayed ? `${what} was already re-charged (${receipt.paymentIntentId}).` : `Collected ${money4(row, receipt.amountCents)} again for ${what}; it is ${receipt.status}.`);
3646
+ refresh();
3647
+ } catch (failure) {
3648
+ setNote(failure instanceof Error ? failure.message : "The charge could not be re-issued.");
3649
+ } finally {
3650
+ setBusy(null);
3651
+ }
3652
+ };
3653
+ const rows = data?.disputes ?? [];
3654
+ return /* @__PURE__ */ jsxs34(Panel, { title: "Card disputes", children: [
3655
+ /* @__PURE__ */ jsx38("p", { children: "A chargeback suspends the membership until the dispute is won or the member clears it with their bank. Re-charging collects the disputed amount again on the saved card, only after a lost dispute and only when you ask." }),
3656
+ loading ? /* @__PURE__ */ jsx38("p", { children: "Loading disputes\u2026" }) : error ? /* @__PURE__ */ jsxs34("p", { role: "alert", children: [
3657
+ "Disputes could not be loaded: ",
3658
+ error
3659
+ ] }) : rows.length ? /* @__PURE__ */ jsx38(DataTable5, { rows, columns: columns3(setConfirming, busy), rowKey: (row) => row.id }) : /* @__PURE__ */ jsx38("p", { children: "No membership carries a dispute." }),
3660
+ data?.truncated ? /* @__PURE__ */ jsx38("p", { role: "alert", children: "Only the most recent memberships were checked; older disputes may exist." }) : null,
3661
+ confirming ? /* @__PURE__ */ jsxs34("div", { role: "group", "aria-label": "Confirm re-charge", children: [
3662
+ /* @__PURE__ */ jsxs34("p", { children: [
3663
+ "Charge ",
3664
+ money4(confirming, confirming.disputeAmountCents ?? confirming.amountCents),
3665
+ " again to the card on file for ",
3666
+ confirming.kind === "seat" ? `the seat for ${confirming.recipientName ?? "the recipient"}` : confirming.applicationId,
3667
+ "?"
3668
+ ] }),
3669
+ /* @__PURE__ */ jsx38(Button20, { mini: true, onClick: () => void recharge(confirming), children: "Yes, charge the card" }),
3670
+ " ",
3671
+ /* @__PURE__ */ jsx38(Button20, { mini: true, onClick: () => setConfirming(null), children: "Cancel" })
3672
+ ] }) : null,
3673
+ note ? /* @__PURE__ */ jsx38("p", { role: "status", children: note }) : null
3674
+ ] });
3675
+ }
3676
+
3677
+ // src/ui/membership-policy-versions.tsx
3678
+ import { Button as Button21, DataTable as DataTable6 } from "@odla-ai/ui/components";
3679
+ import { useState as useState32 } from "preact/hooks";
3680
+ import { Fragment as Fragment15, jsx as jsx39, jsxs as jsxs35 } from "preact/jsx-runtime";
3592
3681
  var PATH = "/api/admin/membership-policy-versions";
3593
3682
  var RETERM = "/api/admin/membership-discount/reterm";
3594
- var day = (ms) => new Date(ms).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric", timeZone: "UTC" });
3595
- var money4 = (cents, currency) => new Intl.NumberFormat("en-US", { style: "currency", currency }).format(cents / 100);
3683
+ var day2 = (ms) => new Date(ms).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric", timeZone: "UTC" });
3684
+ var money5 = (cents, currency) => new Intl.NumberFormat("en-US", { style: "currency", currency }).format(cents / 100);
3596
3685
  var STATE = { active: "Active", scheduled: "Scheduled", superseded: "Superseded", draft: "Draft", retired: "Retired" };
3597
3686
  var MECHANISM = {
3598
3687
  none: "None: cohort status only, no provider discount",
@@ -3600,62 +3689,62 @@ var MECHANISM = {
3600
3689
  stripe_coupon_forever: "Stripe coupon, applied while active",
3601
3690
  stripe_coupon_term_bound: "Stripe coupon, applied once; issuance refuses unless the offering's fixed term ends on the same date"
3602
3691
  };
3603
- var State = ({ row }) => /* @__PURE__ */ jsx38("span", { className: row.state === "active" ? "badge" : "muted", children: STATE[row.state] });
3604
- var superseded = (row) => row.supersededAt === void 0 ? "\u2014" : day(row.supersededAt);
3605
- var Source = ({ row }) => /* @__PURE__ */ jsxs34("span", { children: [
3606
- row.source ?? /* @__PURE__ */ jsx38("span", { className: "muted", children: "Unrecorded" }),
3607
- row.actor ? /* @__PURE__ */ jsxs34(Fragment15, { children: [
3692
+ var State = ({ row }) => /* @__PURE__ */ jsx39("span", { className: row.state === "active" ? "badge" : "muted", children: STATE[row.state] });
3693
+ var superseded = (row) => row.supersededAt === void 0 ? "\u2014" : day2(row.supersededAt);
3694
+ var Source = ({ row }) => /* @__PURE__ */ jsxs35("span", { children: [
3695
+ row.source ?? /* @__PURE__ */ jsx39("span", { className: "muted", children: "Unrecorded" }),
3696
+ row.actor ? /* @__PURE__ */ jsxs35(Fragment15, { children: [
3608
3697
  " \xB7 ",
3609
- /* @__PURE__ */ jsx38("code", { children: row.actor })
3698
+ /* @__PURE__ */ jsx39("code", { children: row.actor })
3610
3699
  ] }) : null,
3611
- row.recordedAt !== void 0 ? /* @__PURE__ */ jsxs34(Fragment15, { children: [
3700
+ row.recordedAt !== void 0 ? /* @__PURE__ */ jsxs35(Fragment15, { children: [
3612
3701
  " \xB7 ",
3613
- day(row.recordedAt)
3702
+ day2(row.recordedAt)
3614
3703
  ] }) : null
3615
3704
  ] });
3616
3705
  var offeringColumns = [
3617
- { key: "version", header: "Version", cell: (row) => /* @__PURE__ */ jsxs34(Fragment15, { children: [
3618
- /* @__PURE__ */ jsxs34("code", { children: [
3706
+ { key: "version", header: "Version", cell: (row) => /* @__PURE__ */ jsxs35(Fragment15, { children: [
3707
+ /* @__PURE__ */ jsxs35("code", { children: [
3619
3708
  "v",
3620
3709
  row.version
3621
3710
  ] }),
3622
3711
  " ",
3623
- /* @__PURE__ */ jsx38(State, { row })
3712
+ /* @__PURE__ */ jsx39(State, { row })
3624
3713
  ] }), sortAs: "number", sortValue: (row) => row.version },
3625
- { key: "sku", header: "SKU", cell: (row) => /* @__PURE__ */ jsx38("code", { children: row.baseSkuId }) },
3626
- { key: "list", header: "List price", cell: (row) => `${money4(row.basePriceCents, row.currency)} / ${row.interval}` },
3627
- { key: "term", header: "Term", cell: (row) => row.term.kind === "fixed_end" ? `Ends ${day(row.term.endsAt)}` : `Rolling ${row.term.months} months` },
3628
- { key: "seat", header: "Seat", cell: (row) => `${row.seatPriceCents === 0 ? "Included" : money4(row.seatPriceCents, row.currency)} \xB7 ${row.seatPurchaseWindowCalendarMonths === void 0 ? "no window" : `${row.seatPurchaseWindowCalendarMonths}-month window`}` },
3629
- { key: "effectiveFrom", header: "Effective from", cell: (row) => day(row.effectiveFrom), sortAs: "number", sortValue: (row) => row.effectiveFrom },
3630
- { key: "effectiveUntil", header: "Effective until", cell: (row) => row.effectiveUntil === void 0 ? "Open" : day(row.effectiveUntil) },
3714
+ { key: "sku", header: "SKU", cell: (row) => /* @__PURE__ */ jsx39("code", { children: row.baseSkuId }) },
3715
+ { key: "list", header: "List price", cell: (row) => `${money5(row.basePriceCents, row.currency)} / ${row.interval}` },
3716
+ { key: "term", header: "Term", cell: (row) => row.term.kind === "fixed_end" ? `Ends ${day2(row.term.endsAt)}` : `Rolling ${row.term.months} months` },
3717
+ { key: "seat", header: "Seat", cell: (row) => `${row.seatPriceCents === 0 ? "Included" : money5(row.seatPriceCents, row.currency)} \xB7 ${row.seatPurchaseWindowCalendarMonths === void 0 ? "no window" : `${row.seatPurchaseWindowCalendarMonths}-month window`}` },
3718
+ { key: "effectiveFrom", header: "Effective from", cell: (row) => day2(row.effectiveFrom), sortAs: "number", sortValue: (row) => row.effectiveFrom },
3719
+ { key: "effectiveUntil", header: "Effective until", cell: (row) => row.effectiveUntil === void 0 ? "Open" : day2(row.effectiveUntil) },
3631
3720
  { key: "supersededAt", header: "Superseded", cell: superseded },
3632
- { key: "source", header: "Source", cell: (row) => /* @__PURE__ */ jsx38(Source, { row }) }
3721
+ { key: "source", header: "Source", cell: (row) => /* @__PURE__ */ jsx39(Source, { row }) }
3633
3722
  ];
3634
3723
  var policyColumns = (getToken) => [
3635
- { key: "version", header: "Version", cell: (row) => /* @__PURE__ */ jsxs34(Fragment15, { children: [
3636
- /* @__PURE__ */ jsxs34("code", { children: [
3724
+ { key: "version", header: "Version", cell: (row) => /* @__PURE__ */ jsxs35(Fragment15, { children: [
3725
+ /* @__PURE__ */ jsxs35("code", { children: [
3637
3726
  "v",
3638
3727
  row.version
3639
3728
  ] }),
3640
3729
  " ",
3641
- /* @__PURE__ */ jsx38(State, { row })
3730
+ /* @__PURE__ */ jsx39(State, { row })
3642
3731
  ] }), sortAs: "number", sortValue: (row) => row.version },
3643
- { key: "cohort", header: "Cohort", cell: (row) => /* @__PURE__ */ jsxs34(Fragment15, { children: [
3732
+ { key: "cohort", header: "Cohort", cell: (row) => /* @__PURE__ */ jsxs35(Fragment15, { children: [
3644
3733
  row.cohortLabel,
3645
3734
  " ",
3646
- /* @__PURE__ */ jsxs34("span", { className: "muted", children: [
3735
+ /* @__PURE__ */ jsxs35("span", { className: "muted", children: [
3647
3736
  "\xB7 soft target ",
3648
3737
  row.softTarget
3649
3738
  ] })
3650
3739
  ] }) },
3651
3740
  { key: "percentOff", header: "Percent off", cell: (row) => `${row.percentOffBps / 100}%` },
3652
3741
  { key: "skus", header: "Discounted SKUs", cell: (row) => row.discountEligibleSkuIds.length ? row.discountEligibleSkuIds.join(", ") : "None" },
3653
- { key: "qualifying", header: "Qualifying window", cell: (row) => `${day(row.qualifyingStartsAt)} \u2192 ${day(row.qualifyingEndsAt)}` },
3654
- { key: "benefit", header: "Benefit duration", cell: (row) => row.benefitDuration.kind === "fixed_end" ? `Until ${day(row.benefitDuration.endsAt)}` : row.benefitDuration.kind === "first_term" ? "First term" : "While active" },
3742
+ { key: "qualifying", header: "Qualifying window", cell: (row) => `${day2(row.qualifyingStartsAt)} \u2192 ${day2(row.qualifyingEndsAt)}` },
3743
+ { key: "benefit", header: "Benefit duration", cell: (row) => row.benefitDuration.kind === "fixed_end" ? `Until ${day2(row.benefitDuration.endsAt)}` : row.benefitDuration.kind === "first_term" ? "First term" : "While active" },
3655
3744
  { key: "mechanism", header: "Provider mechanism", cell: (row) => MECHANISM[row.mechanism] },
3656
3745
  { key: "supersededAt", header: "Superseded", cell: superseded },
3657
- { key: "source", header: "Source", cell: (row) => /* @__PURE__ */ jsx38(Source, { row }) },
3658
- { key: "members", header: "Existing members", cell: (row) => /* @__PURE__ */ jsx38(RetermAction, { row, getToken }) }
3746
+ { key: "source", header: "Source", cell: (row) => /* @__PURE__ */ jsx39(Source, { row }) },
3747
+ { key: "members", header: "Existing members", cell: (row) => /* @__PURE__ */ jsx39(RetermAction, { row, getToken }) }
3659
3748
  ];
3660
3749
  var summary = (receipt) => {
3661
3750
  const skipped = receipt.skipped.reduce((acc, item) => ({ ...acc, [item.reason]: (acc[item.reason] ?? 0) + 1 }), {});
@@ -3667,9 +3756,9 @@ var summary = (receipt) => {
3667
3756
  return `${parts.join(" \xB7 ")}${receipt.more ? " \xB7 more remain, run again" : ""}`;
3668
3757
  };
3669
3758
  function RetermAction({ row, getToken }) {
3670
- const [busy, setBusy] = useState31(false);
3671
- const [result, setResult] = useState31(null);
3672
- if (row.state !== "active" || row.mechanism !== "stripe_coupon_forever") return /* @__PURE__ */ jsx38("span", { className: "muted", children: row.state !== "active" ? "Not the active version" : "Benefit is not while-active" });
3759
+ const [busy, setBusy] = useState32(false);
3760
+ const [result, setResult] = useState32(null);
3761
+ if (row.state !== "active" || row.mechanism !== "stripe_coupon_forever") return /* @__PURE__ */ jsx39("span", { className: "muted", children: row.state !== "active" ? "Not the active version" : "Benefit is not while-active" });
3673
3762
  const run = async () => {
3674
3763
  if (!globalThis.confirm?.(`Move every paid ${row.cohortLabel} member of ${row.chapterId} onto v${row.version}? Their next renewal invoice carries ${row.percentOffBps / 100}% off while they stay active. A member whose renewal this would raise is left alone.`)) return;
3675
3764
  setBusy(true);
@@ -3683,29 +3772,29 @@ function RetermAction({ row, getToken }) {
3683
3772
  setBusy(false);
3684
3773
  }
3685
3774
  };
3686
- return /* @__PURE__ */ jsxs34("span", { style: { display: "inline-flex", flexDirection: "column", gap: 4 }, children: [
3687
- /* @__PURE__ */ jsx38(Button20, { mini: true, disabled: busy, onClick: run, children: busy ? "Moving\u2026" : "Move members to this benefit" }),
3688
- result ? /* @__PURE__ */ jsx38("span", { role: result.tone === "good" ? "status" : "alert", className: result.tone === "danger" ? "danger" : "muted", children: result.text }) : null
3775
+ return /* @__PURE__ */ jsxs35("span", { style: { display: "inline-flex", flexDirection: "column", gap: 4 }, children: [
3776
+ /* @__PURE__ */ jsx39(Button21, { mini: true, disabled: busy, onClick: run, children: busy ? "Moving\u2026" : "Move members to this benefit" }),
3777
+ result ? /* @__PURE__ */ jsx39("span", { role: result.tone === "good" ? "status" : "alert", className: result.tone === "danger" ? "danger" : "muted", children: result.text }) : null
3689
3778
  ] });
3690
3779
  }
3691
3780
  function MembershipPolicyVersions(props) {
3692
3781
  const path = props.chapterId ? `${PATH}?chapterId=${encodeURIComponent(props.chapterId)}` : PATH;
3693
3782
  const { data, loading, error } = useAdminResource(props.getToken, path);
3694
3783
  const scope = props.chapterId ? `chapter ${props.chapterId}` : "any chapter";
3695
- if (loading) return /* @__PURE__ */ jsx38(Panel, { title: "Membership offering versions", children: /* @__PURE__ */ jsx38("p", { role: "status", children: "Loading offering versions\u2026" }) });
3696
- if (error || !data) return /* @__PURE__ */ jsx38(Panel, { title: "Membership offering versions", children: /* @__PURE__ */ jsxs34("p", { role: "alert", children: [
3784
+ if (loading) return /* @__PURE__ */ jsx39(Panel, { title: "Membership offering versions", children: /* @__PURE__ */ jsx39("p", { role: "status", children: "Loading offering versions\u2026" }) });
3785
+ if (error || !data) return /* @__PURE__ */ jsx39(Panel, { title: "Membership offering versions", children: /* @__PURE__ */ jsxs35("p", { role: "alert", children: [
3697
3786
  "Offering versions could not be loaded: ",
3698
3787
  error ?? "empty response"
3699
3788
  ] }) });
3700
- return /* @__PURE__ */ jsxs34(Fragment15, { children: [
3701
- /* @__PURE__ */ jsxs34(Panel, { title: "Membership offering versions", actions: data.truncated ? /* @__PURE__ */ jsx38("span", { className: "badge", children: "Truncated" }) : void 0, children: [
3702
- /* @__PURE__ */ jsxs34("p", { className: "muted", children: [
3789
+ return /* @__PURE__ */ jsxs35(Fragment15, { children: [
3790
+ /* @__PURE__ */ jsxs35(Panel, { title: "Membership offering versions", actions: data.truncated ? /* @__PURE__ */ jsx39("span", { className: "badge", children: "Truncated" }) : void 0, children: [
3791
+ /* @__PURE__ */ jsxs35("p", { className: "muted", children: [
3703
3792
  "The list price a card shows comes from the active offering; the payable price applies the active discount policy. State is judged as of ",
3704
- day(data.now),
3793
+ day2(data.now),
3705
3794
  ", exactly as checkout issuance judges it."
3706
3795
  ] }),
3707
- /* @__PURE__ */ jsx38(
3708
- DataTable5,
3796
+ /* @__PURE__ */ jsx39(
3797
+ DataTable6,
3709
3798
  {
3710
3799
  rows: data.offerings,
3711
3800
  columns: offeringColumns,
@@ -3715,9 +3804,9 @@ function MembershipPolicyVersions(props) {
3715
3804
  }
3716
3805
  )
3717
3806
  ] }),
3718
- /* @__PURE__ */ jsxs34(Panel, { title: "Discount policy versions", children: [
3719
- /* @__PURE__ */ jsx38(
3720
- DataTable5,
3807
+ /* @__PURE__ */ jsxs35(Panel, { title: "Discount policy versions", children: [
3808
+ /* @__PURE__ */ jsx39(
3809
+ DataTable6,
3721
3810
  {
3722
3811
  rows: data.discountPolicies,
3723
3812
  columns: policyColumns(props.getToken),
@@ -3726,7 +3815,7 @@ function MembershipPolicyVersions(props) {
3726
3815
  emptyState: `No discount policy versions are recorded for ${scope}.`
3727
3816
  }
3728
3817
  ),
3729
- data.invalid.length ? /* @__PURE__ */ jsxs34("p", { role: "alert", children: [
3818
+ data.invalid.length ? /* @__PURE__ */ jsxs35("p", { role: "alert", children: [
3730
3819
  data.invalid.length,
3731
3820
  " recorded version",
3732
3821
  data.invalid.length === 1 ? " no longer normalizes and blocks" : "s no longer normalize and block",
@@ -3782,6 +3871,8 @@ export {
3782
3871
  meetingsSection,
3783
3872
  NetworkRecordEditor,
3784
3873
  NetworkSeatBilling,
3874
+ DISPUTE_STATUS_WORDS,
3875
+ MembershipDisputes,
3785
3876
  MembershipPolicyVersions
3786
3877
  };
3787
- //# sourceMappingURL=chunk-L2IPS2FQ.js.map
3878
+ //# sourceMappingURL=chunk-P6X3W2XP.js.map