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

Sign up to get free protection for your applications and to get access to all the features.
@@ -7875,6 +7875,35 @@ function HydrateComponentResponseFromJSONTyped(json, ignoreDiscriminator) {
7875
7875
  };
7876
7876
  }
7877
7877
 
7878
+ // src/api/models/PreviewSubscriptionChangeResponseData.ts
7879
+ function PreviewSubscriptionChangeResponseDataFromJSON(json) {
7880
+ return PreviewSubscriptionChangeResponseDataFromJSONTyped(json, false);
7881
+ }
7882
+ function PreviewSubscriptionChangeResponseDataFromJSONTyped(json, ignoreDiscriminator) {
7883
+ if (json == null) {
7884
+ return json;
7885
+ }
7886
+ return {
7887
+ dueNow: json["due_now"],
7888
+ newCharges: json["new_charges"],
7889
+ proration: json["proration"]
7890
+ };
7891
+ }
7892
+
7893
+ // src/api/models/PreviewCheckoutResponse.ts
7894
+ function PreviewCheckoutResponseFromJSON(json) {
7895
+ return PreviewCheckoutResponseFromJSONTyped(json, false);
7896
+ }
7897
+ function PreviewCheckoutResponseFromJSONTyped(json, ignoreDiscriminator) {
7898
+ if (json == null) {
7899
+ return json;
7900
+ }
7901
+ return {
7902
+ data: PreviewSubscriptionChangeResponseDataFromJSON(json["data"]),
7903
+ params: json["params"]
7904
+ };
7905
+ }
7906
+
7878
7907
  // src/api/apis/CheckoutApi.ts
7879
7908
  var CheckoutApi = class extends BaseAPI {
7880
7909
  /**
@@ -7963,6 +7992,51 @@ var CheckoutApi = class extends BaseAPI {
7963
7992
  );
7964
7993
  return await response.value();
7965
7994
  }
7995
+ /**
7996
+ * Preview checkout
7997
+ */
7998
+ async previewCheckoutRaw(requestParameters, initOverrides) {
7999
+ if (requestParameters["changeSubscriptionRequestBody"] == null) {
8000
+ throw new RequiredError(
8001
+ "changeSubscriptionRequestBody",
8002
+ 'Required parameter "changeSubscriptionRequestBody" was null or undefined when calling previewCheckout().'
8003
+ );
8004
+ }
8005
+ const queryParameters = {};
8006
+ const headerParameters = {};
8007
+ headerParameters["Content-Type"] = "application/json";
8008
+ if (this.configuration && this.configuration.apiKey) {
8009
+ headerParameters["X-Schematic-Api-Key"] = await this.configuration.apiKey(
8010
+ "X-Schematic-Api-Key"
8011
+ );
8012
+ }
8013
+ const response = await this.request(
8014
+ {
8015
+ path: `/checkout/preview`,
8016
+ method: "POST",
8017
+ headers: headerParameters,
8018
+ query: queryParameters,
8019
+ body: ChangeSubscriptionRequestBodyToJSON(
8020
+ requestParameters["changeSubscriptionRequestBody"]
8021
+ )
8022
+ },
8023
+ initOverrides
8024
+ );
8025
+ return new JSONApiResponse(
8026
+ response,
8027
+ (jsonValue) => PreviewCheckoutResponseFromJSON(jsonValue)
8028
+ );
8029
+ }
8030
+ /**
8031
+ * Preview checkout
8032
+ */
8033
+ async previewCheckout(requestParameters, initOverrides) {
8034
+ const response = await this.previewCheckoutRaw(
8035
+ requestParameters,
8036
+ initOverrides
8037
+ );
8038
+ return await response.value();
8039
+ }
7966
8040
  };
7967
8041
 
7968
8042
  // src/context/embed.tsx
@@ -9707,11 +9781,19 @@ function toPrettyDate(date) {
9707
9781
  year: "numeric"
9708
9782
  }).format(new Date(date));
9709
9783
  }
9784
+ function getMonthName(date) {
9785
+ return new Intl.DateTimeFormat("en-US", {
9786
+ month: "long"
9787
+ }).format(new Date(date));
9788
+ }
9710
9789
 
9711
9790
  // src/utils/string.ts
9712
9791
  function camelToHyphen(str) {
9713
9792
  return str.replace(/([a-z][A-Z])/g, (g2) => `${g2[0]}-${g2[1].toLowerCase()}`);
9714
9793
  }
9794
+ function formatNumber(num) {
9795
+ return new Intl.NumberFormat("en-US").format(num);
9796
+ }
9715
9797
  function formatCurrency(amount) {
9716
9798
  try {
9717
9799
  const dollars = amount / 100;
@@ -9740,6 +9822,18 @@ function formatCurrency(amount) {
9740
9822
  }).format(amount / 100);
9741
9823
  }
9742
9824
  }
9825
+ function formatOrdinal(n) {
9826
+ const enOrdinalRules = new Intl.PluralRules("en-US", { type: "ordinal" });
9827
+ const suffixes = /* @__PURE__ */ new Map([
9828
+ ["one", "st"],
9829
+ ["two", "nd"],
9830
+ ["few", "rd"],
9831
+ ["other", "th"]
9832
+ ]);
9833
+ const rule = enOrdinalRules.select(n);
9834
+ const suffix = suffixes.get(rule);
9835
+ return `${n}${suffix}`;
9836
+ }
9743
9837
 
