@usethrottle/auth 0.4.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,11 +3706,42 @@ function InvoicesPanel(props) {
3703
3706
  ) }) }) });
3704
3707
  }
3705
3708
 
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 = {
3725
+ weekly: "week",
3726
+ biweekly: "2 weeks",
3727
+ monthly: "month",
3728
+ quarterly: "quarter",
3729
+ yearly: "year"
3730
+ };
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
+
3706
3739
  // src/react/components/account/SubscriptionsPanel.tsx
3707
- import { jsx as jsx42, jsxs as jsxs32 } from "react/jsx-runtime";
3740
+ import { Fragment as Fragment8, jsx as jsx42, jsxs as jsxs32 } from "react/jsx-runtime";
3708
3741
  var CAN_PAUSE = /* @__PURE__ */ new Set(["active", "trialing"]);
3709
3742
  var CAN_RESUME = /* @__PURE__ */ new Set(["paused"]);
3710
3743
  var CAN_CANCEL2 = /* @__PURE__ */ new Set(["active", "trialing", "paused", "past_due", "unpaid"]);
3744
+ var isInstallment = (sub) => sub.totalPayments != null;
3711
3745
  function SubscriptionsPanel(props) {
3712
3746
  const a = useAppearance(props.appearance);
3713
3747
  const scoped = useAppearanceProviderValue(props.appearance);
@@ -3727,9 +3761,12 @@ function SubscriptionsPanel(props) {
3727
3761
  await run(fn);
3728
3762
  })();
3729
3763
  };
