@usethrottle/auth 0.11.0 → 0.12.1
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.
- package/README.md +52 -0
- package/dist/AccountDashboard-V63ghvjY.d.ts +90 -0
- package/dist/AccountModal-KA54WUFW.js +13 -0
- package/dist/AccountModal-KA54WUFW.js.map +1 -0
- package/dist/AccountModal-pIMgledL.d.ts +141 -0
- package/dist/AuthModal-T2GYI6ZF.js +13 -0
- package/dist/AuthModal-T2GYI6ZF.js.map +1 -0
- package/dist/SignUpPage-BJcMUb2V.d.ts +160 -0
- package/dist/chunk-3B4DNX5T.js +2 -0
- package/dist/chunk-3B4DNX5T.js.map +1 -0
- package/dist/chunk-5EUZYJJL.js +29 -0
- package/dist/chunk-5EUZYJJL.js.map +1 -0
- package/dist/chunk-6WN3J5MM.js +2075 -0
- package/dist/chunk-6WN3J5MM.js.map +1 -0
- package/dist/chunk-CUNMJ2PH.js +1320 -0
- package/dist/chunk-CUNMJ2PH.js.map +1 -0
- package/dist/chunk-ETYOOYYV.js +2 -0
- package/dist/chunk-ETYOOYYV.js.map +1 -0
- package/dist/chunk-JSDZMPCV.js +520 -0
- package/dist/chunk-JSDZMPCV.js.map +1 -0
- package/dist/chunk-QPVS6JXP.js +39 -0
- package/dist/chunk-QPVS6JXP.js.map +1 -0
- package/dist/chunk-RCNUWITB.js +747 -0
- package/dist/chunk-RCNUWITB.js.map +1 -0
- package/dist/{chunk-YY6YATXT.js → chunk-TDQC3LMQ.js} +17 -3
- package/dist/chunk-TDQC3LMQ.js.map +1 -0
- package/dist/{chunk-EFMKBOTL.js → chunk-UFGW76AZ.js} +2 -2
- package/dist/chunk-VDK23T6L.js +230 -0
- package/dist/chunk-VDK23T6L.js.map +1 -0
- package/dist/chunk-X6D35EAX.js +19 -0
- package/dist/chunk-X6D35EAX.js.map +1 -0
- package/dist/client-7LVKfuXO.d.ts +319 -0
- package/dist/hooks-DkpLrEiC.d.ts +148 -0
- package/dist/index.cjs +16 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -3
- package/dist/index.d.ts +34 -3
- package/dist/index.js +16 -2
- package/dist/index.js.map +1 -1
- package/dist/localization-SnIAZXJn.d.ts +389 -0
- package/dist/react/components/account/index.d.ts +37 -0
- package/dist/react/components/account/index.js +44 -0
- package/dist/react/components/account/index.js.map +1 -0
- package/dist/react/components/auth/index.d.ts +17 -0
- package/dist/react/components/auth/index.js +40 -0
- package/dist/react/components/auth/index.js.map +1 -0
- package/dist/react/components/guards.d.ts +21 -0
- package/dist/react/components/guards.js +13 -0
- package/dist/react/components/guards.js.map +1 -0
- package/dist/react/components/index.cjs +3561 -2805
- package/dist/react/components/index.cjs.map +1 -1
- package/dist/react/components/index.d.cts +14 -2
- package/dist/react/components/index.d.ts +14 -821
- package/dist/react/components/index.js +90 -4680
- package/dist/react/components/index.js.map +1 -1
- package/dist/react/components/provider.d.ts +79 -0
- package/dist/react/components/provider.js +18 -0
- package/dist/react/components/provider.js.map +1 -0
- package/dist/react/forms/index.js +1 -1
- package/dist/react/index.cjs +16 -2
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +34 -3
- package/dist/react/index.d.ts +5 -433
- package/dist/react/index.js +3 -2
- package/dist/styles.css +7 -4
- package/package.json +4 -1
- package/dist/chunk-YY6YATXT.js.map +0 -1
- /package/dist/{chunk-EFMKBOTL.js.map → chunk-UFGW76AZ.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react/components/account/AccountModal.tsx","../src/react/components/account/AccountDashboard.tsx","../src/react/components/account/VerifyEmailBanner.tsx","../src/react/components/account/icons.tsx","../src/react/components/account/ProfilePanel.tsx","../src/react/components/account/PanelState.tsx","../src/react/components/account/AddressesPanel.tsx","../src/react/components/account/AddressForm.tsx","../src/react/components/account/PaymentMethodsPanel.tsx","../src/react/components/account/AddCardDialog.tsx","../src/react/components/account/OrdersPanel.tsx","../src/react/components/format.ts","../src/react/components/account/OrderStatus.tsx","../src/react/components/account/AddressBlock.tsx","../src/react/components/account/OrderTimeline.tsx","../src/react/components/account/order-subscription-links.ts","../src/react/components/account/OrderDetail.tsx","../src/react/components/account/InvoicesPanel.tsx","../src/react/components/account/InvoiceDetail.tsx","../src/react/components/account/SubscriptionsPanel.tsx","../../core-cadence/src/cadence.ts","../../core-cadence/src/schedule.ts","../../core-cadence/src/labels.ts","../src/react/components/account/SecurityPanel.tsx","../src/react/components/account/device.ts"],"sourcesContent":["import { useId } from 'react';\nimport { AppearanceProvider, useAppearance, useAppearanceProviderValue, type ThrottleAppearance } from '../appearance';\nimport { useCopy, type ThrottleLocalization } from '../localization';\nimport { Modal } from '../primitives';\nimport { AccountDashboard, type AccountTab } from './AccountDashboard';\n\nexport interface AccountModalProps {\n open: boolean;\n onClose(): void;\n tabs?: AccountTab[];\n appearance?: ThrottleAppearance;\n localization?: ThrottleLocalization;\n /** Where focus returns on close. See `Modal`'s own doc for why a caller\n * sometimes has to name this rather than let the modal capture it. */\n restoreFocusTo?: Element | null;\n}\n\n/**\n * The account dashboard, reachable without going through `UserButton`'s\n * menu — a merchant can wire this to a \"Settings\" control anywhere. Mirrors\n * `AuthModal`'s shape (a `Modal` hosting the existing card/dashboard), so a\n * merchant who wants to own the open/close state themselves has the same\n * kind of component available for the account surface that they already\n * have for sign-in.\n */\nexport function AccountModal(props: AccountModalProps) {\n const a = useAppearance(props.appearance);\n const scoped = useAppearanceProviderValue(props.appearance);\n const { t } = useCopy(props.localization);\n const titleId = useId();\n\n return (\n <AppearanceProvider value={scoped}>\n <Modal\n open={props.open}\n onClose={props.onClose}\n labelledBy={titleId}\n restoreFocusTo={props.restoreFocusTo}\n overlayKey=\"accountModal.overlay\"\n containerKey=\"accountModal.container\"\n >\n <div {...a.el('accountModal.header', 'throttle-modal__header')}>\n <h2 id={titleId} {...a.el('accountModal.title', 'throttle-modal__title')}>{t.account.title}</h2>\n </div>\n <div {...a.el('accountModal.body', 'throttle-modal__body')}>\n <AccountDashboard tabs={props.tabs} appearance={props.appearance} localization={props.localization} />\n </div>\n </Modal>\n </AppearanceProvider>\n );\n}\n","import { useEffect, useId, useState } from 'react';\nimport { useAuth } from '../../context';\nimport { AppearanceProvider, useAppearance, useAppearanceProviderValue, type ThrottleAppearance } from '../appearance';\nimport { useCopy, type ThrottleLocalization } from '../localization';\nimport { Tabs } from '../primitives';\nimport { VerifyEmailBanner } from './VerifyEmailBanner';\nimport { ACCOUNT_ICONS } from './icons';\nimport { ProfilePanel } from './ProfilePanel';\nimport { AddressesPanel } from './AddressesPanel';\nimport { PaymentMethodsPanel } from './PaymentMethodsPanel';\nimport { OrdersPanel, type OrderActionHandlers } from './OrdersPanel';\nimport { InvoicesPanel } from './InvoicesPanel';\nimport { SubscriptionsPanel } from './SubscriptionsPanel';\nimport { SecurityPanel } from './SecurityPanel';\nimport type { AccountPanelVariant } from './AddressesPanel';\n\nexport type AccountTab =\n | 'profile' | 'addresses' | 'paymentMethods' | 'orders' | 'invoices' | 'subscriptions' | 'security';\n\nexport const ACCOUNT_TABS: readonly AccountTab[] = [\n 'profile', 'addresses', 'paymentMethods', 'orders', 'invoices', 'subscriptions', 'security',\n];\n\nconst HASH_FOR: Record<AccountTab, string> = {\n profile: '#/profile', addresses: '#/addresses', paymentMethods: '#/payment-methods',\n orders: '#/orders', invoices: '#/invoices', subscriptions: '#/subscriptions', security: '#/security',\n};\nconst TAB_FOR_HASH: Record<string, AccountTab> = Object.fromEntries(\n Object.entries(HASH_FOR).map(([tab, hash]) => [hash, tab as AccountTab]),\n) as Record<string, AccountTab>;\n\nexport interface AccountDashboardProps extends OrderActionHandlers {\n /** Which panels to show, in order. Defaults to all seven. */\n tabs?: AccountTab[];\n tab?: AccountTab;\n onTabChange?(tab: AccountTab): void;\n routing?: 'virtual' | 'hash';\n /**\n * `'sidebar'` (default) puts the seven panels in a vertical rail beside the\n * content; `'tabs'` is the original horizontal strip above it. Seven is a lot\n * for a strip — at narrow widths most of them sit off-screen behind a scroll\n * with nothing signalling they exist — so the rail is the default. The strip\n * remains for merchants whose surrounding page already has a side nav and\n * would end up with two.\n */\n layout?: 'sidebar' | 'tabs';\n /**\n * Default composition for every panel rendered here. A panel's own\n * `variant` prop cannot be set through the dashboard (it does not expose\n * per-tab overrides), so in practice this is the only source of `variant`\n * each panel receives when rendered through `AccountDashboard` — a panel\n * rendered directly, outside the dashboard, keeps deciding its own default\n * from its own `variant` prop rather than this one.\n */\n panelVariant?: AccountPanelVariant;\n /** Also offer \"Order again\" on orders whose payment is captured or paid. Default false. */\n reorderOnPaid?: boolean;\n appearance?: ThrottleAppearance;\n localization?: ThrottleLocalization;\n}\n\nexport function AccountDashboard(props: AccountDashboardProps) {\n const a = useAppearance(props.appearance);\n const scoped = useAppearanceProviderValue(props.appearance);\n const { t } = useCopy(props.localization);\n const { status } = useAuth();\n const shown = props.tabs ?? [...ACCOUNT_TABS];\n const controlled = props.tab !== undefined;\n const [internal, setInternal] = useState<AccountTab>(shown[0] ?? 'profile');\n // Cross-panel navigation. An invoice links to the order it billed, and the\n // panels each own their own open-record state, so the dashboard carries the\n // id across the tab switch. Without this the links resolved server-side but\n // had nowhere to go, and rendered as nothing at all.\n const [openOrderId, setOpenOrderId] = useState<string | null>(null);\n // Above the signed-out early return: every hook must run on every render.\n const idBase = useId();\n\n useEffect(() => {\n if (props.routing !== 'hash' || typeof window === 'undefined') return;\n const apply = () => {\n // An empty/unrecognized hash (e.g. the browser Back button returning\n // to the pre-navigation URL) falls back to the first shown tab rather\n // than being ignored — otherwise \"Back\" is a dead button once the\n // hash empties out.\n const next = TAB_FOR_HASH[window.location.hash] ?? shown[0];\n // A hash naming a hidden tab is ignored rather than rendering a panel\n // with no tab to go back to.\n if (!next || !shown.includes(next)) return;\n if (controlled) props.onTabChange?.(next);\n else setInternal(next);\n };\n apply();\n window.addEventListener('hashchange', apply);\n return () => window.removeEventListener('hashchange', apply);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [props.routing, controlled, shown.join(',')]);\n\n // Signed out there is nothing to show; an empty tab shell would be worse\n // than nothing. Pair with <SignedIn> or <Protect> for a fallback.\n if (status !== 'authenticated') return null;\n\n const active = controlled ? props.tab! : internal;\n\n const go = (next: AccountTab) => {\n props.onTabChange?.(next);\n if (!controlled) setInternal(next);\n if (props.routing === 'hash' && typeof window !== 'undefined') window.location.hash = HASH_FOR[next];\n };\n\n const shared = { appearance: props.appearance, localization: props.localization };\n const sidebar = (props.layout ?? 'sidebar') === 'sidebar';\n\n const nav = (\n <Tabs\n idBase={idBase}\n orientation={sidebar ? 'vertical' : 'horizontal'}\n active={active}\n onChange={(id) => go(id as AccountTab)}\n tabs={shown.map((id) => ({\n id,\n label: t.account.tabs[id],\n // Icons ride the rail only. In the horizontal strip they cost\n // horizontal room, which is the scarce axis there.\n icon: sidebar ? ACCOUNT_ICONS[id] : undefined,\n }))}\n />\n );\n\n const panel = (\n <div\n {...a.el('accountDashboard.panel', sidebar ? 'throttle-account__content' : 'throttle-tabs__panel')}\n role=\"tabpanel\"\n id={`${idBase}-panel-${active}`}\n aria-labelledby={`${idBase}-tab-${active}`}\n tabIndex={0}\n >\n {active === 'profile' ? <ProfilePanel {...shared} /> : null}\n {active === 'addresses' ? <AddressesPanel {...shared} variant={props.panelVariant} /> : null}\n {active === 'paymentMethods' ? <PaymentMethodsPanel {...shared} variant={props.panelVariant} /> : null}\n {active === 'orders' ? (\n <OrdersPanel {...shared} variant={props.panelVariant} initialOpenId={openOrderId}\n onViewSubscription={() => go('subscriptions')}\n onPayNow={props.onPayNow} onReorder={props.onReorder}\n onTrackShipment={props.onTrackShipment}\n reorderOnPaid={props.reorderOnPaid} />\n ) : null}\n {active === 'invoices' ? (\n <InvoicesPanel\n {...shared}\n variant={props.panelVariant}\n onViewOrder={(orderId) => { setOpenOrderId(orderId); go('orders'); }}\n onViewSubscription={() => go('subscriptions')}\n />\n ) : null}\n {active === 'subscriptions' ? <SubscriptionsPanel {...shared} variant={props.panelVariant} /> : null}\n {active === 'security' ? <SecurityPanel {...shared} variant={props.panelVariant} /> : null}\n </div>\n );\n\n return (\n <AppearanceProvider value={scoped}>\n <div {...a.rootProps}>\n <div {...a.el('accountDashboard.root', 'throttle-panel throttle-account-root')}>\n <VerifyEmailBanner {...shared} />\n {sidebar ? (\n <div className=\"throttle-account\">\n <div {...a.el('accountDashboard.sidebar')}>{nav}</div>\n {panel}\n </div>\n ) : (\n <>\n <div {...a.el('accountDashboard.tabs')}>{nav}</div>\n {panel}\n </>\n )}\n </div>\n </div>\n </AppearanceProvider>\n );\n}\n","import { useState } from 'react';\nimport { useAuth } from '../../context';\nimport { AppearanceProvider, useAppearance, useAppearanceProviderValue, type ThrottleAppearance } from '../appearance';\nimport { useCopy, type ThrottleLocalization } from '../localization';\nimport { useAction } from '../useAction';\nimport { Alert, Button } from '../primitives';\n\nconst DISMISS_KEY = 'throttle-auth:verify-banner-dismissed';\n\n/** Every read and write is guarded: a private window or blocked site data\n * makes the accessor itself throw, and a banner must not take the page down. */\nfunction readDismissed(): boolean {\n try { return sessionStorage.getItem(DISMISS_KEY) === '1'; } catch { return false; }\n}\nfunction writeDismissed(): void {\n try { sessionStorage.setItem(DISMISS_KEY, '1'); } catch { /* not worth reporting */ }\n}\n\nexport function VerifyEmailBanner(props: { appearance?: ThrottleAppearance; localization?: ThrottleLocalization }) {\n const a = useAppearance(props.appearance);\n const scoped = useAppearanceProviderValue(props.appearance);\n const { t } = useCopy(props.localization);\n const { auth, status, emailVerified } = useAuth();\n const { submitting, notice, error, run } = useAction();\n const [dismissed, setDismissed] = useState(readDismissed);\n\n if (status !== 'authenticated' || emailVerified || dismissed) return null;\n\n return (\n <AppearanceProvider value={scoped}>\n <div {...a.rootProps}>\n <div {...a.el('verifyBanner.root', 'throttle-banner')}>\n <span {...a.el('verifyBanner.message')}>{t.verifyBanner.message}</span>\n {notice ? <Alert tone=\"success\">{notice}</Alert> : null}\n {error ? <Alert tone=\"error\">{error}</Alert> : null}\n <span className=\"throttle-actions\">\n <Button\n variant=\"secondary\"\n loading={submitting}\n elementKey=\"verifyBanner.resendButton\"\n onClick={() => void run(async () => {\n await auth.resendVerification();\n return t.verifyEmail.resentNotice;\n })}\n >\n {t.verifyBanner.resendButton}\n </Button>\n <Button\n variant=\"link\"\n elementKey=\"verifyBanner.dismissButton\"\n onClick={() => { writeDismissed(); setDismissed(true); }}\n >\n {t.verifyBanner.dismissButton}\n </Button>\n </span>\n </div>\n </div>\n </AppearanceProvider>\n );\n}\n","import type { ReactNode } from 'react';\nimport type { AccountTab } from './AccountDashboard';\n\n/**\n * One 18px stroked glyph per account tab, drawn inline.\n *\n * Inline rather than an icon dependency because this package ships with no\n * runtime dependencies at all, and stroked rather than filled so a single\n * `currentColor` follows the merchant's own text colour in both themes.\n * `aria-hidden` on every one: the tab's own text is the accessible name, and\n * a second announcement of \"person icon, Profile\" is noise.\n */\nfunction Glyph(props: { children: ReactNode }) {\n return (\n <svg\n className=\"throttle-tabs__railicon\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.6\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n {props.children}\n </svg>\n );\n}\n\nexport const ACCOUNT_ICONS: Record<AccountTab, ReactNode> = {\n profile: (\n <Glyph><circle cx=\"12\" cy=\"8\" r=\"4\" /><path d=\"M4 21c0-4 3.6-6 8-6s8 2 8 6\" /></Glyph>\n ),\n addresses: (\n <Glyph><path d=\"M12 21s7-5.3 7-11a7 7 0 1 0-14 0c0 5.7 7 11 7 11Z\" /><circle cx=\"12\" cy=\"10\" r=\"2.5\" /></Glyph>\n ),\n paymentMethods: (\n <Glyph><rect x=\"2.5\" y=\"5.5\" width=\"19\" height=\"13\" rx=\"2.5\" /><path d=\"M2.5 10h19\" /></Glyph>\n ),\n orders: (\n <Glyph><path d=\"M4 7h16v13H4z\" /><path d=\"M8 7V4h8v3\" /><path d=\"M8 12h8\" /></Glyph>\n ),\n invoices: (\n <Glyph><path d=\"M6 3h12v18l-3-2-3 2-3-2-3 2Z\" /><path d=\"M9 8h6M9 12h6\" /></Glyph>\n ),\n subscriptions: (\n <Glyph><path d=\"M3 12a9 9 0 0 1 15.5-6.2\" /><path d=\"M21 12a9 9 0 0 1-15.5 6.2\" /><path d=\"M18 3v4h-4M6 21v-4h4\" /></Glyph>\n ),\n security: (\n <Glyph><path d=\"M12 3 4 6.5V12c0 5 3.4 8.3 8 9 4.6-.7 8-4 8-9V6.5Z\" /><path d=\"m9 12 2 2 4-4\" /></Glyph>\n ),\n};\n","import { useEffect, useState, useRef } from 'react';\nimport { useAuth } from '../../context';\nimport { useCustomer } from '../../hooks';\nimport { AppearanceProvider, useAppearance, useAppearanceProviderValue, type ThrottleAppearance } from '../appearance';\nimport { useCopy, type ThrottleLocalization } from '../localization';\nimport { useAction } from '../useAction';\nimport { Alert, Button, Field, FieldRow } from '../primitives';\nimport { PanelState } from './PanelState';\n\nexport function ProfilePanel(props: { appearance?: ThrottleAppearance; localization?: ThrottleLocalization }) {\n const a = useAppearance(props.appearance);\n const scoped = useAppearanceProviderValue(props.appearance);\n const { t } = useCopy(props.localization);\n const { status } = useAuth();\n const resource = useCustomer();\n const { submitting, error, notice, run } = useAction();\n\n // No acceptsMarketing here on purpose: the opt-in is not part of this form,\n // and holding a default for it is how a save silently rewrites a preference\n // the buyer set somewhere else.\n const [form, setForm] = useState({ firstName: '', lastName: '', phone: '', company: '' });\n\n // True once the buyer has touched any field, cleared again after a save.\n // Without it, ANY refetch landing mid-edit silently wiped what they had\n // typed — the effect below resets from `resource.data`, and a refetch fires\n // whenever `status`/`emailVerified` change or `update()` completes. Rare in\n // a single tab, certain if verification finishes in another one. It also\n // made the ProfilePanel test flaky: the reset occasionally landed between\n // the keystroke and the submit, so the patch carried '' instead of 'Ada'.\n const edited = useRef(false);\n\n // Reset the form whenever a new profile lands, including after a save — but\n // never on top of edits in progress.\n useEffect(() => {\n const c = resource.data;\n if (!c || edited.current) return;\n setForm({\n firstName: c.firstName ?? '', lastName: c.lastName ?? '',\n phone: c.phone ?? '', company: c.company ?? '',\n });\n }, [resource.data]);\n\n // Mounted standalone (outside <SignedIn>), a signed-out visitor makes\n // useCustomer() resolve to (data: null, error: null) with no network call\n // ever made — a null profile is only genuinely unexpected for a signed-in\n // buyer. Render nothing rather than \"Something went wrong.\" once we know\n // for certain there's no one signed in (not during the initial 'loading'\n // status, which still deserves its skeleton), matching how UserButton\n // already handles being mounted while signed out.\n if (status === 'unauthenticated') return null;\n\n return (\n <AppearanceProvider value={scoped}>\n <div {...a.rootProps}>\n <div {...a.el('profilePanel.root', 'throttle-panel')}>\n <PanelState\n resource={resource}\n isEmpty={(c) => c === null}\n emptyTitle={t.common.somethingWentWrong}\n skeletonRows={4}\n >\n {(customer) => (\n <form\n {...a.el('profilePanel.form', 'throttle-stack')}\n onSubmit={(e) => {\n e.preventDefault();\n void run(async () => {\n // Explicit patch. `email` is not in it — the buyer plane has no\n // email-change route, and sending an unknown field would be\n // rejected rather than silently ignored.\n edited.current = false;\n await resource.update({\n firstName: form.firstName,\n lastName: form.lastName,\n phone: form.phone,\n company: form.company || null,\n });\n return t.profile.savedNotice;\n });\n }}\n >\n <Field label={t.profile.email} type=\"email\" value={customer!.email} onChange={() => {}}\n disabled hint={t.profile.emailReadOnly} />\n <FieldRow>\n <Field label={t.profile.firstName} value={form.firstName} autoComplete=\"given-name\"\n onChange={(v) => { edited.current = true; setForm((f) => ({ ...f, firstName: v })); }} />\n <Field label={t.profile.lastName} value={form.lastName} autoComplete=\"family-name\"\n onChange={(v) => { edited.current = true; setForm((f) => ({ ...f, lastName: v })); }} />\n </FieldRow>\n <FieldRow>\n <Field label={t.profile.phone} type=\"tel\" value={form.phone} autoComplete=\"tel\"\n onChange={(v) => { edited.current = true; setForm((f) => ({ ...f, phone: v })); }} />\n <Field label={t.profile.company} value={form.company} autoComplete=\"organization\"\n onChange={(v) => { edited.current = true; setForm((f) => ({ ...f, company: v })); }} />\n </FieldRow>\n {error ? <Alert tone=\"error\">{error}</Alert> : null}\n {notice ? <Alert tone=\"success\">{notice}</Alert> : null}\n <Button type=\"submit\" loading={submitting} elementKey=\"profilePanel.submitButton\">\n {t.profile.saveButton}\n </Button>\n </form>\n )}\n </PanelState>\n </div>\n </div>\n </AppearanceProvider>\n );\n}\n","import type { ReactNode } from 'react';\nimport type { Resource } from '../../hooks';\nimport { useCopy } from '../localization';\nimport { Alert, Button, EmptyState, Skeleton } from '../primitives';\n\nexport interface PanelStateProps<T> {\n resource: Resource<T>;\n /**\n * True when the buyer is unverified AND this resource is behind the claim\n * cutoff. An empty list then means \"withheld\", not \"none\" — see spec §10.\n */\n gated?: boolean;\n gatedDescription?: string;\n isEmpty(data: T): boolean;\n emptyTitle: string;\n emptyDescription?: string;\n skeletonRows?: number;\n children(data: T): ReactNode;\n}\n\nexport function PanelState<T>(props: PanelStateProps<T>) {\n const { t, errorMessage } = useCopy();\n const { data, isLoading, error, refetch } = props.resource;\n const empty = props.isEmpty(data);\n\n // Only skeleton the FIRST load. A refetch that blanked the panel would make\n // every save flash the whole list away and back.\n if (isLoading && empty) return <Skeleton count={props.skeletonRows ?? 3} />;\n\n const errorBanner = error ? (\n <div className=\"throttle-stack\">\n <Alert tone=\"error\">{errorMessage(error)}</Alert>\n <Button variant=\"secondary\" onClick={() => void refetch()}>{t.common.retry}</Button>\n </div>\n ) : null;\n\n // A verification error is not a failure — it is the gate. Routes differ in\n // how they express it: /me/orders is `buyerAuth: 'session'` so an unverified\n // buyer gets an empty 200, while /me/payment-methods is 'session+verified'\n // and returns 403. Same cause, two signals. Without this, one panel tells the\n // buyer to verify their email and its sibling shows a red alert with a Retry\n // button that cannot possibly succeed.\n const gatedByVerification = (error as { code?: string } | null)?.code === 'verification_required';\n if (gatedByVerification && empty) {\n return <EmptyState title={props.emptyTitle} description={props.gatedDescription ?? props.emptyDescription} />;\n }\n\n // An error with nothing behind it is all there is to show. But a resource\n // can hold an error (e.g. a refetch that blipped after a successful write)\n // while `data` still holds good, freshly-saved content — dropping that\n // content here would report a working save as a failure.\n if (error && empty) return errorBanner;\n\n if (empty) {\n return props.gated\n ? <EmptyState title={props.emptyTitle} description={props.gatedDescription} />\n : <EmptyState title={props.emptyTitle} description={props.emptyDescription} />;\n }\n\n return (\n <>\n {errorBanner}\n {props.children(data)}\n </>\n );\n}\n","import { useState } from 'react';\nimport type { Address } from '../../../types';\nimport { useAddresses } from '../../hooks';\nimport { AppearanceProvider, useAppearance, useAppearanceProviderValue, type ThrottleAppearance } from '../appearance';\nimport { useCopy, type ThrottleLocalization } from '../localization';\nimport { useAction } from '../useAction';\nimport { Alert, Badge, Button, DataTable , useConfirm} from '../primitives';\nimport { PanelState } from './PanelState';\nimport { AddressForm } from './AddressForm';\n\n/**\n * Composition of the list of records a panel renders. `'boxed'` is today's\n * shipped look (each item its own bordered box, outlined action buttons) and\n * must stay byte-for-byte identical to it. `'rows'` separates items with a\n * hairline instead, and renders actions as plain text — the motivation is\n * that the account dashboard is itself a bordered card, so a panel built from\n * bordered boxes is a card inside a card with nothing establishing hierarchy.\n * `'table'` is a real `<table>` with column headers, for merchants who want\n * their buyer's records (especially money) in aligned tabular columns.\n */\nexport type AccountPanelVariant = 'rows' | 'boxed' | 'table';\n\nexport function AddressesPanel(props: {\n appearance?: ThrottleAppearance;\n localization?: ThrottleLocalization;\n variant?: AccountPanelVariant;\n}) {\n const a = useAppearance(props.appearance);\n const scoped = useAppearanceProviderValue(props.appearance);\n const { t } = useCopy(props.localization);\n const resource = useAddresses();\n const { submitting, error, run } = useAction();\n const confirm = useConfirm();\n // `null` = closed, 'new' = creating, an Address = editing that one.\n const [editing, setEditing] = useState<Address | 'new' | null>(null);\n const variant = props.variant ?? 'rows';\n const rowsVariant = variant === 'rows';\n const listBase = rowsVariant ? 'throttle-rows' : 'throttle-stack';\n const itemBase = rowsVariant ? 'throttle-rowitem' : 'throttle-listitem';\n // A destructive action keeps its danger colour even when the rows variant\n // strips the border. Collapsing both to plain 'link' made Delete pixel-\n // identical to Edit — two blue links, one of them irreversible.\n const actionVariant = (base: 'secondary' | 'danger') =>\n rowsVariant ? (base === 'danger' ? 'linkDanger' : 'link') : base;\n\n const close = () => setEditing(null);\n\n const formatAddress = (address: Address) =>\n [address.addressLine2, address.city, address.stateProvince, address.postalCode, address.countryCode]\n .filter(Boolean).join(', ');\n\n return (\n <AppearanceProvider value={scoped}>\n <div {...a.rootProps}>\n <div {...a.el('addressesPanel.root', 'throttle-panel')}>\n {/*\n Only outside the form: AddressForm renders the same `error` itself,\n and showing it twice would be worse than not at all. Without this,\n a failed delete or make-default produced no feedback anywhere — the\n row simply stayed put and the buyer clicked again. Every sibling\n panel already surfaces its action errors here.\n */}\n {!editing && error ? <Alert tone=\"error\">{error}</Alert> : null}\n {editing ? (\n <AddressForm\n initial={editing === 'new' ? undefined : editing}\n submitting={submitting}\n error={error}\n onCancel={close}\n onSubmit={(input) => void run(async () => {\n if (editing === 'new') await resource.create(input);\n else await resource.update(editing.id, input);\n close();\n })}\n />\n ) : (\n <>\n {/* Wrapped for the same reason the detail Back control is: a\n direct child of the column-flex panel stretches to its full\n width, so this rendered as a panel-wide bar. */}\n <div>\n <Button elementKey=\"addressesPanel.addButton\" variant=\"secondary\" onClick={() => setEditing('new')}>\n {t.addresses.addButton}\n </Button>\n </div>\n <PanelState\n resource={resource}\n isEmpty={(rows) => rows.length === 0}\n emptyTitle={t.addresses.empty}\n emptyDescription={t.addresses.emptyDescription}\n >\n {(rows) => (variant === 'table' ? (\n <DataTable\n tableKey=\"addressesPanel.table\"\n rowElementKey=\"addressesPanel.row\"\n rowKey={(address) => address.id}\n rows={rows}\n columns={[\n { key: 'label', label: t.addresses.label, render: (address) => address.label || address.addressLine1 },\n { key: 'address', label: t.addresses.columnAddress, render: (address) => (\n <>\n {address.addressLine1}\n {formatAddress(address) ? `, ${formatAddress(address)}` : ''}\n </>\n ) },\n { key: 'default', label: t.addresses.defaultBadge, render: (address) => (\n address.isDefault ? <Badge tone=\"success\">{t.addresses.defaultBadge}</Badge> : null\n ) },\n { key: 'actions', label: t.common.actions, render: (address) => (\n <div className=\"throttle-actions\">\n {!address.isDefault ? (\n <Button variant=\"secondary\" elementKey=\"addressesPanel.defaultButton\"\n onClick={() => void run(() => resource.update(address.id, { isDefault: true }))}>\n {t.addresses.makeDefault}\n </Button>\n ) : null}\n <Button variant=\"secondary\" elementKey=\"addressesPanel.editButton\"\n onClick={() => setEditing(address)}>\n {t.common.edit}\n </Button>\n <Button\n variant=\"danger\"\n elementKey=\"addressesPanel.deleteButton\"\n disabled={submitting}\n onClick={async () => {\n if (!(await confirm({ title: t.addresses.deleteConfirm, confirmLabel: t.addresses.deleteConfirmAction, tone: 'danger' }))) return;\n void run(() => resource.remove(address.id));\n }}\n >\n {t.common.delete}\n </Button>\n </div>\n ) },\n ]}\n />\n ) : (\n <div {...a.el('addressesPanel.list', listBase)}>\n {rows.map((address) => (\n <div key={address.id} {...a.el('addressesPanel.item', itemBase)}>\n <div>\n <div className=\"throttle-row\">\n <strong>{address.label || address.addressLine1}</strong>\n {address.isDefault ? <Badge tone=\"success\">{t.addresses.defaultBadge}</Badge> : null}\n </div>\n <p className=\"throttle-muted\">\n {/* addressLine1 stays its own text node (not joined into the\n sentence below) so it remains exact-text-matchable on its\n own, the way a merchant's own address list would render it. */}\n {address.addressLine1}\n </p>\n <p className=\"throttle-muted\">\n {formatAddress(address)}\n </p>\n </div>\n <div className=\"throttle-actions\">\n {/* No \"make default\" on the one that already is — a\n control whose only outcome is a no-op is noise. */}\n {!address.isDefault ? (\n <Button variant={actionVariant('secondary')} elementKey=\"addressesPanel.defaultButton\"\n onClick={() => void run(() => resource.update(address.id, { isDefault: true }))}>\n {t.addresses.makeDefault}\n </Button>\n ) : null}\n <Button variant={actionVariant('secondary')} elementKey=\"addressesPanel.editButton\"\n onClick={() => setEditing(address)}>\n {t.common.edit}\n </Button>\n <Button\n variant={actionVariant('danger')}\n elementKey=\"addressesPanel.deleteButton\"\n disabled={submitting}\n onClick={async () => {\n if (!(await confirm({ title: t.addresses.deleteConfirm, confirmLabel: t.addresses.deleteConfirmAction, tone: 'danger' }))) return;\n void run(() => resource.remove(address.id));\n }}\n >\n {t.common.delete}\n </Button>\n </div>\n </div>\n ))}\n </div>\n ))}\n </PanelState>\n </>\n )}\n </div>\n </div>\n </AppearanceProvider>\n );\n}\n","import { useState } from 'react';\nimport type { Address, AddressInput } from '../../../types';\nimport { useAppearance } from '../appearance';\nimport { useCopy } from '../localization';\nimport { Alert, Button, Field, FieldRow } from '../primitives';\n\nexport function AddressForm(props: {\n initial?: Address;\n submitting: boolean;\n error: string | null;\n onSubmit(input: AddressInput): void;\n onCancel(): void;\n /** Hides the saved-address label, for an address that is not saved to the book. */\n hideLabel?: boolean;\n /** Overrides the root element key (defaults to the addresses panel's form). */\n elementKey?: 'addressesPanel.form' | 'subscriptionsPanel.addressForm';\n}) {\n const a = useAppearance();\n const { t } = useCopy();\n const i = props.initial;\n const [form, setForm] = useState({\n label: i?.label ?? '', firstName: i?.firstName ?? '', lastName: i?.lastName ?? '',\n company: i?.company ?? '', addressLine1: i?.addressLine1 ?? '', addressLine2: i?.addressLine2 ?? '',\n city: i?.city ?? '', stateProvince: i?.stateProvince ?? '', postalCode: i?.postalCode ?? '',\n countryCode: i?.countryCode ?? '', phone: i?.phone ?? '',\n });\n const set = (key: keyof typeof form) => (value: string) => setForm((f) => ({ ...f, [key]: value }));\n\n return (\n <form\n {...a.el(props.elementKey ?? 'addressesPanel.form', 'throttle-stack')}\n onSubmit={(e) => {\n e.preventDefault();\n props.onSubmit({\n label: form.label || undefined,\n firstName: form.firstName || undefined,\n lastName: form.lastName || undefined,\n company: form.company || undefined,\n addressLine1: form.addressLine1,\n addressLine2: form.addressLine2 || undefined,\n city: form.city,\n stateProvince: form.stateProvince || undefined,\n postalCode: form.postalCode || undefined,\n // The API wants ISO-3166 alpha-2; uppercase so \"gb\" is not rejected.\n countryCode: form.countryCode.toUpperCase(),\n phone: form.phone || undefined,\n });\n }}\n >\n <FieldRow>\n {props.hideLabel ? null : <Field label={t.addresses.label} value={form.label} onChange={set('label')} />}\n <Field label={t.addresses.company} value={form.company} onChange={set('company')} autoComplete=\"organization\" />\n </FieldRow>\n <FieldRow>\n <Field label={t.addresses.firstName} value={form.firstName} onChange={set('firstName')} autoComplete=\"given-name\" />\n <Field label={t.addresses.lastName} value={form.lastName} onChange={set('lastName')} autoComplete=\"family-name\" />\n </FieldRow>\n <Field label={t.addresses.addressLine1} value={form.addressLine1} onChange={set('addressLine1')}\n required autoComplete=\"address-line1\" />\n <Field label={t.addresses.addressLine2} value={form.addressLine2} onChange={set('addressLine2')}\n autoComplete=\"address-line2\" />\n <FieldRow>\n <Field label={t.addresses.city} value={form.city} onChange={set('city')} required autoComplete=\"address-level2\" />\n <Field label={t.addresses.stateProvince} value={form.stateProvince} onChange={set('stateProvince')}\n autoComplete=\"address-level1\" />\n </FieldRow>\n <FieldRow>\n <Field label={t.addresses.postalCode} value={form.postalCode} onChange={set('postalCode')}\n autoComplete=\"postal-code\" />\n <Field label={t.addresses.countryCode} value={form.countryCode} onChange={set('countryCode')}\n required autoComplete=\"country\" hint=\"ISO 3166-1 alpha-2, e.g. GB\" />\n </FieldRow>\n <Field label={t.addresses.phone} type=\"tel\" value={form.phone} onChange={set('phone')} autoComplete=\"tel\" />\n {props.error ? <Alert tone=\"error\">{props.error}</Alert> : null}\n <div className=\"throttle-actions\">\n <Button type=\"submit\" loading={props.submitting}>{t.common.save}</Button>\n <Button variant=\"link\" onClick={props.onCancel}>{t.common.cancel}</Button>\n </div>\n </form>\n );\n}\n","import { useState } from 'react';\nimport { useAuth } from '../../context';\nimport { useSavedCards } from '../../hooks';\nimport { AppearanceProvider, useAppearance, useAppearanceProviderValue, type ThrottleAppearance } from '../appearance';\nimport { useCopy, type ThrottleLocalization } from '../localization';\nimport { useAction } from '../useAction';\nimport { Alert, Badge, Button, DataTable, useConfirm } from '../primitives';\nimport { PanelState } from './PanelState';\nimport { AddCardDialog } from './AddCardDialog';\nimport type { AccountPanelVariant } from './AddressesPanel';\n\n/**\n * Add, set-default and remove. The card form is hosted by the processor and\n * shown in an iframe by AddCardDialog, so a card number never reaches this\n * component. Adding is verified-only, like listing: what it hands out is the\n * ability to attach a payment instrument to the account.\n */\nexport function PaymentMethodsPanel(props: {\n appearance?: ThrottleAppearance;\n localization?: ThrottleLocalization;\n variant?: AccountPanelVariant;\n}) {\n const a = useAppearance(props.appearance);\n const scoped = useAppearanceProviderValue(props.appearance);\n const { t } = useCopy(props.localization);\n const { emailVerified } = useAuth();\n const resource = useSavedCards();\n const { submitting, error, run } = useAction();\n const confirm = useConfirm();\n const [adding, setAdding] = useState(false);\n const variant = props.variant ?? 'rows';\n const rowsVariant = variant === 'rows';\n const listBase = rowsVariant ? 'throttle-rows' : 'throttle-stack';\n const itemBase = rowsVariant ? 'throttle-rowitem' : 'throttle-listitem';\n // A destructive action keeps its danger colour even when the rows variant\n // strips the border. Collapsing both to plain 'link' made Delete pixel-\n // identical to Edit — two blue links, one of them irreversible.\n const actionVariant = (base: 'secondary' | 'danger') =>\n rowsVariant ? (base === 'danger' ? 'linkDanger' : 'link') : base;\n\n const cardLabel = (card: { cardBrand: string | null; methodType: string; cardLastFour: string | null }) =>\n `${(card.cardBrand ?? card.methodType).toUpperCase()} •••• ${card.cardLastFour ?? '____'}`;\n const expiryLabel = (card: { cardExpMonth: number | null; cardExpYear: number | null }) =>\n card.cardExpMonth && card.cardExpYear\n ? `${String(card.cardExpMonth).padStart(2, '0')}/${card.cardExpYear}`\n : '';\n\n return (\n <AppearanceProvider value={scoped}>\n <div {...a.rootProps}>\n <div {...a.el('paymentMethodsPanel.root', 'throttle-panel')}>\n {error ? <Alert tone=\"error\">{error}</Alert> : null}\n {/* Only offered to a verified buyer — the route refuses anyone else,\n and a button that always fails is worse than no button. */}\n {emailVerified ? (\n <div>\n <Button elementKey=\"paymentMethodsPanel.addButton\" variant=\"secondary\" onClick={() => setAdding(true)}>\n {t.paymentMethods.addButton}\n </Button>\n </div>\n ) : null}\n <AddCardDialog\n open={adding}\n onClose={() => setAdding(false)}\n onAdded={() => { void resource.refetch(); }}\n localization={props.localization}\n />\n {/*\n The real GET /me/payment-methods 403s outright for an unverified\n buyer (buyerAuth: 'session+verified'), which PanelState's own\n error branch already renders — this `gated` prop instead covers\n the OTHER empty case every sibling panel (Orders/Invoices/\n Subscriptions) already covers: signed-out entirely (status !==\n 'authenticated'), where the resource resets to empty/no-error\n without ever calling the network. Before this, PaymentMethodsPanel\n was the only one of the four that showed the plain \"No saved\n cards\" copy there instead of matching its siblings.\n */}\n <PanelState\n resource={resource}\n gated={!emailVerified}\n gatedDescription={t.paymentMethods.gatedDescription}\n isEmpty={(rows) => rows.length === 0}\n emptyTitle={t.paymentMethods.empty}\n emptyDescription={t.paymentMethods.emptyDescription}\n >\n {(rows) => (variant === 'table' ? (\n <DataTable\n tableKey=\"paymentMethodsPanel.table\"\n rowElementKey=\"paymentMethodsPanel.row\"\n rowKey={(card) => card.id}\n rows={rows}\n columns={[\n { key: 'card', label: t.paymentMethods.columnCard, render: (card) => cardLabel(card) },\n { key: 'expires', label: t.paymentMethods.expires, render: (card) => expiryLabel(card) },\n { key: 'default', label: t.paymentMethods.defaultBadge, render: (card) => (\n card.isDefault ? <Badge tone=\"success\">{t.paymentMethods.defaultBadge}</Badge> : null\n ) },\n { key: 'actions', label: t.common.actions, render: (card) => (\n <div className=\"throttle-actions\">\n {!card.isDefault ? (\n <Button variant=\"secondary\" loading={submitting}\n elementKey=\"paymentMethodsPanel.defaultButton\"\n onClick={() => void run(() => resource.setDefault(card.id))}>\n {t.paymentMethods.makeDefault}\n </Button>\n ) : null}\n <Button\n variant=\"danger\"\n elementKey=\"paymentMethodsPanel.deleteButton\"\n disabled={submitting}\n onClick={async () => {\n if (!(await confirm({ title: t.paymentMethods.deleteConfirm, confirmLabel: t.paymentMethods.deleteConfirmAction, tone: 'danger' }))) return;\n void run(() => resource.remove(card.id));\n }}\n >\n {t.common.delete}\n </Button>\n </div>\n ) },\n ]}\n />\n ) : (\n <div {...a.el('paymentMethodsPanel.list', listBase)}>\n {rows.map((card) => (\n <div key={card.id} {...a.el('paymentMethodsPanel.item', itemBase)}>\n <div>\n <div className=\"throttle-row\">\n <strong>{cardLabel(card)}</strong>\n {card.isDefault ? <Badge tone=\"success\">{t.paymentMethods.defaultBadge}</Badge> : null}\n </div>\n {card.cardExpMonth && card.cardExpYear ? (\n <p className=\"throttle-muted\">\n {t.paymentMethods.expires} {String(card.cardExpMonth).padStart(2, '0')}/{card.cardExpYear}\n </p>\n ) : null}\n </div>\n <div className=\"throttle-actions\">\n {!card.isDefault ? (\n <Button variant={actionVariant('secondary')} loading={submitting}\n elementKey=\"paymentMethodsPanel.defaultButton\"\n onClick={() => void run(() => resource.setDefault(card.id))}>\n {t.paymentMethods.makeDefault}\n </Button>\n ) : null}\n <Button\n variant={actionVariant('danger')}\n elementKey=\"paymentMethodsPanel.deleteButton\"\n disabled={submitting}\n onClick={async () => {\n if (!(await confirm({ title: t.paymentMethods.deleteConfirm, confirmLabel: t.paymentMethods.deleteConfirmAction, tone: 'danger' }))) return;\n void run(() => resource.remove(card.id));\n }}\n >\n {t.common.delete}\n </Button>\n </div>\n </div>\n ))}\n </div>\n ))}\n </PanelState>\n </div>\n </div>\n </AppearanceProvider>\n );\n}\n","import { useEffect, useId, useRef, useState } from 'react';\nimport { useAuth } from '../../context';\nimport { useCopy, type ThrottleLocalization } from '../localization';\nimport { Alert, Modal, Spinner } from '../primitives';\nimport { messageForError } from '../../forms/messages';\n\n/**\n * The card form itself is hosted by the processor and shown in an iframe, so a\n * card number never touches this SDK, the merchant's page, or our API. When the\n * card is vaulted the frame posts `throttle.completed`, and the transaction id\n * on that message is what we hand back to record the card.\n */\nexport function AddCardDialog(props: {\n open: boolean;\n onClose(): void;\n onAdded(): void;\n localization?: ThrottleLocalization;\n}) {\n const { account } = useAuth();\n const titleId = useId();\n const { t } = useCopy(props.localization);\n const [src, setSrc] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [busy, setBusy] = useState(false);\n // Read inside the message listener without making the listener depend on\n // them — re-subscribing mid-flow would drop the one message that matters.\n const onAdded = useRef(props.onAdded);\n const onClose = useRef(props.onClose);\n onAdded.current = props.onAdded;\n onClose.current = props.onClose;\n\n useEffect(() => {\n if (!props.open) { setSrc(null); setError(null); return; }\n let live = true;\n setError(null);\n account.startCardSetup().then(\n (session) => {\n if (!live) return;\n // The hosted page checks who is embedding it against the merchant's\n // allowed origins, and reads that from `parentOrigin`. Omit it and the\n // frame renders \"Embed not authorized\" — the feature is dead in a real\n // browser while every unit test still passes. Found by driving it.\n let url = session.embedUrl;\n try {\n const u = new URL(session.embedUrl, window.location.origin);\n u.searchParams.set('parentOrigin', window.location.origin);\n url = u.toString();\n } catch {\n // A relative or malformed embedUrl is not worth throwing over; the\n // frame will report the origin problem itself.\n }\n setSrc(url);\n },\n (err) => { if (live) setError(messageForError(err)); },\n );\n return () => { live = false; };\n }, [props.open, account]);\n\n useEffect(() => {\n if (!src) return;\n // Only ever trust messages from the frame we opened. Without this any page\n // could post a transaction id at us and have it recorded as this buyer's\n // card.\n const frameOrigin = (() => { try { return new URL(src).origin; } catch { return null; } })();\n if (!frameOrigin) return;\n\n async function onMessage(event: MessageEvent) {\n if (event.origin !== frameOrigin) return;\n const data = event.data as { type?: string; paymentId?: string; code?: string; message?: string } | null;\n if (!data || typeof data.type !== 'string') return;\n\n if (data.type === 'throttle.completed' && data.paymentId) {\n setBusy(true);\n try {\n await account.confirmCardSetup(data.paymentId);\n onAdded.current();\n onClose.current();\n } catch (err) {\n setError(messageForError(err));\n } finally {\n setBusy(false);\n }\n } else if (data.type === 'throttle.error') {\n setError(data.message || t.common.somethingWentWrong);\n } else if (data.type === 'throttle.cancelled') {\n onClose.current();\n }\n }\n\n window.addEventListener('message', onMessage);\n return () => window.removeEventListener('message', onMessage);\n }, [src, account, t]);\n\n if (!props.open) return null;\n\n return (\n <Modal open onClose={props.onClose} labelledBy={titleId}>\n {/* Same header/body structure AccountModal uses. Rendered bare, the\n heading sat flush against the modal edge and collided with the close\n control, because the padding lives on these classes. */}\n <div className=\"throttle-modal__header\">\n <h2 id={titleId} className=\"throttle-modal__title\">{t.paymentMethods.addTitle}</h2>\n </div>\n <div className=\"throttle-modal__body\">\n {error ? <Alert tone=\"error\">{error}</Alert> : null}\n {busy ? (\n <div className=\"throttle-centre\"><Spinner /></div>\n ) : src ? (\n <iframe\n className=\"throttle-cardframe\"\n src={src}\n title={t.paymentMethods.addTitle}\n // The frame needs scripts and same-origin for the processor widget;\n // it does NOT need to navigate this page or open popups.\n sandbox=\"allow-scripts allow-forms allow-same-origin\"\n />\n ) : !error ? (\n <div className=\"throttle-centre\"><Spinner /></div>\n ) : null}\n </div>\n </Modal>\n );\n}\n","import { useEffect, useState } from 'react';\nimport { useAuth } from '../../context';\nimport { useOrders } from '../../hooks';\nimport { AppearanceProvider, useAppearance, useAppearanceProviderValue, type ThrottleAppearance } from '../appearance';\nimport { useCopy, type ThrottleLocalization } from '../localization';\nimport { formatDate, formatMoney } from '../format';\nimport { Button, DataTable } from '../primitives';\nimport { PanelState } from './PanelState';\nimport { OrderDetail } from './OrderDetail';\nimport { OrderStatus } from './OrderStatus';\nimport type { AccountPanelVariant } from './AddressesPanel';\n\n/**\n * The order the buyer is acting on, including its line items — so \"order\n * again\" can rebuild a cart without fetching the order a second time.\n */\nexport interface OrderActionTarget {\n id: string;\n orderNumber: string;\n currency: string;\n lineItems: Array<{\n name: string; unitPrice: number; quantity: number;\n /** The catalog SKU (the line's `referenceId`), for re-adding it. Never display it. */\n sku: string | null;\n subscriptionId: string | null;\n }>;\n}\n\nexport interface OrderActionHandlers {\n onPayNow?(order: OrderActionTarget): void;\n onReorder?(order: OrderActionTarget): void;\n onTrackShipment?(order: OrderActionTarget): void;\n}\n\nexport function OrdersPanel(props: OrderActionHandlers & {\n appearance?: ThrottleAppearance;\n localization?: ThrottleLocalization;\n variant?: AccountPanelVariant;\n onViewSubscription?(id: string): void;\n /** Forwarded to `OrderDetail`, where both default to on. */\n allowCancel?: boolean;\n allowReturn?: boolean;\n /** Forwarded to `OrderDetail`: also offer \"Order again\" on orders whose payment is captured or paid. */\n reorderOnPaid?: boolean;\n /** Opens straight to this order. Set by the dashboard on cross-panel navigation. */\n initialOpenId?: string | null;\n}) {\n const a = useAppearance(props.appearance);\n const scoped = useAppearanceProviderValue(props.appearance);\n const { t, locale } = useCopy(props.localization);\n const { emailVerified } = useAuth();\n const resource = useOrders();\n // Seeded by the dashboard when another panel navigates here (an invoice\n // linking to its order). Held in state rather than read directly so the\n // buyer can still press Back out of the record they were sent to.\n const [openId, setOpenId] = useState<string | null>(props.initialOpenId ?? null);\n useEffect(() => { if (props.initialOpenId) setOpenId(props.initialOpenId); }, [props.initialOpenId]);\n // Orders/Invoices already render a DataTable, so `table` stays their default\n // — a merchant configuring nothing keeps money in aligned tabular columns.\n const variant = props.variant ?? 'table';\n const rowsVariant = variant === 'rows';\n const listBase = rowsVariant ? 'throttle-rows' : 'throttle-stack';\n const itemBase = rowsVariant ? 'throttle-rowitem' : 'throttle-listitem';\n\n if (openId) {\n return (\n <OrderDetail\n orderId={openId}\n onBack={() => setOpenId(null)}\n onPayNow={props.onPayNow}\n onReorder={props.onReorder}\n onTrackShipment={props.onTrackShipment}\n onViewSubscription={props.onViewSubscription}\n allowCancel={props.allowCancel}\n allowReturn={props.allowReturn}\n reorderOnPaid={props.reorderOnPaid}\n appearance={props.appearance}\n localization={props.localization}\n />\n );\n }\n\n return (\n <AppearanceProvider value={scoped}>\n <div {...a.rootProps}>\n <div {...a.el('ordersPanel.root', 'throttle-panel')}>\n <PanelState\n resource={resource}\n // An unverified buyer is behind the claim cutoff: an empty list here\n // means \"withheld\", not \"none\".\n gated={!emailVerified}\n gatedDescription={t.orders.gatedDescription}\n isEmpty={(rows) => rows.length === 0}\n emptyTitle={t.orders.empty}\n emptyDescription={t.orders.emptyDescription}\n >\n {(rows) => (variant === 'table' ? (\n <DataTable\n tableKey=\"ordersPanel.table\"\n rowElementKey=\"ordersPanel.row\"\n rowKey={(o) => o.id}\n onRowClick={(o) => setOpenId(o.id)}\n rows={rows}\n columns={[\n { key: 'orderNumber', label: t.orders.number },\n { key: 'createdAt', label: t.orders.date, render: (o) => formatDate(o.createdAt, locale) },\n { key: 'status', label: t.orders.status,\n render: (o) => <OrderStatus status={o.status} paymentStatus={o.paymentStatus} t={t} /> },\n { key: 'total', label: t.orders.total,\n render: (o) => <span className=\"throttle-table__money\">{formatMoney(o.total, o.currency, locale)}</span> },\n ]}\n />\n ) : (\n <div {...a.el('ordersPanel.list', listBase)}>\n {rows.map((o) => (\n <div key={o.id} {...a.el('ordersPanel.item', itemBase)}>\n <div>\n <div className=\"throttle-row\">\n <strong>{o.orderNumber}</strong>\n <OrderStatus status={o.status} paymentStatus={o.paymentStatus} t={t} />\n </div>\n <p className=\"throttle-muted\">{formatDate(o.createdAt, locale)}</p>\n <p className=\"throttle-muted\">{formatMoney(o.total, o.currency, locale)}</p>\n </div>\n <div className=\"throttle-actions\">\n <Button variant={rowsVariant ? 'link' : 'secondary'} elementKey=\"ordersPanel.viewButton\"\n onClick={() => setOpenId(o.id)}>\n {t.common.view}\n </Button>\n </div>\n </div>\n ))}\n </div>\n ))}\n </PanelState>\n </div>\n </div>\n </AppearanceProvider>\n );\n}\n","/**\n * The only place minor units become major units. Every amount on the wire is\n * an integer in the currency's smallest unit, and the exponent varies: USD and\n * EUR are 2, JPY and KRW are 0, and a few are 3. `Intl` knows all of them, so\n * ask it rather than hardcoding 100.\n */\nexport function formatMoney(minorUnits: number, currency: string, locale: string): string {\n const code = (currency || 'USD').toUpperCase();\n\n // The exponent is a property of the currency, not of the display locale, so\n // probe it with a fixed locale rather than the caller's — a locale problem\n // must never be able to corrupt the amount.\n let digits = 2;\n try {\n digits = new Intl.NumberFormat('en-US', { style: 'currency', currency: code }).resolvedOptions()\n .maximumFractionDigits ?? 2;\n } catch {\n // Only a malformed code (not 3 letters) reaches here. 2 is a guess for\n // that case, not a rule about currencies in general.\n }\n const major = minorUnits / 10 ** digits;\n\n try {\n return new Intl.NumberFormat(locale, { style: 'currency', currency: code }).format(major);\n } catch {\n try {\n return new Intl.NumberFormat('en-US', { style: 'currency', currency: code }).format(major);\n } catch {\n // Both locales rejected the code outright. Label the amount with the\n // code rather than showing a bare number — a buyer seeing \"US 25.00\"\n // is better served than one seeing an unlabelled \"25\".\n return `${code} ${major.toFixed(digits)}`;\n }\n }\n}\n\nexport function formatDate(value: string | Date, locale: string): string {\n const date = value instanceof Date ? value : new Date(value);\n // An unparseable date must not render the literal text \"Invalid Date\".\n if (Number.isNaN(date.getTime())) return '';\n try {\n return new Intl.DateTimeFormat(locale, { dateStyle: 'medium' }).format(date);\n } catch {\n return date.toISOString().slice(0, 10);\n }\n}\n\n/**\n * A scheduled payment's date. One that waits an hours gap (`intervalUnit` is\n * the gap before it) also shows its time, in UTC and labelled, as the checkout\n * disclosure and billing page do; every other payment shows the date only.\n */\nexport function scheduleDueLabel(row: { dueAt: string; intervalUnit: string | null }, locale: string): string {\n if (row.intervalUnit !== 'hour') return formatDate(row.dueAt, locale);\n const date = new Date(row.dueAt);\n if (Number.isNaN(date.getTime())) return '';\n const opts: Intl.DateTimeFormatOptions = {\n dateStyle: 'medium',\n timeStyle: 'short',\n timeZone: 'UTC',\n };\n try {\n return `${new Intl.DateTimeFormat(locale, opts).format(date)} UTC`;\n } catch {\n return `${new Intl.DateTimeFormat('en-US', opts).format(date)} UTC`;\n }\n}\n","import { Badge } from '../primitives';\nimport type { ResolvedCopy } from '../localization';\n\n/**\n * An order's status is two facts, not one string: where it is in the\n * fulfilment lifecycle, and — only when there is something to say — what the\n * money is doing. The server models them as two columns for the same reason:\n * fulfilment only moves forward while money moves both ways, so a shipped\n * order can still be refunded.\n *\n * Rendering them as two badges rather than one compound label keeps the common\n * case (paid in full) to a single quiet pill, and keeps the money half legible\n * at table scale instead of truncating \"Fulfilled — Partially refunded\".\n */\n\n/** snake_case on the wire, camelCase in the copy object. */\nfunction copyKey(wire: string): string {\n return wire.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase());\n}\n\n/**\n * The money states a buyer must act on or would want to notice. Everything\n * else stays neutral — a lifecycle state is a fact, not good or bad news, and\n * a table where every row carries a tone teaches buyers to ignore all of them.\n */\nconst ATTENTION_PAYMENT_STATES = new Set(['pending', 'failed', 'disputed', 'expired']);\n\n/**\n * Renders one status value through a copy map, falling back to a readable form\n * of the wire value. Shared by orders, invoices and subscriptions so a status\n * added server-side degrades the same way everywhere instead of leaking\n * snake_case into one panel and not another.\n */\n/**\n * States that are over. They get the quiet outline tier rather than the filled\n * neutral one: a cancelled order and a processing order previously drew the\n * same pill, so a buyer scanning a list could not tell live from finished\n * without reading every row.\n */\nconst TERMINAL_STATUSES = new Set(['cancelled', 'closed', 'void', 'expired', 'voided']);\n\nexport function StatusBadge(props: { status: string; labels: Record<string, string | undefined> }) {\n const label = props.labels[copyKey(props.status)] ?? props.status.replace(/_/g, ' ');\n return <Badge tone={TERMINAL_STATUSES.has(props.status) ? 'muted' : 'neutral'}>{label}</Badge>;\n}\n\nexport function OrderStatus(props: { status: string; paymentStatus?: string | null; t: ResolvedCopy['t'] }) {\n const labels = props.t.orders.statusLabels as Record<string, string | undefined>;\n const payLabels = props.t.orders.paymentLabels as Record<string, string | undefined>;\n\n // An unrecognised status still has to render something a buyer can read, so\n // fall back to the wire value with its underscores removed rather than\n // showing `partially_fulfilled` or an empty pill.\n const lifecycle = labels[copyKey(props.status)] ?? props.status.replace(/_/g, ' ');\n const money = props.paymentStatus ? payLabels[copyKey(props.paymentStatus)] : undefined;\n\n return (\n <>\n <Badge tone={TERMINAL_STATUSES.has(props.status) ? 'muted' : 'neutral'}>{lifecycle}</Badge>\n {money ? (\n <Badge tone={ATTENTION_PAYMENT_STATES.has(props.paymentStatus!) ? 'warning' : 'neutral'}>{money}</Badge>\n ) : null}\n </>\n );\n}\n","import { useAppearance } from '../appearance';\n\n/**\n * A shipping or billing address as stored on an order. The payload types these\n * as `unknown` because the shape is the merchant's, so every field is read\n * defensively and an address with nothing usable renders nothing at all rather\n * than a heading over blanks.\n */\nexport function addressLines(address: unknown): string[] {\n if (!address || typeof address !== 'object') return [];\n const a = address as Record<string, unknown>;\n const str = (k: string) => (typeof a[k] === 'string' && (a[k] as string).trim() ? (a[k] as string).trim() : null);\n const name = [str('firstName'), str('lastName')].filter(Boolean).join(' ');\n const cityLine = [str('city'), str('stateProvince'), str('postalCode')].filter(Boolean).join(', ');\n return [\n name || null,\n str('company'),\n str('addressLine1') ?? str('line1'),\n str('addressLine2') ?? str('line2'),\n cityLine || null,\n str('countryCode') ?? str('country'),\n ].filter((l): l is string => Boolean(l));\n}\n\nexport function AddressBlock(props: { heading: string; address: unknown; elementKey?: string }) {\n const a = useAppearance();\n const lines = addressLines(props.address);\n if (lines.length === 0) return null;\n return (\n <div {...a.el((props.elementKey ?? 'orderDetail.address') as any, 'throttle-addressblock')}>\n <h4 className=\"throttle-section__title\">{props.heading}</h4>\n {lines.map((l) => <p key={l} className=\"throttle-addressblock__line throttle-muted\">{l}</p>)}\n </div>\n );\n}\n","import { formatDate } from '../format';\nimport { useAppearance } from '../appearance';\n\n/**\n * What happened to this order, from the dates the buyer plane actually returns.\n *\n * Deliberately not a fabricated shipping narrative: the buyer payload carries\n * no fulfillment or tracking records, so inventing \"Shipped\" from a status\n * would be telling the buyer something we cannot stand behind. Every entry\n * here has a timestamp behind it.\n */\nexport interface TimelineEntry { label: string; at: string }\n\nexport function orderTimeline(\n order: { createdAt: string; completedAt: string | null; cancelledAt: string | null; closedAt: string | null },\n labels: { placed: string; completed: string; cancelled: string; closed: string },\n): TimelineEntry[] {\n const entries: TimelineEntry[] = [{ label: labels.placed, at: order.createdAt }];\n if (order.completedAt) entries.push({ label: labels.completed, at: order.completedAt });\n if (order.cancelledAt) entries.push({ label: labels.cancelled, at: order.cancelledAt });\n if (order.closedAt) entries.push({ label: labels.closed, at: order.closedAt });\n // Oldest first: a history reads forwards.\n return entries.sort((x, y) => new Date(x.at).getTime() - new Date(y.at).getTime());\n}\n\nexport function OrderTimeline(props: { entries: TimelineEntry[]; locale: string; heading: string }) {\n const a = useAppearance();\n if (props.entries.length <= 1) return null;\n return (\n <div {...a.el('orderDetail.timeline', 'throttle-timeline')}>\n <h4 className=\"throttle-section__title\">{props.heading}</h4>\n {props.entries.map((e) => (\n <div key={`${e.label}-${e.at}`} className=\"throttle-timeline__row\">\n <span className=\"throttle-timeline__dot\" aria-hidden=\"true\" />\n <span className=\"throttle-timeline__label\">{e.label}</span>\n <span className=\"throttle-muted\">{formatDate(e.at, props.locale)}</span>\n </div>\n ))}\n </div>\n );\n}\n","/**\n * One \"View subscription\" per subscription the order created (M6/U9). A\n * single subscription keeps today's plain label. Several are told apart by the\n * line that created each, since two buttons both reading \"View subscription\"\n * give the buyer no way to choose.\n */\nexport function orderSubscriptionLinks(\n order: {\n subscriptionId: string | null;\n subscriptionIds?: string[];\n lineItems: Array<{ name: string; subscriptionId?: string | null }>;\n },\n labels: { single: string; named: string },\n): Array<{ id: string; label: string }> {\n const ids = order.subscriptionIds?.length\n ? order.subscriptionIds\n : order.subscriptionId\n ? [order.subscriptionId]\n : [];\n if (ids.length === 1) return [{ id: ids[0], label: labels.single }];\n return ids.map((id, index) => {\n const name = order.lineItems.find((li) => li.subscriptionId === id)?.name;\n return { id, label: name ? `${labels.named} ${name}` : `${labels.single} ${index + 1}` };\n });\n}\n","import { useAuth } from '../../context';\nimport { useOrder } from '../../hooks';\nimport { OrderStatus } from './OrderStatus';\nimport { AppearanceProvider, useAppearance, useAppearanceProviderValue, type ThrottleAppearance } from '../appearance';\nimport { useCopy, type ThrottleLocalization } from '../localization';\nimport { useAction } from '../useAction';\nimport { formatDate, formatMoney } from '../format';\nimport { Alert, Button, useConfirm } from '../primitives';\nimport { PanelState } from './PanelState';\nimport type { OrderActionTarget } from './OrdersPanel';\nimport { AddressBlock } from './AddressBlock';\nimport { OrderTimeline, orderTimeline } from './OrderTimeline';\nimport { orderSubscriptionLinks } from './order-subscription-links';\n\n/** Unpaid and not yet shipped: the buyer can still settle it. */\nconst CAN_PAY = new Set(['draft', 'pending']);\n/** Nothing more will happen to it, so buying the same things again is the\n * only useful thing left. */\nconst CAN_REORDER = new Set(['fulfilled', 'cancelled', 'closed']);\n/**\n * Mirrors the buyer-plane route's own guards (`platform-storefront`\n * `routes/orders.ts`). Kept in step deliberately: showing a control the server\n * will refuse is worse than not showing it, and these two lists are the whole\n * contract. A cancel is only offered before goods move AND before money is\n * taken — past either, the return request is the honest option.\n */\nconst CAN_CANCEL = new Set(['draft', 'pending', 'processing']);\n/** Money taken and not (even partly) returned: what `reorderOnPaid` unlocks. */\nconst REORDER_PAID_PAYMENT = new Set(['captured', 'paid']);\nconst SETTLED_PAYMENT = new Set(['captured', 'paid', 'partially_refunded', 'refunded']);\nconst CAN_RETURN = new Set(['fulfilled', 'partially_fulfilled', 'closed']);\n\nfunction Line(props: { label: string; value: string; strong?: boolean }) {\n return (\n <div className=\"throttle-row\">\n <span className=\"throttle-muted\">{props.label}</span>\n <span>{props.strong ? <strong>{props.value}</strong> : props.value}</span>\n </div>\n );\n}\n\nexport function OrderDetail(props: {\n orderId: string;\n onBack?(): void;\n onViewSubscription?(id: string): void;\n onViewInvoice?(id: string): void;\n /**\n * Status-dependent actions the MERCHANT owns. Each renders only when its\n * handler is supplied, because the buyer plane cannot perform them: a\n * built-in Pay or Track button would be a control that always fails.\n */\n onPayNow?(order: OrderActionTarget): void;\n onReorder?(order: OrderActionTarget): void;\n onTrackShipment?(order: OrderActionTarget): void;\n /**\n * Cancel and return, by contrast, ARE buyer-plane capabilities, so they are\n * wired in here and need no handler. Opt out with `false` for a storefront\n * that handles them elsewhere.\n */\n allowCancel?: boolean;\n allowReturn?: boolean;\n /**\n * Also offer \"Order again\" on an order whose payment is captured or paid,\n * whatever its status. Default false.\n */\n reorderOnPaid?: boolean;\n appearance?: ThrottleAppearance;\n localization?: ThrottleLocalization;\n}) {\n const a = useAppearance(props.appearance);\n const scoped = useAppearanceProviderValue(props.appearance);\n const { t, locale } = useCopy(props.localization);\n const { account } = useAuth();\n const resource = useOrder(props.orderId);\n const { submitting, error, run } = useAction();\n const confirm = useConfirm();\n\n const allowCancel = props.allowCancel ?? true;\n const allowReturn = props.allowReturn ?? true;\n\n return (\n <AppearanceProvider value={scoped}>\n <div {...a.rootProps}>\n <div {...a.el('orderDetail.root', 'throttle-panel')}>\n {props.onBack ? (\n // Wrapped on purpose. The panel is a column flex container, so a\n // direct child stretches to its full width however `width: auto`\n // the link variant is — the control rendered 748px wide with a\n // centred label. The wrapper takes the stretch; the button keeps\n // its own width. A CSS fix would need a compound selector, and\n // those outrank the merchant overrides in `appearance.elements`.\n <div>\n <Button variant=\"link\" elementKey=\"orderDetail.backButton\" onClick={props.onBack}>\n {t.common.back}\n </Button>\n </div>\n ) : null}\n\n {error ? <Alert tone=\"error\">{error}</Alert> : null}\n\n <PanelState\n resource={resource}\n isEmpty={(o) => o === null}\n emptyTitle={t.orders.empty}\n skeletonRows={5}\n >\n {(order) => {\n const target: OrderActionTarget = {\n id: order!.id, orderNumber: order!.orderNumber, currency: order!.currency,\n lineItems: order!.lineItems.map((li) => ({\n name: li.name, unitPrice: li.unitPrice, quantity: li.quantity,\n sku: li.referenceId ?? null, subscriptionId: li.subscriptionId ?? null,\n })),\n };\n const money = (v: number) => formatMoney(v, order!.currency, locale);\n const paid = SETTLED_PAYMENT.has(order!.paymentStatus);\n const showCancel = allowCancel && CAN_CANCEL.has(order!.status) && !paid;\n const showReorder = !!props.onReorder && (\n CAN_REORDER.has(order!.status) ||\n (!!props.reorderOnPaid && REORDER_PAID_PAYMENT.has(order!.paymentStatus))\n );\n const showReturn = allowReturn && CAN_RETURN.has(order!.status);\n\n return (\n <div {...a.el('orderDetail.layout', 'throttle-detail')}>\n <div {...a.el('orderDetail.main', 'throttle-detail__main')}>\n <div className=\"throttle-detail__section\">\n <div className=\"throttle-row\">\n <h3>{order!.orderNumber}</h3>\n <OrderStatus status={order!.status} paymentStatus={order!.paymentStatus} t={t} />\n </div>\n <p className=\"throttle-muted\">{formatDate(order!.createdAt, locale)}</p>\n </div>\n\n <div className=\"throttle-detail__section\">\n <span className=\"throttle-detail__label\">{t.orders.items}</span>\n <div {...a.el('orderDetail.lineItems', 'throttle-stack')}>\n {order!.lineItems.map((item) => (\n <div key={item.id} {...a.el('orderDetail.lineItem', 'throttle-lineitem')}>\n {item.imageUrl ? (\n <img className=\"throttle-lineitem__image\" src={item.imageUrl} alt=\"\" />\n ) : null}\n <div style={{ flex: 1 }}>\n <strong>{item.name}</strong>\n {item.description ? <p className=\"throttle-lineitem__desc\">{item.description}</p> : null}\n <p className=\"throttle-lineitem__meta\">\n {t.orders.quantity} {item.quantity} × {money(item.unitPrice)}\n </p>\n </div>\n <span>{money(item.total)}</span>\n </div>\n ))}\n </div>\n </div>\n\n <OrderTimeline\n heading={t.orders.history}\n locale={locale}\n entries={orderTimeline(order!, {\n placed: t.orders.placed, completed: t.orders.completed,\n cancelled: t.orders.cancelledAt, closed: t.orders.closedAt,\n })}\n />\n\n <div {...a.el('orderDetail.addresses', 'throttle-addresses')}>\n <AddressBlock heading={t.orders.shipTo} address={order!.shippingAddress}\n elementKey=\"orderDetail.shippingAddress\" />\n <AddressBlock heading={t.orders.billTo} address={order!.billingAddress}\n elementKey=\"orderDetail.billingAddress\" />\n </div>\n </div>\n\n <aside {...a.el('orderDetail.rail', 'throttle-detail__rail')}>\n <div className=\"throttle-detail__section\">\n <span className=\"throttle-detail__label\">{t.orders.total}</span>\n <span className=\"throttle-detail__headline\">{money(order!.total)}</span>\n </div>\n\n <div {...a.el('orderDetail.totals', 'throttle-totals')}>\n <Line label={t.orders.subtotal} value={money(order!.subtotal)} />\n {order!.discountTotal ? (\n <Line label={t.orders.discount} value={money(-order!.discountTotal)} />\n ) : null}\n <Line label={t.orders.shipping} value={money(order!.shippingTotal)} />\n <Line label={t.orders.tax} value={money(order!.taxTotal)} />\n </div>\n\n <div {...a.el('orderDetail.actions', 'throttle-detail__actions')}>\n {props.onPayNow && CAN_PAY.has(order!.status) ? (\n <Button elementKey=\"orderDetail.payButton\" onClick={() => props.onPayNow!(target)}>\n {t.orders.payNow}\n </Button>\n ) : null}\n\n {/* Offered whenever an invoice exists for this order, in\n every status: a buyer needs the receipt for a\n delivered order as much as for an open one. */}\n {order!.invoiceId ? (\n <Button\n variant=\"secondary\"\n loading={submitting}\n elementKey=\"orderDetail.invoiceButton\"\n onClick={() => void run(async () => {\n // Fetched on click, never on render: the signed URL\n // lives 600 seconds, so a link prepared at page load\n // would be dead by the time it was clicked.\n const { url } = await account.getInvoicePdfUrl(order!.invoiceId!);\n // The user-activation token does not survive the\n // await, so Safari blocks the popup outright.\n const opened = window.open(url, '_blank', 'noopener,noreferrer');\n if (!opened) window.location.assign(url);\n })}\n >\n {t.orders.downloadInvoice}\n </Button>\n ) : null}\n\n {props.onTrackShipment && order!.status === 'partially_fulfilled' ? (\n <Button variant=\"secondary\" elementKey=\"orderDetail.trackButton\"\n onClick={() => props.onTrackShipment!(target)}>\n {t.orders.track}\n </Button>\n ) : null}\n\n {showReorder ? (\n <Button variant=\"secondary\" elementKey=\"orderDetail.reorderButton\"\n onClick={() => props.onReorder!(target)}>\n {t.orders.reorder}\n </Button>\n ) : null}\n\n {props.onViewSubscription\n ? orderSubscriptionLinks(order!, {\n single: t.orders.viewSubscription,\n named: t.orders.viewSubscriptionFor,\n }).map((link) => (\n <Button key={link.id} variant=\"secondary\"\n elementKey=\"orderDetail.subscriptionButton\"\n onClick={() => props.onViewSubscription!(link.id)}>\n {link.label}\n </Button>\n ))\n : null}\n\n {showReturn ? (\n <Button\n variant=\"secondary\"\n disabled={submitting}\n elementKey=\"orderDetail.returnButton\"\n onClick={() => void (async () => {\n if (!(await confirm({\n title: t.orders.requestReturnConfirm,\n body: t.orders.requestReturnBody,\n confirmLabel: t.orders.requestReturnAction,\n }))) return;\n await run(async () => {\n // Whole order, every line. Partial returns need a\n // per-line quantity picker; until that exists,\n // asking for everything is the honest default —\n // the merchant adjusts on approval either way.\n await account.requestOrderReturn(order!.id, {\n items: order!.lineItems.map((li) => ({\n lineItemId: li.id, quantity: li.quantity,\n })),\n });\n await resource.refetch();\n });\n })()}\n >\n {t.orders.requestReturn}\n </Button>\n ) : null}\n\n {showCancel ? (\n <Button\n variant=\"danger\"\n disabled={submitting}\n elementKey=\"orderDetail.cancelButton\"\n onClick={() => void (async () => {\n if (!(await confirm({\n title: t.orders.cancelOrderConfirm,\n body: t.orders.cancelOrderBody,\n confirmLabel: t.orders.cancelOrderAction,\n tone: 'danger',\n }))) return;\n await run(async () => {\n await account.cancelOrder(order!.id);\n await resource.refetch();\n });\n })()}\n >\n {t.orders.cancelOrder}\n </Button>\n ) : null}\n </div>\n </aside>\n </div>\n );\n }}\n </PanelState>\n </div>\n </div>\n </AppearanceProvider>\n );\n}\n","import { useEffect, useState } from 'react';\nimport { StatusBadge } from './OrderStatus';\nimport { useAuth } from '../../context';\nimport { useInvoices } from '../../hooks';\nimport { AppearanceProvider, useAppearance, useAppearanceProviderValue, type ThrottleAppearance } from '../appearance';\nimport { useCopy, type ThrottleLocalization } from '../localization';\nimport { formatDate, formatMoney } from '../format';\nimport { Badge, Button, DataTable } from '../primitives';\nimport { PanelState } from './PanelState';\nimport { InvoiceDetail } from './InvoiceDetail';\nimport type { AccountPanelVariant } from './AddressesPanel';\n\nexport function InvoicesPanel(props: {\n appearance?: ThrottleAppearance;\n localization?: ThrottleLocalization;\n variant?: AccountPanelVariant;\n /** Navigation out of an invoice, forwarded to `InvoiceDetail`. */\n onViewOrder?(orderId: string): void;\n onViewSubscription?(subscriptionId: string): void;\n onPay?(invoice: { id: string; number: string; total: number; currency: string }): void;\n /** Opens straight to this invoice. Set by the dashboard on cross-panel navigation. */\n initialOpenId?: string | null;\n}) {\n const a = useAppearance(props.appearance);\n const scoped = useAppearanceProviderValue(props.appearance);\n const { t, locale } = useCopy(props.localization);\n const { emailVerified } = useAuth();\n const resource = useInvoices();\n // Seeded by the dashboard when another panel navigates here (an invoice\n // linking to its order). Held in state rather than read directly so the\n // buyer can still press Back out of the record they were sent to.\n const [openId, setOpenId] = useState<string | null>(props.initialOpenId ?? null);\n useEffect(() => { if (props.initialOpenId) setOpenId(props.initialOpenId); }, [props.initialOpenId]);\n // Orders/Invoices already render a DataTable, so `table` stays their default\n // — a merchant configuring nothing keeps money in aligned tabular columns.\n const variant = props.variant ?? 'table';\n const rowsVariant = variant === 'rows';\n const listBase = rowsVariant ? 'throttle-rows' : 'throttle-stack';\n const itemBase = rowsVariant ? 'throttle-rowitem' : 'throttle-listitem';\n\n if (openId) {\n return (\n <InvoiceDetail invoiceId={openId} onBack={() => setOpenId(null)}\n onViewOrder={props.onViewOrder}\n onViewSubscription={props.onViewSubscription}\n onPay={props.onPay}\n appearance={props.appearance} localization={props.localization} />\n );\n }\n\n return (\n <AppearanceProvider value={scoped}>\n <div {...a.rootProps}>\n <div {...a.el('invoicesPanel.root', 'throttle-panel')}>\n <PanelState\n resource={resource}\n gated={!emailVerified}\n gatedDescription={t.invoices.gatedDescription}\n isEmpty={(rows) => rows.length === 0}\n emptyTitle={t.invoices.empty}\n emptyDescription={t.invoices.emptyDescription}\n >\n {(rows) => (variant === 'table' ? (\n <DataTable\n tableKey=\"invoicesPanel.table\"\n rowElementKey=\"invoicesPanel.row\"\n rowKey={(i) => i.id}\n onRowClick={(i) => setOpenId(i.id)}\n rows={rows}\n columns={[\n { key: 'number', label: t.invoices.number },\n { key: 'issuedAt', label: t.invoices.issued, render: (i) => formatDate(i.issuedAt, locale) },\n { key: 'status', label: t.invoices.status, render: (i) => <StatusBadge status={i.status} labels={t.invoices.statusLabels} /> },\n { key: 'total', label: t.invoices.total,\n render: (i) => <span className=\"throttle-table__money\">{formatMoney(i.total, i.currency, locale)}</span> },\n ]}\n />\n ) : (\n <div {...a.el('invoicesPanel.list', listBase)}>\n {rows.map((i) => (\n <div key={i.id} {...a.el('invoicesPanel.item', itemBase)}>\n <div>\n <div className=\"throttle-row\">\n <strong>{i.number}</strong>\n <StatusBadge status={i.status} labels={t.invoices.statusLabels} />\n </div>\n <p className=\"throttle-muted\">{formatDate(i.issuedAt, locale)}</p>\n <p className=\"throttle-muted\">{formatMoney(i.total, i.currency, locale)}</p>\n </div>\n <div className=\"throttle-actions\">\n <Button variant={rowsVariant ? 'link' : 'secondary'} elementKey=\"invoicesPanel.viewButton\"\n onClick={() => setOpenId(i.id)}>\n {t.common.view}\n </Button>\n </div>\n </div>\n ))}\n </div>\n ))}\n </PanelState>\n </div>\n </div>\n </AppearanceProvider>\n );\n}\n","import { useAuth } from '../../context';\nimport { StatusBadge } from './OrderStatus';\nimport { useInvoice } from '../../hooks';\nimport { AppearanceProvider, useAppearance, useAppearanceProviderValue, type ThrottleAppearance } from '../appearance';\nimport { useCopy, type ThrottleLocalization } from '../localization';\nimport { useAction } from '../useAction';\nimport { formatDate, formatMoney } from '../format';\nimport { Alert, Button } from '../primitives';\nimport { PanelState } from './PanelState';\n\n/** An invoice with money still owed is one a buyer may want to settle. */\nconst PAYABLE = new Set(['open']);\n\nfunction Line(props: { label: string; value: string }) {\n return (\n <div className=\"throttle-row\">\n <span className=\"throttle-muted\">{props.label}</span>\n <span>{props.value}</span>\n </div>\n );\n}\n\nexport function InvoiceDetail(props: {\n invoiceId: string;\n onBack?(): void;\n /**\n * Navigation out of the invoice. An invoice is a record OF something — an\n * order or a subscription — and without these it was a dead end: the buyer\n * could read what they were charged but not reach the thing that charged\n * them. Each link renders only when the handler is supplied AND the server\n * resolved the id.\n */\n onViewOrder?(orderId: string): void;\n onViewSubscription?(subscriptionId: string): void;\n /** Settle an open invoice. Merchant-owned, like the order's Pay now. */\n onPay?(invoice: { id: string; number: string; total: number; currency: string }): void;\n appearance?: ThrottleAppearance;\n localization?: ThrottleLocalization;\n}) {\n const a = useAppearance(props.appearance);\n const scoped = useAppearanceProviderValue(props.appearance);\n const { t, locale } = useCopy(props.localization);\n const { account } = useAuth();\n const resource = useInvoice(props.invoiceId);\n const { submitting, error, run } = useAction();\n\n return (\n <AppearanceProvider value={scoped}>\n <div {...a.rootProps}>\n <div {...a.el('invoiceDetail.root', 'throttle-panel')}>\n {props.onBack ? (\n // Wrapped on purpose — see OrderDetail's back button for why a\n // direct flex child stretched to 748px.\n <div>\n <Button variant=\"link\" elementKey=\"invoiceDetail.backButton\" onClick={props.onBack}>\n {t.common.back}\n </Button>\n </div>\n ) : null}\n\n {error ? <Alert tone=\"error\">{error}</Alert> : null}\n\n <PanelState resource={resource} isEmpty={(i) => i === null} emptyTitle={t.invoices.empty} skeletonRows={4}>\n {(invoice) => {\n const money = (v: number) => formatMoney(v, invoice!.currency, locale);\n const lines = invoice!.lineItems ?? [];\n // Bills less than the order (a Net-N balance after a deposit, a\n // comp, a deposit's own receipt): the same rows the PDF prints.\n const partOfOrder = invoice!.orderTotal != null;\n const isDepositReceipt = partOfOrder && invoice!.balanceDue != null;\n const headlineLabel = !partOfOrder\n ? t.invoices.total\n : isDepositReceipt ? t.invoices.amountPaid : t.invoices.amountDue;\n\n return (\n <div {...a.el('invoiceDetail.layout', 'throttle-detail')}>\n <div {...a.el('invoiceDetail.main', 'throttle-detail__main')}>\n <div className=\"throttle-detail__section\">\n <div className=\"throttle-row\">\n <h3>{invoice!.number}</h3>\n <StatusBadge status={invoice!.status} labels={t.invoices.statusLabels} />\n </div>\n <p className=\"throttle-muted\">\n {t.invoices.issued} {formatDate(invoice!.issuedAt, locale)}\n </p>\n </div>\n\n {/* Frozen at issue, so this is what was actually billed —\n it cannot drift from the PDF the buyer downloads. */}\n {lines.length > 0 ? (\n <div className=\"throttle-detail__section\">\n <span className=\"throttle-detail__label\">{t.invoices.items}</span>\n <div {...a.el('invoiceDetail.lineItems', 'throttle-stack')}>\n {lines.map((item, i) => (\n <div key={i} {...a.el('invoiceDetail.lineItem', 'throttle-lineitem')}>\n <div style={{ flex: 1 }}>\n <strong>{item.name}</strong>\n {item.description ? <p className=\"throttle-lineitem__desc\">{item.description}</p> : null}\n <p className=\"throttle-lineitem__meta\">\n {t.orders.quantity} {item.quantity} × {money(item.unitPrice)}\n </p>\n </div>\n <span>{money(item.total)}</span>\n </div>\n ))}\n </div>\n </div>\n ) : null}\n </div>\n\n <aside {...a.el('invoiceDetail.rail', 'throttle-detail__rail')}>\n <div className=\"throttle-detail__section\">\n <span className=\"throttle-detail__label\">{headlineLabel}</span>\n <span className=\"throttle-detail__headline\">{money(invoice!.total)}</span>\n </div>\n\n <div {...a.el('invoiceDetail.totals', 'throttle-totals')}>\n {partOfOrder ? (\n <Line label={t.invoices.orderTotal} value={money(invoice!.orderTotal!)} />\n ) : null}\n {partOfOrder && invoice!.amountPaid ? (\n <Line label={t.invoices.amountPaid} value={`-${money(invoice!.amountPaid)}`} />\n ) : null}\n {partOfOrder && invoice!.compWaived ? (\n <Line label={t.invoices.waived} value={`-${money(invoice!.compWaived)}`} />\n ) : null}\n {isDepositReceipt && invoice!.balanceDue ? (\n <Line label={t.invoices.balanceDue} value={money(invoice!.balanceDue)} />\n ) : null}\n {invoice!.dueAt ? <Line label={t.invoices.due} value={formatDate(invoice!.dueAt, locale)} /> : null}\n {invoice!.periodStart && invoice!.periodEnd ? (\n <Line\n label={t.invoices.period}\n value={`${formatDate(invoice!.periodStart, locale)} – ${formatDate(invoice!.periodEnd, locale)}`}\n />\n ) : null}\n {invoice!.amountRefunded ? (\n <Line label={t.invoices.refunded} value={money(invoice!.amountRefunded)} />\n ) : null}\n </div>\n\n <div {...a.el('invoiceDetail.actions', 'throttle-detail__actions')}>\n {props.onPay && PAYABLE.has(invoice!.status) ? (\n <Button\n elementKey=\"invoiceDetail.payButton\"\n onClick={() => props.onPay!({\n id: invoice!.id, number: invoice!.number,\n total: invoice!.total, currency: invoice!.currency,\n })}\n >\n {t.invoices.payButton}\n </Button>\n ) : null}\n\n <Button\n variant=\"secondary\"\n loading={submitting}\n elementKey=\"invoiceDetail.downloadButton\"\n onClick={() => void run(async () => {\n // Fetched on click, never on render: the signed URL lives 600\n // seconds, so a link prepared when the page loaded would be\n // dead by the time a buyer reading the invoice clicked it.\n const { url } = await account.getInvoicePdfUrl(invoice!.id);\n // The user-activation token does not survive the await, so\n // Safari blocks this popup outright and Chrome does past\n // about a second. window.open then returns null and the\n // buyer saw the spinner stop with nothing else happening.\n // Navigating the current tab always works; the PDF is a\n // terminal destination, so nothing is lost by not opening\n // a new one.\n const opened = window.open(url, '_blank', 'noopener,noreferrer');\n if (!opened) window.location.assign(url);\n })}\n >\n {t.invoices.downloadButton}\n </Button>\n\n {invoice!.orderId && props.onViewOrder ? (\n <Button\n variant=\"secondary\"\n elementKey=\"invoiceDetail.orderLink\"\n onClick={() => props.onViewOrder!(invoice!.orderId!)}\n >\n {invoice!.orderNumber\n ? `${t.invoices.viewOrder} ${invoice!.orderNumber}`\n : t.invoices.viewOrder}\n </Button>\n ) : null}\n\n {invoice!.subscriptionId && props.onViewSubscription ? (\n <Button\n variant=\"secondary\"\n elementKey=\"invoiceDetail.subscriptionLink\"\n onClick={() => props.onViewSubscription!(invoice!.subscriptionId!)}\n >\n {t.invoices.viewSubscription}\n </Button>\n ) : null}\n </div>\n </aside>\n </div>\n );\n }}\n </PanelState>\n </div>\n </div>\n </AppearanceProvider>\n );\n}\n","import { useState } from 'react';\nimport { cadenceNoun, isVariedSchedule, scheduleDeal, upcomingSchedulePayments } from '@core/cadence';\nimport type { Address, SubscriptionShippingAddress } from '../../../types';\nimport { AddressForm } from './AddressForm';\nimport { useAuth } from '../../context';\nimport { StatusBadge } from './OrderStatus';\nimport { useSubscriptions } from '../../hooks';\nimport { AppearanceProvider, useAppearance, useAppearanceProviderValue, type ThrottleAppearance } from '../appearance';\nimport { useCopy, type ThrottleLocalization } from '../localization';\nimport { useAction } from '../useAction';\nimport { formatDate, formatMoney, scheduleDueLabel } from '../format';\nimport { Alert, Badge, Button, DataTable, useConfirm } from '../primitives';\nimport { PanelState } from './PanelState';\nimport type { AccountPanelVariant } from './AddressesPanel';\n\n// Lifecycle controls only make sense in some states. Acting on a cancelled\n// subscription either 400s or silently no-ops depending on the action, so the\n// controls are hidden rather than shown and allowed to fail.\n// D22: the engine's pause() only accepts 'active' (service.ts) — a buyer\n// Pause on a 'trialing' row 400s.\nconst CAN_PAUSE = new Set(['active']);\nconst CAN_RESUME = new Set(['paused']);\n// 'unpaid' is the terminal dunning state — cancel() does not short-circuit on\n// it (only on 'cancelled'), so a buyer stuck there must still be able to get\n// out rather than being left with no control but \"contact support\".\nconst CAN_CANCEL = new Set(['active', 'trialing', 'paused', 'past_due', 'unpaid']);\n\n// Installment plans are paused, resumed and cancelled only by the merchant\n// (D33); the API refuses a buyer session with installment_plan_merchant_only.\nconst isInstallment = (sub: { totalPayments?: number | null }) => sub.totalPayments != null;\n\n// A physical subscription ships a box each cycle; its address can move until\n// it ends. Allowed on installment plans: the address is not a locked term.\nconst canChangeAddress = (sub: { status: string; deliveryMethod?: string }) =>\n sub.deliveryMethod === 'shipment' && sub.status !== 'cancelled' && sub.status !== 'completed';\n\nfunction oneLine(address: SubscriptionShippingAddress | null | undefined): string | null {\n if (!address) return null;\n const parts = [address.addressLine1, address.addressLine2, address.city, address.stateProvince, address.postalCode, address.countryCode];\n return parts.filter(Boolean).join(', ') || null;\n}\n\ntype ScheduleRowLike = {\n amount: number; discount: number; intervalUnit: string | null; intervalCount: number | null;\n};\n\nexport function SubscriptionsPanel(props: {\n appearance?: ThrottleAppearance;\n localization?: ThrottleLocalization;\n variant?: AccountPanelVariant;\n}) {\n const a = useAppearance(props.appearance);\n const scoped = useAppearanceProviderValue(props.appearance);\n const { t, locale } = useCopy(props.localization);\n const { emailVerified } = useAuth();\n const resource = useSubscriptions();\n const { submitting, error, run } = useAction();\n const confirm = useConfirm();\n const [editingAddress, setEditingAddress] = useState<string | null>(null);\n const variant = props.variant ?? 'rows';\n const rowsVariant = variant === 'rows';\n const listBase = rowsVariant ? 'throttle-rows' : 'throttle-stack';\n const itemBase = rowsVariant ? 'throttle-rowitem' : 'throttle-listitem';\n // Subscription lifecycle actions stay real buttons in every variant.\n // Elsewhere the rows variant renders actions as text links, which suits\n // Edit and Delete on an address; here the same treatment put \"Resume\" and\n // \"Cancel immediately\" on a row as two underlined strings, so the controls\n // that restart billing and end it read as body copy and their underlines\n // were the most button-like thing about them. These move money — they get\n // the affordance.\n const actionVariant = (base: 'secondary' | 'danger') => base;\n\n /**\n * Every lifecycle action asks first. Pause and resume are reversible, so they\n * ask in the neutral tone; cancelling is not, so it asks in danger and names\n * the consequence.\n */\n const confirmThen = (\n fn: () => Promise<void>,\n ask: { title: string; confirmLabel: string; tone?: 'danger' | 'neutral' },\n ) => () => {\n void (async () => {\n if (!(await confirm({ ...ask, tone: ask.tone ?? 'neutral' }))) return;\n await run(fn);\n })();\n };\n\n const priceLabel = (sub: {\n amount: number; currency: string; interval: string; quantity: number;\n intervalUnit: string | null; intervalCount: number | null;\n paymentSchedule?: ScheduleRowLike[] | null; scheduleTotal?: number | null;\n }) => {\n const deal = scheduleDeal(sub);\n return deal\n ? t.subscriptions.installmentTotal.replace('{amount}', formatMoney(deal.total, sub.currency, locale))\n : `${formatMoney(sub.amount, sub.currency, locale)} / ${cadenceNoun(sub)}${sub.quantity > 1 ? ` × ${sub.quantity}` : ''}`;\n };\n\n // A payment schedule's next charge differs from `amount`, so say it outright.\n const nextPaymentLabel = (sub: {\n currency: string; currentPeriodEnd: string; nextPaymentAmount?: number | null;\n paymentSchedule?: Array<{ status: string; dueAt: string | null; intervalUnit: string | null }> | null;\n }) => {\n if (!isVariedSchedule(sub.paymentSchedule as ScheduleRowLike[] | null) || !sub.paymentSchedule || sub.nextPaymentAmount == null) return null;\n const upcoming = sub.paymentSchedule.find((r) => r.status !== 'paid');\n return t.subscriptions.installmentNext\n .replace('{amount}', formatMoney(sub.nextPaymentAmount, sub.currency, locale))\n .replace(\n '{date}',\n upcoming?.dueAt\n ? scheduleDueLabel({ dueAt: upcoming.dueAt, intervalUnit: upcoming.intervalUnit }, locale)\n : formatDate(sub.currentPeriodEnd, locale),\n );\n };\n\n // Spec §5: the same dated list the checkout showed, for what is still to come.\n // Empty (renders nothing) for an equal plan.\n const upcomingList = (sub: {\n currency: string;\n paymentSchedule?: Array<ScheduleRowLike & { net: number; status: string; dueAt: string | null }> | null;\n }) => {\n const upcoming = upcomingSchedulePayments(sub.paymentSchedule);\n if (upcoming.length === 0) return null;\n return (\n <ul className=\"throttle-muted\" aria-label={t.subscriptions.upcomingPayments}>\n {upcoming.map((r) => (\n <li key={r.dueAt}>\n {t.subscriptions.upcomingPayment\n .replace('{amount}', formatMoney(r.net, sub.currency, locale))\n .replace('{date}', scheduleDueLabel(r, locale))}\n </li>\n ))}\n </ul>\n );\n };\n\n const shipsTo = (sub: { deliveryMethod?: string; shippingAddress?: SubscriptionShippingAddress | null }) =>\n sub.deliveryMethod === 'shipment' && oneLine(sub.shippingAddress) ? (\n <p className=\"throttle-muted\">{t.subscriptions.shipsTo} {oneLine(sub.shippingAddress)}</p>\n ) : null;\n\n const addressAction = (\n sub: { id: string; status: string; deliveryMethod?: string },\n variantFor: (base: 'secondary' | 'danger') => 'secondary' | 'danger' | 'link' | 'linkDanger',\n ) => (canChangeAddress(sub) ? (\n <Button variant={variantFor('secondary')} elementKey=\"subscriptionsPanel.changeAddressButton\"\n disabled={submitting} onClick={() => setEditingAddress(sub.id)}>\n {t.subscriptions.changeAddress}\n </Button>\n ) : null);\n\n const renewsLabel = (sub: { status: string; cancelledAt: string | null; completedAt: string | null; currentPeriodEnd: string }) =>\n formatDate(\n sub.status === 'completed'\n ? (sub.completedAt ?? sub.currentPeriodEnd)\n : sub.status === 'cancelled' ? (sub.cancelledAt ?? sub.currentPeriodEnd) : sub.currentPeriodEnd,\n locale,\n );\n\n const lifecycleActions = (\n sub: { id: string; status: string; cancelAtPeriodEnd: boolean; totalPayments?: number | null },\n variantFor: (base: 'secondary' | 'danger') => 'secondary' | 'danger' | 'link' | 'linkDanger',\n ) => (isInstallment(sub) ? null : (\n <div className=\"throttle-actions\">\n {CAN_PAUSE.has(sub.status) ? (\n <Button variant={variantFor('secondary')} loading={submitting}\n elementKey=\"subscriptionsPanel.pauseButton\"\n onClick={confirmThen(() => resource.pause(sub.id), {\n title: t.subscriptions.pauseConfirm,\n confirmLabel: t.subscriptions.pauseButton,\n })}>\n {t.subscriptions.pauseButton}\n </Button>\n ) : null}\n {CAN_RESUME.has(sub.status) ? (\n <Button variant={variantFor('secondary')} loading={submitting}\n elementKey=\"subscriptionsPanel.resumeButton\"\n onClick={confirmThen(() => resource.resume(sub.id), {\n title: t.subscriptions.resumeConfirm,\n confirmLabel: t.subscriptions.resumeButton,\n })}>\n {t.subscriptions.resumeButton}\n </Button>\n ) : null}\n {CAN_CANCEL.has(sub.status) && !sub.cancelAtPeriodEnd ? (\n <Button variant={variantFor('secondary')} elementKey=\"subscriptionsPanel.cancelButton\" disabled={submitting}\n onClick={confirmThen(() => resource.cancel(sub.id, { atPeriodEnd: true }), {\n title: t.subscriptions.cancelConfirm,\n confirmLabel: t.subscriptions.cancelConfirmAction,\n tone: 'danger',\n })}>\n {t.subscriptions.cancelAtPeriodEnd}\n </Button>\n ) : null}\n {CAN_CANCEL.has(sub.status) ? (\n <Button variant={variantFor('danger')} elementKey=\"subscriptionsPanel.cancelNowButton\" disabled={submitting}\n onClick={confirmThen(() => resource.cancel(sub.id, { atPeriodEnd: false }), {\n title: t.subscriptions.cancelNowConfirm,\n confirmLabel: t.subscriptions.cancelConfirmAction,\n tone: 'danger',\n })}>\n {t.subscriptions.cancelNow}\n </Button>\n ) : null}\n </div>\n ));\n\n return (\n <AppearanceProvider value={scoped}>\n <div {...a.rootProps}>\n <div {...a.el('subscriptionsPanel.root', 'throttle-panel')}>\n {error && !editingAddress ? <Alert tone=\"error\">{error}</Alert> : null}\n {editingAddress ? (() => {\n const sub = resource.data.find((row) => row.id === editingAddress);\n const current = sub?.shippingAddress;\n return (\n <div className=\"throttle-stack\">\n <strong>{t.subscriptions.changeAddressTitle}</strong>\n <p className=\"throttle-muted\">{t.subscriptions.changeAddressHint}</p>\n <AddressForm\n elementKey=\"subscriptionsPanel.addressForm\"\n hideLabel\n // AddressForm reads a saved-address shape; only its fields are used.\n initial={current ? ({ ...current, label: null } as unknown as Address) : undefined}\n submitting={submitting}\n error={error}\n onCancel={() => setEditingAddress(null)}\n onSubmit={({ label: _label, isDefault: _isDefault, ...address }) => {\n void run(async () => {\n await resource.updateShippingAddress(editingAddress, address);\n setEditingAddress(null);\n });\n }}\n />\n </div>\n );\n })() : null}\n <PanelState\n resource={resource}\n gated={!emailVerified}\n gatedDescription={t.subscriptions.gatedDescription}\n isEmpty={(rows) => rows.length === 0}\n emptyTitle={t.subscriptions.empty}\n emptyDescription={t.subscriptions.emptyDescription}\n >\n {(rows) => (variant === 'table' ? (\n <DataTable\n tableKey=\"subscriptionsPanel.table\"\n rowElementKey=\"subscriptionsPanel.row\"\n rowKey={(sub) => sub.id}\n rows={rows}\n columns={[\n { key: 'plan', label: t.subscriptions.columnPlan, render: (sub) => (\n <>\n {sub.planName ?? sub.planReference}\n {sub.totalPayments != null ? (\n <div className=\"throttle-muted\">\n {t.subscriptions.installmentProgress\n .replace('{paid}', String(Math.min(sub.paymentsMade ?? 0, sub.totalPayments)))\n .replace('{total}', String(sub.totalPayments))}\n </div>\n ) : null}\n {nextPaymentLabel(sub) ? <div className=\"throttle-muted\">{nextPaymentLabel(sub)}</div> : null}\n {upcomingList(sub)}\n {shipsTo(sub)}\n </>\n ) },\n { key: 'price', label: t.subscriptions.columnPrice, render: (sub) => (\n <span className=\"throttle-table__money\">{priceLabel(sub)}</span>\n ) },\n { key: 'renews', label: t.subscriptions.columnRenews, render: (sub) => renewsLabel(sub) },\n { key: 'status', label: t.subscriptions.columnStatus, render: (sub) => (\n <div className=\"throttle-row\">\n <StatusBadge status={sub.status} labels={t.subscriptions.statusLabels} />\n {sub.cancelAtPeriodEnd ? <Badge tone=\"warning\">{t.subscriptions.cancelScheduled}</Badge> : null}\n </div>\n ) },\n { key: 'actions', label: t.common.actions, render: (sub) => (\n <>\n {lifecycleActions(sub, (base) => base)}\n {addressAction(sub, (base) => base)}\n </>\n ) },\n ]}\n />\n ) : (\n <div {...a.el('subscriptionsPanel.list', listBase)}>\n {rows.map((sub) => (\n <div key={sub.id} {...a.el('subscriptionsPanel.item', itemBase)}>\n <div>\n <div className=\"throttle-row\">\n <strong>{sub.planName ?? sub.planReference}</strong>\n <StatusBadge status={sub.status} labels={t.subscriptions.statusLabels} />\n </div>\n {sub.totalPayments != null ? (\n <div className=\"throttle-muted\">\n {t.subscriptions.installmentProgress\n .replace('{paid}', String(Math.min(sub.paymentsMade ?? 0, sub.totalPayments)))\n .replace('{total}', String(sub.totalPayments))}\n </div>\n ) : null}\n {nextPaymentLabel(sub) ? <div className=\"throttle-muted\">{nextPaymentLabel(sub)}</div> : null}\n {upcomingList(sub)}\n <p className=\"throttle-muted\">{priceLabel(sub)}</p>\n {shipsTo(sub)}\n {sub.status === 'completed' ? (\n <p className=\"throttle-muted\">\n {t.subscriptions.statusLabels.completed} {formatDate(sub.completedAt ?? sub.currentPeriodEnd, locale)}\n </p>\n ) : sub.status === 'cancelled' ? (\n <p className=\"throttle-muted\">\n {t.subscriptions.cancelledOn} {formatDate(sub.cancelledAt ?? sub.currentPeriodEnd, locale)}\n </p>\n ) : (\n <p className=\"throttle-muted\">\n {sub.cancelAtPeriodEnd ? t.subscriptions.endsOn : t.subscriptions.renewsOn}{' '}\n {formatDate(sub.currentPeriodEnd, locale)}\n </p>\n )}\n {sub.trialEnd ? (\n <p className=\"throttle-muted\">{t.subscriptions.trialEnds} {formatDate(sub.trialEnd, locale)}</p>\n ) : null}\n {sub.cancelAtPeriodEnd ? (\n <Badge tone=\"warning\">{t.subscriptions.cancelScheduled}</Badge>\n ) : null}\n </div>\n {lifecycleActions(sub, actionVariant)}\n {addressAction(sub, actionVariant)}\n </div>\n ))}\n </div>\n ))}\n </PanelState>\n </div>\n </div>\n </AppearanceProvider>\n );\n}\n","/**\n * A subscription's billing cadence: \"every N units\".\n *\n * Every subscription row stores a unit and a count; the five named intervals\n * are shorthand for particular combinations. This module is the only place\n * that knows the vocabulary, the bounds, and how a period boundary is\n * computed — the engine, the renewal cron, the API, the dashboard and the\n * buyer surfaces all import it. Before it existed there were three divergent\n * copies of the period math, and the renewal cron's advanced months with\n * `setMonth`, which overflows: a subscription started on Jan 31 renewed on\n * Mar 3 and never returned to the 31st.\n */\n\nexport const INTERVAL_UNITS = ['hour', 'day', 'week', 'month'] as const;\nexport type IntervalUnit = (typeof INTERVAL_UNITS)[number];\n\nexport const NAMED_INTERVALS = ['weekly', 'biweekly', 'monthly', 'quarterly', 'yearly'] as const;\nexport type NamedInterval = (typeof NAMED_INTERVALS)[number];\n\n/** What the `interval` field holds: a named interval, or `custom` for everything else. */\nexport const INTERVAL_VALUES = [...NAMED_INTERVALS, 'custom'] as const;\nexport type IntervalValue = (typeof INTERVAL_VALUES)[number];\n\nexport interface Cadence {\n interval: IntervalValue;\n unit: IntervalUnit;\n count: number;\n}\n\n/** Anything that describes a cadence the way the API and the database do. */\nexport interface CadenceLike {\n interval: string;\n intervalUnit?: string | null;\n intervalCount?: number | null;\n}\n\nexport interface CadenceInput {\n interval?: string | null;\n intervalUnit?: string | null;\n intervalCount?: number | null;\n}\n\nexport const NAMED_SHORTHAND: Readonly<Record<NamedInterval, { unit: IntervalUnit; count: number }>> = {\n weekly: { unit: 'week', count: 1 },\n biweekly: { unit: 'week', count: 2 },\n monthly: { unit: 'month', count: 1 },\n quarterly: { unit: 'month', count: 3 },\n // month × 12 rather than a year unit, so a Feb 29 anniversary clamps to Feb\n // 28 and comes back to Feb 29 in leap years like every other month cadence.\n yearly: { unit: 'month', count: 12 },\n};\n\n/** At most one year in every unit. The shortest cadence is 1 hour. */\nexport const MAX_INTERVAL_COUNT: Readonly<Record<IntervalUnit, number>> = {\n hour: 8760,\n day: 365,\n week: 52,\n month: 12,\n};\n\nexport const HOUR_MS = 3_600_000;\nexport const DAY_MS = 24 * HOUR_MS;\nexport const WEEK_MS = 7 * DAY_MS;\n\nconst FIXED_UNIT_MS = { hour: HOUR_MS, day: DAY_MS, week: WEEK_MS } as const;\n\nexport class CadenceError extends Error {\n readonly statusCode = 400;\n constructor(\n readonly code: 'invalid_interval' | 'interval_conflict',\n message: string,\n ) {\n super(message);\n this.name = 'CadenceError';\n }\n}\n\nexport function isNamedInterval(value: unknown): value is NamedInterval {\n return typeof value === 'string' && (NAMED_INTERVALS as readonly string[]).includes(value);\n}\n\nexport function isIntervalUnit(value: unknown): value is IntervalUnit {\n return typeof value === 'string' && (INTERVAL_UNITS as readonly string[]).includes(value);\n}\n\nfunction isIntervalValue(value: unknown): value is IntervalValue {\n return typeof value === 'string' && (INTERVAL_VALUES as readonly string[]).includes(value);\n}\n\nfunction reduceToLargestUnit(unit: IntervalUnit, count: number): { unit: IntervalUnit; count: number } {\n let u = unit;\n let c = count;\n if (u === 'hour' && c % 24 === 0) {\n u = 'day';\n c = c / 24;\n }\n if (u === 'day' && c % 7 === 0) {\n u = 'week';\n c = c / 7;\n }\n return { unit: u, count: c };\n}\n\nfunction namedFor(unit: IntervalUnit, count: number): NamedInterval | null {\n for (const name of NAMED_INTERVALS) {\n const s = NAMED_SHORTHAND[name];\n if (s.unit === unit && s.count === count) return name;\n }\n return null;\n}\n\n/**\n * Turn whatever a caller sent into the one stored form. Accepts a named\n * interval alone, a unit and count alone, or both — in which case they must\n * agree. The result is reduced to its largest exact unit and mapped to a named\n * interval whenever one matches, so there is exactly one representation per\n * cadence and \"every 2 weeks\" can never be filed apart from \"biweekly\".\n */\nexport function canonicalizeCadence(input: CadenceInput): Cadence {\n const interval = input.interval ?? undefined;\n if (interval !== undefined && !isIntervalValue(interval)) {\n throw new CadenceError('invalid_interval', `Unknown interval \"${interval}\"`);\n }\n const hasUnit = input.intervalUnit != null;\n const hasCount = input.intervalCount != null;\n if (hasUnit !== hasCount) {\n throw new CadenceError('invalid_interval', 'intervalUnit and intervalCount must be sent together');\n }\n if (!hasUnit) {\n if (isNamedInterval(interval)) return { interval, ...NAMED_SHORTHAND[interval] };\n throw new CadenceError(\n 'invalid_interval',\n interval === 'custom'\n ? 'A custom interval needs intervalUnit and intervalCount'\n : 'Send an interval, or intervalUnit and intervalCount',\n );\n }\n\n const unit = input.intervalUnit;\n const count = input.intervalCount as number;\n if (!isIntervalUnit(unit)) {\n throw new CadenceError('invalid_interval', 'intervalUnit must be one of hour, day, week, month');\n }\n if (!Number.isInteger(count) || count < 1) {\n throw new CadenceError('invalid_interval', 'intervalCount must be a whole number of at least 1');\n }\n if (count > MAX_INTERVAL_COUNT[unit]) {\n throw new CadenceError(\n 'invalid_interval',\n `A cadence can be at most one year: ${MAX_INTERVAL_COUNT[unit]} ${unit}s`,\n );\n }\n\n const reduced = reduceToLargestUnit(unit, count);\n const cadence: Cadence = { interval: namedFor(reduced.unit, reduced.count) ?? 'custom', ...reduced };\n if (interval !== undefined && interval !== 'custom' && interval !== cadence.interval) {\n throw new CadenceError(\n 'interval_conflict',\n `interval \"${interval}\" does not match every ${count} ${unit}${count === 1 ? '' : 's'}`,\n );\n }\n return cadence;\n}\n\n/**\n * Read the cadence off a stored subscription. A named interval always means\n * its shorthand, whatever the unit/count columns hold: a canonical row's\n * columns match the shorthand anyway, and code that predates the columns\n * (still serving between migration 0224 and the deploy) changes `interval`\n * without touching them, so for a named row they can be stale. Only a\n * `custom` row is read from its unit and count. The same rule applies to the\n * pending cadence — pass `{ interval: pendingInterval, intervalUnit:\n * pendingIntervalUnit, intervalCount: pendingIntervalCount }`.\n */\nexport function cadenceOf(row: CadenceLike): Cadence {\n if (isNamedInterval(row.interval)) return { interval: row.interval, ...NAMED_SHORTHAND[row.interval] };\n if (row.interval === 'custom' && row.intervalUnit != null && row.intervalCount != null && isIntervalUnit(row.intervalUnit)) {\n return { interval: 'custom', unit: row.intervalUnit, count: row.intervalCount };\n }\n throw new Error(`Unknown subscription interval: ${row.interval}`);\n}\n\n/** The exact period length for hour/day/week cadences; null for months, which vary. */\nexport function fixedPeriodMs(cadence: Cadence): number | null {\n return cadence.unit === 'month' ? null : cadence.count * FIXED_UNIT_MS[cadence.unit];\n}\n\n/** The shortest a period can be. A month counts as 28 days. */\nexport function minimumPeriodMs(cadence: Cadence): number {\n return fixedPeriodMs(cadence) ?? cadence.count * 28 * DAY_MS;\n}\n\n/** anchor + months, keeping the anchor's day-of-month (clamped to month end) and UTC time of day. */\nexport function addMonthsAnchored(anchor: Date, months: number): Date {\n const monthIndex = anchor.getUTCMonth() + months;\n const year = anchor.getUTCFullYear() + Math.floor(monthIndex / 12);\n const month = ((monthIndex % 12) + 12) % 12;\n const lastDay = new Date(Date.UTC(year, month + 1, 0)).getUTCDate();\n return new Date(\n Date.UTC(\n year,\n month,\n Math.min(anchor.getUTCDate(), lastDay),\n anchor.getUTCHours(),\n anchor.getUTCMinutes(),\n anchor.getUTCSeconds(),\n anchor.getUTCMilliseconds(),\n ),\n );\n}\n\n/**\n * The first period boundary strictly after `after`, on the grid measured from\n * `anchor`. Never chained from a previous boundary — that is what made the\n * month-end clamp stick on the 28th. An `after` that is off the grid (a late\n * tick, a recovery) resolves to the next grid date.\n */\nexport function nextPeriodEnd(args: { anchor: Date; cadence: Cadence; after: Date }): Date {\n const { anchor, cadence, after } = args;\n const step = fixedPeriodMs(cadence);\n if (step !== null) {\n const k = Math.max(1, Math.floor((after.getTime() - anchor.getTime()) / step) + 1);\n return new Date(anchor.getTime() + k * step);\n }\n const monthsElapsed =\n (after.getUTCFullYear() - anchor.getUTCFullYear()) * 12 + (after.getUTCMonth() - anchor.getUTCMonth());\n let k = Math.max(1, Math.floor(monthsElapsed / cadence.count));\n let boundary = addMonthsAnchored(anchor, k * cadence.count);\n while (boundary.getTime() <= after.getTime()) {\n k += 1;\n boundary = addMonthsAnchored(anchor, k * cadence.count);\n }\n return boundary;\n}\n\n/**\n * The grid period that contains `at`: the latest boundary at or before it (never\n * before the anchor) and the one after. A subscription that fell more than a\n * period behind is billed once, for this period, and the periods it missed are\n * skipped rather than charged back to back (D38).\n */\nexport function periodContaining(args: { anchor: Date; cadence: Cadence; at: Date }): { start: Date; end: Date } {\n const { anchor, cadence, at } = args;\n const step = fixedPeriodMs(cadence);\n if (step !== null) {\n const k = Math.max(0, Math.floor((at.getTime() - anchor.getTime()) / step));\n const start = new Date(anchor.getTime() + k * step);\n return { start, end: new Date(start.getTime() + step) };\n }\n const monthsElapsed =\n (at.getUTCFullYear() - anchor.getUTCFullYear()) * 12 + (at.getUTCMonth() - anchor.getUTCMonth());\n let k = Math.max(0, Math.floor(monthsElapsed / cadence.count));\n let start = addMonthsAnchored(anchor, k * cadence.count);\n while (k > 0 && start.getTime() > at.getTime()) {\n k -= 1;\n start = addMonthsAnchored(anchor, k * cadence.count);\n }\n return { start, end: addMonthsAnchored(anchor, (k + 1) * cadence.count) };\n}\n\nconst RETRY_CAP_DAYS = [1, 3, 7] as const;\n\n/**\n * How long to wait before retry number `failureNumber` (1..3). Short cadences\n * retry proportionally faster; anything of a week or longer lands on the\n * original 1 / 3 / 7 days exactly.\n */\nexport function dunningRetryDelayMs(cadence: Cadence, failureNumber: number): number {\n const n = Math.min(Math.max(Math.trunc(failureNumber), 1), RETRY_CAP_DAYS.length);\n return Math.min(n * minimumPeriodMs(cadence), RETRY_CAP_DAYS[n - 1] * DAY_MS);\n}\n\n/** The 3-days-ahead renewal reminder only makes sense for cadences of a week or longer. */\nexport function sendsRenewalReminder(cadence: Cadence): boolean {\n return minimumPeriodMs(cadence) >= WEEK_MS;\n}\n\n/**\n * Multiply a period's charge by this to get its monthly equivalent. Chosen so\n * `weekly` is exactly 52/12 and `biweekly` exactly 26/12, the factors\n * analytics already report — no existing MRR number moves.\n */\nexport function monthlyEquivalentFactor(cadence: Cadence): number {\n if (cadence.unit === 'month') return 1 / cadence.count;\n return (52 / 12) * (WEEK_MS / (fixedPeriodMs(cadence) as number));\n}\n","// packages/core-cadence/src/schedule.ts\n/**\n * Installment schedules: a plan whose payments differ in amount and in the gap\n * before each one. Row 0 is charged at signup and has no gap; row i's gap is\n * how long after payment i-1 it falls due. Gaps use the custom-cadence units\n * and bounds. Due dates are anchored and cumulative (spec S26): months are\n * clamped against the anchor's day, so a Jan 31 plan pays Feb 28, Mar 31,\n * Apr 30 — never chained from a clamped date.\n */\nimport {\n addMonthsAnchored,\n canonicalizeCadence,\n cadenceOf,\n CadenceError,\n fixedPeriodMs,\n isIntervalUnit,\n nextPeriodEnd,\n type Cadence,\n type IntervalUnit,\n} from './cadence';\nimport { MAX_TOTAL_PAYMENTS, MIN_TOTAL_PAYMENTS } from './installments';\n\nexport interface ScheduleRow {\n /** Gross, per unit of the line, minor units. */\n amount: number;\n intervalUnit: IntervalUnit | null;\n intervalCount: number | null;\n}\n\n/** What `subscriptions.payment_schedule` holds, one per payment. */\nexport interface PaymentScheduleRow {\n /** Gross, per unit. */\n unitAmount: number;\n /** This payment's share of the deal discount, line total (quantity included). */\n discount: number;\n intervalUnit: IntervalUnit | null;\n intervalCount: number | null;\n}\n\nexport type GapRow = { intervalUnit: IntervalUnit | null; intervalCount: number | null };\n\nexport type ScheduleErrorCode = 'invalid_schedule' | 'schedule_first_payment_mismatch';\n\nexport class ScheduleError extends Error {\n readonly statusCode = 400;\n constructor(\n readonly code: ScheduleErrorCode,\n message: string,\n ) {\n super(message);\n this.name = 'ScheduleError';\n }\n}\n\nconst ROW_KEYS = new Set(['amount', 'intervalUnit', 'intervalCount']);\n\nfunction invalid(message: string): ScheduleError {\n return new ScheduleError('invalid_schedule', message);\n}\n\n/** Validate and canonicalize a schedule. Every message starts with the row it is about. */\nexport function normalizeSchedule(input: unknown): ScheduleRow[] {\n if (!Array.isArray(input) || input.length < MIN_TOTAL_PAYMENTS || input.length > MAX_TOTAL_PAYMENTS) {\n throw invalid(`schedule must be an array of ${MIN_TOTAL_PAYMENTS} to ${MAX_TOTAL_PAYMENTS} payments`);\n }\n return input.map((raw, i) => {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) throw invalid(`schedule[${i}] must be an object`);\n const row = raw as Record<string, unknown>;\n const unknown = Object.keys(row).filter((k) => !ROW_KEYS.has(k));\n if (unknown.length > 0) throw invalid(`schedule[${i}] has unsupported field(s): ${unknown.join(', ')}`);\n const amount = row.amount;\n if (typeof amount !== 'number' || !Number.isInteger(amount) || amount <= 0) {\n throw invalid(`schedule[${i}].amount must be a whole number of minor units above 0`);\n }\n const hasUnit = row.intervalUnit != null;\n const hasCount = row.intervalCount != null;\n if (i === 0) {\n if (hasUnit || hasCount) throw invalid('schedule[0] is paid at signup and cannot have intervalUnit or intervalCount');\n return { amount, intervalUnit: null, intervalCount: null };\n }\n if (!hasUnit || !hasCount) throw invalid(`schedule[${i}] needs intervalUnit and intervalCount`);\n if (!isIntervalUnit(row.intervalUnit)) {\n throw invalid(`schedule[${i}].intervalUnit must be one of hour, day, week, month`);\n }\n let gap: Cadence;\n try {\n gap = canonicalizeCadence({ intervalUnit: row.intervalUnit, intervalCount: row.intervalCount as number });\n } catch (err) {\n if (err instanceof CadenceError) throw invalid(`schedule[${i}].intervalCount: ${err.message}`);\n throw err;\n }\n return { amount, intervalUnit: gap.unit, intervalCount: gap.count };\n });\n}\n\nexport function assertScheduleFirstPayment(schedule: ScheduleRow[], unitPrice: number): void {\n if (schedule[0].amount !== unitPrice) {\n throw new ScheduleError(\n 'schedule_first_payment_mismatch',\n `unitPrice (${unitPrice}) must equal schedule[0].amount (${schedule[0].amount}): payment 1 is what the line charges today`,\n );\n }\n}\n\nexport function scheduleUnitTotal(schedule: Array<{ amount: number }>): number {\n return schedule.reduce((sum, row) => sum + row.amount, 0);\n}\n\n/** A row's gap as a canonical cadence (interval name included), for the subscription's cadence columns. */\nexport function scheduleGapCadence(row: GapRow): Cadence {\n return canonicalizeCadence({ intervalUnit: row.intervalUnit, intervalCount: row.intervalCount });\n}\n\n/** Due time of payment `index`: the anchor plus every gap after `anchorIndex`, months first. */\nexport function scheduleDueAt(args: { anchor: Date; anchorIndex: number; rows: GapRow[]; index: number }): Date {\n const { anchor, anchorIndex, rows, index } = args;\n if (index < anchorIndex) throw new Error(`payment ${index} is before the anchor row ${anchorIndex}`);\n let months = 0;\n let fixedMs = 0;\n for (let j = anchorIndex + 1; j <= index; j += 1) {\n const gap = scheduleGapCadence(rows[j]);\n if (gap.unit === 'month') months += gap.count;\n else fixedMs += fixedPeriodMs(gap) as number;\n }\n return new Date(addMonthsAnchored(anchor, months).getTime() + fixedMs);\n}\n\n/**\n * The end of the period payment `index` pays for: the next payment's due time,\n * or — for the last payment, which nothing follows — its own gap once more.\n */\nexport function scheduleCoveredUntil(args: { anchor: Date; anchorIndex: number; rows: GapRow[]; index: number }): Date {\n const { rows, index } = args;\n if (index + 1 < rows.length) return scheduleDueAt({ ...args, index: index + 1 });\n const extended = [...rows, rows[index]];\n return scheduleDueAt({ ...args, rows: extended, index: index + 1 });\n}\n\n/** A line's subtotal as the discount engine sees it: the whole deal for an installment line (S33). */\nexport function lineDealSubtotal(line: {\n unitPrice?: number | null;\n quantity?: number | null;\n subtotal?: number | null;\n recurring?: unknown;\n}): number {\n const quantity = Number(line.quantity ?? 1);\n const unitPrice = Number(line.unitPrice ?? 0);\n const subtotal = line.subtotal != null ? Number(line.subtotal) : unitPrice * quantity;\n const r = line.recurring as { plan?: unknown; schedule?: unknown; totalPayments?: unknown; trialDays?: unknown } | null | undefined;\n if (!r || typeof r.plan !== 'string') return subtotal;\n if (Array.isArray(r.schedule)) return scheduleUnitTotal(r.schedule as Array<{ amount: number }>) * quantity;\n if (typeof r.totalPayments === 'number' && Number(r.trialDays ?? 0) === 0) return r.totalPayments * unitPrice * quantity;\n return subtotal;\n}\n\n/** S33: the part of a deal-wide discount that today's charge carries. */\nexport function todayShareOfDealDiscount(args: { dealDiscount: number; todayWeight: number; dealWeight: number }): number {\n const { dealDiscount, todayWeight, dealWeight } = args;\n if (dealDiscount <= 0 || dealWeight <= 0 || todayWeight <= 0) return 0;\n return Math.min(dealDiscount, Math.round((dealDiscount * todayWeight) / dealWeight));\n}\n\nexport interface PaymentScheduleViewRow {\n index: number;\n amount: number;\n discount: number;\n net: number;\n intervalUnit: IntervalUnit | null;\n intervalCount: number | null;\n status: 'paid' | 'due' | 'upcoming';\n dueAt: string | null;\n}\n\nexport interface PaymentScheduleView {\n rows: PaymentScheduleViewRow[];\n scheduleTotal: number;\n nextPaymentAmount: number | null;\n}\n\nexport type ScheduleSubLike = {\n status: string;\n amount: number;\n quantity?: number | null;\n totalPayments?: number | null;\n paymentsMade?: number | null;\n interval: string;\n intervalUnit?: string | null;\n intervalCount?: number | null;\n billingAnchorAt?: Date | string | null;\n currentPeriodEnd?: Date | string | null;\n scheduleRows?: PaymentScheduleRow[] | null;\n scheduleAnchorIndex?: number | null;\n};\n\nconst toDate = (v: Date | string | null | undefined): Date | null => (v == null ? null : new Date(v));\n\n/** The response view (spec §2, S35). Null for an ongoing subscription. */\nexport function paymentScheduleView(sub: ScheduleSubLike, _now: Date = new Date()): PaymentScheduleView | null {\n if (sub.totalPayments == null) return null;\n const quantity = sub.quantity ?? 1;\n const made = Math.min(sub.paymentsMade ?? 0, sub.totalPayments);\n const billing = ['active', 'past_due', 'paused', 'unpaid'].includes(sub.status);\n const rows: PaymentScheduleRow[] =\n sub.scheduleRows && sub.scheduleRows.length > 0\n ? sub.scheduleRows\n : Array.from({ length: sub.totalPayments }, (_, i) => ({\n unitAmount: sub.amount,\n discount: 0,\n intervalUnit: i === 0 ? null : ((sub.intervalUnit ?? null) as IntervalUnit | null),\n intervalCount: i === 0 ? null : (sub.intervalCount ?? null),\n }));\n const nextDue = toDate(sub.currentPeriodEnd);\n const dueAtOf = (i: number): string | null => {\n if (i < made || !billing || !nextDue) return null;\n if (sub.scheduleRows && sub.scheduleRows.length > 0) {\n const anchor = toDate(sub.billingAnchorAt) ?? nextDue;\n return scheduleDueAt({ anchor, anchorIndex: sub.scheduleAnchorIndex ?? 0, rows, index: i }).toISOString();\n }\n // Equal plan: the stored period end, then the anchored grid.\n const cadence = cadenceOf({ interval: sub.interval, intervalUnit: sub.intervalUnit, intervalCount: sub.intervalCount });\n const anchor = toDate(sub.billingAnchorAt) ?? nextDue;\n let at = nextDue;\n for (let k = made; k < i; k += 1) at = nextPeriodEnd({ anchor, cadence, after: at });\n return at.toISOString();\n };\n const view = rows.map((row, i) => {\n const net = row.unitAmount * quantity - row.discount;\n const status: PaymentScheduleViewRow['status'] =\n i < made ? 'paid' : i === made && (sub.status === 'past_due' || sub.status === 'unpaid') ? 'due' : 'upcoming';\n return {\n index: i, amount: row.unitAmount, discount: row.discount, net,\n intervalUnit: row.intervalUnit, intervalCount: row.intervalCount, status, dueAt: dueAtOf(i),\n };\n });\n return {\n rows: view,\n scheduleTotal: view.reduce((s, r) => s + r.net, 0),\n nextPaymentAmount: billing && made < view.length ? view[made].net : null,\n };\n}\n\n/**\n * True when a subscription's synthesized payment rows are a genuinely custom schedule: any discount,\n * any amount differing from payment 1, or any gap (payments 2..N) differing from payment 2's.\n * Equal installment plans also carry synthesized rows and must render as before.\n */\nexport function isVariedSchedule(\n rows: Array<{ amount: number; discount: number; intervalUnit: string | null; intervalCount: number | null }> | null | undefined,\n): boolean {\n if (!rows || rows.length === 0) return false;\n return rows.some(\n (r, i) =>\n r.discount !== 0 ||\n r.amount !== rows[0].amount ||\n (i > 1 && (r.intervalUnit !== rows[1].intervalUnit || r.intervalCount !== rows[1].intervalCount)),\n );\n}\n\n/**\n * A varied schedule's payments still to come — unpaid rows that carry an\n * estimated date — for the buyer-facing dated lists (spec §5: order\n * confirmation, portal, billing page). Empty for an equal plan, so those\n * surfaces render exactly as before. Each surface formats amount and date itself.\n */\nexport function upcomingSchedulePayments<\n R extends { amount: number; discount: number; intervalUnit: string | null; intervalCount: number | null; status: string; dueAt: string | null },\n>(rows: R[] | null | undefined): Array<R & { dueAt: string }> {\n if (!rows || !isVariedSchedule(rows)) return [];\n return rows.filter((r): r is R & { dueAt: string } => r.status !== 'paid' && r.dueAt != null);\n}\n","import { isIntervalUnit, isNamedInterval, type CadenceLike, type NamedInterval } from './cadence';\nimport { isVariedSchedule, scheduleUnitTotal } from './schedule';\n\nconst NAMED_NOUN: Record<NamedInterval, string> = {\n weekly: 'week',\n biweekly: '2 weeks',\n monthly: 'month',\n quarterly: 'quarter',\n yearly: 'year',\n};\n\nconst NAMED_LABEL: Record<NamedInterval, string> = {\n weekly: 'Weekly',\n biweekly: 'Biweekly',\n monthly: 'Monthly',\n quarterly: 'Quarterly',\n yearly: 'Yearly',\n};\n\n/**\n * The period as a noun — what reads correctly after a slash: \"$49.00 / 10\n * days\". This replaces the per-file `INTERVAL_WORD` maps whose drift shipped\n * \"$49.00 / biweekly\" once already. Unknown input falls through unchanged so a\n * value this build doesn't know still renders instead of vanishing.\n */\nexport function cadenceNoun(cadence: CadenceLike): string {\n if (isNamedInterval(cadence.interval)) return NAMED_NOUN[cadence.interval];\n if (isIntervalUnit(cadence.intervalUnit) && cadence.intervalCount != null) {\n return cadence.intervalCount === 1 ? cadence.intervalUnit : `${cadence.intervalCount} ${cadence.intervalUnit}s`;\n }\n return cadence.interval;\n}\n\n/** The cadence as a standalone label, e.g. an Interval column: \"Monthly\", \"Every 10 days\". */\nexport function cadenceLabel(cadence: CadenceLike): string {\n if (isNamedInterval(cadence.interval)) return NAMED_LABEL[cadence.interval];\n if (isIntervalUnit(cadence.intervalUnit) && cadence.intervalCount != null) return `Every ${cadenceNoun(cadence)}`;\n return cadence.interval;\n}\n\n/** Sub-daily cadences show the time of the next charge, not just its date. */\nexport function isSubDaily(cadence: CadenceLike): boolean {\n return cadence.intervalUnit === 'hour';\n}\n\n/** A subscription line's terms, the fields a label needs. */\nexport interface RecurringTermsLike extends CadenceLike {\n totalPayments?: number | null;\n trialDays?: number | null;\n schedule?: Array<{ amount: number }> | null;\n}\n\n/**\n * One short label for a subscription line's terms, for carts and quotes:\n * \"$20.00 / month\", \"$20.00 / 10 days · 3 payments\", \"Free for 14 days, then\n * $20.00 / month\", \"$100.00 total · 4 payments\". The label computes the money\n * itself from the line's unit price and seats — for a schedule, the deal total\n * (every payment × seats), never the line's unit price (payment 1) — and hands\n * it to `money`, so each surface keeps its own money style.\n */\nexport function recurringTermsLabel(\n terms: RecurringTermsLike,\n price: { unitPrice: number; quantity?: number | null },\n money: (minor: number) => string,\n): string {\n const quantity = price.quantity ?? 1;\n if (terms.schedule && terms.schedule.length > 0) {\n return `${money(scheduleUnitTotal(terms.schedule) * quantity)} total · ${terms.schedule.length} payments`;\n }\n const each = money(price.unitPrice * quantity);\n const noun = cadenceNoun(terms);\n const trialDays = terms.trialDays ?? 0;\n if (trialDays > 0) return `Free for ${trialDays} day${trialDays === 1 ? '' : 's'}, then ${each} / ${noun}`;\n return `${each} / ${noun}` + (terms.totalPayments != null ? ` · ${terms.totalPayments} payments` : '');\n}\n\n/** A subscription's public schedule fields, as the API returns them. */\nexport interface ScheduleDealLike {\n paymentSchedule?: Array<{ amount: number; discount: number; intervalUnit: string | null; intervalCount: number | null }> | null;\n scheduleTotal?: number | null;\n}\n\n/**\n * A varied schedule's deal — its total (every row's net: seats in, discounts\n * out) and its payment count — or null for an equal plan, whose synthesized\n * schedule keeps the per-period label, and for an ongoing plan. A varied\n * schedule has no per-period price: `amount` and the cadence columns hold only\n * the next row's (ruling R-FR4). Every surface gates both its price and its\n * cadence cells on this one answer.\n */\nexport function scheduleDeal(sub: ScheduleDealLike): { total: number; payments: number } | null {\n if (!sub.paymentSchedule || sub.scheduleTotal == null || !isVariedSchedule(sub.paymentSchedule)) return null;\n return { total: sub.scheduleTotal, payments: sub.paymentSchedule.length };\n}\n\n/** \"$100.00 total · 4 payments\" for a varied schedule, else null. `money` keeps each surface's money style. */\nexport function scheduleDealLabel(sub: ScheduleDealLike, money: (minor: number) => string): string | null {\n const deal = scheduleDeal(sub);\n return deal ? `${money(deal.total)} total · ${deal.payments} payments` : null;\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { useAuth } from '../../context';\nimport type { DeviceSession } from '../../../client';\nimport { AppearanceProvider, useAppearance, useAppearanceProviderValue, type ThrottleAppearance } from '../appearance';\nimport { useCopy, type ThrottleLocalization } from '../localization';\nimport { useAction } from '../useAction';\nimport { formatDate } from '../format';\nimport { describeDevice } from './device';\nimport { Alert, Badge, Button, DataTable, Field, Skeleton } from '../primitives';\nimport type { AccountPanelVariant } from './AddressesPanel';\n\nexport function SecurityPanel(props: {\n appearance?: ThrottleAppearance;\n localization?: ThrottleLocalization;\n variant?: AccountPanelVariant;\n}) {\n const a = useAppearance(props.appearance);\n const scoped = useAppearanceProviderValue(props.appearance);\n const { t, locale, errorMessage } = useCopy(props.localization);\n const { auth } = useAuth();\n const variant = props.variant ?? 'rows';\n const rowsVariant = variant === 'rows';\n const itemBase = rowsVariant ? 'throttle-rowitem' : 'throttle-listitem';\n // Revoking a session is destructive, so it keeps the danger colour even\n // when the rows variant strips the border — matching every other panel.\n // Plain 'link' made it pixel-identical to a neutral action, which is the\n // bug AddressesPanel's comment describes.\n const revokeVariant = rowsVariant ? 'linkDanger' : 'danger';\n\n const [password, setPassword] = useState('');\n const passwordAction = useAction();\n const sessionAction = useAction();\n\n const [sessions, setSessions] = useState<DeviceSession[] | null>(null);\n const [listError, setListError] = useState<string | null>(null);\n\n // `errorMessage` is held in a ref rather than listed as a dependency. It comes\n // from useCopy(props.localization), which re-memoises whenever the merchant\n // passes a fresh object literal — `<AccountDashboard localization={{ … }} />`\n // is the normal way to write it — so depending on it re-created `load` on\n // every parent render and re-fired GET /me/sessions each time. The callback\n // only needs the latest formatter, never a reason to be rebuilt.\n const errorMessageRef = useRef(errorMessage);\n useEffect(() => { errorMessageRef.current = errorMessage; });\n\n const load = useCallback(async () => {\n try {\n setSessions(await auth.listSessions());\n setListError(null);\n } catch (err) {\n setListError(errorMessageRef.current(err));\n }\n }, [auth]);\n\n useEffect(() => { void load(); }, [load]);\n\n const others = (sessions ?? []).filter((s) => !s.current);\n\n return (\n <AppearanceProvider value={scoped}>\n <div {...a.rootProps}>\n <div {...a.el('securityPanel.root', 'throttle-panel')}>\n <form\n {...a.el('securityPanel.passwordForm', 'throttle-stack')}\n onSubmit={(e) => {\n e.preventDefault();\n void passwordAction.run(async () => {\n // May raise step_up_required; the core opens the provider's dialog\n // and retries. Nothing to do here but await the result.\n await auth.changePassword(password);\n setPassword('');\n return t.security.changedNotice;\n });\n }}\n >\n <h3>{t.security.passwordTitle}</h3>\n <Field label={t.security.newPassword} type=\"password\" autoComplete=\"new-password\" required\n value={password} onChange={setPassword} />\n {passwordAction.error ? <Alert tone=\"error\">{passwordAction.error}</Alert> : null}\n {passwordAction.notice ? <Alert tone=\"success\">{passwordAction.notice}</Alert> : null}\n <Button type=\"submit\" loading={passwordAction.submitting} elementKey=\"securityPanel.passwordButton\">\n {t.security.changeButton}\n </Button>\n </form>\n\n <div {...a.el('securityPanel.sessionList', 'throttle-stack')}>\n <h3>{t.security.sessionsTitle}</h3>\n {listError ? (\n <>\n <Alert tone=\"error\">{listError}</Alert>\n <Button variant=\"secondary\" onClick={() => void load()}>{t.common.retry}</Button>\n </>\n ) : null}\n {sessionAction.error ? <Alert tone=\"error\">{sessionAction.error}</Alert> : null}\n {sessions === null && !listError ? <Skeleton count={2} /> : null}\n\n {sessions !== null && !listError && variant === 'table' ? (\n <DataTable\n tableKey=\"securityPanel.table\"\n rowElementKey=\"securityPanel.row\"\n rowKey={(session) => session.id}\n rows={sessions}\n columns={[\n { key: 'device', label: t.security.columnDevice, render: (session) => (\n <div className=\"throttle-row\">\n <span>{describeDevice(session.userAgent) || session.ipPrefix || session.id}</span>\n {session.current ? <Badge tone=\"success\">{t.security.thisDevice}</Badge> : null}\n </div>\n ) },\n { key: 'lastActive', label: t.security.lastActive, render: (session) => formatDate(session.lastUsedAt, locale) },\n { key: 'actions', label: t.common.actions, render: (session) => (\n !session.current ? (\n <Button\n variant=\"danger\"\n loading={sessionAction.submitting}\n elementKey=\"securityPanel.revokeButton\"\n onClick={() => void sessionAction.run(async () => {\n await auth.revokeSession(session.id);\n await load();\n })}\n >\n {t.security.revokeButton}\n </Button>\n ) : null\n ) },\n ]}\n />\n ) : (\n (sessions ?? []).map((session) => (\n <div key={session.id} {...a.el('securityPanel.sessionItem', itemBase)}>\n <div>\n <div className=\"throttle-row\">\n <strong>{describeDevice(session.userAgent) || session.ipPrefix || session.id}</strong>\n {session.current ? <Badge tone=\"success\">{t.security.thisDevice}</Badge> : null}\n </div>\n <p className=\"throttle-muted\">\n {t.security.lastActive} {formatDate(session.lastUsedAt, locale)}\n </p>\n </div>\n {/* No revoke on the current session: that is just signing out, and\n a button that logs you out while labelled \"sign out of this\n device\" in a device list is a trap. */}\n {!session.current ? (\n <Button\n variant={revokeVariant}\n loading={sessionAction.submitting}\n elementKey=\"securityPanel.revokeButton\"\n onClick={() => void sessionAction.run(async () => {\n await auth.revokeSession(session.id);\n await load();\n })}\n >\n {t.security.revokeButton}\n </Button>\n ) : null}\n </div>\n ))\n )}\n\n {sessions !== null && others.length === 0 ? (\n <p className=\"throttle-muted\">{t.security.sessionsEmpty}</p>\n ) : null}\n\n {others.length > 0 ? (\n <Button\n variant=\"danger\"\n loading={sessionAction.submitting}\n elementKey=\"securityPanel.revokeAllButton\"\n onClick={() => void sessionAction.run(async () => {\n // Revoke the other sessions individually rather than calling\n // signOutEverywhere(). That posts /auth/logout-all, which\n // revokes EVERY session including this one and then clears\n // local state — so a button labelled \"all other devices\"\n // signed the buyer out of the device they were reading it on\n // and blanked the dashboard with no explanation. Exactly the\n // trap the per-row comment above rejects.\n //\n // `others` is already the list this button is gated on, and\n // the per-row control uses this same endpoint. A session\n // created between the load and the click is missed; that is\n // worth far less than not logging the buyer out by surprise,\n // and the reload below immediately shows any that remain.\n for (const session of others) {\n await auth.revokeSession(session.id);\n }\n await load();\n })}\n >\n {t.security.revokeAllButton}\n </Button>\n ) : null}\n </div>\n </div>\n </div>\n </AppearanceProvider>\n );\n}\n","/**\n * Turns a session's user agent into something a shopper can recognise.\n *\n * The device list exists so a buyer can spot a session that is not theirs and\n * revoke it. A raw 120-character UA string does not support that decision, so\n * this reduces it to browser + platform. Order matters in both tables: Edge and\n * Opera both carry \"Chrome\", and Chrome carries \"Safari\", so the more specific\n * pattern has to be tested first or every Edge session reads as Chrome.\n */\nconst BROWSERS: ReadonlyArray<readonly [RegExp, string]> = [\n [/\\bEdg(?:e|A|iOS)?\\//, 'Edge'],\n [/\\bOPR\\/|\\bOpera\\b/, 'Opera'],\n // No leading \\b: real agents ship prefixed builds (HeadlessChrome), and a\n // word boundary there sends them to the Safari rule instead.\n [/Chrome\\/|CriOS\\//, 'Chrome'],\n [/\\bFirefox\\/|\\bFxiOS\\//, 'Firefox'],\n [/\\bSafari\\//, 'Safari'],\n];\n\nconst PLATFORMS: ReadonlyArray<readonly [RegExp, string]> = [\n [/\\biPhone\\b|\\biPad\\b|\\biPod\\b/, 'iOS'],\n [/\\bAndroid\\b/, 'Android'],\n [/\\bMac OS X\\b|\\bMacintosh\\b/, 'macOS'],\n [/\\bWindows\\b/, 'Windows'],\n [/\\bLinux\\b|\\bX11\\b/, 'Linux'],\n];\n\nfunction first(ua: string, table: ReadonlyArray<readonly [RegExp, string]>) {\n for (const [pattern, label] of table) if (pattern.test(ua)) return label;\n return null;\n}\n\nexport function describeDevice(userAgent: string | null | undefined): string {\n const ua = (userAgent ?? '').trim();\n if (!ua) return '';\n const browser = first(ua, BROWSERS);\n // Nothing recognisable — an API client or a bot. Its own name is the most\n // useful thing we can show, so hand the string back untouched.\n if (!browser) return ua;\n const platform = first(ua, PLATFORMS);\n return platform ? `${browser} on ${platform}` : browser;\n}\n"],"mappings":"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","names":["useId","useEffect","useId","useState","jsx","jsxs","useState","jsx","jsxs","jsx","jsxs","useState","useState","useState","jsx","jsxs","useState","Fragment","jsx","jsxs","useState","useState","useEffect","useRef","useState","jsx","jsxs","useState","useRef","useEffect","jsx","jsxs","useState","useEffect","useState","Fragment","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","useState","useEffect","useEffect","useState","jsx","jsxs","Line","jsx","jsxs","useState","useEffect","useState","Fragment","jsx","jsxs","CAN_CANCEL","useState","useEffect","useRef","useState","Fragment","jsx","jsxs","useState","useRef","useEffect","Fragment","jsx","jsxs","useState","useId","useEffect","jsx","jsxs","useId"]}
|