9744
9838
  // src/const/index.ts
9745
9839
  var TEXT_BASE_SIZE = 16;
@@ -10701,8 +10795,8 @@ var FeatureName = ({
10701
10795
  if (entitlement.metricPeriod) {
10702
10796
  period = {
10703
10797
  current_day: "day",
10704
- current_month: "mo",
10705
- current_year: "yr"
10798
+ current_month: "month",
10799
+ current_year: "year"
10706
10800
  }[entitlement.metricPeriod];
10707
10801
  }
10708
10802
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Flex, { $alignItems: "center", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
@@ -10713,12 +10807,8 @@ var FeatureName = ({
10713
10807
  $weight: theme.typography.text.fontWeight,
10714
10808
  $color: theme.typography.text.color,
10715
10809
  children: [
10716
- typeof entitlement.valueNumeric === "number" ? (0, import_pluralize.default)(
10717
- entitlement.feature.name,
10718
- entitlement.valueNumeric,
10719
- true
10720
- ) : `Unlimited ${(0, import_pluralize.default)(entitlement.feature.name)}`,
10721
- period && `/${period}`
10810
+ typeof entitlement.valueNumeric === "number" ? `${formatNumber(entitlement.valueNumeric)} ${(0, import_pluralize.default)(entitlement.feature.name, entitlement.valueNumeric)}` : `Unlimited ${(0, import_pluralize.default)(entitlement.feature.name)}`,
10811
+ period && ` per ${period}`
10722
10812
  ]
10723
10813
  }
10724
10814
  ) });
@@ -10744,6 +10834,7 @@ var CheckoutDialog = () => {
10744
10834
  () => data.company?.plan?.planPeriod || "month"
10745
10835
  );
10746
10836
  const [selectedPlan, setSelectedPlan] = (0, import_react10.useState)();
10837
+ const [charges, setCharges] = (0, import_react10.useState)();
10747
10838
  const [paymentMethodId, setPaymentMethodId] = (0, import_react10.useState)();
10748
10839
  const [isLoading, setIsLoading] = (0, import_react10.useState)(false);
10749
10840
  const [error, setError] = (0, import_react10.useState)();
@@ -10786,9 +10877,54 @@ var CheckoutDialog = () => {
10786
10877
  }
10787
10878
  return 0;
10788
10879
  }, [selectedPlan]);
10880
+ const subscriptionPrice = (0, import_react10.useMemo)(() => {
10881
+ if (!selectedPlan || !selectedPlan.monthlyPrice || !selectedPlan.yearlyPrice) {
10882
+ return;
10883
+ }
10884
+ return formatCurrency(
10885
+ (planPeriod === "month" ? selectedPlan.monthlyPrice : selectedPlan.yearlyPrice)?.price
10886
+ );
10887
+ }, [selectedPlan, planPeriod]);
10789
10888
  const isLightBackground = (0, import_react10.useMemo)(() => {
10790
10889
  return hexToHSL(theme.card.background).l > 50;
10791
10890
  }, [theme.card.background]);
10891
+ const selectPlan = (0, import_react10.useCallback)(
10892
+ async (plan, newPeriod) => {
10893
+ setSelectedPlan(plan);
10894
+ setCharges(void 0);
10895
+ const period = newPeriod || planPeriod;
10896
+ const priceId = (period === "month" ? plan?.monthlyPrice : plan?.yearlyPrice)?.id;
10897
+ if (!priceId || !api) {
10898
+ return;
10899
+ }
10900
+ try {
10901
+ setIsLoading(true);
10902
+ const { data: data2 } = await api.previewCheckout({
10903
+ changeSubscriptionRequestBody: {
10904
+ newPlanId: plan.id,
10905
+ newPriceId: priceId
10906
+ }
10907
+ });
10908
+ setCharges(data2);
10909
+ } catch {
10910
+ setError(
10911
+ "Error retrieving plan details. Please try again in a moment."
10912
+ );
10913
+ } finally {
10914
+ setIsLoading(false);
10915
+ }
10916
+ },
10917
+ [api, planPeriod]
10918
+ );
10919
+ const changePlanPeriod = (0, import_react10.useCallback)(
10920
+ (period) => {
10921
+ setPlanPeriod(period);
10922
+ if (selectedPlan) {
10923
+ selectPlan(selectedPlan, period);
10924
+ }
10925
+ },
10926
+ [selectedPlan, selectPlan]
10927
+ );
10792
10928
  const allowCheckout = api && selectedPlan && selectedPlan?.id !== currentPlan?.id && (paymentMethod && !showPaymentForm || paymentMethodId) && !isLoading;
