@usethrottle/auth 0.6.1 → 0.8.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.
@@ -44,7 +44,7 @@ type ThrottleVariables = Partial<Record<keyof typeof VARIABLE_PROPERTY, string>>
44
44
  * rendered element without adding its key here ships something a merchant
45
45
  * cannot restyle, which the drift test in Task 15 catches.
46
46
  */
47
- declare const THROTTLE_ELEMENT_KEYS: readonly ["card", "card.header", "card.title", "card.description", "card.body", "card.footer", "card.logo", "field", "field.label", "field.input", "field.hint", "field.error", "field.group", "button", "alert", "spinner", "skeleton", "avatar", "badge", "emptyState", "emptyState.title", "emptyState.description", "modal.overlay", "modal.container", "modal.closeButton", "dropdown.trigger", "dropdown.menu", "dropdown.item", "dropdown.separator", "tabs.list", "tabs.tab", "table", "table.head", "table.row", "table.cell", "signIn.root", "signIn.title", "signIn.logo", "signIn.emailField", "signIn.passwordField", "signIn.submitButton", "signIn.forgotLink", "signIn.switchLink", "signUp.root", "signUp.title", "signUp.logo", "signUp.emailField", "signUp.passwordField", "signUp.submitButton", "signUp.switchLink", "forgotPassword.root", "forgotPassword.title", "forgotPassword.logo", "forgotPassword.emailField", "forgotPassword.submitButton", "forgotPassword.backLink", "resetPassword.root", "resetPassword.title", "resetPassword.logo", "resetPassword.passwordField", "resetPassword.submitButton", "verifyEmail.root", "verifyEmail.title", "verifyEmail.logo", "verifyEmail.resendButton", "authFlow.root", "authModal.overlay", "authModal.container", "signInButton.root", "signUpButton.root", "signOutButton.root", "stepUp.root", "stepUp.title", "stepUp.passwordField", "stepUp.submitButton", "stepUp.cancelButton", "signInPage.root", "signInPage.logo", "signInPage.footer", "signUpPage.root", "signUpPage.logo", "signUpPage.footer", "userButton.root", "userButton.trigger", "userButton.menu", "userButton.identity", "userButton.email", "userButton.badge", "userButton.item", "userButton.manageButton", "userButton.signOutButton", "userButton.signOutAllButton", "accountDashboard.root", "accountDashboard.tabs", "accountDashboard.sidebar", "accountDashboard.panel", "accountModal.overlay", "accountModal.container", "accountModal.header", "accountModal.title", "accountModal.body", "verifyBanner.root", "verifyBanner.message", "verifyBanner.resendButton", "verifyBanner.dismissButton", "profilePanel.root", "profilePanel.form", "profilePanel.submitButton", "addressesPanel.root", "addressesPanel.list", "addressesPanel.item", "addressesPanel.addButton", "addressesPanel.form", "addressesPanel.defaultButton", "addressesPanel.editButton", "addressesPanel.deleteButton", "addressesPanel.table", "addressesPanel.row", "paymentMethodsPanel.root", "paymentMethodsPanel.list", "paymentMethodsPanel.item", "paymentMethodsPanel.defaultButton", "paymentMethodsPanel.deleteButton", "paymentMethodsPanel.addButton", "paymentMethodsPanel.addDialog", "orderDetail.addresses", "orderDetail.shippingAddress", "orderDetail.billingAddress", "orderDetail.timeline", "orderDetail.payButton", "orderDetail.trackButton", "orderDetail.reorderButton", "orderDetail.layout", "orderDetail.main", "orderDetail.rail", "orderDetail.cancelButton", "orderDetail.returnButton", "orderDetail.invoiceButton", "orderDetail.actions", "invoiceDetail.layout", "invoiceDetail.main", "invoiceDetail.rail", "invoiceDetail.lineItems", "invoiceDetail.lineItem", "invoiceDetail.orderLink", "invoiceDetail.subscriptionLink", "invoiceDetail.payButton", "invoiceDetail.actions", "fieldRow", "confirm.header", "confirm.title", "confirm.body", "confirm.confirmButton", "confirm.cancelButton", "paymentMethodsPanel.table", "paymentMethodsPanel.row", "ordersPanel.root", "ordersPanel.table", "ordersPanel.row", "ordersPanel.list", "ordersPanel.item", "ordersPanel.viewButton", "orderDetail.root", "orderDetail.backButton", "orderDetail.lineItems", "orderDetail.lineItem", "orderDetail.totals", "invoicesPanel.root", "invoicesPanel.table", "invoicesPanel.row", "invoicesPanel.list", "invoicesPanel.item", "invoicesPanel.viewButton", "invoiceDetail.root", "invoiceDetail.backButton", "invoiceDetail.downloadButton", "invoiceDetail.totals", "subscriptionsPanel.root", "subscriptionsPanel.list", "subscriptionsPanel.item", "subscriptionsPanel.cancelButton", "subscriptionsPanel.cancelNowButton", "subscriptionsPanel.pauseButton", "subscriptionsPanel.resumeButton", "subscriptionsPanel.table", "subscriptionsPanel.row", "securityPanel.root", "securityPanel.passwordForm", "securityPanel.passwordButton", "securityPanel.sessionList", "securityPanel.sessionItem", "securityPanel.revokeButton", "securityPanel.revokeAllButton", "securityPanel.table", "securityPanel.row"];
47
+ declare const THROTTLE_ELEMENT_KEYS: readonly ["card", "card.header", "card.title", "card.description", "card.body", "card.footer", "card.logo", "field", "field.label", "field.input", "field.hint", "field.error", "field.group", "button", "alert", "spinner", "skeleton", "avatar", "badge", "emptyState", "emptyState.title", "emptyState.description", "modal.overlay", "modal.container", "modal.closeButton", "dropdown.trigger", "dropdown.menu", "dropdown.item", "dropdown.separator", "tabs.list", "tabs.tab", "table", "table.head", "table.row", "table.cell", "signIn.root", "signIn.title", "signIn.logo", "signIn.emailField", "signIn.passwordField", "signIn.submitButton", "signIn.forgotLink", "signIn.switchLink", "signUp.root", "signUp.title", "signUp.logo", "signUp.emailField", "signUp.passwordField", "signUp.submitButton", "signUp.switchLink", "forgotPassword.root", "forgotPassword.title", "forgotPassword.logo", "forgotPassword.emailField", "forgotPassword.submitButton", "forgotPassword.backLink", "resetPassword.root", "resetPassword.title", "resetPassword.logo", "resetPassword.passwordField", "resetPassword.submitButton", "verifyEmail.root", "verifyEmail.title", "verifyEmail.logo", "verifyEmail.resendButton", "authFlow.root", "authModal.overlay", "authModal.container", "signInButton.root", "signUpButton.root", "signOutButton.root", "stepUp.root", "stepUp.title", "stepUp.passwordField", "stepUp.submitButton", "stepUp.cancelButton", "signInPage.root", "signInPage.logo", "signInPage.footer", "signUpPage.root", "signUpPage.logo", "signUpPage.footer", "userButton.root", "userButton.trigger", "userButton.menu", "userButton.identity", "userButton.email", "userButton.badge", "userButton.item", "userButton.manageButton", "userButton.signOutButton", "userButton.signOutAllButton", "accountDashboard.root", "accountDashboard.tabs", "accountDashboard.sidebar", "accountDashboard.panel", "accountModal.overlay", "accountModal.container", "accountModal.header", "accountModal.title", "accountModal.body", "verifyBanner.root", "verifyBanner.message", "verifyBanner.resendButton", "verifyBanner.dismissButton", "profilePanel.root", "profilePanel.form", "profilePanel.submitButton", "addressesPanel.root", "addressesPanel.list", "addressesPanel.item", "addressesPanel.addButton", "addressesPanel.form", "addressesPanel.defaultButton", "addressesPanel.editButton", "addressesPanel.deleteButton", "addressesPanel.table", "addressesPanel.row", "paymentMethodsPanel.root", "paymentMethodsPanel.list", "paymentMethodsPanel.item", "paymentMethodsPanel.defaultButton", "paymentMethodsPanel.deleteButton", "paymentMethodsPanel.addButton", "paymentMethodsPanel.addDialog", "orderDetail.addresses", "orderDetail.shippingAddress", "orderDetail.billingAddress", "orderDetail.timeline", "orderDetail.payButton", "orderDetail.trackButton", "orderDetail.reorderButton", "orderDetail.layout", "orderDetail.main", "orderDetail.rail", "orderDetail.cancelButton", "orderDetail.returnButton", "orderDetail.invoiceButton", "orderDetail.subscriptionButton", "orderDetail.actions", "invoiceDetail.layout", "invoiceDetail.main", "invoiceDetail.rail", "invoiceDetail.lineItems", "invoiceDetail.lineItem", "invoiceDetail.orderLink", "invoiceDetail.subscriptionLink", "invoiceDetail.payButton", "invoiceDetail.actions", "fieldRow", "confirm.header", "confirm.title", "confirm.body", "confirm.confirmButton", "confirm.cancelButton", "paymentMethodsPanel.table", "paymentMethodsPanel.row", "ordersPanel.root", "ordersPanel.table", "ordersPanel.row", "ordersPanel.list", "ordersPanel.item", "ordersPanel.viewButton", "orderDetail.root", "orderDetail.backButton", "orderDetail.lineItems", "orderDetail.lineItem", "orderDetail.totals", "invoicesPanel.root", "invoicesPanel.table", "invoicesPanel.row", "invoicesPanel.list", "invoicesPanel.item", "invoicesPanel.viewButton", "invoiceDetail.root", "invoiceDetail.backButton", "invoiceDetail.downloadButton", "invoiceDetail.totals", "subscriptionsPanel.root", "subscriptionsPanel.list", "subscriptionsPanel.item", "subscriptionsPanel.cancelButton", "subscriptionsPanel.cancelNowButton", "subscriptionsPanel.pauseButton", "subscriptionsPanel.resumeButton", "subscriptionsPanel.table", "subscriptionsPanel.row", "securityPanel.root", "securityPanel.passwordForm", "securityPanel.passwordButton", "securityPanel.sessionList", "securityPanel.sessionItem", "securityPanel.revokeButton", "securityPanel.revokeAllButton", "securityPanel.table", "securityPanel.row"];
48
48
  type ThrottleElementKey = (typeof THROTTLE_ELEMENT_KEYS)[number];
