@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.
@@ -68,6 +68,6 @@ require("./use-portal-card-add-3ds-flow-DPX94F0H.cjs");
68
68
  require("./display-C4lR3Fx6.cjs");
69
69
  require("./Combobox-CSQBMeAc.cjs");
70
70
  require("./prop-types-RKmVoT8k.cjs");
71
- const require_SubscriptionsScreen = require("./SubscriptionsScreen-DoyP5YBP.cjs");
71
+ const require_SubscriptionsScreen = require("./SubscriptionsScreen-DPymXVC4.cjs");
72
72
  exports.SubscriptionsScreen = require_SubscriptionsScreen.SubscriptionsScreen;
73
73
  exports.subscriptionsScreenPropertySchema = require_SubscriptionsScreen.subscriptionsScreenPropertySchema;
@@ -2680,22 +2680,30 @@ function formatTime(dateString, timezone, locale = "en-US") {
2680
2680
  return "";
2681
2681
  }
2682
2682
  }
2683
- function getNextBillDisplay(subscription, labels = {
2683
+ function getNextBillDisplay(nextBillDate, displayStatus, labels = {
2684
2684
  cancelled: "Cancelled",
2685
2685
  completed: "Completed",
2686
2686
  paused: "Paused",
2687
2687
  notAvailable: "N/A"
2688
2688
  }, locale = "en-US") {
2689
- if (subscription?.billing_cycle_limit_reached) return labels.completed;
2690
- if (subscription?.status === "cancelled") return labels.cancelled;
2691
- if (subscription?.next_bill_date) return formatDate(subscription.next_bill_date, locale);
2692
- if (subscription?.status === "paused") return labels.paused;
2689
+ if (displayStatus === "completed") return labels.completed;
2690
+ if (displayStatus === "cancelled") return labels.cancelled;
2691
+ if (nextBillDate) return formatDate(nextBillDate, locale);
2692
+ if (displayStatus === "paused") return labels.paused;
2693
2693
  return labels.notAvailable;
2694
2694
  }
2695
2695
  //#endregion
2696
2696
  //#region ../../subscriptions/core/src/utils/subscription-actions.ts
2697
+ /**
2698
+ * The one rule for a completed subscription: its current plan's
2699
+ * billing-cycle limit is reached. Every "completed" presentation and
2700
+ * gate reads this, so a new terminal condition lands here once.
2701
+ */
2702
+ function isSubscriptionCompleted(subscription) {
2703
+ return subscription?.billing_cycle_limit_reached === true;
2704
+ }
2697
2705
  function getSubscriptionDisplayStatus(subscription) {
2698
- return subscription.billingCycleLimitReached === true ? "completed" : subscription.status;
2706
+ return isSubscriptionCompleted(subscription) ? "completed" : subscription.status;
2699
2707
  }
2700
2708
  function hasPendingSubscriptionSkip(skips, today = /* @__PURE__ */ new Date()) {
2701
2709
  if (!skips?.length) return false;
@@ -2707,13 +2715,11 @@ function hasPendingSubscriptionSkip(skips, today = /* @__PURE__ */ new Date()) {
2707
2715
  });
2708
2716
  }
2709
2717
  function getSubscriptionActionPolicy(subscription) {
2710
- if (subscription.billingCycleLimitReached === true) return {
2711
- primary: null,
2712
- order: [],
2713
- menu: [],
2714
- recovery: null
2715
- };
2716
- if (subscription.status === "active") {
2718
+ const status = getSubscriptionDisplayStatus({
2719
+ status: subscription.status,
2720
+ billing_cycle_limit_reached: subscription.billingCycleLimitReached
2721
+ });
2722
+ if (status === "active") {
2717
2723
  const skipAllowanceAvailable = subscription.maxSkips == null || (subscription.skippedCount ?? 0) < subscription.maxSkips;
2718
2724
  const canSkip = subscription.allowSkipping === true && subscription.nextBillDate != null && skipAllowanceAvailable;
2719
2725
  const order = [];
@@ -2728,19 +2734,19 @@ function getSubscriptionActionPolicy(subscription) {
2728
2734
  recovery: null
2729
2735
  };
2730
2736
  }
2731
- if (subscription.status === "paused") return {
2737
+ if (status === "paused") return {
2732
2738
  primary: "resume_subscription",
2733
2739
  order: [],
2734
2740
  menu: ["cancel_subscription"],
2735
2741
  recovery: null
2736
2742
  };
2737
- if (subscription.status === "cancelled") return {
2743
+ if (status === "cancelled") return {
2738
2744
  primary: "reactivate_subscription",
2739
2745
  order: [],
2740
2746
  menu: [],
2741
2747
  recovery: null
2742
2748
  };
2743
- if (subscription.status === "past_due") {
2749
+ if (status === "past_due") {
2744
2750
  const isExhausted = subscription.nextRetryAt == null;
2745
2751
  const secondary = subscription.canChangePaymentMethod ? "change_payment_method" : null;
2746
2752
  return {
@@ -2756,13 +2762,13 @@ function getSubscriptionActionPolicy(subscription) {
2756
2762
  }
2757
2763
  };
2758
2764
  }
2759
- if (subscription.status === "completed") return {
2765
+ if (status === "completed") return {
2760
2766
  primary: null,
2761
2767
  order: [],
2762
2768
  menu: [],
2763
2769
  recovery: null
2764
2770
  };
2765
- if (["pending", "trial"].includes(subscription.status)) return {
2771
+ if (["pending", "trial"].includes(status)) return {
2766
2772
  primary: null,
2767
2773
  order: [],
2768
2774
  menu: ["cancel_subscription"],
@@ -6487,12 +6493,14 @@ function SubscriptionItemsSection({ subscription, displayQuantity, displayNextBi
6487
6493
  const variant = subscription.variant;
6488
6494
  const product = variant?.product;
6489
6495
  const quantity = displayQuantity ?? subscription.quantity;
6496
+ const displayStatus = getSubscriptionDisplayStatus(subscription);
6497
+ const paymentFailed = displayStatus === "past_due";
6490
6498
  const quantityInputId = `subscription-${subscription.subscription_token}-quantity`;
6491
6499
  const pricing = computeSubscriptionPricing(subscription);
6492
6500
  const subtotal = formatCurrency(pricing.subtotalUnit * quantity);
6493
6501
  const totalPrice = formatCurrency(pricing.totalUnit * quantity);
6494
6502
  const effectiveNextBillDate = displayNextBillDate ?? subscription.next_bill_date;
6495
- const nextOrderTimeOfDay = subscription.billing_cycle_limit_reached ? "" : formatTime(effectiveNextBillDate, subscription.timezone, locale);
6503
+ const nextOrderTimeOfDay = displayStatus === "completed" ? "" : formatTime(effectiveNextBillDate, subscription.timezone, locale);
6496
6504
  const nextBillDisplayLabels = {
6497
6505
  cancelled: t("date_cancelled"),
6498
6506
  completed: t("list_status_completed"),
@@ -6516,14 +6524,11 @@ function SubscriptionItemsSection({ subscription, displayQuantity, displayNextBi
6516
6524
  children: [
6517
6525
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6518
6526
  className: "text-muted-foreground mb-1 text-sm",
6519
- children: subscription.status === "past_due" && !subscription.billing_cycle_limit_reached ? t("payment_failed_on") : t("next_order_date")
6527
+ children: paymentFailed ? t("payment_failed_on") : t("next_order_date")
6520
6528
  }),
6521
6529
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6522
6530
  className: "text-foreground text-2xl font-bold",
6523
- children: subscription.status === "past_due" && !subscription.billing_cycle_limit_reached ? subscription.last_failed_at ? formatOptionalDate(subscription.last_failed_at, locale) : "—" : getNextBillDisplay(displayNextBillDate ? {
6524
- ...subscription,
6525
- next_bill_date: displayNextBillDate
6526
- } : subscription, nextBillDisplayLabels, locale)
6531
+ children: paymentFailed ? subscription.last_failed_at ? formatOptionalDate(subscription.last_failed_at, locale) : "—" : getNextBillDisplay(effectiveNextBillDate, displayStatus, nextBillDisplayLabels, locale)
6527
6532
  }),
6528
6533
  nextOrderTimeOfDay && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6529
6534
  className: "text-muted-foreground mt-1 text-xs",
@@ -6654,10 +6659,7 @@ function SubscriptionManagementSection({ subscription, actionPolicy, isMutating,
6654
6659
  const plan = subscription.subscription_plan;
6655
6660
  const quantity = subscription.quantity;
6656
6661
  const totalPrice = formatCurrency(subscription.price * quantity);
6657
- const displayStatus = getSubscriptionDisplayStatus({
6658
- status: subscription.status,
6659
- billingCycleLimitReached: subscription.billing_cycle_limit_reached
6660
- });
6662
+ const displayStatus = getSubscriptionDisplayStatus(subscription);
6661
6663
  const cadenceKey = getCadenceKey(plan.billing_interval_unit);
6662
6664
  const interval = plan.billing_interval;
6663
6665
  const unitKeys = UNIT_KEYS[plan.billing_interval_unit.toLowerCase()];
@@ -6852,7 +6854,7 @@ function SubscriptionManagementSection({ subscription, actionPolicy, isMutating,
6852
6854
  subscriptionToken: subscription.subscription_token,
6853
6855
  customerId: subscription.customer?.id ?? 0,
6854
6856
  countryCode: subscription.address?.country_code ?? "US",
6855
- disabled: subscription.billing_cycle_limit_reached
6857
+ disabled: isSubscriptionCompleted(subscription)
6856
6858
  }) : subscription.address && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6857
6859
  className: "border-border mb-6 border-b pb-4",
6858
6860
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -6989,7 +6991,7 @@ function SubscriptionDetail({ token, onNotFound, onError, onSuccess, onMutationE
6989
6991
  const { data, isLoading, error } = useSubscription(token);
6990
6992
  const subscription = data?.subscription;
6991
6993
  const customerId = subscription?.customer?.id ?? 0;
6992
- const waiverPreviewEnabled = subscription?.status === "past_due" && subscription.billing_cycle_limit_reached !== true && subscription.next_retry_at == null;
6994
+ const waiverPreviewEnabled = subscription?.status === "past_due" && !isSubscriptionCompleted(subscription) && subscription.next_retry_at == null;
6993
6995
  const waiverPreviewQuery = useFailedCycleWaiverPreview(token, { enabled: waiverPreviewEnabled });
6994
6996
  const isWaiverPreviewLoading = waiverPreviewEnabled && waiverPreviewQuery.isFetching;
6995
6997
  const waiverPreview = waiverPreviewQuery.data?.failed_cycle_waiver;
@@ -7149,7 +7151,8 @@ function SubscriptionDetail({ token, onNotFound, onError, onSuccess, onMutationE
7149
7151
  if (isLoading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SubscriptionDetailSkeleton, {});
7150
7152
  if (!subscription) return null;
7151
7153
  const plan = subscription.subscription_plan;
7152
- const isActive = subscription.status === "active" && !subscription.billing_cycle_limit_reached;
7154
+ const displayStatus = getSubscriptionDisplayStatus(subscription);
7155
+ const isActive = displayStatus === "active";
7153
7156
  const actionPolicy = getSubscriptionActionPolicy({
7154
7157
  status: subscription.status,
7155
7158
  billingCycleLimitReached: subscription.billing_cycle_limit_reached,
@@ -7168,7 +7171,7 @@ function SubscriptionDetail({ token, onNotFound, onError, onSuccess, onMutationE
7168
7171
  const childPaymentRecoveryDisabled = childPaymentRecoveryToken === token;
7169
7172
  const waiverMutationPending = waiverMutation.isPending && waiverMutation.variables?.subscriptionToken === token;
7170
7173
  const aggregateRecoveryDisabled = directParentRecoveryDisabled || childPaymentRecoveryDisabled || waiverMutationPending;
7171
- const paymentMethodDisabled = subscription.billing_cycle_limit_reached || directParentRecoveryDisabled || waiverMutationPending || independentParentMutationDisabled;
7174
+ const paymentMethodDisabled = isSubscriptionCompleted(subscription) || directParentRecoveryDisabled || waiverMutationPending || independentParentMutationDisabled;
7172
7175
  const isMutating = independentParentMutationDisabled || aggregateRecoveryDisabled;
7173
7176
  const handlePauseConfirm = (selection) => {
7174
7177
  const pauseParams = { customerId };
@@ -7225,7 +7228,7 @@ function SubscriptionDetail({ token, onNotFound, onError, onSuccess, onMutationE
7225
7228
  }, { onSuccess: () => setShowReactivateModal(false) });
7226
7229
  };
7227
7230
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
7228
- subscription.status === "past_due" && !subscription.billing_cycle_limit_reached && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7231
+ displayStatus === "past_due" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7229
7232
  className: "mb-4 px-2 sm:px-0 lg:mb-6",
7230
7233
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PastDueBanner, {
7231
7234
  productTitle: subscription.variant?.product?.title ?? null,
@@ -7545,7 +7548,7 @@ async function invalidateSubscriptionPaymentRecoveryCache(queryClient, subscript
7545
7548
  }
7546
7549
  async function completeSubscriptionPaymentUpdate(args) {
7547
7550
  const cached = args.queryClient.getQueryData(subscriptionsKeys.detail(args.updatedSubscriptionToken));
7548
- if (cached?.subscription.status === "past_due" && cached.subscription.billing_cycle_limit_reached !== true) {
7551
+ if (cached?.subscription.status === "past_due" && !isSubscriptionCompleted(cached.subscription)) {
7549
7552
  args.queueRetry(args.updatedSubscriptionToken);
7550
7553
  return;
7551
7554
  }
@@ -8336,7 +8339,6 @@ function PortalSubscriptionShippingAddressSectionInner({ addressId, address: cur
8336
8339
  addressList: addresses,
8337
8340
  selectedAddressId: addressId ?? 0,
8338
8341
  onSelectAddress: (addr) => {
8339
- if (disabled) return;
8340
8342
  if (addr.id === addressId) return;
8341
8343
  updateSubscription.mutate({
8342
8344
  subscriptionToken,
@@ -8344,7 +8346,6 @@ function PortalSubscriptionShippingAddressSectionInner({ addressId, address: cur
8344
8346
  });
8345
8347
  },
8346
8348
  onAddAddressClick: () => {
8347
- if (disabled) return;
8348
8349
  setEditingAddress(null);
8349
8350
  setIsFormDialogOpen(true);
8350
8351
  },
@@ -8614,4 +8615,4 @@ Object.defineProperty(exports, "subscriptionsScreenPropertySchema", {
8614
8615
  }
8615
8616
  });
8616
8617
 
8617
- //# sourceMappingURL=SubscriptionsScreen-DoyP5YBP.cjs.map
8618
+ //# sourceMappingURL=SubscriptionsScreen-DPymXVC4.cjs.map