10793
10929
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Modal, { size: "lg", children: [
10794
10930
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ModalHeader, { bordered: true, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Flex, { $gap: "1rem", children: [
@@ -10923,7 +11059,15 @@ var CheckoutDialog = () => {
10923
11059
  }
10924
11060
  )
10925
11061
  ] }),
10926
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Flex, { $flexWrap: "wrap", $gap: "1rem", $flexGrow: "1", children: availablePlans?.map((plan) => {
11062
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Flex, { $flexWrap: "wrap", $gap: "1rem", $flexGrow: "1", children: availablePlans.sort((a2, b2) => {
11063
+ if (planPeriod === "year" && a2.yearlyPrice && b2.yearlyPrice) {
11064
+ return a2.yearlyPrice?.price - b2.yearlyPrice?.price;
11065
+ }
11066
+ if (planPeriod === "month" && a2.monthlyPrice && b2.monthlyPrice) {
11067
+ return a2.monthlyPrice.price - b2.monthlyPrice.price;
11068
+ }
11069
+ return 0;
11070
+ }).map((plan) => {
10927
11071
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
10928
11072
  Flex,
10929
11073
  {
@@ -11065,7 +11209,7 @@ var CheckoutDialog = () => {
11065
11209
  {
11066
11210
  disabled: plan.valid === false,
11067
11211
  ...plan.valid === true && {
11068
- onClick: () => setSelectedPlan(plan)
11212
+ onClick: () => selectPlan(plan)
11069
11213
  },
11070
11214
  $size: "sm",
11071
11215
  $color: "primary",
@@ -11180,7 +11324,7 @@ var CheckoutDialog = () => {
11180
11324
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11181
11325
  Flex,
11182
11326
  {
11183
- onClick: () => setPlanPeriod("month"),
11327
+ onClick: () => changePlanPeriod("month"),
11184
11328
  $justifyContent: "center",
11185
11329
  $alignItems: "center",
11186
11330
  $padding: "0.25rem 0.5rem",
@@ -11204,7 +11348,7 @@ var CheckoutDialog = () => {
11204
11348
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11205
11349
  Flex,
11206
11350
  {
11207
- onClick: () => setPlanPeriod("year"),
11351
+ onClick: () => changePlanPeriod("year"),
11208
11352
  $justifyContent: "center",
11209
11353
  $alignItems: "center",
11210
11354
  $padding: "0.25rem 0.5rem",
@@ -11246,7 +11390,7 @@ var CheckoutDialog = () => {
11246
11390
  {
11247
11391
  $flexDirection: "column",
11248
11392
  $position: "relative",
11249
- $gap: "1rem",
11393
+ $gap: "0.5rem",
11250
11394
  $width: "100%",
11251
11395
  $height: "auto",
11252
11396
  $padding: "1.5rem",
@@ -11301,14 +11445,14 @@ var CheckoutDialog = () => {
11301
11445
  }
11302
11446
  ) })
11303
11447
  ] }),
11304
- selectedPlan && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
11448
+ selectedPlan && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box, { $marginBottom: "1rem", children: [
11305
11449
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11306
11450
  Box,
11307
11451
  {
11308
11452
  $width: "100%",
11309
11453
  $textAlign: "left",
11310
11454
  $opacity: "50%",
11311
- $marginBottom: "-0.25rem",
11455
+ $marginBottom: "0.25rem",
11312
11456
  $marginTop: "-0.25rem",
11313
11457
  children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11314
11458
  Icon2,
@@ -11350,6 +11494,51 @@ var CheckoutDialog = () => {
11350
11494
  ) })
11351
11495
  ] })
11352
11496
  ] })
11497
+ ] }),
11498
+ charges?.proration && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
11499
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box, { $opacity: "0.625", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11500
+ Text,
11501
+ {
11502
+ $font: theme.typography.text.fontFamily,
11503
+ $size: 14,
11504
+ $weight: theme.typography.text.fontWeight,
11505
+ $color: theme.typography.text.color,
11506
+ children: charges?.proration && charges.proration > 0 ? "Proration" : "Credits"
11507
+ }
11508
+ ) }),
11509
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Flex, { $flexDirection: "column", $gap: "0.5rem", children: currentPlan && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
11510
+ Flex,
11511
+ {
11512
+ $justifyContent: "space-between",
11513
+ $alignItems: "center",
11514
+ $gap: "1rem",
11515
+ children: [
11516
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Flex, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
11517
+ Text,
11518
+ {
11519
+ $font: theme.typography.heading4.fontFamily,
11520
+ $size: theme.typography.heading4.fontSize,
11521
+ $weight: theme.typography.heading4.fontWeight,
11522
+ $color: theme.typography.heading4.color,
11523
+ children: [
11524
+ "Unused time with ",
11525
+ currentPlan.name
11526
+ ]
11527
+ }
11528
+ ) }),
11529
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Flex, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11530
+ Text,
11531
+ {
11532
+ $font: theme.typography.text.fontFamily,
11533
+ $size: theme.typography.text.fontSize,
11534
+ $weight: theme.typography.text.fontWeight,
11535
+ $color: theme.typography.text.color,
11536
+ children: formatCurrency(charges.proration)
11537
+ }
11538
+ ) })
11539
+ ]
11540
+ }
11541
+ ) })
11353
11542
  ] })
11354
11543
  ]
11355
11544
  }
