@fluid-app/portal-sdk 0.1.482 → 0.1.484

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.
@@ -32,7 +32,7 @@ import "./preview-context-Dy8QjidU.mjs";
32
32
  import "./CalendarWidget-Bigs2Yvo.mjs";
33
33
  import "./error-state-D0yEb7vf.mjs";
34
34
  import "./src-CfaFafsq.mjs";
35
- import { n as subscriptionsScreenPropertySchema, t as SubscriptionsScreen } from "./SubscriptionsScreen-0Giqwkng.mjs";
35
+ import { n as subscriptionsScreenPropertySchema, t as SubscriptionsScreen } from "./SubscriptionsScreen-BKJALFrF.mjs";
36
36
  import "./WidgetLoadingSkeleton-ruGYRKhU.mjs";
37
37
  import "./CardWidget-Cz2BRDba.mjs";
38
38
  import "./helpers-BCelXIdD.mjs";
@@ -2618,22 +2618,30 @@ function formatTime(dateString, timezone, locale = "en-US") {
2618
2618
  return "";
2619
2619
  }
2620
2620
  }
2621
- function getNextBillDisplay(subscription, labels = {
2621
+ function getNextBillDisplay(nextBillDate, displayStatus, labels = {
2622
2622
  cancelled: "Cancelled",
2623
2623
  completed: "Completed",
2624
2624
  paused: "Paused",
2625
2625
  notAvailable: "N/A"
2626
2626
  }, locale = "en-US") {
2627
- if (subscription?.billing_cycle_limit_reached) return labels.completed;
2628
- if (subscription?.status === "cancelled") return labels.cancelled;
2629
- if (subscription?.next_bill_date) return formatDate(subscription.next_bill_date, locale);
2630
- if (subscription?.status === "paused") return labels.paused;
2627
+ if (displayStatus === "completed") return labels.completed;
2628
+ if (displayStatus === "cancelled") return labels.cancelled;
2629
+ if (nextBillDate) return formatDate(nextBillDate, locale);
2630
+ if (displayStatus === "paused") return labels.paused;
2631
2631
  return labels.notAvailable;
2632
2632
  }
2633
2633
  //#endregion
2634
2634
  //#region ../../subscriptions/core/src/utils/subscription-actions.ts
2635
+ /**
2636
+ * The one rule for a completed subscription: its current plan's
2637
+ * billing-cycle limit is reached. Every "completed" presentation and
2638
+ * gate reads this, so a new terminal condition lands here once.
2639
+ */
2640
+ function isSubscriptionCompleted(subscription) {
2641
+ return subscription?.billing_cycle_limit_reached === true;
2642
+ }
2635
2643
  function getSubscriptionDisplayStatus(subscription) {
2636
- return subscription.billingCycleLimitReached === true ? "completed" : subscription.status;
2644
+ return isSubscriptionCompleted(subscription) ? "completed" : subscription.status;
2637
2645
  }
2638
2646
  function hasPendingSubscriptionSkip(skips, today = /* @__PURE__ */ new Date()) {
2639
2647
  if (!skips?.length) return false;
@@ -2645,13 +2653,11 @@ function hasPendingSubscriptionSkip(skips, today = /* @__PURE__ */ new Date()) {
2645
2653
  });
2646
2654
  }
2647
2655
  function getSubscriptionActionPolicy(subscription) {
2648
- if (subscription.billingCycleLimitReached === true) return {
2649
- primary: null,
2650
- order: [],
2651
- menu: [],
2652
- recovery: null
2653
- };
2654
- if (subscription.status === "active") {
2656
+ const status = getSubscriptionDisplayStatus({
2657
+ status: subscription.status,
2658
+ billing_cycle_limit_reached: subscription.billingCycleLimitReached
2659
+ });
2660
+ if (status === "active") {
2655
2661
  const skipAllowanceAvailable = subscription.maxSkips == null || (subscription.skippedCount ?? 0) < subscription.maxSkips;
2656
2662
  const canSkip = subscription.allowSkipping === true && subscription.nextBillDate != null && skipAllowanceAvailable;
2657
2663
  const order = [];
@@ -2666,19 +2672,19 @@ function getSubscriptionActionPolicy(subscription) {
2666
2672
  recovery: null
2667
2673
  };
2668
2674
  }
2669
- if (subscription.status === "paused") return {
2675
+ if (status === "paused") return {
2670
2676
  primary: "resume_subscription",
2671
2677
  order: [],
2672
2678
  menu: ["cancel_subscription"],
2673
2679
  recovery: null
2674
2680
  };
2675
- if (subscription.status === "cancelled") return {
2681
+ if (status === "cancelled") return {
2676
2682
  primary: "reactivate_subscription",
2677
2683
  order: [],
2678
2684
  menu: [],
2679
2685
  recovery: null
2680
2686
  };
2681
- if (subscription.status === "past_due") {
2687
+ if (status === "past_due") {
2682
2688
  const isExhausted = subscription.nextRetryAt == null;
2683
2689
  const secondary = subscription.canChangePaymentMethod ? "change_payment_method" : null;
2684
2690
  return {
@@ -2694,13 +2700,13 @@ function getSubscriptionActionPolicy(subscription) {
2694
2700
  }
2695
2701
  };
2696
2702
  }
2697
- if (subscription.status === "completed") return {
2703
+ if (status === "completed") return {
2698
2704
  primary: null,
2699
2705
  order: [],
2700
2706
  menu: [],
2701
2707
  recovery: null
2702
2708
  };
2703
- if (["pending", "trial"].includes(subscription.status)) return {
2709
+ if (["pending", "trial"].includes(status)) return {
2704
2710
  primary: null,
2705
2711
  order: [],
2706
2712
  menu: ["cancel_subscription"],
@@ -6425,12 +6431,14 @@ function SubscriptionItemsSection({ subscription, displayQuantity, displayNextBi
6425
6431
  const variant = subscription.variant;
6426
6432
  const product = variant?.product;
6427
6433
  const quantity = displayQuantity ?? subscription.quantity;
6434
+ const displayStatus = getSubscriptionDisplayStatus(subscription);
6435
+ const paymentFailed = displayStatus === "past_due";
6428
6436
  const quantityInputId = `subscription-${subscription.subscription_token}-quantity`;
6429
6437
  const pricing = computeSubscriptionPricing(subscription);
6430
6438
  const subtotal = formatCurrency(pricing.subtotalUnit * quantity);
6431
6439
  const totalPrice = formatCurrency(pricing.totalUnit * quantity);
6432
6440
  const effectiveNextBillDate = displayNextBillDate ?? subscription.next_bill_date;
6433
- const nextOrderTimeOfDay = subscription.billing_cycle_limit_reached ? "" : formatTime(effectiveNextBillDate, subscription.timezone, locale);
6441
+ const nextOrderTimeOfDay = displayStatus === "completed" ? "" : formatTime(effectiveNextBillDate, subscription.timezone, locale);
6434
6442
  const nextBillDisplayLabels = {
6435
6443
  cancelled: t("date_cancelled"),
6436
6444
  completed: t("list_status_completed"),
@@ -6454,14 +6462,11 @@ function SubscriptionItemsSection({ subscription, displayQuantity, displayNextBi
6454
6462
  children: [
6455
6463
  /* @__PURE__ */ jsx("div", {
6456
6464
  className: "text-muted-foreground mb-1 text-sm",
6457
- children: subscription.status === "past_due" && !subscription.billing_cycle_limit_reached ? t("payment_failed_on") : t("next_order_date")
6465
+ children: paymentFailed ? t("payment_failed_on") : t("next_order_date")
6458
6466
  }),
6459
6467
  /* @__PURE__ */ jsx("div", {
6460
6468
  className: "text-foreground text-2xl font-bold",
6461
- children: subscription.status === "past_due" && !subscription.billing_cycle_limit_reached ? subscription.last_failed_at ? formatOptionalDate(subscription.last_failed_at, locale) : "—" : getNextBillDisplay(displayNextBillDate ? {
6462
- ...subscription,
6463
- next_bill_date: displayNextBillDate
6464
- } : subscription, nextBillDisplayLabels, locale)
6469
+ children: paymentFailed ? subscription.last_failed_at ? formatOptionalDate(subscription.last_failed_at, locale) : "—" : getNextBillDisplay(effectiveNextBillDate, displayStatus, nextBillDisplayLabels, locale)
6465
6470
  }),
6466
6471
  nextOrderTimeOfDay && /* @__PURE__ */ jsxs("div", {
6467
6472
  className: "text-muted-foreground mt-1 text-xs",
@@ -6592,10 +6597,7 @@ function SubscriptionManagementSection({ subscription, actionPolicy, isMutating,
6592
6597
  const plan = subscription.subscription_plan;
6593
6598
  const quantity = subscription.quantity;
6594
6599
  const totalPrice = formatCurrency(subscription.price * quantity);
6595
- const displayStatus = getSubscriptionDisplayStatus({
6596
- status: subscription.status,
6597
- billingCycleLimitReached: subscription.billing_cycle_limit_reached
6598
- });
6600
+ const displayStatus = getSubscriptionDisplayStatus(subscription);
6599
6601
  const cadenceKey = getCadenceKey(plan.billing_interval_unit);
6600
6602
  const interval = plan.billing_interval;
6601
6603
  const unitKeys = UNIT_KEYS[plan.billing_interval_unit.toLowerCase()];
@@ -6790,7 +6792,7 @@ function SubscriptionManagementSection({ subscription, actionPolicy, isMutating,
6790
6792
  subscriptionToken: subscription.subscription_token,
6791
6793
  customerId: subscription.customer?.id ?? 0,
6792
6794
  countryCode: subscription.address?.country_code ?? "US",
6793
- disabled: subscription.billing_cycle_limit_reached
6795
+ disabled: isSubscriptionCompleted(subscription)
6794
6796
  }) : subscription.address && /* @__PURE__ */ jsxs("div", {
6795
6797
  className: "border-border mb-6 border-b pb-4",
6796
6798
  children: [/* @__PURE__ */ jsx("div", {
@@ -6927,7 +6929,7 @@ function SubscriptionDetail({ token, onNotFound, onError, onSuccess, onMutationE
6927
6929
  const { data, isLoading, error } = useSubscription(token);
6928
6930
  const subscription = data?.subscription;
6929
6931
  const customerId = subscription?.customer?.id ?? 0;
6930
- const waiverPreviewEnabled = subscription?.status === "past_due" && subscription.billing_cycle_limit_reached !== true && subscription.next_retry_at == null;
6932
+ const waiverPreviewEnabled = subscription?.status === "past_due" && !isSubscriptionCompleted(subscription) && subscription.next_retry_at == null;
6931
6933
  const waiverPreviewQuery = useFailedCycleWaiverPreview(token, { enabled: waiverPreviewEnabled });
6932
6934
  const isWaiverPreviewLoading = waiverPreviewEnabled && waiverPreviewQuery.isFetching;
6933
6935
  const waiverPreview = waiverPreviewQuery.data?.failed_cycle_waiver;
@@ -7087,7 +7089,8 @@ function SubscriptionDetail({ token, onNotFound, onError, onSuccess, onMutationE
7087
7089
  if (isLoading) return /* @__PURE__ */ jsx(SubscriptionDetailSkeleton, {});
7088
7090
  if (!subscription) return null;
7089
7091
  const plan = subscription.subscription_plan;
7090
- const isActive = subscription.status === "active" && !subscription.billing_cycle_limit_reached;
7092
+ const displayStatus = getSubscriptionDisplayStatus(subscription);
7093
+ const isActive = displayStatus === "active";
7091
7094
  const actionPolicy = getSubscriptionActionPolicy({
7092
7095
  status: subscription.status,
7093
7096
  billingCycleLimitReached: subscription.billing_cycle_limit_reached,
@@ -7106,7 +7109,7 @@ function SubscriptionDetail({ token, onNotFound, onError, onSuccess, onMutationE
7106
7109
  const childPaymentRecoveryDisabled = childPaymentRecoveryToken === token;
7107
7110
  const waiverMutationPending = waiverMutation.isPending && waiverMutation.variables?.subscriptionToken === token;
7108
7111
  const aggregateRecoveryDisabled = directParentRecoveryDisabled || childPaymentRecoveryDisabled || waiverMutationPending;
7109
- const paymentMethodDisabled = subscription.billing_cycle_limit_reached || directParentRecoveryDisabled || waiverMutationPending || independentParentMutationDisabled;
7112
+ const paymentMethodDisabled = isSubscriptionCompleted(subscription) || directParentRecoveryDisabled || waiverMutationPending || independentParentMutationDisabled;
7110
7113
  const isMutating = independentParentMutationDisabled || aggregateRecoveryDisabled;
7111
7114
  const handlePauseConfirm = (selection) => {
7112
7115
  const pauseParams = { customerId };
@@ -7163,7 +7166,7 @@ function SubscriptionDetail({ token, onNotFound, onError, onSuccess, onMutationE
7163
7166
  }, { onSuccess: () => setShowReactivateModal(false) });
7164
7167
  };
7165
7168
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [
7166
- subscription.status === "past_due" && !subscription.billing_cycle_limit_reached && /* @__PURE__ */ jsx("div", {
7169
+ displayStatus === "past_due" && /* @__PURE__ */ jsx("div", {
7167
7170
  className: "mb-4 px-2 sm:px-0 lg:mb-6",
7168
7171
  children: /* @__PURE__ */ jsx(PastDueBanner, {
7169
7172
  productTitle: subscription.variant?.product?.title ?? null,
@@ -7483,7 +7486,7 @@ async function invalidateSubscriptionPaymentRecoveryCache(queryClient, subscript
7483
7486
  }
7484
7487
  async function completeSubscriptionPaymentUpdate(args) {
7485
7488
  const cached = args.queryClient.getQueryData(subscriptionsKeys.detail(args.updatedSubscriptionToken));
7486
- if (cached?.subscription.status === "past_due" && cached.subscription.billing_cycle_limit_reached !== true) {
7489
+ if (cached?.subscription.status === "past_due" && !isSubscriptionCompleted(cached.subscription)) {
7487
7490
  args.queueRetry(args.updatedSubscriptionToken);
7488
7491
  return;
7489
7492
  }
@@ -8274,7 +8277,6 @@ function PortalSubscriptionShippingAddressSectionInner({ addressId, address: cur
8274
8277
  addressList: addresses,
8275
8278
  selectedAddressId: addressId ?? 0,
8276
8279
  onSelectAddress: (addr) => {
8277
- if (disabled) return;
8278
8280
  if (addr.id === addressId) return;
8279
8281
  updateSubscription.mutate({
8280
8282
  subscriptionToken,
@@ -8282,7 +8284,6 @@ function PortalSubscriptionShippingAddressSectionInner({ addressId, address: cur
8282
8284
  });
8283
8285
  },
8284
8286
  onAddAddressClick: () => {
8285
- if (disabled) return;
8286
8287
  setEditingAddress(null);
8287
8288
  setIsFormDialogOpen(true);
8288
8289
  },
@@ -8541,4 +8542,4 @@ const subscriptionsScreenPropertySchema = {
8541
8542
  //#endregion
8542
8543
  export { subscriptionsScreenPropertySchema as n, SubscriptionsScreen as t };
8543
8544
 
8544
- //# sourceMappingURL=SubscriptionsScreen-0Giqwkng.mjs.map
8545
+ //# sourceMappingURL=SubscriptionsScreen-BKJALFrF.mjs.map