@usethrottle/auth 0.5.0 → 0.6.0

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.
@@ -322,6 +322,7 @@ declare const enUS: {
322
322
  endsOn: string;
323
323
  cancelledOn: string;
324
324
  trialEnds: string;
325
+ installmentProgress: string;
325
326
  cancelButton: string;
326
327
  cancelAtPeriodEnd: string;
327
328
  cancelNow: string;
@@ -337,7 +338,8 @@ declare const enUS: {
337
338
  * Display copy for `subscription.status`. Mirrors SubscriptionStatus in
338
339
  * `@commerce/subscriptions`; copied rather than imported because this
339
340
  * package has no runtime dependencies. Without it a buyer in dunning saw
340
- * the literal pill `past_due`.
341
+ * the literal pill `past_due`. `completed` is an installment plan that
342
+ * has taken its last payment.
341
343
  */
342
344
  statusLabels: {
343
345
  active: string;
@@ -346,6 +348,7 @@ declare const enUS: {
346
348
  pastDue: string;
347
349
  trialing: string;
348
350
  unpaid: string;
351
+ completed: string;
349
352
  };
350
353
  };
351
354
  security: {
@@ -322,6 +322,7 @@ declare const enUS: {
322
322
  endsOn: string;
323
323
  cancelledOn: string;
324
324
  trialEnds: string;
325
+ installmentProgress: string;
325
326
  cancelButton: string;
326
327
  cancelAtPeriodEnd: string;
327
328
  cancelNow: string;
@@ -337,7 +338,8 @@ declare const enUS: {
337
338
  * Display copy for `subscription.status`. Mirrors SubscriptionStatus in
338
339
  * `@commerce/subscriptions`; copied rather than imported because this
339
340
  * package has no runtime dependencies. Without it a buyer in dunning saw
340
- * the literal pill `past_due`.
341
+ * the literal pill `past_due`. `completed` is an installment plan that
342
+ * has taken its last payment.
341
343
  */
342
344
  statusLabels: {
343
345
  active: string;
@@ -346,6 +348,7 @@ declare const enUS: {
346
348
  pastDue: string;
347
349
  trialing: string;
348
350
  unpaid: string;
351
+ completed: string;
349
352
  };
350
353
  };
351
354
  security: {
@@ -671,6 +671,7 @@ var enUS = {
671
671
  endsOn: "Ends on",
672
672
  cancelledOn: "Cancelled on",
673
673
  trialEnds: "Trial ends",
674
+ installmentProgress: "Payment {paid} of {total}",
674
675
  cancelButton: "Cancel",
675
676
  cancelAtPeriodEnd: "Cancel at period end",
676
677
  cancelNow: "Cancel immediately",
@@ -686,7 +687,8 @@ var enUS = {
686
687
  * Display copy for `subscription.status`. Mirrors SubscriptionStatus in
687
688
  * `@commerce/subscriptions`; copied rather than imported because this
688
689
  * package has no runtime dependencies. Without it a buyer in dunning saw
689
- * the literal pill `past_due`.
690
+ * the literal pill `past_due`. `completed` is an installment plan that
691
+ * has taken its last payment.
690
692
  */
691
693
  statusLabels: {
692
694
  active: "Active",
@@ -694,7 +696,8 @@ var enUS = {
694
696
  cancelled: "Cancelled",
695
697
  pastDue: "Payment overdue",
696
698
  trialing: "Trial",
697
- unpaid: "Unpaid"
699
+ unpaid: "Unpaid",
700
+ completed: "Paid in full"
698
701
  }
699
702
  },
700
703
  security: {
@@ -3703,19 +3706,42 @@ function InvoicesPanel(props) {
3703
3706
  ) }) }) });
3704
3707
  }
3705
3708
 
3706
- // src/react/components/account/SubscriptionsPanel.tsx
3707
- import { jsx as jsx42, jsxs as jsxs32 } from "react/jsx-runtime";
3708
- var CAN_PAUSE = /* @__PURE__ */ new Set(["active", "trialing"]);
3709
- var CAN_RESUME = /* @__PURE__ */ new Set(["paused"]);
3710
- var CAN_CANCEL2 = /* @__PURE__ */ new Set(["active", "trialing", "paused", "past_due", "unpaid"]);
3711
- var INTERVAL_WORD = {
3709
+ // ../core-cadence/src/cadence.ts
3710
+ var INTERVAL_UNITS = ["hour", "day", "week", "month"];
3711
+ var NAMED_INTERVALS = ["weekly", "biweekly", "monthly", "quarterly", "yearly"];
3712
+ var INTERVAL_VALUES = [...NAMED_INTERVALS, "custom"];
3713
+ var HOUR_MS = 36e5;
3714
+ var DAY_MS = 24 * HOUR_MS;
3715
+ var WEEK_MS = 7 * DAY_MS;
3716
+ function isNamedInterval(value) {
3717
+ return typeof value === "string" && NAMED_INTERVALS.includes(value);
3718
+ }
3719
+ function isIntervalUnit(value) {
3720
+ return typeof value === "string" && INTERVAL_UNITS.includes(value);
3721
+ }
3722
+
3723
+ // ../core-cadence/src/labels.ts
3724
+ var NAMED_NOUN = {
3712
3725
  weekly: "week",
3713
3726
  biweekly: "2 weeks",
3714
3727
  monthly: "month",
3715
3728
  quarterly: "quarter",
3716
3729
  yearly: "year"
3717
3730
  };
3718
- var intervalWord = (interval) => INTERVAL_WORD[interval] ?? interval;
3731
+ function cadenceNoun(cadence) {
3732
+ if (isNamedInterval(cadence.interval)) return NAMED_NOUN[cadence.interval];
3733
+ if (isIntervalUnit(cadence.intervalUnit) && cadence.intervalCount != null) {
3734
+ return cadence.intervalCount === 1 ? cadence.intervalUnit : `${cadence.intervalCount} ${cadence.intervalUnit}s`;
3735
+ }
3736
+ return cadence.interval;
3737
+ }
3738
+
3739
+ // src/react/components/account/SubscriptionsPanel.tsx
3740
+ import { Fragment as Fragment8, jsx as jsx42, jsxs as jsxs32 } from "react/jsx-runtime";
3741
+ var CAN_PAUSE = /* @__PURE__ */ new Set(["active", "trialing"]);
3742
+ var CAN_RESUME = /* @__PURE__ */ new Set(["paused"]);
3743
+ var CAN_CANCEL2 = /* @__PURE__ */ new Set(["active", "trialing", "paused", "past_due", "unpaid"]);
3744
+ var isInstallment = (sub) => sub.totalPayments != null;
3719
3745
  function SubscriptionsPanel(props) {
3720
3746
  const a = useAppearance(props.appearance);
3721
3747
  const scoped = useAppearanceProviderValue(props.appearance);
@@ -3735,9 +3761,12 @@ function SubscriptionsPanel(props) {
3735
3761
  await run(fn);
3736
3762
  })();
3737
3763
  };
3738
- const priceLabel = (sub) => `${formatMoney(sub.amount, sub.currency, locale)} / ${intervalWord(sub.interval)}${sub.quantity > 1 ? ` \xD7 ${sub.quantity}` : ""}`;
3739
- const renewsLabel = (sub) => formatDate(sub.status === "cancelled" ? sub.cancelledAt ?? sub.currentPeriodEnd : sub.currentPeriodEnd, locale);
3740
- const lifecycleActions = (sub, variantFor) => /* @__PURE__ */ jsxs32("div", { className: "throttle-actions", children: [
3764
+ const priceLabel = (sub) => `${formatMoney(sub.amount, sub.currency, locale)} / ${cadenceNoun(sub)}${sub.quantity > 1 ? ` \xD7 ${sub.quantity}` : ""}`;
3765
+ const renewsLabel = (sub) => formatDate(
3766
+ sub.status === "completed" ? sub.completedAt ?? sub.currentPeriodEnd : sub.status === "cancelled" ? sub.cancelledAt ?? sub.currentPeriodEnd : sub.currentPeriodEnd,
3767
+ locale
3768
+ );
3769
+ const lifecycleActions = (sub, variantFor) => isInstallment(sub) ? null : /* @__PURE__ */ jsxs32("div", { className: "throttle-actions", children: [
3741
3770
  CAN_PAUSE.has(sub.status) ? /* @__PURE__ */ jsx42(
3742
3771
  Button,
3743
3772
  {
@@ -3812,7 +3841,10 @@ function SubscriptionsPanel(props) {
3812
3841
  rowKey: (sub) => sub.id,
3813
3842
  rows,
3814
3843
  columns: [
3815
- { key: "plan", label: t.subscriptions.columnPlan, render: (sub) => sub.planName ?? sub.planReference },
3844
+ { key: "plan", label: t.subscriptions.columnPlan, render: (sub) => /* @__PURE__ */ jsxs32(Fragment8, { children: [
3845
+ sub.planName ?? sub.planReference,
3846
+ sub.totalPayments != null ? /* @__PURE__ */ jsx42("div", { className: "throttle-muted", children: t.subscriptions.installmentProgress.replace("{paid}", String(Math.min(sub.paymentsMade ?? 0, sub.totalPayments))).replace("{total}", String(sub.totalPayments)) }) : null
3847
+ ] }) },
3816
3848
  { key: "price", label: t.subscriptions.columnPrice, render: (sub) => /* @__PURE__ */ jsx42("span", { className: "throttle-table__money", children: priceLabel(sub) }) },
3817
3849
  { key: "renews", label: t.subscriptions.columnRenews, render: (sub) => renewsLabel(sub) },
3818
3850
  { key: "status", label: t.subscriptions.columnStatus, render: (sub) => /* @__PURE__ */ jsxs32("div", { className: "throttle-row", children: [
@@ -3828,13 +3860,18 @@ function SubscriptionsPanel(props) {
3828
3860
  /* @__PURE__ */ jsx42("strong", { children: sub.planName ?? sub.planReference }),
3829
3861
  /* @__PURE__ */ jsx42(StatusBadge, { status: sub.status, labels: t.subscriptions.statusLabels })
3830
3862
  ] }),
3863
+ sub.totalPayments != null ? /* @__PURE__ */ jsx42("div", { className: "throttle-muted", children: t.subscriptions.installmentProgress.replace("{paid}", String(Math.min(sub.paymentsMade ?? 0, sub.totalPayments))).replace("{total}", String(sub.totalPayments)) }) : null,
3831
3864
  /* @__PURE__ */ jsxs32("p", { className: "throttle-muted", children: [
3832
3865
  formatMoney(sub.amount, sub.currency, locale),
3833
3866
  " / ",
3834
- intervalWord(sub.interval),
3867
+ cadenceNoun(sub),
3835
3868
  sub.quantity > 1 ? ` \xD7 ${sub.quantity}` : ""
3836
3869
  ] }),
3837
- sub.status === "cancelled" ? /* @__PURE__ */ jsxs32("p", { className: "throttle-muted", children: [
3870
+ sub.status === "completed" ? /* @__PURE__ */ jsxs32("p", { className: "throttle-muted", children: [
3871
+ t.subscriptions.statusLabels.completed,
3872
+ " ",
3873
+ formatDate(sub.completedAt ?? sub.currentPeriodEnd, locale)
3874
+ ] }) : sub.status === "cancelled" ? /* @__PURE__ */ jsxs32("p", { className: "throttle-muted", children: [
3838
3875
  t.subscriptions.cancelledOn,
3839
3876
  " ",
3840
3877
  formatDate(sub.cancelledAt ?? sub.currentPeriodEnd, locale)
@@ -3891,7 +3928,7 @@ function describeDevice(userAgent) {
3891
3928
  }
3892
3929
 
3893
3930
  // src/react/components/account/SecurityPanel.tsx
3894
- import { Fragment as Fragment8, jsx as jsx43, jsxs as jsxs33 } from "react/jsx-runtime";
3931
+ import { Fragment as Fragment9, jsx as jsx43, jsxs as jsxs33 } from "react/jsx-runtime";
3895
3932
  function SecurityPanel(props) {
3896
3933
  const a = useAppearance(props.appearance);
3897
3934
  const scoped = useAppearanceProviderValue(props.appearance);
@@ -3956,7 +3993,7 @@ function SecurityPanel(props) {
3956
3993
  ),
3957
3994
  /* @__PURE__ */ jsxs33("div", { ...a.el("securityPanel.sessionList", "throttle-stack"), children: [
3958
3995
  /* @__PURE__ */ jsx43("h3", { children: t.security.sessionsTitle }),
3959
- listError ? /* @__PURE__ */ jsxs33(Fragment8, { children: [
3996
+ listError ? /* @__PURE__ */ jsxs33(Fragment9, { children: [
3960
3997
  /* @__PURE__ */ jsx43(Alert, { tone: "error", children: listError }),
3961
3998
  /* @__PURE__ */ jsx43(Button, { variant: "secondary", onClick: () => void load(), children: t.common.retry })
3962
3999
  ] }) : null,
@@ -4037,7 +4074,7 @@ function SecurityPanel(props) {
4037
4074
  }
4038
4075
 
4039
4076
  // src/react/components/account/AccountDashboard.tsx
4040
- import { Fragment as Fragment9, jsx as jsx44, jsxs as jsxs34 } from "react/jsx-runtime";
4077
+ import { Fragment as Fragment10, jsx as jsx44, jsxs as jsxs34 } from "react/jsx-runtime";
4041
4078
  var ACCOUNT_TABS = [
4042
4079
  "profile",
4043
4080
  "addresses",
@@ -4152,7 +4189,7 @@ function AccountDashboard(props) {
4152
4189
  sidebar ? /* @__PURE__ */ jsxs34("div", { className: "throttle-account", children: [
4153
4190
  /* @__PURE__ */ jsx44("div", { ...a.el("accountDashboard.sidebar"), children: nav }),
4154
4191
  panel
4155
- ] }) : /* @__PURE__ */ jsxs34(Fragment9, { children: [
4192
+ ] }) : /* @__PURE__ */ jsxs34(Fragment10, { children: [
4156
4193
  /* @__PURE__ */ jsx44("div", { ...a.el("accountDashboard.tabs"), children: nav }),
4157
4194
  panel
4158
4195
  ] })
@@ -4477,21 +4514,21 @@ function SignUpPage(props) {
4477
4514
  }
4478
4515
 
4479
4516
  // src/react/components/guards.tsx
4480
- import { Fragment as Fragment10, jsx as jsx53 } from "react/jsx-runtime";
4517
+ import { Fragment as Fragment11, jsx as jsx53 } from "react/jsx-runtime";
4481
4518
  function SignedIn(props) {
4482
4519
  const { status } = useAuth();
4483
- return status === "authenticated" ? /* @__PURE__ */ jsx53(Fragment10, { children: props.children }) : null;
4520
+ return status === "authenticated" ? /* @__PURE__ */ jsx53(Fragment11, { children: props.children }) : null;
4484
4521
  }
4485
4522
  function SignedOut(props) {
4486
4523
  const { status } = useAuth();
4487
- return status === "unauthenticated" ? /* @__PURE__ */ jsx53(Fragment10, { children: props.children }) : null;
4524
+ return status === "unauthenticated" ? /* @__PURE__ */ jsx53(Fragment11, { children: props.children }) : null;
4488
4525
  }
4489
4526
  function Protect(props) {
4490
4527
  const { status, emailVerified } = useAuth();
4491
4528
  if (status === "loading") return null;
4492
- if (status !== "authenticated") return /* @__PURE__ */ jsx53(Fragment10, { children: props.fallback ?? null });
4493
- if (props.requireVerified && !emailVerified) return /* @__PURE__ */ jsx53(Fragment10, { children: props.fallback ?? null });
4494
- return /* @__PURE__ */ jsx53(Fragment10, { children: props.children });
4529
+ if (status !== "authenticated") return /* @__PURE__ */ jsx53(Fragment11, { children: props.fallback ?? null });
4530
+ if (props.requireVerified && !emailVerified) return /* @__PURE__ */ jsx53(Fragment11, { children: props.fallback ?? null });
4531
+ return /* @__PURE__ */ jsx53(Fragment11, { children: props.children });
4495
4532
  }
4496
4533
 
4497
4534
  // src/react/components/UserButton.tsx