@@ -11364,7 +11553,7 @@ var CheckoutDialog = () => {
11364
11553
  $height: "auto",
11365
11554
  $padding: "1.5rem",
11366
11555
  children: [
11367
- selectedPlan && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Flex, { $justifyContent: "space-between", children: [
11556
+ selectedPlan && subscriptionPrice && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Flex, { $justifyContent: "space-between", children: [
11368
11557
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box, { $opacity: "0.625", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
11369
11558
  Text,
11370
11559
  {
@@ -11374,8 +11563,7 @@ var CheckoutDialog = () => {
11374
11563
  $color: theme.typography.text.color,
11375
11564
  children: [
11376
11565
  planPeriod === "month" ? "Monthly" : "Yearly",
11377
- " total:",
11378
- " "
11566
+ " total:"
11379
11567
  ]
11380
11568
  }
11381
11569
  ) }),
@@ -11387,15 +11575,35 @@ var CheckoutDialog = () => {
11387
11575
  $weight: theme.typography.text.fontWeight,
11388
11576
  $color: theme.typography.text.color,
11389
11577
  children: [
11390
- formatCurrency(
11391
- (planPeriod === "month" ? selectedPlan.monthlyPrice : selectedPlan.yearlyPrice)?.price ?? 0
11392
- ),
11578
+ subscriptionPrice,
11393
11579
  "/",
11394
11580
  planPeriod
11395
11581
  ]
11396
11582
  }
11397
11583
  ) })
11398
11584
  ] }),
11585
+ charges && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Flex, { $justifyContent: "space-between", children: [
11586
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box, { $opacity: "0.625", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11587
+ Text,
11588
+ {
11589
+ $font: theme.typography.text.fontFamily,
11590
+ $size: theme.typography.text.fontSize,
11591
+ $weight: theme.typography.text.fontWeight,
11592
+ $color: theme.typography.text.color,
11593
+ children: "Due today:"
11594
+ }
11595
+ ) }),
11596
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11597
+ Text,
11598
+ {
11599
+ $font: theme.typography.text.fontFamily,
11600
+ $size: theme.typography.text.fontSize,
11601
+ $weight: theme.typography.text.fontWeight,
11602
+ $color: theme.typography.text.color,
11603
+ children: formatCurrency(charges.dueNow)
11604
+ }
11605
+ ) })
11606
+ ] }),
11399
11607
  checkoutStage === "plan" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11400
11608
  StyledButton,
11401
11609
  {
@@ -11448,24 +11656,25 @@ var CheckoutDialog = () => {
11448
11656
  children: "Pay now"
11449
11657
  }
11450
11658
  ),
11451
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box, { $opacity: "0.625", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11659
+ !isLoading && error && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11452
11660
  Text,
11453
11661
  {
11454
11662
  $font: theme.typography.text.fontFamily,
11455
11663
  $size: theme.typography.text.fontSize,
11456
- $weight: theme.typography.text.fontWeight,
11457
- $color: theme.typography.text.color,
11458
- children: "Discounts & credits applied at checkout"
11664
+ $weight: 500,
11665
+ $color: "#DB6669",
11666
+ children: error
11459
11667
  }
11460
11668
  ) }),
11461
- error && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11669
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box, { $opacity: "0.625", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11462
11670
  Text,
11463
11671
  {
11464
11672
  $font: theme.typography.text.fontFamily,
11465
11673
  $size: theme.typography.text.fontSize,
11466
- $weight: 500,
11467
- $color: "#DB6669",
11468
- children: error
11674
+ $weight: theme.typography.text.fontWeight,
11675
+ $color: theme.typography.text.color,
11676
+ children: checkoutStage === "plan" ? "Discounts & credits applied at checkout" : subscriptionPrice && `You will be billed ${subscriptionPrice} for this subscription
11677
+ 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.`
11469
11678
  }
11470
11679
  ) })
11471
11680
  ]