3730
- const priceLabel = (sub) => `${formatMoney(sub.amount, sub.currency, locale)} / ${sub.interval}${sub.quantity > 1 ? ` \xD7 ${sub.quantity}` : ""}`;
3731
- const renewsLabel = (sub) => formatDate(sub.status === "cancelled" ? sub.cancelledAt ?? sub.currentPeriodEnd : sub.currentPeriodEnd, locale);
3732
- 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: [
3733
3770
  CAN_PAUSE.has(sub.status) ? /* @__PURE__ */ jsx42(
3734
3771
  Button,
3735
3772
  {
@@ -3804,7 +3841,10 @@ function SubscriptionsPanel(props) {
3804
3841
  rowKey: (sub) => sub.id,
3805
3842
  rows,
3806
3843
  columns: [
3807
- { 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
+ ] }) },
3808
3848
  { key: "price", label: t.subscriptions.columnPrice, render: (sub) => /* @__PURE__ */ jsx42("span", { className: "throttle-table__money", children: priceLabel(sub) }) },
3809
3849
  { key: "renews", label: t.subscriptions.columnRenews, render: (sub) => renewsLabel(sub) },
3810
3850
  { key: "status", label: t.subscriptions.columnStatus, render: (sub) => /* @__PURE__ */ jsxs32("div", { className: "throttle-row", children: [
@@ -3820,13 +3860,18 @@ function SubscriptionsPanel(props) {
3820
3860
  /* @__PURE__ */ jsx42("strong", { children: sub.planName ?? sub.planReference }),
3821
3861
  /* @__PURE__ */ jsx42(StatusBadge, { status: sub.status, labels: t.subscriptions.statusLabels })
3822
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,
3823
3864
  /* @__PURE__ */ jsxs32("p", { className: "throttle-muted", children: [
3824
3865
  formatMoney(sub.amount, sub.currency, locale),
3825
3866
  " / ",
3826
- sub.interval,
3867
+ cadenceNoun(sub),
3827
3868
  sub.quantity > 1 ? ` \xD7 ${sub.quantity}` : ""
3828
3869
  ] }),
3829
- 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: [
3830
3875
  t.subscriptions.cancelledOn,
3831
3876
  " ",
3832
3877
  formatDate(sub.cancelledAt ?? sub.currentPeriodEnd, locale)
@@ -3883,7 +3928,7 @@ function describeDevice(userAgent) {
3883
3928
  }
3884
3929
 
3885
3930
  // src/react/components/account/SecurityPanel.tsx
3886
- 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";
3887
3932
  function SecurityPanel(props) {
3888
3933
  const a = useAppearance(props.appearance);
3889
3934
  const scoped = useAppearanceProviderValue(props.appearance);
@@ -3948,7 +3993,7 @@ function SecurityPanel(props) {
3948
3993
  ),
3949
3994
  /* @__PURE__ */ jsxs33("div", { ...a.el("securityPanel.sessionList", "throttle-stack"), children: [
3950
3995
  /* @__PURE__ */ jsx43("h3", { children: t.security.sessionsTitle }),
3951
- listError ? /* @__PURE__ */ jsxs33(Fragment8, { children: [
3996
+ listError ? /* @__PURE__ */ jsxs33(Fragment9, { children: [
3952
3997
  /* @__PURE__ */ jsx43(Alert, { tone: "error", children: listError }),
3953
3998
  /* @__PURE__ */ jsx43(Button, { variant: "secondary", onClick: () => void load(), children: t.common.retry })
3954
3999
  ] }) : null,
@@ -4029,7 +4074,7 @@ function SecurityPanel(props) {
4029
4074
  }
4030
4075
 
4031
4076
  // src/react/components/account/AccountDashboard.tsx
4032
- 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";
4033
4078
  var ACCOUNT_TABS = [
4034
4079
  "profile",
4035
4080
  "addresses",
@@ -4144,7 +4189,7 @@ function AccountDashboard(props) {
4144
4189
  sidebar ? /* @__PURE__ */ jsxs34("div", { className: "throttle-account", children: [
4145
4190
  /* @__PURE__ */ jsx44("div", { ...a.el("accountDashboard.sidebar"), children: nav }),
4146
4191
  panel
4147
- ] }) : /* @__PURE__ */ jsxs34(Fragment9, { children: [
4192
+ ] }) : /* @__PURE__ */ jsxs34(Fragment10, { children: [
4148
4193
  /* @__PURE__ */ jsx44("div", { ...a.el("accountDashboard.tabs"), children: nav }),
4149
4194
  panel
4150
4195
  ] })
@@ -4469,21 +4514,21 @@ function SignUpPage(props) {
4469
4514
  }
4470
4515
 
4471
4516
  // src/react/components/guards.tsx
4472
- import { Fragment as Fragment10, jsx as jsx53 } from "react/jsx-runtime";
4517
+ import { Fragment as Fragment11, jsx as jsx53 } from "react/jsx-runtime";
4473
4518
  function SignedIn(props) {
4474
4519
  const { status } = useAuth();
4475
- return status === "authenticated" ? /* @__PURE__ */ jsx53(Fragment10, { children: props.children }) : null;
4520
+ return status === "authenticated" ? /* @__PURE__ */ jsx53(Fragment11, { children: props.children }) : null;
4476
4521
  }
4477
4522
  function SignedOut(props) {
4478
4523
  const { status } = useAuth();
4479
- return status === "unauthenticated" ? /* @__PURE__ */ jsx53(Fragment10, { children: props.children }) : null;
4524
+ return status === "unauthenticated" ? /* @__PURE__ */ jsx53(Fragment11, { children: props.children }) : null;
4480
4525
  }
4481
4526
  function Protect(props) {
4482
4527
  const { status, emailVerified } = useAuth();
4483
4528
  if (status === "loading") return null;
4484
- if (status !== "authenticated") return /* @__PURE__ */ jsx53(Fragment10, { children: props.fallback ?? null });
4485
- if (props.requireVerified && !emailVerified) return /* @__PURE__ */ jsx53(Fragment10, { children: props.fallback ?? null });
4486
- 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 });
4487
4532
  }
4488
4533
 
4489
4534
  // src/react/components/UserButton.tsx