@schematichq/schematic-react 0.2.0-rc.8 → 0.2.0-rc.9

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.
@@ -7836,6 +7836,35 @@ function HydrateComponentResponseFromJSONTyped(json, ignoreDiscriminator) {
7836
7836
  };
7837
7837
  }
7838
7838
 
7839
+ // src/api/models/PreviewSubscriptionChangeResponseData.ts
7840
+ function PreviewSubscriptionChangeResponseDataFromJSON(json) {
7841
+ return PreviewSubscriptionChangeResponseDataFromJSONTyped(json, false);
7842
+ }
7843
+ function PreviewSubscriptionChangeResponseDataFromJSONTyped(json, ignoreDiscriminator) {
7844
+ if (json == null) {
7845
+ return json;
7846
+ }
7847
+ return {
7848
+ dueNow: json["due_now"],
7849
+ newCharges: json["new_charges"],
7850
+ proration: json["proration"]
7851
+ };
7852
+ }
7853
+
7854
+ // src/api/models/PreviewCheckoutResponse.ts
7855
+ function PreviewCheckoutResponseFromJSON(json) {
7856
+ return PreviewCheckoutResponseFromJSONTyped(json, false);
7857
+ }
7858
+ function PreviewCheckoutResponseFromJSONTyped(json, ignoreDiscriminator) {
7859
+ if (json == null) {
7860
+ return json;
7861
+ }
7862
+ return {
7863
+ data: PreviewSubscriptionChangeResponseDataFromJSON(json["data"]),
7864
+ params: json["params"]
7865
+ };
7866
+ }
7867
+
7839
7868
  // src/api/apis/CheckoutApi.ts
7840
7869
  var CheckoutApi = class extends BaseAPI {
7841
7870
  /**
@@ -7924,6 +7953,51 @@ var CheckoutApi = class extends BaseAPI {
7924
7953
  );
7925
7954
  return await response.value();
7926
7955
  }
7956
+ /**
7957
+ * Preview checkout
7958
+ */
7959
+ async previewCheckoutRaw(requestParameters, initOverrides) {
7960
+ if (requestParameters["changeSubscriptionRequestBody"] == null) {
7961
+ throw new RequiredError(
7962
+ "changeSubscriptionRequestBody",
7963
+ 'Required parameter "changeSubscriptionRequestBody" was null or undefined when calling previewCheckout().'
7964
+ );
7965
+ }
7966
+ const queryParameters = {};
7967
+ const headerParameters = {};
7968
+ headerParameters["Content-Type"] = "application/json";
7969
+ if (this.configuration && this.configuration.apiKey) {
7970
+ headerParameters["X-Schematic-Api-Key"] = await this.configuration.apiKey(
7971
+ "X-Schematic-Api-Key"
7972
+ );
7973
+ }
7974
+ const response = await this.request(
7975
+ {
7976
+ path: `/checkout/preview`,
7977
+ method: "POST",
7978
+ headers: headerParameters,
7979
+ query: queryParameters,
7980
+ body: ChangeSubscriptionRequestBodyToJSON(
7981
+ requestParameters["changeSubscriptionRequestBody"]
7982
+ )
7983
+ },
7984
+ initOverrides
7985
+ );
7986
+ return new JSONApiResponse(
7987
+ response,
7988
+ (jsonValue) => PreviewCheckoutResponseFromJSON(jsonValue)
7989
+ );
7990
+ }
7991
+ /**
7992
+ * Preview checkout
7993
+ */
7994
+ async previewCheckout(requestParameters, initOverrides) {
7995
+ const response = await this.previewCheckoutRaw(
7996
+ requestParameters,
7997
+ initOverrides
7998
+ );
7999
+ return await response.value();
8000
+ }
7927
8001
  };
7928
8002
 
7929
8003
  // src/context/embed.tsx
@@ -9668,11 +9742,19 @@ function toPrettyDate(date) {
9668
9742
  year: "numeric"
9669
9743
  }).format(new Date(date));
9670
9744
  }
9745
+ function getMonthName(date) {
9746
+ return new Intl.DateTimeFormat("en-US", {
9747
+ month: "long"
9748
+ }).format(new Date(date));
9749
+ }
9671
9750
 
9672
9751
  // src/utils/string.ts
9673
9752
  function camelToHyphen(str) {
9674
9753
  return str.replace(/([a-z][A-Z])/g, (g2) => `${g2[0]}-${g2[1].toLowerCase()}`);
9675
9754
  }
9755
+ function formatNumber(num) {
9756
+ return new Intl.NumberFormat("en-US").format(num);
9757
+ }
9676
9758
  function formatCurrency(amount) {
9677
9759
  try {
9678
9760
  const dollars = amount / 100;
@@ -9701,6 +9783,18 @@ function formatCurrency(amount) {
9701
9783
  }).format(amount / 100);
9702
9784
  }
9703
9785
  }
9786
+ function formatOrdinal(n) {
9787
+ const enOrdinalRules = new Intl.PluralRules("en-US", { type: "ordinal" });
9788
+ const suffixes = /* @__PURE__ */ new Map([
9789
+ ["one", "st"],
9790
+ ["two", "nd"],
9791
+ ["few", "rd"],
9792
+ ["other", "th"]
9793
+ ]);
9794
+ const rule = enOrdinalRules.select(n);
9795
+ const suffix = suffixes.get(rule);
9796
+ return `${n}${suffix}`;
9797
+ }
9704
9798
 
9705
9799
  // src/const/index.ts
9706
9800
  var TEXT_BASE_SIZE = 16;