@@ -11515,9 +11724,9 @@ var PlanManager = (0, import_react11.forwardRef)(({ children, className, portal,
11515
11724
  const { currentPlan, canChangePlan } = (0, import_react11.useMemo)(() => {
11516
11725
  return {
11517
11726
  currentPlan: data.company?.plan,
11518
- canChangePlan: stripe !== null
11727
+ canChangePlan: data.activePlans.length > 0 && data.stripeEmbed?.publishableKey && data.stripeEmbed?.setupIntentClientSecret && stripe !== null
11519
11728
  };
11520
- }, [data.company, stripe]);
11729
+ }, [data.company, data.activePlans, data.stripeEmbed, stripe]);
11521
11730
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { ref, className, children: [
11522
11731
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
11523
11732
  Flex,
@@ -11620,6 +11829,7 @@ var IncludedFeatures = (0, import_react12.forwardRef)(({ className, ...rest }, r
11620
11829
  const props = resolveDesignProps3(rest);
11621
11830
  const theme = nt();
11622
11831
  const { data } = useEmbed();
11832
+ const elements = (0, import_react12.useRef)([]);
11623
11833
  const features = (0, import_react12.useMemo)(() => {
11624
11834
  return (data.featureUsage?.features || []).map(
11625
11835
  ({
@@ -11650,6 +11860,34 @@ var IncludedFeatures = (0, import_react12.forwardRef)(({ className, ...rest }, r
11650
11860
  const isLightBackground = (0, import_react12.useMemo)(() => {
11651
11861
  return hexToHSL(theme.card.background).l > 50;
11652
11862
  }, [theme.card.background]);
11863
+ (0, import_react12.useLayoutEffect)(() => {
11864
+ const assignRows = (parent) => {
11865
+ let isWrapped = true;
11866
+ [...parent.children].forEach((el) => {
11867
+ if (!(el instanceof HTMLElement)) {
11868
+ return;
11869
+ }
11870
+ if (!el.previousElementSibling || el.offsetLeft <= el.previousElementSibling.offsetLeft) {
11871
+ isWrapped = !isWrapped;
11872
+ }
11873
+ if (isWrapped) {
11874
+ el.style.textAlign = "left";
11875
+ } else if (el.previousElementSibling) {
11876
+ el.style.textAlign = "right";
11877
+ }
11878
+ });
11879
+ };
11880
+ elements.current.forEach((el) => {
11881
+ if (!el) return;
11882
+ const observer = new ResizeObserver((entries) => {
11883
+ entries.forEach((entry) => {
11884
+ assignRows(entry.target);
11885
+ });
11886
+ });
11887
+ observer.observe(el);
11888
+ assignRows(el);
11889
+ });
11890
+ }, [elements.current.length]);
11653
11891
  return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Flex, { ref, className, $flexDirection: "column", $gap: "1.5rem", children: [
11654
11892
  props.header.isVisible && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Box, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
11655
11893
  Text,
@@ -11671,6 +11909,7 @@ var IncludedFeatures = (0, import_react12.forwardRef)(({ className, ...rest }, r
11671
11909
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
11672
11910
  Flex,
11673
11911
  {
11912
+ ref: (el) => elements.current.push(el),
11674
11913
  $flexWrap: "wrap",
11675
11914
  $justifyContent: "space-between",
11676
11915
  $alignItems: "center",
@@ -11699,7 +11938,7 @@ var IncludedFeatures = (0, import_react12.forwardRef)(({ className, ...rest }, r
11699
11938
  }
11700
11939
  ) })
11701
11940
  ] }),
11702
- allocationType === "numeric" && feature?.name && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Box, { $textAlign: "right", children: [
11941
+ allocationType === "numeric" && feature?.name && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Box, { $textAlign: "right", $paddingLeft: "3.5rem", children: [
11703
11942
  props.entitlement.isVisible && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
11704
11943
  Text,
11705
11944
  {
@@ -11709,7 +11948,7 @@ var IncludedFeatures = (0, import_react12.forwardRef)(({ className, ...rest }, r
11709
11948
  $weight: theme.typography[props.entitlement.fontStyle].fontWeight,
11710
11949
  $lineHeight: 1.5,
11711
11950
  $color: theme.typography[props.entitlement.fontStyle].color,
11712
- children: typeof allocation === "number" ? (0, import_pluralize2.default)(feature.name, allocation, true) : `Unlimited ${(0, import_pluralize2.default)(feature.name)}`
11951
+ children: typeof allocation === "number" ? `${formatNumber(allocation)} ${(0, import_pluralize2.default)(feature.name, allocation)}` : `Unlimited ${(0, import_pluralize2.default)(feature.name)}`
11713
11952
  }
11714
11953
  ),
11715
11954
  props.usage.isVisible && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
@@ -11721,7 +11960,7 @@ var IncludedFeatures = (0, import_react12.forwardRef)(({ className, ...rest }, r
11721
11960
  $weight: theme.typography[props.usage.fontStyle].fontWeight,
11722
11961
  $lineHeight: 1.5,
11723
11962
  $color: theme.typography[props.usage.fontStyle].color,
11724
- children: typeof allocation === "number" ? `${usage} of ${allocation} used` : `${usage} used`
11963
+ children: typeof usage === "number" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_jsx_runtime13.Fragment, { children: typeof allocation === "number" ? `${formatNumber(usage)} of ${formatNumber(allocation)} used` : `${formatNumber(usage)} used` })
11725
11964
  }
11726
11965
  )
11727
11966
  ] })
@@ -11953,14 +12192,19 @@ var UpcomingBill = (0, import_react14.forwardRef)(({ className, ...rest }, ref)
11953
12192
  children: formatCurrency(upcomingInvoice.amountDue)
11954
12193
  }
11955
12194
  ) }),
11956
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Box, { $maxWidth: "10rem", $lineHeight: "1", $textAlign: "right", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
12195
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Box, { $maxWidth: "10rem", $lineHeight: "1", $textAlign: "right", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
11957
12196
  Text,
11958
12197
  {
11959
12198
  $font: theme.typography[props.contractEndDate.fontStyle].fontFamily,
11960
12199
  $size: theme.typography[props.contractEndDate.fontStyle].fontSize,
11961
12200
  $weight: theme.typography[props.contractEndDate.fontStyle].fontWeight,
11962
12201
  $color: theme.typography[props.contractEndDate.fontStyle].color,
11963
- children: "Estimated monthly bill."
12202
+ children: [
12203
+ "Estimated",
12204
+ " ",
12205
+ upcomingInvoice.interval === "year" ? "yearly" : "monthly",
12206
+ " bill."
12207
+ ]
11964
12208
  }
11965
12209
  ) })
11966
12210
  ] })
@@ -12069,10 +12313,10 @@ var Invoices = (0, import_react15.forwardRef)(({ className, ...rest }, ref) => {
12069
12313
  });
12070
12314
 
12071
12315
  // src/components/embed/ComponentTree.tsx
12072
- var import_react23 = require("react");
12316
+ var import_react22 = require("react");
12073
12317
 
12074
12318
  // src/components/embed/renderer.ts
12075
- var import_react22 = require("react");
12319
+ var import_react21 = require("react");
12076
12320
 
12077
12321
  // src/components/layout/root/Root.tsx
12078
12322
  var import_react16 = require("react");
@@ -12096,53 +12340,131 @@ var StyledViewport = dt.div`
12096
12340
  `;
12097
12341
 
12098
12342
  // src/components/layout/RenderLayout.tsx
12099
- var import_react17 = require("react");
12100
12343
  var import_react18 = require("react");
12344
+
12345
+ // src/components/layout/card/Card.tsx
12346
+ var import_react17 = require("react");
12347
+
12348
+ // src/components/layout/card/styles.ts
12349
+ var StyledCard = dt.div(
12350
+ ({
12351
+ theme,
12352
+ $sectionLayout = "merged",
12353
+ $borderRadius = 8,
12354
+ $padding = 48,
12355
+ $shadow = true
12356
+ }) => {
12357
+ return lt`
12358
+ box-sizing: border-box;
12359
+ font-size: ${TEXT_BASE_SIZE}px;
12360
+
12361
+ *,
12362
+ *::before,
12363
+ *::after {
12364
+ box-sizing: inherit;
12365
+ }
12366
+
12367
+ > * {
12368
+ padding: ${$padding * 0.75 / TEXT_BASE_SIZE}rem
12369
+ ${$padding / TEXT_BASE_SIZE}rem;
12370
+ color: ${theme.typography.text.color};
12371
+ }
12372
+
12373
+ ${() => {
12374
+ const { l: l2 } = hexToHSL(theme.card.background);
12375
+ const borderColor = l2 > 50 ? "hsla(0, 0%, 0%, 0.1)" : "hsla(0, 0%, 100%, 0.2)";
12376
+ const borderRadius = `${$borderRadius / TEXT_BASE_SIZE}rem`;
12377
+ const boxShadow = "0px 1px 20px 0px #1018280F, 0px 1px 3px 0px #1018281A";
12378
+ if ($sectionLayout === "merged") {
12379
+ return lt`
12380
+ background: ${({ theme: theme2 }) => theme2.card.background};
12381
+ border-radius: ${borderRadius};
12382
+
12383
+ ${$shadow && `box-shadow: ${boxShadow};`}
12384
+
12385
+ > :not(:last-child) {
12386
+ border-bottom: 1px solid ${borderColor};
12387
+ }
12388
+ `;
12389
+ }
12390
+ return lt`
12391
+ > :not(:last-child) {
12392
+ margin-bottom: 1rem;
12393
+ }
12394
+
12395
+ > * {
12396
+ background: ${theme.card.background};
12397
+ border-radius: ${borderRadius};
12398
+ ${$shadow && `box-shadow: ${boxShadow};`}
12399
+ }
12400
+ `;
12401
+ }}
12402
+ `;
12403
+ }
12404
+ );
12405
+
12406
+ // src/components/layout/card/Card.tsx
12101
12407
  var import_jsx_runtime18 = require("react/jsx-runtime");
12102
- var DisabledState = () => {
12408
+ var Card = (0, import_react17.forwardRef)(
12409
+ ({ children, className }, ref) => {
12410
+ const theme = nt();
12411
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
12412
+ StyledCard,
12413
+ {
12414
+ ref,
12415
+ className,
12416
+ $sectionLayout: theme?.sectionLayout,
12417
+ $borderRadius: theme?.card?.borderRadius,
12418
+ $padding: theme?.card?.padding,
12419
+ $shadow: theme?.card?.hasShadow,
12420
+ children
12421
+ }
12422
+ );
12423
+ }
12424
+ );
12425
+
12426
+ // src/components/layout/RenderLayout.tsx
12427
+ var import_jsx_runtime19 = require("react/jsx-runtime");
12428
+ var Disabled = () => {
12103
12429
  const theme = nt();
12104
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Box, { $width: "100%", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
12430
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Box, { $width: "max-content", $height: "max-content", $margin: "0 auto", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Card, { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
12105
12431
  Flex,
12106
12432
  {
12107
12433
  $flexDirection: "column",
12108
- $padding: `${theme.card.padding / TEXT_BASE_SIZE}rem`,
12109
- $width: "100%",
12110
- $height: "auto",
12111
- $borderRadius: `${theme.card.borderRadius / TEXT_BASE_SIZE}rem`,
12112
- $backgroundColor: theme.card.background,
12113
- $alignItems: "center",
12114
12434
  $justifyContent: "center",
12435
+ $alignItems: "center",
12436
+ $whiteSpace: "nowrap",
12115
12437
  children: [
12116
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
12117
- Box,
12438
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Box, { $marginBottom: "0.5rem", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
12439
+ Text,
12118
12440
  {
12119
- $marginBottom: "8px",
12120
- $fontSize: `${theme.typography.heading1.fontSize / TEXT_BASE_SIZE}rem`,
12121
- $fontFamily: theme.typography.heading1.fontFamily,
12122
- $fontWeight: theme.typography.heading1.fontWeight,
12441
+ as: "h1",
12442
+ $font: theme.typography.heading1.fontFamily,
12443
+ $size: theme.typography.heading1.fontSize,
12444
+ $weight: theme.typography.heading1.fontWeight,
12123
12445
  $color: theme.typography.heading1.color,
12124
- children: "Coming soon"
12446
+ children: "Portal not found"
12125
12447
  }
12126
- ),
12127
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
12128
- Box,
12448
+ ) }),
12449
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
12450
+ Text,
12129
12451
  {
12130
- $marginBottom: "8px",
12131
- $fontSize: `${theme.typography.text.fontSize / TEXT_BASE_SIZE}rem`,
12132
- $fontFamily: theme.typography.text.fontFamily,
12133
- $fontWeight: theme.typography.text.fontWeight,
12452
+ as: "p",
12453
+ $font: theme.typography.text.fontFamily,
12454
+ $size: theme.typography.text.fontSize,
12455
+ $weight: theme.typography.text.fontWeight,
12134
12456
  $color: theme.typography.text.color,
12135
- children: "The plan manager will be back very soon."
12457
+ children: "Please try again later."
12136
12458
  }
12137
12459
  )
12138
12460
  ]
12139
12461
  }
12140
- ) });
12462
+ ) }) });
12141
12463
  };