49
49
  interface ThrottleSlots {
50
50
  Spinner?: ComponentType<{
@@ -283,6 +283,7 @@ declare const enUS: {
283
283
  shippingAddress: string;
284
284
  billingAddress: string;
285
285
  viewSubscription: string;
286
+ viewSubscriptionFor: string;
286
287
  };
287
288
  invoices: {
288
289
  empty: string;
@@ -323,6 +324,11 @@ declare const enUS: {
323
324
  cancelledOn: string;
324
325
  trialEnds: string;
325
326
  installmentProgress: string;
327
+ installmentTotal: string;
328
+ installmentNext: string;
329
+ /** Spec §5: a varied schedule's dated list; dates are estimates, hence "~". */
330
+ upcomingPayments: string;
331
+ upcomingPayment: string;
326
332
  cancelButton: string;
327
333
  cancelAtPeriodEnd: string;
328
334
  cancelNow: string;
@@ -44,7 +44,7 @@ type ThrottleVariables = Partial<Record<keyof typeof VARIABLE_PROPERTY, string>>
44
44
  * rendered element without adding its key here ships something a merchant
45
45
  * cannot restyle, which the drift test in Task 15 catches.
46
46
  */
47
- declare const THROTTLE_ELEMENT_KEYS: readonly ["card", "card.header", "card.title", "card.description", "card.body", "card.footer", "card.logo", "field", "field.label", "field.input", "field.hint", "field.error", "field.group", "button", "alert", "spinner", "skeleton", "avatar", "badge", "emptyState", "emptyState.title", "emptyState.description", "modal.overlay", "modal.container", "modal.closeButton", "dropdown.trigger", "dropdown.menu", "dropdown.item", "dropdown.separator", "tabs.list", "tabs.tab", "table", "table.head", "table.row", "table.cell", "signIn.root", "signIn.title", "signIn.logo", "signIn.emailField", "signIn.passwordField", "signIn.submitButton", "signIn.forgotLink", "signIn.switchLink", "signUp.root", "signUp.title", "signUp.logo", "signUp.emailField", "signUp.passwordField", "signUp.submitButton", "signUp.switchLink", "forgotPassword.root", "forgotPassword.title", "forgotPassword.logo", "forgotPassword.emailField", "forgotPassword.submitButton", "forgotPassword.backLink", "resetPassword.root", "resetPassword.title", "resetPassword.logo", "resetPassword.passwordField", "resetPassword.submitButton", "verifyEmail.root", "verifyEmail.title", "verifyEmail.logo", "verifyEmail.resendButton", "authFlow.root", "authModal.overlay", "authModal.container", "signInButton.root", "signUpButton.root", "signOutButton.root", "stepUp.root", "stepUp.title", "stepUp.passwordField", "stepUp.submitButton", "stepUp.cancelButton", "signInPage.root", "signInPage.logo", "signInPage.footer", "signUpPage.root", "signUpPage.logo", "signUpPage.footer", "userButton.root", "userButton.trigger", "userButton.menu", "userButton.identity", "userButton.email", "userButton.badge", "userButton.item", "userButton.manageButton", "userButton.signOutButton", "userButton.signOutAllButton", "accountDashboard.root", "accountDashboard.tabs", "accountDashboard.sidebar", "accountDashboard.panel", "accountModal.overlay", "accountModal.container", "accountModal.header", "accountModal.title", "accountModal.body", "verifyBanner.root", "verifyBanner.message", "verifyBanner.resendButton", "verifyBanner.dismissButton", "profilePanel.root", "profilePanel.form", "profilePanel.submitButton", "addressesPanel.root", "addressesPanel.list", "addressesPanel.item", "addressesPanel.addButton", "addressesPanel.form", "addressesPanel.defaultButton", "addressesPanel.editButton", "addressesPanel.deleteButton", "addressesPanel.table", "addressesPanel.row", "paymentMethodsPanel.root", "paymentMethodsPanel.list", "paymentMethodsPanel.item", "paymentMethodsPanel.defaultButton", "paymentMethodsPanel.deleteButton", "paymentMethodsPanel.addButton", "paymentMethodsPanel.addDialog", "orderDetail.addresses", "orderDetail.shippingAddress", "orderDetail.billingAddress", "orderDetail.timeline", "orderDetail.payButton", "orderDetail.trackButton", "orderDetail.reorderButton", "orderDetail.layout", "orderDetail.main", "orderDetail.rail", "orderDetail.cancelButton", "orderDetail.returnButton", "orderDetail.invoiceButton", "orderDetail.actions", "invoiceDetail.layout", "invoiceDetail.main", "invoiceDetail.rail", "invoiceDetail.lineItems", "invoiceDetail.lineItem", "invoiceDetail.orderLink", "invoiceDetail.subscriptionLink", "invoiceDetail.payButton", "invoiceDetail.actions", "fieldRow", "confirm.header", "confirm.title", "confirm.body", "confirm.confirmButton", "confirm.cancelButton", "paymentMethodsPanel.table", "paymentMethodsPanel.row", "ordersPanel.root", "ordersPanel.table", "ordersPanel.row", "ordersPanel.list", "ordersPanel.item", "ordersPanel.viewButton", "orderDetail.root", "orderDetail.backButton", "orderDetail.lineItems", "orderDetail.lineItem", "orderDetail.totals", "invoicesPanel.root", "invoicesPanel.table", "invoicesPanel.row", "invoicesPanel.list", "invoicesPanel.item", "invoicesPanel.viewButton", "invoiceDetail.root", "invoiceDetail.backButton", "invoiceDetail.downloadButton", "invoiceDetail.totals", "subscriptionsPanel.root", "subscriptionsPanel.list", "subscriptionsPanel.item", "subscriptionsPanel.cancelButton", "subscriptionsPanel.cancelNowButton", "subscriptionsPanel.pauseButton", "subscriptionsPanel.resumeButton", "subscriptionsPanel.table", "subscriptionsPanel.row", "securityPanel.root", "securityPanel.passwordForm", "securityPanel.passwordButton", "securityPanel.sessionList", "securityPanel.sessionItem", "securityPanel.revokeButton", "securityPanel.revokeAllButton", "securityPanel.table", "securityPanel.row"];
47
+ declare const THROTTLE_ELEMENT_KEYS: readonly ["card", "card.header", "card.title", "card.description", "card.body", "card.footer", "card.logo", "field", "field.label", "field.input", "field.hint", "field.error", "field.group", "button", "alert", "spinner", "skeleton", "avatar", "badge", "emptyState", "emptyState.title", "emptyState.description", "modal.overlay", "modal.container", "modal.closeButton", "dropdown.trigger", "dropdown.menu", "dropdown.item", "dropdown.separator", "tabs.list", "tabs.tab", "table", "table.head", "table.row", "table.cell", "signIn.root", "signIn.title", "signIn.logo", "signIn.emailField", "signIn.passwordField", "signIn.submitButton", "signIn.forgotLink", "signIn.switchLink", "signUp.root", "signUp.title", "signUp.logo", "signUp.emailField", "signUp.passwordField", "signUp.submitButton", "signUp.switchLink", "forgotPassword.root", "forgotPassword.title", "forgotPassword.logo", "forgotPassword.emailField", "forgotPassword.submitButton", "forgotPassword.backLink", "resetPassword.root", "resetPassword.title", "resetPassword.logo", "resetPassword.passwordField", "resetPassword.submitButton", "verifyEmail.root", "verifyEmail.title", "verifyEmail.logo", "verifyEmail.resendButton", "authFlow.root", "authModal.overlay", "authModal.container", "signInButton.root", "signUpButton.root", "signOutButton.root", "stepUp.root", "stepUp.title", "stepUp.passwordField", "stepUp.submitButton", "stepUp.cancelButton", "signInPage.root", "signInPage.logo", "signInPage.footer", "signUpPage.root", "signUpPage.logo", "signUpPage.footer", "userButton.root", "userButton.trigger", "userButton.menu", "userButton.identity", "userButton.email", "userButton.badge", "userButton.item", "userButton.manageButton", "userButton.signOutButton", "userButton.signOutAllButton", "accountDashboard.root", "accountDashboard.tabs", "accountDashboard.sidebar", "accountDashboard.panel", "accountModal.overlay", "accountModal.container", "accountModal.header", "accountModal.title", "accountModal.body", "verifyBanner.root", "verifyBanner.message", "verifyBanner.resendButton", "verifyBanner.dismissButton", "profilePanel.root", "profilePanel.form", "profilePanel.submitButton", "addressesPanel.root", "addressesPanel.list", "addressesPanel.item", "addressesPanel.addButton", "addressesPanel.form", "addressesPanel.defaultButton", "addressesPanel.editButton", "addressesPanel.deleteButton", "addressesPanel.table", "addressesPanel.row", "paymentMethodsPanel.root", "paymentMethodsPanel.list", "paymentMethodsPanel.item", "paymentMethodsPanel.defaultButton", "paymentMethodsPanel.deleteButton", "paymentMethodsPanel.addButton", "paymentMethodsPanel.addDialog", "orderDetail.addresses", "orderDetail.shippingAddress", "orderDetail.billingAddress", "orderDetail.timeline", "orderDetail.payButton", "orderDetail.trackButton", "orderDetail.reorderButton", "orderDetail.layout", "orderDetail.main", "orderDetail.rail", "orderDetail.cancelButton", "orderDetail.returnButton", "orderDetail.invoiceButton", "orderDetail.subscriptionButton", "orderDetail.actions", "invoiceDetail.layout", "invoiceDetail.main", "invoiceDetail.rail", "invoiceDetail.lineItems", "invoiceDetail.lineItem", "invoiceDetail.orderLink", "invoiceDetail.subscriptionLink", "invoiceDetail.payButton", "invoiceDetail.actions", "fieldRow", "confirm.header", "confirm.title", "confirm.body", "confirm.confirmButton", "confirm.cancelButton", "paymentMethodsPanel.table", "paymentMethodsPanel.row", "ordersPanel.root", "ordersPanel.table", "ordersPanel.row", "ordersPanel.list", "ordersPanel.item", "ordersPanel.viewButton", "orderDetail.root", "orderDetail.backButton", "orderDetail.lineItems", "orderDetail.lineItem", "orderDetail.totals", "invoicesPanel.root", "invoicesPanel.table", "invoicesPanel.row", "invoicesPanel.list", "invoicesPanel.item", "invoicesPanel.viewButton", "invoiceDetail.root", "invoiceDetail.backButton", "invoiceDetail.downloadButton", "invoiceDetail.totals", "subscriptionsPanel.root", "subscriptionsPanel.list", "subscriptionsPanel.item", "subscriptionsPanel.cancelButton", "subscriptionsPanel.cancelNowButton", "subscriptionsPanel.pauseButton", "subscriptionsPanel.resumeButton", "subscriptionsPanel.table", "subscriptionsPanel.row", "securityPanel.root", "securityPanel.passwordForm", "securityPanel.passwordButton", "securityPanel.sessionList", "securityPanel.sessionItem", "securityPanel.revokeButton", "securityPanel.revokeAllButton", "securityPanel.table", "securityPanel.row"];
48
48
  type ThrottleElementKey = (typeof THROTTLE_ELEMENT_KEYS)[number];
49
49
  interface ThrottleSlots {
50
50
  Spinner?: ComponentType<{
@@ -283,6 +283,7 @@ declare const enUS: {
283
283
  shippingAddress: string;
284
284
  billingAddress: string;
285
285
  viewSubscription: string;
286
+ viewSubscriptionFor: string;
286
287
  };
287
288
  invoices: {
288
289
  empty: string;
@@ -323,6 +324,11 @@ declare const enUS: {
323
324
  cancelledOn: string;
324
325
  trialEnds: string;
325
326
  installmentProgress: string;
327
+ installmentTotal: string;
328
+ installmentNext: string;
329
+ /** Spec §5: a varied schedule's dated list; dates are estimates, hence "~". */
330
+ upcomingPayments: string;
331
+ upcomingPayment: string;
326
332
  cancelButton: string;
327
333
  cancelAtPeriodEnd: string;
328
334
  cancelNow: string;
@@ -300,6 +300,7 @@ var THROTTLE_ELEMENT_KEYS = [
300
300
  "orderDetail.cancelButton",
301
301
  "orderDetail.returnButton",
302
302
  "orderDetail.invoiceButton",
303
+ "orderDetail.subscriptionButton",
303
304
  "orderDetail.actions",
304
305
  "invoiceDetail.layout",
305
306
  "invoiceDetail.main",
@@ -633,7 +634,8 @@ var enUS = {
633
634
  quantity: "Qty",
634
635
  shippingAddress: "Shipping address",
635
636
  billingAddress: "Billing address",
636
- viewSubscription: "View subscription"
637
+ viewSubscription: "View subscription",
638
+ viewSubscriptionFor: "View subscription for"
637
639
  },
638
640
  invoices: {
639
641
  empty: "No invoices yet",
@@ -672,6 +674,11 @@ var enUS = {
672
674
  cancelledOn: "Cancelled on",
673
675
  trialEnds: "Trial ends",
674
676
  installmentProgress: "Payment {paid} of {total}",
677
+ installmentTotal: "{amount} total",
678
+ installmentNext: "Next {amount} on {date}",
679
+ /** Spec §5: a varied schedule's dated list; dates are estimates, hence "~". */
680
+ upcomingPayments: "Upcoming payments",
681
+ upcomingPayment: "{amount} \xB7 ~{date}",
675
682
  cancelButton: "Cancel",
676
683
  cancelAtPeriodEnd: "Cancel at period end",
677
684
  cancelNow: "Cancel immediately",
@@ -3185,6 +3192,16 @@ function OrderTimeline(props) {
3185
3192
  ] });
3186
3193
  }
3187
3194
 
3195
+ // src/react/components/account/order-subscription-links.ts
3196
+ function orderSubscriptionLinks(order, labels) {
3197
+ const ids = order.subscriptionIds?.length ? order.subscriptionIds : order.subscriptionId ? [order.subscriptionId] : [];
3198
+ if (ids.length === 1) return [{ id: ids[0], label: labels.single }];
3199
+ return ids.map((id, index) => {
3200
+ const name = order.lineItems.find((li) => li.subscriptionId === id)?.name;
3201
+ return { id, label: name ? `${labels.named} ${name}` : `${labels.single} ${index + 1}` };
3202
+ });
3203
+ }
3204
+
3188
3205
  // src/react/components/account/OrderDetail.tsx
3189
3206
  import { jsx as jsx38, jsxs as jsxs28 } from "react/jsx-runtime";
3190
3207
  var CAN_PAY = /* @__PURE__ */ new Set(["draft", "pending"]);
@@ -3345,14 +3362,19 @@ function OrderDetail(props) {
3345
3362
  children: t.orders.reorder
3346
3363
  }
3347
3364
  ) : null,
3348
- order.subscriptionId && props.onViewSubscription ? /* @__PURE__ */ jsx38(
3365
+ props.onViewSubscription ? orderSubscriptionLinks(order, {
3366
+ single: t.orders.viewSubscription,
3367
+ named: t.orders.viewSubscriptionFor
3368
+ }).map((link) => /* @__PURE__ */ jsx38(
3349
3369
  Button,
3350
3370
  {
3351
3371
  variant: "secondary",
3352
- onClick: () => props.onViewSubscription(order.subscriptionId),
3353
- children: t.orders.viewSubscription
3354
- }
3355
- ) : null,
3372
+ elementKey: "orderDetail.subscriptionButton",
3373
+ onClick: () => props.onViewSubscription(link.id),
3374
+ children: link.label
3375
+ },
3376
+ link.id
3377
+ )) : null,
3356
3378
  showReturn ? /* @__PURE__ */ jsx38(
3357
3379
  Button,
3358
3380
  {
@@ -3720,6 +3742,18 @@ function isIntervalUnit(value) {
3720
3742
  return typeof value === "string" && INTERVAL_UNITS.includes(value);
3721
3743
  }
3722
3744
 
3745
+ // ../core-cadence/src/schedule.ts
3746
+ function isVariedSchedule(rows) {
3747
+ if (!rows || rows.length === 0) return false;
3748
+ return rows.some(
3749
+ (r, i) => r.discount !== 0 || r.amount !== rows[0].amount || i > 1 && (r.intervalUnit !== rows[1].intervalUnit || r.intervalCount !== rows[1].intervalCount)
3750
+ );
3751
+ }
3752
+ function upcomingSchedulePayments(rows) {
3753
+ if (!rows || !isVariedSchedule(rows)) return [];
3754
+ return rows.filter((r) => r.status !== "paid" && r.dueAt != null);
3755
+ }
3756
+
3723
3757
  // ../core-cadence/src/labels.ts
3724
3758
  var NAMED_NOUN = {
3725
3759
  weekly: "week",
@@ -3735,6 +3769,10 @@ function cadenceNoun(cadence) {
3735
3769
  }
3736
3770
  return cadence.interval;
3737
3771
  }
3772
+ function scheduleDeal(sub) {
3773
+ if (!sub.paymentSchedule || sub.scheduleTotal == null || !isVariedSchedule(sub.paymentSchedule)) return null;
3774
+ return { total: sub.scheduleTotal, payments: sub.paymentSchedule.length };
3775
+ }
3738
3776
 
3739
3777
  // src/react/components/account/SubscriptionsPanel.tsx
3740
3778
  import { Fragment as Fragment8, jsx as jsx42, jsxs as jsxs32 } from "react/jsx-runtime";
@@ -3761,7 +3799,20 @@ function SubscriptionsPanel(props) {
3761
3799
  await run(fn);
3762
3800
  })();
3763
3801
  };
3764
- const priceLabel = (sub) => `${formatMoney(sub.amount, sub.currency, locale)} / ${cadenceNoun(sub)}${sub.quantity > 1 ? ` \xD7 ${sub.quantity}` : ""}`;
3802
+ const priceLabel = (sub) => {
3803
+ const deal = scheduleDeal(sub);
3804
+ return deal ? t.subscriptions.installmentTotal.replace("{amount}", formatMoney(deal.total, sub.currency, locale)) : `${formatMoney(sub.amount, sub.currency, locale)} / ${cadenceNoun(sub)}${sub.quantity > 1 ? ` \xD7 ${sub.quantity}` : ""}`;
3805
+ };
3806
+ const nextPaymentLabel = (sub) => {
3807
+ if (!isVariedSchedule(sub.paymentSchedule) || !sub.paymentSchedule || sub.nextPaymentAmount == null) return null;
3808
+ const upcoming = sub.paymentSchedule.find((r) => r.status !== "paid");
3809
+ return t.subscriptions.installmentNext.replace("{amount}", formatMoney(sub.nextPaymentAmount, sub.currency, locale)).replace("{date}", formatDate(upcoming?.dueAt ?? sub.currentPeriodEnd, locale));
3810
+ };
3811
+ const upcomingList = (sub) => {
3812
+ const upcoming = upcomingSchedulePayments(sub.paymentSchedule);
3813
+ if (upcoming.length === 0) return null;
3814
+ return /* @__PURE__ */ jsx42("ul", { className: "throttle-muted", "aria-label": t.subscriptions.upcomingPayments, children: upcoming.map((r) => /* @__PURE__ */ jsx42("li", { children: t.subscriptions.upcomingPayment.replace("{amount}", formatMoney(r.net, sub.currency, locale)).replace("{date}", formatDate(r.dueAt, locale)) }, r.dueAt)) });
3815
+ };
3765
3816
  const renewsLabel = (sub) => formatDate(
3766
3817
  sub.status === "completed" ? sub.completedAt ?? sub.currentPeriodEnd : sub.status === "cancelled" ? sub.cancelledAt ?? sub.currentPeriodEnd : sub.currentPeriodEnd,
3767
3818
  locale
@@ -3843,7 +3894,9 @@ function SubscriptionsPanel(props) {
3843
3894
  columns: [
3844
3895
  { key: "plan", label: t.subscriptions.columnPlan, render: (sub) => /* @__PURE__ */ jsxs32(Fragment8, { children: [
3845
3896
  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
3897
+ 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,
3898
+ nextPaymentLabel(sub) ? /* @__PURE__ */ jsx42("div", { className: "throttle-muted", children: nextPaymentLabel(sub) }) : null,
3899
+ upcomingList(sub)
3847
3900
  ] }) },
3848
3901
  { key: "price", label: t.subscriptions.columnPrice, render: (sub) => /* @__PURE__ */ jsx42("span", { className: "throttle-table__money", children: priceLabel(sub) }) },
3849
3902
  { key: "renews", label: t.subscriptions.columnRenews, render: (sub) => renewsLabel(sub) },
@@ -3861,12 +3914,9 @@ function SubscriptionsPanel(props) {
3861
3914
  /* @__PURE__ */ jsx42(StatusBadge, { status: sub.status, labels: t.subscriptions.statusLabels })
3862
3915
  ] }),
3863
3916
  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,
3864
- /* @__PURE__ */ jsxs32("p", { className: "throttle-muted", children: [
3865
- formatMoney(sub.amount, sub.currency, locale),
3866
- " / ",
3867
- cadenceNoun(sub),
3868
- sub.quantity > 1 ? ` \xD7 ${sub.quantity}` : ""
3869
- ] }),
3917
+ nextPaymentLabel(sub) ? /* @__PURE__ */ jsx42("div", { className: "throttle-muted", children: nextPaymentLabel(sub) }) : null,
3918
+ upcomingList(sub),
3919
+ /* @__PURE__ */ jsx42("p", { className: "throttle-muted", children: priceLabel(sub) }),
3870
3920
  sub.status === "completed" ? /* @__PURE__ */ jsxs32("p", { className: "throttle-muted", children: [
3871
3921
  t.subscriptions.statusLabels.completed,
3872
3922
  " ",