@@ -10156,7 +10250,7 @@ var ProgressBar = ({
10156
10250
  };
10157
10251
 
10158
10252
  // src/components/elements/plan-manager/CheckoutDialog.tsx
10159
- import { useMemo as useMemo6, useState as useState3 } from "react";
10253
+ import { useCallback as useCallback5, useMemo as useMemo6, useState as useState3 } from "react";
10160
10254
  var import_pluralize = __toESM(require_pluralize());
10161
10255
 
10162
10256
  // src/components/elements/payment-method/PaymentMethod.tsx
@@ -10665,8 +10759,8 @@ var FeatureName = ({
10665
10759
  if (entitlement.metricPeriod) {
10666
10760
  period = {
10667
10761
  current_day: "day",
10668
- current_month: "mo",
10669
- current_year: "yr"
10762
+ current_month: "month",
10763
+ current_year: "year"
10670
10764
  }[entitlement.metricPeriod];
10671
10765
  }
10672
10766
  return /* @__PURE__ */ jsx11(Flex, { $alignItems: "center", children: /* @__PURE__ */ jsxs6(
@@ -10677,12 +10771,8 @@ var FeatureName = ({
10677
10771
  $weight: theme.typography.text.fontWeight,
10678
10772
  $color: theme.typography.text.color,
10679
10773
  children: [
10680
- typeof entitlement.valueNumeric === "number" ? (0, import_pluralize.default)(
10681
- entitlement.feature.name,
10682
- entitlement.valueNumeric,
10683
- true
10684
- ) : `Unlimited ${(0, import_pluralize.default)(entitlement.feature.name)}`,
10685
- period && `/${period}`
10774
+ typeof entitlement.valueNumeric === "number" ? `${formatNumber(entitlement.valueNumeric)} ${(0, import_pluralize.default)(entitlement.feature.name, entitlement.valueNumeric)}` : `Unlimited ${(0, import_pluralize.default)(entitlement.feature.name)}`,
10775
+ period && ` per ${period}`
10686
10776
  ]
10687
10777
  }
10688
10778
  ) });
@@ -10708,6 +10798,7 @@ var CheckoutDialog = () => {
10708
10798
  () => data.company?.plan?.planPeriod || "month"
10709
10799
  );
10710
10800
  const [selectedPlan, setSelectedPlan] = useState3();
10801
+ const [charges, setCharges] = useState3();
10711
10802
  const [paymentMethodId, setPaymentMethodId] = useState3();
10712
10803
  const [isLoading, setIsLoading] = useState3(false);
10713
10804
  const [error, setError] = useState3();
@@ -10750,9 +10841,54 @@ var CheckoutDialog = () => {
10750
10841
  }
10751
10842
  return 0;
10752
10843
  }, [selectedPlan]);
10844
+ const subscriptionPrice = useMemo6(() => {
10845
+ if (!selectedPlan || !selectedPlan.monthlyPrice || !selectedPlan.yearlyPrice) {
10846
+ return;
10847
+ }
10848
+ return formatCurrency(
10849
+ (planPeriod === "month" ? selectedPlan.monthlyPrice : selectedPlan.yearlyPrice)?.price
10850
+ );
10851
+ }, [selectedPlan, planPeriod]);
10753
10852
  const isLightBackground = useMemo6(() => {
10754
10853
  return hexToHSL(theme.card.background).l > 50;
10755
10854
  }, [theme.card.background]);
10855
+ const selectPlan = useCallback5(
10856
+ async (plan, newPeriod) => {
10857
+ setSelectedPlan(plan);
10858
+ setCharges(void 0);
10859
+ const period = newPeriod || planPeriod;
10860
+ const priceId = (period === "month" ? plan?.monthlyPrice : plan?.yearlyPrice)?.id;
10861
+ if (!priceId || !api) {
10862
+ return;
10863
+ }
10864
+ try {
10865
+ setIsLoading(true);
10866
+ const { data: data2 } = await api.previewCheckout({
10867
+ changeSubscriptionRequestBody: {
10868
+ newPlanId: plan.id,
10869
+ newPriceId: priceId
10870
+ }
10871
+ });
10872
+ setCharges(data2);
10873
+ } catch {
10874
+ setError(
10875
+ "Error retrieving plan details. Please try again in a moment."
10876
+ );
10877
+ } finally {
10878
+ setIsLoading(false);
10879
+ }
10880
+ },
10881
+ [api, planPeriod]
10882
+ );
10883
+ const changePlanPeriod = useCallback5(
10884
+ (period) => {
10885
+ setPlanPeriod(period);
10886
+ if (selectedPlan) {
10887
+ selectPlan(selectedPlan, period);
10888
+ }
10889
+ },
10890
+ [selectedPlan, selectPlan]
10891
+ );
10756
10892
  const allowCheckout = api && selectedPlan && selectedPlan?.id !== currentPlan?.id && (paymentMethod && !showPaymentForm || paymentMethodId) && !isLoading;
10757
10893
  return /* @__PURE__ */ jsxs6(Modal, { size: "lg", children: [
10758
10894
  /* @__PURE__ */ jsx11(ModalHeader, { bordered: true, children: /* @__PURE__ */ jsxs6(Flex, { $gap: "1rem", children: [
@@ -10887,7 +11023,15 @@ var CheckoutDialog = () => {
10887
11023
  }
10888
11024
  )
10889
11025
  ] }),
10890
- /* @__PURE__ */ jsx11(Flex, { $flexWrap: "wrap", $gap: "1rem", $flexGrow: "1", children: availablePlans?.map((plan) => {
11026
+ /* @__PURE__ */ jsx11(Flex, { $flexWrap: "wrap", $gap: "1rem", $flexGrow: "1", children: availablePlans.sort((a2, b2) => {
11027
+ if (planPeriod === "year" && a2.yearlyPrice && b2.yearlyPrice) {
11028
+ return a2.yearlyPrice?.price - b2.yearlyPrice?.price;
11029
+ }
11030
+ if (planPeriod === "month" && a2.monthlyPrice && b2.monthlyPrice) {
11031
+ return a2.monthlyPrice.price - b2.monthlyPrice.price;
11032
+ }
11033
+ return 0;
11034
+ }).map((plan) => {
10891
11035
  return /* @__PURE__ */ jsxs6(
10892
11036
  Flex,
10893
11037
  {
@@ -11029,7 +11173,7 @@ var CheckoutDialog = () => {
11029
11173
  {
11030
11174
  disabled: plan.valid === false,
11031
11175
  ...plan.valid === true && {
11032
- onClick: () => setSelectedPlan(plan)
11176
+ onClick: () => selectPlan(plan)
11033
11177
  },
11034
11178
  $size: "sm",
11035
11179
  $color: "primary",
@@ -11144,7 +11288,7 @@ var CheckoutDialog = () => {
11144
11288
  /* @__PURE__ */ jsx11(
11145
11289
  Flex,
11146
11290
  {
11147
- onClick: () => setPlanPeriod("month"),
11291
+ onClick: () => changePlanPeriod("month"),
11148
11292
  $justifyContent: "center",
11149
11293
  $alignItems: "center",
11150
11294
  $padding: "0.25rem 0.5rem",
@@ -11168,7 +11312,7 @@ var CheckoutDialog = () => {
11168
11312
  /* @__PURE__ */ jsx11(
11169
11313
  Flex,
11170
11314
  {
11171
- onClick: () => setPlanPeriod("year"),
11315
+ onClick: () => changePlanPeriod("year"),
11172
11316
  $justifyContent: "center",
11173
11317
  $alignItems: "center",
11174
11318
  $padding: "0.25rem 0.5rem",
@@ -11210,7 +11354,7 @@ var CheckoutDialog = () => {
11210
11354
  {
11211
11355
  $flexDirection: "column",
11212
11356
  $position: "relative",
11213
- $gap: "1rem",
11357
+ $gap: "0.5rem",
11214
11358
  $width: "100%",
11215
11359
  $height: "auto",
11216
11360
  $padding: "1.5rem",
@@ -11265,14 +11409,14 @@ var CheckoutDialog = () => {
11265
11409
  }
11266
11410
  ) })
11267
11411
  ] }),
11268
- selectedPlan && /* @__PURE__ */ jsxs6(Fragment, { children: [
11412
+ selectedPlan && /* @__PURE__ */ jsxs6(Box, { $marginBottom: "1rem", children: [
11269
11413
  /* @__PURE__ */ jsx11(
11270
11414
  Box,
11271
11415
  {
11272
11416
  $width: "100%",
11273
11417
  $textAlign: "left",
11274
11418
  $opacity: "50%",
11275
- $marginBottom: "-0.25rem",
11419
+ $marginBottom: "0.25rem",
11276
11420
  $marginTop: "-0.25rem",
11277
11421
  children: /* @__PURE__ */ jsx11(
11278
11422
  Icon2,
@@ -11314,6 +11458,51 @@ var CheckoutDialog = () => {
11314
11458
  ) })
11315
11459
  ] })
11316
11460
  ] })
11461
+ ] }),
11462
+ charges?.proration && /* @__PURE__ */ jsxs6(Fragment, { children: [
11463
+ /* @__PURE__ */ jsx11(Box, { $opacity: "0.625", children: /* @__PURE__ */ jsx11(
11464
+ Text,
11465
+ {
11466
+ $font: theme.typography.text.fontFamily,
11467
+ $size: 14,
11468
+ $weight: theme.typography.text.fontWeight,
11469
+ $color: theme.typography.text.color,
11470
+ children: charges?.proration && charges.proration > 0 ? "Proration" : "Credits"
11471
+ }
11472
+ ) }),
11473
+ /* @__PURE__ */ jsx11(Flex, { $flexDirection: "column", $gap: "0.5rem", children: currentPlan && /* @__PURE__ */ jsxs6(
11474
+ Flex,
11475
+ {
11476
+ $justifyContent: "space-between",
11477
+ $alignItems: "center",
11478
+ $gap: "1rem",
11479
+ children: [
11480
+ /* @__PURE__ */ jsx11(Flex, { children: /* @__PURE__ */ jsxs6(
11481
+ Text,
11482
+ {
11483
+ $font: theme.typography.heading4.fontFamily,
11484
+ $size: theme.typography.heading4.fontSize,
11485
+ $weight: theme.typography.heading4.fontWeight,
11486
+ $color: theme.typography.heading4.color,
11487
+ children: [
11488
+ "Unused time with ",
11489
+ currentPlan.name
11490
+ ]
11491
+ }
11492
+ ) }),
11493
+ /* @__PURE__ */ jsx11(Flex, { children: /* @__PURE__ */ jsx11(
11494
+ Text,
11495
+ {
11496
+ $font: theme.typography.text.fontFamily,
11497
+ $size: theme.typography.text.fontSize,
11498
+ $weight: theme.typography.text.fontWeight,
11499
+ $color: theme.typography.text.color,
11500
+ children: formatCurrency(charges.proration)
11501
+ }
11502
+ ) })
11503
+ ]
11504
+ }
11505
+ ) })
11317
11506
  ] })
11318
11507
  ]
11319
11508
  }
@@ -11328,7 +11517,7 @@ var CheckoutDialog = () => {
11328
11517
  $height: "auto",
11329
11518
  $padding: "1.5rem",
11330
11519
  children: [
11331
- selectedPlan && /* @__PURE__ */ jsxs6(Flex, { $justifyContent: "space-between", children: [
11520
+ selectedPlan && subscriptionPrice && /* @__PURE__ */ jsxs6(Flex, { $justifyContent: "space-between", children: [
11332
11521
  /* @__PURE__ */ jsx11(Box, { $opacity: "0.625", children: /* @__PURE__ */ jsxs6(
11333
11522
  Text,
11334
11523
  {
@@ -11338,8 +11527,7 @@ var CheckoutDialog = () => {
11338
11527
  $color: theme.typography.text.color,
11339
11528
  children: [
11340
11529
  planPeriod === "month" ? "Monthly" : "Yearly",
11341
- " total:",
11342
- " "
11530
+ " total:"
11343
11531
  ]
11344
11532
  }
11345
11533
  ) }),
@@ -11351,15 +11539,35 @@ var CheckoutDialog = () => {
11351
11539
  $weight: theme.typography.text.fontWeight,
11352
11540
  $color: theme.typography.text.color,
11353
11541
  children: [
11354
- formatCurrency(
11355
- (planPeriod === "month" ? selectedPlan.monthlyPrice : selectedPlan.yearlyPrice)?.price ?? 0
11356
- ),
11542
+ subscriptionPrice,
11357
11543
  "/",
11358
11544
  planPeriod
11359
11545
  ]
11360
11546
  }
11361
11547
  ) })
11362
11548
  ] }),
11549
+ charges && /* @__PURE__ */ jsxs6(Flex, { $justifyContent: "space-between", children: [
11550
+ /* @__PURE__ */ jsx11(Box, { $opacity: "0.625", children: /* @__PURE__ */ jsx11(
11551
+ Text,
11552
+ {
11553
+ $font: theme.typography.text.fontFamily,
11554
+ $size: theme.typography.text.fontSize,
11555
+ $weight: theme.typography.text.fontWeight,
11556
+ $color: theme.typography.text.color,
11557
+ children: "Due today:"
11558
+ }
11559
+ ) }),
11560
+ /* @__PURE__ */ jsx11(Box, { children: /* @__PURE__ */ jsx11(
11561
+ Text,
11562
+ {
11563
+ $font: theme.typography.text.fontFamily,
11564
+ $size: theme.typography.text.fontSize,
11565
+ $weight: theme.typography.text.fontWeight,
11566
+ $color: theme.typography.text.color,
11567
+ children: formatCurrency(charges.dueNow)
11568
+ }
11569
+ ) })
11570
+ ] }),
11363
11571
  checkoutStage === "plan" ? /* @__PURE__ */ jsx11(
11364
11572
  StyledButton,
11365
11573
  {
@@ -11412,24 +11620,25 @@ var CheckoutDialog = () => {
11412
11620
  children: "Pay now"
11413
11621
  }
11414
11622
  ),
11415
- /* @__PURE__ */ jsx11(Box, { $opacity: "0.625", children: /* @__PURE__ */ jsx11(
11623
+ !isLoading && error && /* @__PURE__ */ jsx11(Box, { children: /* @__PURE__ */ jsx11(
11416
11624
  Text,
11417
11625
  {
11418
11626
  $font: theme.typography.text.fontFamily,
11419
11627
  $size: theme.typography.text.fontSize,
11420
- $weight: theme.typography.text.fontWeight,
11421
- $color: theme.typography.text.color,
11422
- children: "Discounts & credits applied at checkout"
11628
+ $weight: 500,
11629
+ $color: "#DB6669",
11630
+ children: error
11423
11631
  }
11424
11632
  ) }),
11425
- error && /* @__PURE__ */ jsx11(Box, { children: /* @__PURE__ */ jsx11(
11633
+ /* @__PURE__ */ jsx11(Box, { $opacity: "0.625", children: /* @__PURE__ */ jsx11(
11426
11634
  Text,
11427
11635
  {
11428
11636
  $font: theme.typography.text.fontFamily,
11429
11637
  $size: theme.typography.text.fontSize,
11430
- $weight: 500,
11431
- $color: "#DB6669",
11432
- children: error
11638
+ $weight: theme.typography.text.fontWeight,
11639
+ $color: theme.typography.text.color,
11640
+ children: checkoutStage === "plan" ? "Discounts & credits applied at checkout" : subscriptionPrice && `You will be billed ${subscriptionPrice} for this subscription
11641
+ every ${planPeriod} on the ${data.subscription?.latestInvoice?.dueDate && formatOrdinal(new Date(data.subscription.latestInvoice.dueDate).getDate())} ${planPeriod === "year" && data.subscription?.latestInvoice?.dueDate ? `of ${getMonthName(data.subscription.latestInvoice.dueDate)}` : ""} unless you unsubscribe.`
11433
11642
  }
11434
11643
  ) })
11435
11644
  ]
@@ -11479,9 +11688,9 @@ var PlanManager = forwardRef2(({ children, className, portal, ...rest }, ref) =>
11479
11688
  const { currentPlan, canChangePlan } = useMemo7(() => {
11480
11689
  return {
11481
11690
  currentPlan: data.company?.plan,
11482
- canChangePlan: stripe !== null
11691
+ canChangePlan: data.activePlans.length > 0 && data.stripeEmbed?.publishableKey && data.stripeEmbed?.setupIntentClientSecret && stripe !== null
11483
11692
  };
11484
- }, [data.company, stripe]);
11693
+ }, [data.company, data.activePlans, data.stripeEmbed, stripe]);
11485
11694
  return /* @__PURE__ */ jsxs7("div", { ref, className, children: [
11486
11695
  /* @__PURE__ */ jsx12(
11487
11696
  Flex,
@@ -11555,9 +11764,9 @@ var PlanManager = forwardRef2(({ children, className, portal, ...rest }, ref) =>
11555
11764
  });
11556
11765
 
11557
11766
  // src/components/elements/included-features/IncludedFeatures.tsx
11558
- import { forwardRef as forwardRef3, useMemo as useMemo8 } from "react";
11767
+ import { forwardRef as forwardRef3, useLayoutEffect, useMemo as useMemo8, useRef as useRef3 } from "react";
11559
11768
  var import_pluralize2 = __toESM(require_pluralize());
11560
- import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
11769
+ import { Fragment as Fragment2, jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
11561
11770
  function resolveDesignProps3(props) {
11562
11771
  return {
11563
11772
  header: {
@@ -11584,6 +11793,7 @@ var IncludedFeatures = forwardRef3(({ className, ...rest }, ref) => {
11584
11793
  const props = resolveDesignProps3(rest);
11585
11794
  const theme = nt();
11586
11795
  const { data } = useEmbed();
11796
+ const elements = useRef3([]);
11587
11797
  const features = useMemo8(() => {
11588
11798
  return (data.featureUsage?.features || []).map(
11589
11799
  ({
@@ -11614,6 +11824,34 @@ var IncludedFeatures = forwardRef3(({ className, ...rest }, ref) => {
11614
11824
  const isLightBackground = useMemo8(() => {
11615
11825
  return hexToHSL(theme.card.background).l > 50;
11616
11826
  }, [theme.card.background]);
11827
+ useLayoutEffect(() => {
11828
+ const assignRows = (parent) => {
11829
+ let isWrapped = true;
11830
+ [...parent.children].forEach((el) => {
11831
+ if (!(el instanceof HTMLElement)) {
11832
+ return;
11833
+ }
11834
+ if (!el.previousElementSibling || el.offsetLeft <= el.previousElementSibling.offsetLeft) {
11835
+ isWrapped = !isWrapped;
11836
+ }
11837
+ if (isWrapped) {
11838
+ el.style.textAlign = "left";
11839
+ } else if (el.previousElementSibling) {
11840
+ el.style.textAlign = "right";
11841
+ }
11842
+ });
11843
+ };
11844
+ elements.current.forEach((el) => {
11845
+ if (!el) return;
11846
+ const observer = new ResizeObserver((entries) => {
11847
+ entries.forEach((entry) => {
11848
+ assignRows(entry.target);
11849
+ });
11850
+ });
11851
+ observer.observe(el);
11852
+ assignRows(el);
11853
+ });
11854
+ }, [elements.current.length]);
11617
11855
  return /* @__PURE__ */ jsxs8(Flex, { ref, className, $flexDirection: "column", $gap: "1.5rem", children: [
11618
11856
  props.header.isVisible && /* @__PURE__ */ jsx13(Box, { children: /* @__PURE__ */ jsx13(
11619
11857
  Text,
@@ -11635,6 +11873,7 @@ var IncludedFeatures = forwardRef3(({ className, ...rest }, ref) => {
11635
11873
  /* @__PURE__ */ jsxs8(
11636
11874
  Flex,
11637
11875
  {
11876
+ ref: (el) => elements.current.push(el),
11638
11877
  $flexWrap: "wrap",
11639
11878
  $justifyContent: "space-between",
11640
11879
  $alignItems: "center",
@@ -11663,7 +11902,7 @@ var IncludedFeatures = forwardRef3(({ className, ...rest }, ref) => {
11663
11902
  }
11664
11903
  ) })
11665
11904
  ] }),
11666
- allocationType === "numeric" && feature?.name && /* @__PURE__ */ jsxs8(Box, { $textAlign: "right", children: [
11905
+ allocationType === "numeric" && feature?.name && /* @__PURE__ */ jsxs8(Box, { $textAlign: "right", $paddingLeft: "3.5rem", children: [
11667
11906
  props.entitlement.isVisible && /* @__PURE__ */ jsx13(
11668
11907
  Text,
11669
11908
  {
@@ -11673,7 +11912,7 @@ var IncludedFeatures = forwardRef3(({ className, ...rest }, ref) => {
11673
11912
  $weight: theme.typography[props.entitlement.fontStyle].fontWeight,
11674
11913
  $lineHeight: 1.5,
11675
11914
  $color: theme.typography[props.entitlement.fontStyle].color,
11676
- children: typeof allocation === "number" ? (0, import_pluralize2.default)(feature.name, allocation, true) : `Unlimited ${(0, import_pluralize2.default)(feature.name)}`
11915
+ children: typeof allocation === "number" ? `${formatNumber(allocation)} ${(0, import_pluralize2.default)(feature.name, allocation)}` : `Unlimited ${(0, import_pluralize2.default)(feature.name)}`
11677
11916
  }
11678
11917
  ),
11679
11918
  props.usage.isVisible && /* @__PURE__ */ jsx13(
@@ -11685,7 +11924,7 @@ var IncludedFeatures = forwardRef3(({ className, ...rest }, ref) => {
11685
11924
  $weight: theme.typography[props.usage.fontStyle].fontWeight,
11686
11925
  $lineHeight: 1.5,
11687
11926
  $color: theme.typography[props.usage.fontStyle].color,
11688
- children: typeof allocation === "number" ? `${usage} of ${allocation} used` : `${usage} used`
11927
+ children: typeof usage === "number" && /* @__PURE__ */ jsx13(Fragment2, { children: typeof allocation === "number" ? `${formatNumber(usage)} of ${formatNumber(allocation)} used` : `${formatNumber(usage)} used` })
11689
11928
  }
11690
11929
  )
11691
11930
  ] })
@@ -11917,14 +12156,19 @@ var UpcomingBill = forwardRef5(({ className, ...rest }, ref) => {
11917
12156
  children: formatCurrency(upcomingInvoice.amountDue)
11918
12157
  }
11919
12158
  ) }),
11920
- /* @__PURE__ */ jsx15(Box, { $maxWidth: "10rem", $lineHeight: "1", $textAlign: "right", children: /* @__PURE__ */ jsx15(
12159
+ /* @__PURE__ */ jsx15(Box, { $maxWidth: "10rem", $lineHeight: "1", $textAlign: "right", children: /* @__PURE__ */ jsxs10(
11921
12160
  Text,
11922
12161
  {
11923
12162
  $font: theme.typography[props.contractEndDate.fontStyle].fontFamily,
11924
12163
  $size: theme.typography[props.contractEndDate.fontStyle].fontSize,
11925
12164
  $weight: theme.typography[props.contractEndDate.fontStyle].fontWeight,
11926
12165
  $color: theme.typography[props.contractEndDate.fontStyle].color,
11927
- children: "Estimated monthly bill."
12166
+ children: [
12167
+ "Estimated",
12168
+ " ",
12169
+ upcomingInvoice.interval === "year" ? "yearly" : "monthly",
12170
+ " bill."
12171
+ ]
11928
12172
  }
11929
12173
  ) })
11930
12174
  ] })
@@ -12048,7 +12292,7 @@ var Root = forwardRef7(
12048
12292
  );
12049
12293
 
12050
12294
  // src/components/layout/viewport/Viewport.tsx
12051
- import { forwardRef as forwardRef8 } from "react";
12295
+ import { forwardRef as forwardRef9 } from "react";
12052
12296
 
12053
12297
  // src/components/layout/viewport/styles.ts
12054
12298
  var StyledViewport = dt.div`
@@ -12060,53 +12304,131 @@ var StyledViewport = dt.div`
12060
12304
  `;
12061
12305
 
12062
12306
  // src/components/layout/RenderLayout.tsx
12063
- import { useState as useState4 } from "react";
12064
- import { useEffect as useEffect4 } from "react";
12065
- import { jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
12066
- var DisabledState = () => {
12307
+ import { useEffect as useEffect4, useState as useState4 } from "react";
12308
+
12309
+ // src/components/layout/card/Card.tsx
12310
+ import { forwardRef as forwardRef8 } from "react";
12311
+
12312
+ // src/components/layout/card/styles.ts
12313
+ var StyledCard = dt.div(
12314
+ ({
12315
+ theme,
12316
+ $sectionLayout = "merged",
12317
+ $borderRadius = 8,
12318
+ $padding = 48,
12319
+ $shadow = true
12320
+ }) => {
12321
+ return lt`
12322
+ box-sizing: border-box;
12323
+ font-size: ${TEXT_BASE_SIZE}px;
12324
+
12325
+ *,
12326
+ *::before,
12327
+ *::after {
12328
+ box-sizing: inherit;
12329
+ }
12330
+
12331
+ > * {
12332
+ padding: ${$padding * 0.75 / TEXT_BASE_SIZE}rem
12333
+ ${$padding / TEXT_BASE_SIZE}rem;
12334
+ color: ${theme.typography.text.color};
12335
+ }
12336
+
12337
+ ${() => {
12338
+ const { l: l2 } = hexToHSL(theme.card.background);
12339
+ const borderColor = l2 > 50 ? "hsla(0, 0%, 0%, 0.1)" : "hsla(0, 0%, 100%, 0.2)";
12340
+ const borderRadius = `${$borderRadius / TEXT_BASE_SIZE}rem`;
12341
+ const boxShadow = "0px 1px 20px 0px #1018280F, 0px 1px 3px 0px #1018281A";
12342
+ if ($sectionLayout === "merged") {
12343
+ return lt`
12344
+ background: ${({ theme: theme2 }) => theme2.card.background};
12345
+ border-radius: ${borderRadius};
12346
+
12347
+ ${$shadow && `box-shadow: ${boxShadow};`}
12348
+
12349
+ > :not(:last-child) {
12350
+ border-bottom: 1px solid ${borderColor};
12351
+ }
12352
+ `;
12353
+ }
12354
+ return lt`
12355
+ > :not(:last-child) {
12356
+ margin-bottom: 1rem;
12357
+ }
12358
+
12359
+ > * {
12360
+ background: ${theme.card.background};
12361
+ border-radius: ${borderRadius};
12362
+ ${$shadow && `box-shadow: ${boxShadow};`}
12363
+ }
12364
+ `;
12365
+ }}
12366
+ `;
12367
+ }
12368
+ );
12369
+
12370
+ // src/components/layout/card/Card.tsx
12371
+ import { jsx as jsx18 } from "react/jsx-runtime";
12372
+ var Card = forwardRef8(
12373
+ ({ children, className }, ref) => {
12374
+ const theme = nt();
12375
+ return /* @__PURE__ */ jsx18(
12376
+ StyledCard,
12377
+ {
12378
+ ref,
12379
+ className,
12380
+ $sectionLayout: theme?.sectionLayout,
12381
+ $borderRadius: theme?.card?.borderRadius,
12382
+ $padding: theme?.card?.padding,
12383
+ $shadow: theme?.card?.hasShadow,
12384
+ children
12385
+ }
12386
+ );
12387
+ }
12388
+ );
12389
+
12390
+ // src/components/layout/RenderLayout.tsx
12391
+ import { jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
12392
+ var Disabled = () => {
12067
12393
  const theme = nt();
12068
- return /* @__PURE__ */ jsx18(Box, { $width: "100%", children: /* @__PURE__ */ jsxs12(
12394
+ return /* @__PURE__ */ jsx19(Box, { $width: "max-content", $height: "max-content", $margin: "0 auto", children: /* @__PURE__ */ jsx19(Card, { children: /* @__PURE__ */ jsxs12(
12069
12395
  Flex,
12070
12396
  {
12071
12397
  $flexDirection: "column",
12072
- $padding: `${theme.card.padding / TEXT_BASE_SIZE}rem`,
12073
- $width: "100%",
12074
- $height: "auto",
12075
- $borderRadius: `${theme.card.borderRadius / TEXT_BASE_SIZE}rem`,
12076
- $backgroundColor: theme.card.background,
12077
- $alignItems: "center",
12078
12398
  $justifyContent: "center",
12399
+ $alignItems: "center",
12400
+ $whiteSpace: "nowrap",
12079
12401
  children: [
12080
- /* @__PURE__ */ jsx18(
12081
- Box,
12402
+ /* @__PURE__ */ jsx19(Box, { $marginBottom: "0.5rem", children: /* @__PURE__ */ jsx19(
12403
+ Text,
12082
12404
  {
12083
- $marginBottom: "8px",
12084
- $fontSize: `${theme.typography.heading1.fontSize / TEXT_BASE_SIZE}rem`,
12085
- $fontFamily: theme.typography.heading1.fontFamily,
12086
- $fontWeight: theme.typography.heading1.fontWeight,
12405
+ as: "h1",
12406
+ $font: theme.typography.heading1.fontFamily,
12407
+ $size: theme.typography.heading1.fontSize,
12408
+ $weight: theme.typography.heading1.fontWeight,
12087
12409
  $color: theme.typography.heading1.color,
12088
- children: "Coming soon"
12410
+ children: "Portal not found"
12089
12411
  }
12090
- ),
12091
- /* @__PURE__ */ jsx18(
12092
- Box,
12412
+ ) }),
12413
+ /* @__PURE__ */ jsx19(
12414
+ Text,
12093
12415
  {
12094
- $marginBottom: "8px",
12095
- $fontSize: `${theme.typography.text.fontSize / TEXT_BASE_SIZE}rem`,
12096
- $fontFamily: theme.typography.text.fontFamily,
12097
- $fontWeight: theme.typography.text.fontWeight,
12416
+ as: "p",
12417
+ $font: theme.typography.text.fontFamily,
12418
+ $size: theme.typography.text.fontSize,
12419
+ $weight: theme.typography.text.fontWeight,
12098
12420
  $color: theme.typography.text.color,
12099
- children: "The plan manager will be back very soon."
12421
+ children: "Please try again later."
12100
12422
  }
12101
12423
  )
12102
12424
  ]
12103
12425
  }
12104
- ) });
12426
+ ) }) });
12105
12427
  };
12106
- var SuccessState = () => {
12107
- const [isOpen, setIsOpen] = useState4(true);
12428
+ var Success = () => {
12108
12429
  const theme = nt();
12109
12430
  const { hydrate, data, api, setLayout, isPending } = useEmbed();
12431
+ const [isOpen, setIsOpen] = useState4(true);
12110
12432
  useEffect4(() => {
12111
12433
  if (api && data.component?.id) {
12112
12434
  hydrate();
@@ -12118,31 +12440,23 @@ var SuccessState = () => {
12118
12440
  setLayout("portal");
12119
12441
  }
12120
12442
  }, [isPending, isOpen, setLayout]);
12121
- return /* @__PURE__ */ jsxs12(
12443
+ return /* @__PURE__ */ jsx19(Box, { $width: "max-content", $height: "max-content", $margin: "0 auto", children: /* @__PURE__ */ jsx19(Card, { children: /* @__PURE__ */ jsxs12(
12122
12444
  Flex,
12123
12445
  {
12124
12446
  $flexDirection: "column",
12125
12447
  $justifyContent: "center",
12126
12448
  $alignItems: "center",
12127
- $gap: `${32 / TEXT_BASE_SIZE}rem`,
12128
- $width: "min-content",
12129
- $height: "min-content",
12130
- $margin: "auto",
12131
- $padding: `${theme.card.padding / TEXT_BASE_SIZE}rem ${theme.card.padding * 1.5 / TEXT_BASE_SIZE}rem`,
12132
12449
  $whiteSpace: "nowrap",
12133
- $backgroundColor: theme.card.background,
12134
- $borderRadius: "0.5rem",
12135
- $boxShadow: "0px 1px 20px 0px #1018280F, 0px 1px 3px 0px #1018281A;",
12136
12450
  children: [
12137
- /* @__PURE__ */ jsx18(
12451
+ /* @__PURE__ */ jsx19(Box, { $marginBottom: "1.5rem", children: /* @__PURE__ */ jsx19(
12138
12452
  IconRound,
12139
12453
  {
12140
12454
  name: "check",
12141
12455
  size: "3xl",
12142
12456
  colors: [theme.card.background, theme.primary]
12143
12457
  }
12144
- ),
12145
- /* @__PURE__ */ jsx18(
12458
+ ) }),
12459
+ /* @__PURE__ */ jsx19(Box, { $marginBottom: "0.5rem", children: /* @__PURE__ */ jsx19(
12146
12460
  Text,
12147
12461
  {
12148
12462
  as: "h1",
@@ -12152,8 +12466,8 @@ var SuccessState = () => {
12152
12466
  $color: theme.typography.heading1.color,
12153
12467
  children: "Subscription updated!"
12154
12468
  }
12155
- ),
12156
- /* @__PURE__ */ jsx18(
12469
+ ) }),
12470
+ /* @__PURE__ */ jsx19(
12157
12471
  Text,
12158
12472
  {
12159
12473
  as: "p",
@@ -12161,37 +12475,37 @@ var SuccessState = () => {
12161
12475
  $size: theme.typography.text.fontSize,
12162
12476
  $weight: theme.typography.text.fontWeight,
12163
12477
  $color: theme.typography.text.color,
12164
- children: "Loading..."
12478
+ children: "Loading\u2026"
12165
12479
  }
12166
12480
  )
12167
12481
  ]
12168
12482
  }
12169
- );
12483
+ ) }) });
12170
12484
  };
12171
12485
  var RenderLayout = ({ children }) => {
12172
12486
  const { layout } = useEmbed();
12173
12487
  switch (layout) {
12174
12488
  case "disabled":
12175
- return /* @__PURE__ */ jsx18(DisabledState, {});
12489
+ return /* @__PURE__ */ jsx19(Disabled, {});
12176
12490
  case "success":
12177
- return /* @__PURE__ */ jsx18(SuccessState, {});
12491
+ return /* @__PURE__ */ jsx19(Success, {});
12178
12492
  default:
12179
12493
  return children;
12180
12494
  }
12181
12495
  };
12182
12496
 
12183
12497
  // src/components/layout/viewport/Viewport.tsx
12184
- import { jsx as jsx19 } from "react/jsx-runtime";
12185
- var Viewport = forwardRef8(
12498
+ import { jsx as jsx20 } from "react/jsx-runtime";
12499
+ var Viewport = forwardRef9(
12186
12500
  ({ children, ...props }, ref) => {
12187
12501
  const theme = nt();
12188
- return /* @__PURE__ */ jsx19(
12502
+ return /* @__PURE__ */ jsx20(
12189
12503
  StyledViewport,
12190
12504
  {
12191
12505
  ref,
12192
12506
  $numberOfColumns: theme.numberOfColumns,
12193
12507
  ...props,
12194
- children: /* @__PURE__ */ jsx19(RenderLayout, { children })
12508
+ children: /* @__PURE__ */ jsx20(RenderLayout, { children })
12195
12509
  }
12196
12510
  );
12197
12511
  }
@@ -12200,87 +12514,6 @@ var Viewport = forwardRef8(
12200
12514
  // src/components/layout/column/Column.tsx
12201
12515
  import { forwardRef as forwardRef10 } from "react";
12202
12516
 
12203
- // src/components/layout/card/Card.tsx
12204
- import { forwardRef as forwardRef9 } from "react";
12205
-
12206
- // src/components/layout/card/styles.ts
12207
- var StyledCard = dt.div(
12208
- ({
12209
- theme,
12210
- $sectionLayout = "merged",
12211
- $borderRadius = 8,
12212
- $padding = 48,
12213
- $shadow = true
12214
- }) => {
12215
- return lt`
12216
- box-sizing: border-box;
12217
- font-size: ${TEXT_BASE_SIZE}px;
12218
-
12219
- *,
12220
- *::before,
12221
- *::after {
12222
- box-sizing: inherit;
12223
- }
12224
-
12225
- > * {
12226
- padding: ${$padding * 0.75 / TEXT_BASE_SIZE}rem
12227
- ${$padding / TEXT_BASE_SIZE}rem;
12228
- color: ${theme.typography.text.color};
12229
- }
12230
-
12231
- ${() => {
12232
- const { l: l2 } = hexToHSL(theme.card.background);
12233
- const borderColor = l2 > 50 ? "hsla(0, 0%, 0%, 0.1)" : "hsla(0, 0%, 100%, 0.2)";
12234
- const borderRadius = `${$borderRadius / TEXT_BASE_SIZE}rem`;
12235
- const boxShadow = "0px 1px 20px 0px #1018280F, 0px 1px 3px 0px #1018281A";
12236
- if ($sectionLayout === "merged") {
12237
- return lt`
12238
- background: ${({ theme: theme2 }) => theme2.card.background};
12239
- border-radius: ${borderRadius};
12240
-
12241
- ${$shadow && `box-shadow: ${boxShadow};`}
12242
-
12243
- > :not(:last-child) {
12244
- border-bottom: 1px solid ${borderColor};
12245
- }
12246
- `;
12247
- }
12248
- return lt`
12249
- > :not(:last-child) {
12250
- margin-bottom: 1rem;
12251
- }
12252
-
12253
- > * {
12254
- background: ${theme.card.background};
12255
- border-radius: ${borderRadius};
12256
- ${$shadow && `box-shadow: ${boxShadow};`}
12257
- }
12258
- `;
12259
- }}
12260
- `;
12261
- }
12262
- );
12263
-
12264
- // src/components/layout/card/Card.tsx
12265
- import { jsx as jsx20 } from "react/jsx-runtime";
12266
- var Card = forwardRef9(
12267
- ({ children, className }, ref) => {
12268
- const theme = nt();
12269
- return /* @__PURE__ */ jsx20(
12270
- StyledCard,
12271
- {
12272
- ref,
12273
- className,
12274
- $sectionLayout: theme?.sectionLayout,
12275
- $borderRadius: theme?.card?.borderRadius,
12276
- $padding: theme?.card?.padding,
12277
- $shadow: theme?.card?.hasShadow,
12278
- children
12279
- }
12280
- );
12281
- }
12282
- );
12283
-
12284
12517
  // src/components/layout/column/styles.ts
12285
12518
  var StyledColumn = dt.div`
12286
12519
  flex-grow: 1;
@@ -12336,7 +12569,7 @@ function createRenderer(options) {
12336
12569
  }
12337
12570
 
12338
12571
  // src/components/embed/ComponentTree.tsx
12339
- import { Fragment as Fragment2, jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
12572
+ import { Fragment as Fragment3, jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
12340
12573
  var Loading = () => {
12341
12574
  const theme = nt();
12342
12575
  return /* @__PURE__ */ jsx22(
@@ -12404,7 +12637,7 @@ var ComponentTree = () => {
12404
12637
  if (Children.count(children) === 0) {
12405
12638
  return /* @__PURE__ */ jsx22(Loading, {});
12406
12639
  }
12407
- return /* @__PURE__ */ jsx22(Fragment2, { children });
12640
+ return /* @__PURE__ */ jsx22(Fragment3, { children });
12408
12641
  };
12409
12642
 
12410
12643
  // src/components/embed/Embed.tsx