12142
- var SuccessState = () => {
12143
- const [isOpen, setIsOpen] = (0, import_react17.useState)(true);
12464
+ var Success = () => {
12144
12465
  const theme = nt();
12145
12466
  const { hydrate, data, api, setLayout, isPending } = useEmbed();
12467
+ const [isOpen, setIsOpen] = (0, import_react18.useState)(true);
12146
12468
  (0, import_react18.useEffect)(() => {
12147
12469
  if (api && data.component?.id) {
12148
12470
  hydrate();
@@ -12154,31 +12476,23 @@ var SuccessState = () => {
12154
12476
  setLayout("portal");
12155
12477
  }
12156
12478
  }, [isPending, isOpen, setLayout]);
12157
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
12479
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Box, { $width: "max-content", $height: "max-content", $margin: "0 auto", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Card, { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
12158
12480
  Flex,
12159
12481
  {
12160
12482
  $flexDirection: "column",
12161
12483
  $justifyContent: "center",
12162
12484
  $alignItems: "center",
12163
- $gap: `${32 / TEXT_BASE_SIZE}rem`,
12164
- $width: "min-content",
12165
- $height: "min-content",
12166
- $margin: "auto",
12167
- $padding: `${theme.card.padding / TEXT_BASE_SIZE}rem ${theme.card.padding * 1.5 / TEXT_BASE_SIZE}rem`,
12168
12485
  $whiteSpace: "nowrap",
12169
- $backgroundColor: theme.card.background,
12170
- $borderRadius: "0.5rem",
12171
- $boxShadow: "0px 1px 20px 0px #1018280F, 0px 1px 3px 0px #1018281A;",
12172
12486
  children: [
12173
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
12487
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Box, { $marginBottom: "1.5rem", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
12174
12488
  IconRound,
12175
12489
  {
12176
12490
  name: "check",
12177
12491
  size: "3xl",
12178
12492
  colors: [theme.card.background, theme.primary]
12179
12493
  }
12180
- ),
12181
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
12494
+ ) }),
12495
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Box, { $marginBottom: "0.5rem", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
12182
12496
  Text,
12183
12497
  {
12184
12498
  as: "h1",
@@ -12188,8 +12502,8 @@ var SuccessState = () => {
12188
12502
  $color: theme.typography.heading1.color,
12189
12503
  children: "Subscription updated!"
12190
12504
  }
12191
- ),
12192
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
12505
+ ) }),
12506
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
12193
12507
  Text,
12194
12508
  {
12195
12509
  as: "p",
@@ -12197,126 +12511,45 @@ var SuccessState = () => {
12197
12511
  $size: theme.typography.text.fontSize,
12198
12512
  $weight: theme.typography.text.fontWeight,
12199
12513
  $color: theme.typography.text.color,
12200
- children: "Loading..."
12514
+ children: "Loading\u2026"
12201
12515
  }
12202
12516
  )
12203
12517
  ]
12204
12518
  }
12205
- );
12519
+ ) }) });
12206
12520
  };
12207
12521
  var RenderLayout = ({ children }) => {
12208
12522
  const { layout } = useEmbed();
12209
12523
  switch (layout) {
12210
12524
  case "disabled":
12211
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DisabledState, {});
12525
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Disabled, {});
12212
12526
  case "success":
12213
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SuccessState, {});
12527
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Success, {});
12214
12528
  default:
12215
12529
  return children;
12216
12530
  }
12217
12531
  };
12218
12532
 
12219
12533
  // src/components/layout/viewport/Viewport.tsx
12220
- var import_jsx_runtime19 = require("react/jsx-runtime");
12534
+ var import_jsx_runtime20 = require("react/jsx-runtime");
12221
12535
  var Viewport = (0, import_react19.forwardRef)(
12222
12536
  ({ children, ...props }, ref) => {
12223
12537
  const theme = nt();
12224
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
12538
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
12225
12539
  StyledViewport,
12226
12540
  {
12227
12541
  ref,
12228
12542
  $numberOfColumns: theme.numberOfColumns,
12229
12543
  ...props,
12230
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(RenderLayout, { children })
12544
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(RenderLayout, { children })
12231
12545
  }
12232
12546
  );
12233
12547
  }
12234
12548
  );
12235
12549
 
12236
12550
  // src/components/layout/column/Column.tsx
12237
- var import_react21 = require("react");
12238
-
12239
- // src/components/layout/card/Card.tsx
12240
12551
  var import_react20 = require("react");
12241
12552
 
12242
- // src/components/layout/card/styles.ts
12243
- var StyledCard = dt.div(
12244
- ({
12245
- theme,
12246
- $sectionLayout = "merged",
12247
- $borderRadius = 8,
12248
- $padding = 48,
12249
- $shadow = true
12250
- }) => {
12251
- return lt`
12252
- box-sizing: border-box;
12253
- font-size: ${TEXT_BASE_SIZE}px;
12254
-
12255
- *,
12256
- *::before,
12257
- *::after {
12258
- box-sizing: inherit;
12259
- }
12260
-
12261
- > * {
12262
- padding: ${$padding * 0.75 / TEXT_BASE_SIZE}rem
12263
- ${$padding / TEXT_BASE_SIZE}rem;
12264
- color: ${theme.typography.text.color};
12265
- }
12266
-
12267
- ${() => {
12268
- const { l: l2 } = hexToHSL(theme.card.background);
12269
- const borderColor = l2 > 50 ? "hsla(0, 0%, 0%, 0.1)" : "hsla(0, 0%, 100%, 0.2)";
12270
- const borderRadius = `${$borderRadius / TEXT_BASE_SIZE}rem`;
12271
- const boxShadow = "0px 1px 20px 0px #1018280F, 0px 1px 3px 0px #1018281A";
12272
- if ($sectionLayout === "merged") {
12273
- return lt`
12274
- background: ${({ theme: theme2 }) => theme2.card.background};
12275
- border-radius: ${borderRadius};
12276
-
12277
- ${$shadow && `box-shadow: ${boxShadow};`}
12278
-
12279
- > :not(:last-child) {
12280
- border-bottom: 1px solid ${borderColor};
12281
- }
12282
- `;
12283
- }
12284
- return lt`
12285
- > :not(:last-child) {
12286
- margin-bottom: 1rem;
12287
- }
12288
-
12289
- > * {
12290
- background: ${theme.card.background};
12291
- border-radius: ${borderRadius};
12292
- ${$shadow && `box-shadow: ${boxShadow};`}
12293
- }
12294
- `;
12295
- }}
12296
- `;
12297
- }
12298
- );
12299
-
12300
- // src/components/layout/card/Card.tsx
12301
- var import_jsx_runtime20 = require("react/jsx-runtime");
12302
- var Card = (0, import_react20.forwardRef)(
12303
- ({ children, className }, ref) => {
12304
- const theme = nt();
12305
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
12306
- StyledCard,
12307
- {
12308
- ref,
12309
- className,
12310
- $sectionLayout: theme?.sectionLayout,
12311
- $borderRadius: theme?.card?.borderRadius,
12312
- $padding: theme?.card?.padding,
12313
- $shadow: theme?.card?.hasShadow,
12314
- children
12315
- }
12316
- );
12317
- }
12318
- );
12319
-
12320
12553
  // src/components/layout/column/styles.ts
12321
12554
  var StyledColumn = dt.div`
12322
12555
  flex-grow: 1;
@@ -12324,7 +12557,7 @@ var StyledColumn = dt.div`
12324
12557
 
12325
12558
  // src/components/layout/column/Column.tsx
12326
12559
  var import_jsx_runtime21 = require("react/jsx-runtime");
12327
- var Column = (0, import_react21.forwardRef)(
12560
+ var Column = (0, import_react20.forwardRef)(
12328
12561
  ({ children, basis, ...props }, ref) => {
12329
12562
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(StyledColumn, { ref, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Card, { children }) });
12330
12563
  }
@@ -12359,7 +12592,7 @@ function createRenderer(options) {
12359
12592
  const { className, ...rest } = props;
12360
12593
  const resolvedProps = component === "div" ? rest : props;
12361
12594
  const resolvedChildren = children.map(renderNode);
12362
- return (0, import_react22.createElement)(
12595
+ return (0, import_react21.createElement)(
12363
12596
  component,
12364
12597
  {
12365
12598
  key: index,
@@ -12429,15 +12662,15 @@ var Error2 = ({ message }) => {
12429
12662
  };
12430
12663
  var ComponentTree = () => {
12431
12664
  const { error, nodes } = useEmbed();
12432
- const [children, setChildren] = (0, import_react23.useState)(/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Loading, {}));
12433
- (0, import_react23.useEffect)(() => {
12665
+ const [children, setChildren] = (0, import_react22.useState)(/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Loading, {}));
12666
+ (0, import_react22.useEffect)(() => {
12434
12667
  const renderer = createRenderer();
12435
12668
  setChildren(nodes.map(renderer));
12436
12669
  }, [nodes]);
12437
12670
  if (error) {
12438
12671
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Error2, { message: error.message });
12439
12672
  }
12440
- if (import_react23.Children.count(children) === 0) {
12673
+ if (import_react22.Children.count(children) === 0) {
12441
12674
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Loading, {});
12442
12675
  }
12443
12676
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_jsx_runtime22.Fragment, { children });