@burdenoff/microfe-subscriberbot 2026.1014.1 → 2026.1023.2

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.
Files changed (48) hide show
  1. package/dist/node_modules/clsx/dist/clsx.js.map +1 -1
  2. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +97 -18
  3. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -1
  4. package/dist/subscriberbot/SubscriberBotRoot.js.map +1 -1
  5. package/dist/subscriberbot/SubscriberBotRoutes.js.map +1 -1
  6. package/dist/subscriberbot/admin/AdminDashboardPage.js.map +1 -1
  7. package/dist/subscriberbot/admin/AdminRoot.js.map +1 -1
  8. package/dist/subscriberbot/components/EmptyState.js.map +1 -1
  9. package/dist/subscriberbot/components/MetricsCard.js.map +1 -1
  10. package/dist/subscriberbot/components/Modal.js.map +1 -1
  11. package/dist/subscriberbot/components/PageLayout.js.map +1 -1
  12. package/dist/subscriberbot/components/StateViews.js.map +1 -1
  13. package/dist/subscriberbot/components/StatusBadge.js.map +1 -1
  14. package/dist/subscriberbot/components/viz.js.map +1 -1
  15. package/dist/subscriberbot/context/SubscriberBotContext.js.map +1 -1
  16. package/dist/subscriberbot/hooks/useSubscriberBotApi.d.ts +19 -19
  17. package/dist/subscriberbot/hooks/useSubscriberBotApi.d.ts.map +1 -1
  18. package/dist/subscriberbot/hooks/useSubscriberBotApi.js +9 -0
  19. package/dist/subscriberbot/hooks/useSubscriberBotApi.js.map +1 -1
  20. package/dist/subscriberbot/hooks/useTr.js.map +1 -1
  21. package/dist/subscriberbot/pages/AssetVaultPage.js.map +1 -1
  22. package/dist/subscriberbot/pages/DashboardPage.d.ts.map +1 -1
  23. package/dist/subscriberbot/pages/DashboardPage.js +4 -4
  24. package/dist/subscriberbot/pages/DashboardPage.js.map +1 -1
  25. package/dist/subscriberbot/pages/InboxPage.js.map +1 -1
  26. package/dist/subscriberbot/pages/InsightsPage.js.map +1 -1
  27. package/dist/subscriberbot/pages/InvoicesPage.js.map +1 -1
  28. package/dist/subscriberbot/pages/WorkflowsPage.js.map +1 -1
  29. package/dist/subscriberbot/pages/agents/AgentDetailPage.js.map +1 -1
  30. package/dist/subscriberbot/pages/agents/AgentNewPage.js.map +1 -1
  31. package/dist/subscriberbot/pages/agents/AgentsListPage.js.map +1 -1
  32. package/dist/subscriberbot/pages/providers/ProviderDetailPage.js.map +1 -1
  33. package/dist/subscriberbot/pages/providers/ProviderNewPage.js.map +1 -1
  34. package/dist/subscriberbot/pages/providers/ProvidersListPage.js.map +1 -1
  35. package/dist/subscriberbot/pages/relationships/RelationshipDetailPage.d.ts.map +1 -1
  36. package/dist/subscriberbot/pages/relationships/RelationshipDetailPage.js +48 -15
  37. package/dist/subscriberbot/pages/relationships/RelationshipDetailPage.js.map +1 -1
  38. package/dist/subscriberbot/pages/relationships/RelationshipNewPage.js.map +1 -1
  39. package/dist/subscriberbot/pages/relationships/RelationshipsListPage.js.map +1 -1
  40. package/dist/subscriberbot/services/createSandboxAssistantTransport.js.map +1 -1
  41. package/dist/subscriberbot/store/subscriberbotStore.js.map +1 -1
  42. package/dist/subscriberbot/types/index.d.ts +1 -0
  43. package/dist/subscriberbot/types/index.d.ts.map +1 -1
  44. package/dist/subscriberbot/utils/cn.js.map +1 -1
  45. package/dist/subscriberbot/utils/formatters.js.map +1 -1
  46. package/dist/subscriberbot/utils/navigation.js.map +1 -1
  47. package/dist/subscriberbot/utils/pageContext.js.map +1 -1
  48. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"RelationshipNewPage.js","names":[],"sources":["../../../../src/subscriberbot/pages/relationships/RelationshipNewPage.tsx"],"sourcesContent":["/**\n * Create relationship\n * @module subscriberbot/pages/relationships\n *\n * Manual-add form for a recurring relationship AI can't auto-detect.\n * Writes `subCreateRelationship`. Provider + plan are optional pickers\n * sourced from the real registry (`subListProviders` / `subListPlans`).\n */\n\nimport { useState, type ReactNode } from 'react';\nimport { ArrowLeft, Tag, Building2, Wallet, StickyNote } from 'lucide-react';\nimport { GlassCard, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { ErrorView } from '../../components/StateViews';\nimport { useSubscriberBot } from '../../context/SubscriberBotContext';\nimport { useCreateRelationship, useProviders, usePlans } from '../../hooks/useSubscriberBotApi';\nimport { useTr } from '../../hooks/useTr';\nimport { formatEnumLabel } from '../../utils/formatters';\nimport type {\n SubBillingInterval,\n SubCreateRelationshipInput,\n SubRelationshipKind,\n} from '../../types';\n\nconst KINDS: SubRelationshipKind[] = [\n 'SUBSCRIPTION',\n 'MEMBERSHIP',\n 'LICENSE',\n 'CONTRACT',\n 'NEWSLETTER',\n 'RECURRING_PAYMENT',\n 'ENROLLMENT',\n 'TRIAL',\n];\n\nconst INTERVALS: SubBillingInterval[] = [\n 'MONTHLY',\n 'YEARLY',\n 'QUARTERLY',\n 'WEEKLY',\n 'DAILY',\n 'USAGE_BASED',\n 'LIFETIME',\n 'FREE',\n];\n\nconst KIND_KEY: Record<SubRelationshipKind, string> = {\n SUBSCRIPTION: 'relationships.kinds.subscription',\n MEMBERSHIP: 'relationships.kinds.membership',\n LICENSE: 'relationships.kinds.license',\n CONTRACT: 'relationships.kinds.contract',\n NEWSLETTER: 'relationships.kinds.newsletter',\n RECURRING_PAYMENT: 'relationships.kinds.recurringPayment',\n ENROLLMENT: 'relationships.kinds.enrollment',\n TRIAL: 'relationships.kinds.trial',\n};\n\nconst inputCls =\n 'w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2.5 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]';\nconst labelCls = 'mb-1.5 block text-xs font-medium text-text-secondary';\n\n/** Grouped form section on a glass surface. */\nfunction FormSection({\n icon,\n title,\n description,\n children,\n}: {\n icon: ReactNode;\n title: string;\n description: string;\n children: ReactNode;\n}) {\n return (\n <GlassCard treatment=\"metric\" className=\"p-5 sm:p-6\">\n <div className=\"flex items-start gap-3\">\n <span className=\"mt-0.5 flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-bg-sunken text-text-secondary\">\n {icon}\n </span>\n <div className=\"min-w-0\">\n <h2 className=\"text-sm font-semibold text-text-primary\">{title}</h2>\n <p className=\"mt-0.5 text-xs text-text-secondary\">{description}</p>\n </div>\n </div>\n <div className=\"mt-4\">{children}</div>\n </GlassCard>\n );\n}\n\nexport function RelationshipNewPage() {\n const tr = useTr();\n const { navigateTo } = useSubscriberBot();\n const create = useCreateRelationship();\n const providersQ = useProviders({ pagination: { limit: 100, offset: 0 } });\n\n const [label, setLabel] = useState('');\n const [kind, setKind] = useState<SubRelationshipKind>('SUBSCRIPTION');\n const [providerId, setProviderId] = useState('');\n const [planId, setPlanId] = useState('');\n const [amount, setAmount] = useState('');\n const [currency, setCurrency] = useState('USD');\n const [interval, setInterval] = useState<SubBillingInterval>('MONTHLY');\n const [renewsAt, setRenewsAt] = useState('');\n const [autoRenew, setAutoRenew] = useState(true);\n const [notes, setNotes] = useState('');\n const [formError, setFormError] = useState<string | null>(null);\n\n const plansQ = usePlans(providerId || undefined);\n const providers = providersQ.data?.items ?? [];\n const plans = plansQ.data ?? [];\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n setFormError(null);\n if (!label.trim()) {\n setFormError(tr('relationships.new.basics.labelRequired', 'A label is required.'));\n return;\n }\n const input: SubCreateRelationshipInput = {\n label: label.trim(),\n kind,\n interval,\n autoRenew,\n currency: currency.trim() || 'USD',\n ...(providerId ? { providerId } : {}),\n ...(planId ? { planId } : {}),\n ...(amount ? { amount: Number(amount) } : {}),\n ...(renewsAt ? { renewsAt: new Date(renewsAt).toISOString() } : {}),\n ...(notes.trim() ? { notes: notes.trim() } : {}),\n };\n create.mutate(input, {\n onSuccess: (rel) => navigateTo(`/relationships/${rel.id}`),\n onError: (err) =>\n setFormError(\n err instanceof Error\n ? err.message\n : tr('relationships.new.error', 'Could not create relationship.')\n ),\n });\n };\n\n if (providersQ.isError) {\n return (\n <PageLayout title={tr('relationships.new.title', 'Add relationship')}>\n <ErrorView\n message={tr('relationships.new.providerError', 'Could not load the provider registry.')}\n onRetry={() => void providersQ.refetch()}\n />\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title={tr('relationships.new.title', 'Add relationship')}\n description={tr(\n 'relationships.new.description',\n 'Track a new recurring digital relationship'\n )}\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/relationships')}\n className=\"inline-flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken\"\n >\n <ArrowLeft className=\"h-4 w-4\" /> {tr('relationships.new.back', 'Back')}\n </button>\n }\n >\n <PagePurpose className=\"mb-6\">\n {tr(\n 'relationships.new.purpose',\n 'Manually add a subscription, membership, license or contract. Link it to a provider and plan from the registry, set the price and renewal date, and Subscriber Bot will track its lifecycle from here.'\n )}\n </PagePurpose>\n\n <form onSubmit={handleSubmit} className=\"max-w-3xl space-y-5\">\n {formError && (\n <div className=\"rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-4 py-2 text-sm text-status-error-text\">\n {formError}\n </div>\n )}\n\n {/* Basics */}\n <FormSection\n icon={<Tag className=\"h-4 w-4\" />}\n title={tr('relationships.new.basics.title', 'Basics')}\n description={tr(\n 'relationships.new.basics.description',\n 'Name this relationship and choose what kind it is.'\n )}\n >\n <div className=\"space-y-4\">\n <div>\n <label htmlFor=\"rel-label\" className={labelCls}>\n {tr('relationships.new.basics.labelLabel', 'Label')}{' '}\n <span className=\"text-status-error-text\">*</span>\n </label>\n <input\n id=\"rel-label\"\n type=\"text\"\n value={label}\n onChange={(e) => setLabel(e.target.value)}\n placeholder={tr(\n 'relationships.new.basics.labelPlaceholder',\n 'e.g. Netflix Premium, AWS Production'\n )}\n className={inputCls}\n required\n />\n </div>\n <div className=\"max-w-xs\">\n <label htmlFor=\"rel-kind\" className={labelCls}>\n {tr('relationships.new.basics.kindLabel', 'Kind')}\n </label>\n <select\n id=\"rel-kind\"\n value={kind}\n onChange={(e) => setKind(e.target.value as SubRelationshipKind)}\n className={inputCls}\n >\n {KINDS.map((k) => (\n <option key={k} value={k}>\n {tr(KIND_KEY[k], formatEnumLabel(k))}\n </option>\n ))}\n </select>\n </div>\n </div>\n </FormSection>\n\n {/* Provider & plan */}\n <FormSection\n icon={<Building2 className=\"h-4 w-4\" />}\n title={tr('relationships.new.providerPlan.title', 'Provider & plan')}\n description={tr(\n 'relationships.new.providerPlan.description',\n 'Link this relationship to a provider and plan from the registry (optional).'\n )}\n >\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label htmlFor=\"rel-provider\" className={labelCls}>\n {tr('relationships.new.providerPlan.providerLabel', 'Provider')}\n </label>\n <select\n id=\"rel-provider\"\n value={providerId}\n onChange={(e) => {\n setProviderId(e.target.value);\n setPlanId('');\n }}\n className={inputCls}\n >\n <option value=\"\">\n {tr('relationships.new.providerPlan.providerNone', '— None —')}\n </option>\n {providers.map((p) => (\n <option key={p.id} value={p.id}>\n {p.name}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label htmlFor=\"rel-plan\" className={labelCls}>\n {tr('relationships.new.providerPlan.planLabel', 'Plan')}\n </label>\n <select\n id=\"rel-plan\"\n value={planId}\n onChange={(e) => setPlanId(e.target.value)}\n className={inputCls}\n disabled={!providerId || plans.length === 0}\n >\n <option value=\"\">\n {providerId\n ? plans.length === 0\n ? tr('relationships.new.providerPlan.noPlans', 'No plans available')\n : tr('relationships.new.providerPlan.planNone', '— None —')\n : tr(\n 'relationships.new.providerPlan.selectProviderFirst',\n 'Select a provider first'\n )}\n </option>\n {plans.map((pl) => (\n <option key={pl.id} value={pl.id}>\n {pl.name}\n </option>\n ))}\n </select>\n </div>\n </div>\n </FormSection>\n\n {/* Pricing & billing */}\n <FormSection\n icon={<Wallet className=\"h-4 w-4\" />}\n title={tr('relationships.new.pricing.title', 'Pricing & billing')}\n description={tr(\n 'relationships.new.pricing.description',\n 'Set the price, cadence and next renewal so Subscriber Bot can track it.'\n )}\n >\n <div className=\"space-y-4\">\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <div>\n <label htmlFor=\"rel-amount\" className={labelCls}>\n {tr('relationships.new.pricing.amountLabel', 'Amount')}\n </label>\n <input\n id=\"rel-amount\"\n type=\"number\"\n min=\"0\"\n step=\"0.01\"\n value={amount}\n onChange={(e) => setAmount(e.target.value)}\n placeholder={tr('relationships.new.pricing.amountPlaceholder', '0.00')}\n className={inputCls}\n />\n </div>\n <div>\n <label htmlFor=\"rel-currency\" className={labelCls}>\n {tr('relationships.new.pricing.currencyLabel', 'Currency')}\n </label>\n <input\n id=\"rel-currency\"\n type=\"text\"\n value={currency}\n onChange={(e) => setCurrency(e.target.value.toUpperCase())}\n placeholder={tr('relationships.new.pricing.currencyPlaceholder', 'USD')}\n maxLength={3}\n className={inputCls}\n />\n </div>\n <div>\n <label htmlFor=\"rel-interval\" className={labelCls}>\n {tr('relationships.new.pricing.intervalLabel', 'Billing interval')}\n </label>\n <select\n id=\"rel-interval\"\n value={interval}\n onChange={(e) => setInterval(e.target.value as SubBillingInterval)}\n className={inputCls}\n >\n {INTERVALS.map((i) => (\n <option key={i} value={i}>\n {formatEnumLabel(i)}\n </option>\n ))}\n </select>\n </div>\n </div>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label htmlFor=\"rel-renews\" className={labelCls}>\n {tr('relationships.new.pricing.renewsOnLabel', 'Renews on')}\n </label>\n <input\n id=\"rel-renews\"\n type=\"date\"\n value={renewsAt}\n onChange={(e) => setRenewsAt(e.target.value)}\n className={inputCls}\n />\n </div>\n <label className=\"flex items-center gap-3 rounded-lg border border-border-subtle bg-bg-surface px-3 py-2.5 sm:mt-6\">\n <input\n type=\"checkbox\"\n checked={autoRenew}\n onChange={(e) => setAutoRenew(e.target.checked)}\n className=\"size-4 rounded border-border-subtle\"\n />\n <span className=\"text-sm text-text-primary\">\n {tr('relationships.new.pricing.autoRenews', 'Auto-renews')}\n </span>\n </label>\n </div>\n </div>\n </FormSection>\n\n {/* Notes */}\n <FormSection\n icon={<StickyNote className=\"h-4 w-4\" />}\n title={tr('relationships.new.notes.title', 'Notes')}\n description={tr(\n 'relationships.new.notes.description',\n 'Anything worth remembering about this relationship.'\n )}\n >\n <textarea\n id=\"rel-notes\"\n aria-label={tr('relationships.new.notes.title', 'Notes')}\n value={notes}\n onChange={(e) => setNotes(e.target.value)}\n rows={3}\n placeholder={tr(\n 'relationships.new.notes.placeholder',\n 'Anything worth remembering about this relationship…'\n )}\n className={inputCls}\n />\n </FormSection>\n\n <div className=\"flex flex-col gap-3 sm:flex-row\">\n <button\n type=\"submit\"\n disabled={create.isPending}\n className=\"rounded-lg bg-action-primary-bg px-5 py-2.5 text-sm font-medium text-action-primary-text hover:opacity-90 disabled:opacity-50\"\n >\n {create.isPending\n ? tr('relationships.new.creating', 'Creating…')\n : tr('relationships.new.submit', 'Create relationship')}\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo('/relationships')}\n className=\"rounded-lg border border-border-subtle px-5 py-2.5 text-sm font-medium text-text-primary hover:bg-bg-sunken\"\n >\n {tr('relationships.new.cancel', 'Cancel')}\n </button>\n </div>\n </form>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"RelationshipNewPage.js","names":[],"sources":["../../../../src/subscriberbot/pages/relationships/RelationshipNewPage.tsx"],"sourcesContent":["/**\n * Create relationship\n * @module subscriberbot/pages/relationships\n *\n * Manual-add form for a recurring relationship AI can't auto-detect.\n * Writes `subCreateRelationship`. Provider + plan are optional pickers\n * sourced from the real registry (`subListProviders` / `subListPlans`).\n */\n\nimport { useState, type ReactNode } from 'react';\nimport { ArrowLeft, Tag, Building2, Wallet, StickyNote } from 'lucide-react';\nimport { GlassCard, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { ErrorView } from '../../components/StateViews';\nimport { useSubscriberBot } from '../../context/SubscriberBotContext';\nimport { useCreateRelationship, useProviders, usePlans } from '../../hooks/useSubscriberBotApi';\nimport { useTr } from '../../hooks/useTr';\nimport { formatEnumLabel } from '../../utils/formatters';\nimport type {\n SubBillingInterval,\n SubCreateRelationshipInput,\n SubRelationshipKind,\n} from '../../types';\n\nconst KINDS: SubRelationshipKind[] = [\n 'SUBSCRIPTION',\n 'MEMBERSHIP',\n 'LICENSE',\n 'CONTRACT',\n 'NEWSLETTER',\n 'RECURRING_PAYMENT',\n 'ENROLLMENT',\n 'TRIAL',\n];\n\nconst INTERVALS: SubBillingInterval[] = [\n 'MONTHLY',\n 'YEARLY',\n 'QUARTERLY',\n 'WEEKLY',\n 'DAILY',\n 'USAGE_BASED',\n 'LIFETIME',\n 'FREE',\n];\n\nconst KIND_KEY: Record<SubRelationshipKind, string> = {\n SUBSCRIPTION: 'relationships.kinds.subscription',\n MEMBERSHIP: 'relationships.kinds.membership',\n LICENSE: 'relationships.kinds.license',\n CONTRACT: 'relationships.kinds.contract',\n NEWSLETTER: 'relationships.kinds.newsletter',\n RECURRING_PAYMENT: 'relationships.kinds.recurringPayment',\n ENROLLMENT: 'relationships.kinds.enrollment',\n TRIAL: 'relationships.kinds.trial',\n};\n\nconst inputCls =\n 'w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2.5 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]';\nconst labelCls = 'mb-1.5 block text-xs font-medium text-text-secondary';\n\n/** Grouped form section on a glass surface. */\nfunction FormSection({\n icon,\n title,\n description,\n children,\n}: {\n icon: ReactNode;\n title: string;\n description: string;\n children: ReactNode;\n}) {\n return (\n <GlassCard treatment=\"metric\" className=\"p-5 sm:p-6\">\n <div className=\"flex items-start gap-3\">\n <span className=\"mt-0.5 flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-bg-sunken text-text-secondary\">\n {icon}\n </span>\n <div className=\"min-w-0\">\n <h2 className=\"text-sm font-semibold text-text-primary\">{title}</h2>\n <p className=\"mt-0.5 text-xs text-text-secondary\">{description}</p>\n </div>\n </div>\n <div className=\"mt-4\">{children}</div>\n </GlassCard>\n );\n}\n\nexport function RelationshipNewPage() {\n const tr = useTr();\n const { navigateTo } = useSubscriberBot();\n const create = useCreateRelationship();\n const providersQ = useProviders({ pagination: { limit: 100, offset: 0 } });\n\n const [label, setLabel] = useState('');\n const [kind, setKind] = useState<SubRelationshipKind>('SUBSCRIPTION');\n const [providerId, setProviderId] = useState('');\n const [planId, setPlanId] = useState('');\n const [amount, setAmount] = useState('');\n const [currency, setCurrency] = useState('USD');\n const [interval, setInterval] = useState<SubBillingInterval>('MONTHLY');\n const [renewsAt, setRenewsAt] = useState('');\n const [autoRenew, setAutoRenew] = useState(true);\n const [notes, setNotes] = useState('');\n const [formError, setFormError] = useState<string | null>(null);\n\n const plansQ = usePlans(providerId || undefined);\n const providers = providersQ.data?.items ?? [];\n const plans = plansQ.data ?? [];\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n setFormError(null);\n if (!label.trim()) {\n setFormError(tr('relationships.new.basics.labelRequired', 'A label is required.'));\n return;\n }\n const input: SubCreateRelationshipInput = {\n label: label.trim(),\n kind,\n interval,\n autoRenew,\n currency: currency.trim() || 'USD',\n ...(providerId ? { providerId } : {}),\n ...(planId ? { planId } : {}),\n ...(amount ? { amount: Number(amount) } : {}),\n ...(renewsAt ? { renewsAt: new Date(renewsAt).toISOString() } : {}),\n ...(notes.trim() ? { notes: notes.trim() } : {}),\n };\n create.mutate(input, {\n onSuccess: (rel) => navigateTo(`/relationships/${rel.id}`),\n onError: (err) =>\n setFormError(\n err instanceof Error\n ? err.message\n : tr('relationships.new.error', 'Could not create relationship.')\n ),\n });\n };\n\n if (providersQ.isError) {\n return (\n <PageLayout title={tr('relationships.new.title', 'Add relationship')}>\n <ErrorView\n message={tr('relationships.new.providerError', 'Could not load the provider registry.')}\n onRetry={() => void providersQ.refetch()}\n />\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title={tr('relationships.new.title', 'Add relationship')}\n description={tr(\n 'relationships.new.description',\n 'Track a new recurring digital relationship'\n )}\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/relationships')}\n className=\"inline-flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken\"\n >\n <ArrowLeft className=\"h-4 w-4\" /> {tr('relationships.new.back', 'Back')}\n </button>\n }\n >\n <PagePurpose className=\"mb-6\">\n {tr(\n 'relationships.new.purpose',\n 'Manually add a subscription, membership, license or contract. Link it to a provider and plan from the registry, set the price and renewal date, and Subscriber Bot will track its lifecycle from here.'\n )}\n </PagePurpose>\n\n <form onSubmit={handleSubmit} className=\"max-w-3xl space-y-5\">\n {formError && (\n <div className=\"rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-4 py-2 text-sm text-status-error-text\">\n {formError}\n </div>\n )}\n\n {/* Basics */}\n <FormSection\n icon={<Tag className=\"h-4 w-4\" />}\n title={tr('relationships.new.basics.title', 'Basics')}\n description={tr(\n 'relationships.new.basics.description',\n 'Name this relationship and choose what kind it is.'\n )}\n >\n <div className=\"space-y-4\">\n <div>\n <label htmlFor=\"rel-label\" className={labelCls}>\n {tr('relationships.new.basics.labelLabel', 'Label')}{' '}\n <span className=\"text-status-error-text\">*</span>\n </label>\n <input\n id=\"rel-label\"\n type=\"text\"\n value={label}\n onChange={(e) => setLabel(e.target.value)}\n placeholder={tr(\n 'relationships.new.basics.labelPlaceholder',\n 'e.g. Netflix Premium, AWS Production'\n )}\n className={inputCls}\n required\n />\n </div>\n <div className=\"max-w-xs\">\n <label htmlFor=\"rel-kind\" className={labelCls}>\n {tr('relationships.new.basics.kindLabel', 'Kind')}\n </label>\n <select\n id=\"rel-kind\"\n value={kind}\n onChange={(e) => setKind(e.target.value as SubRelationshipKind)}\n className={inputCls}\n >\n {KINDS.map((k) => (\n <option key={k} value={k}>\n {tr(KIND_KEY[k], formatEnumLabel(k))}\n </option>\n ))}\n </select>\n </div>\n </div>\n </FormSection>\n\n {/* Provider & plan */}\n <FormSection\n icon={<Building2 className=\"h-4 w-4\" />}\n title={tr('relationships.new.providerPlan.title', 'Provider & plan')}\n description={tr(\n 'relationships.new.providerPlan.description',\n 'Link this relationship to a provider and plan from the registry (optional).'\n )}\n >\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label htmlFor=\"rel-provider\" className={labelCls}>\n {tr('relationships.new.providerPlan.providerLabel', 'Provider')}\n </label>\n <select\n id=\"rel-provider\"\n value={providerId}\n onChange={(e) => {\n setProviderId(e.target.value);\n setPlanId('');\n }}\n className={inputCls}\n >\n <option value=\"\">\n {tr('relationships.new.providerPlan.providerNone', '— None —')}\n </option>\n {providers.map((p) => (\n <option key={p.id} value={p.id}>\n {p.name}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label htmlFor=\"rel-plan\" className={labelCls}>\n {tr('relationships.new.providerPlan.planLabel', 'Plan')}\n </label>\n <select\n id=\"rel-plan\"\n value={planId}\n onChange={(e) => setPlanId(e.target.value)}\n className={inputCls}\n disabled={!providerId || plans.length === 0}\n >\n <option value=\"\">\n {providerId\n ? plans.length === 0\n ? tr('relationships.new.providerPlan.noPlans', 'No plans available')\n : tr('relationships.new.providerPlan.planNone', '— None —')\n : tr(\n 'relationships.new.providerPlan.selectProviderFirst',\n 'Select a provider first'\n )}\n </option>\n {plans.map((pl) => (\n <option key={pl.id} value={pl.id}>\n {pl.name}\n </option>\n ))}\n </select>\n </div>\n </div>\n </FormSection>\n\n {/* Pricing & billing */}\n <FormSection\n icon={<Wallet className=\"h-4 w-4\" />}\n title={tr('relationships.new.pricing.title', 'Pricing & billing')}\n description={tr(\n 'relationships.new.pricing.description',\n 'Set the price, cadence and next renewal so Subscriber Bot can track it.'\n )}\n >\n <div className=\"space-y-4\">\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <div>\n <label htmlFor=\"rel-amount\" className={labelCls}>\n {tr('relationships.new.pricing.amountLabel', 'Amount')}\n </label>\n <input\n id=\"rel-amount\"\n type=\"number\"\n min=\"0\"\n step=\"0.01\"\n value={amount}\n onChange={(e) => setAmount(e.target.value)}\n placeholder={tr('relationships.new.pricing.amountPlaceholder', '0.00')}\n className={inputCls}\n />\n </div>\n <div>\n <label htmlFor=\"rel-currency\" className={labelCls}>\n {tr('relationships.new.pricing.currencyLabel', 'Currency')}\n </label>\n <input\n id=\"rel-currency\"\n type=\"text\"\n value={currency}\n onChange={(e) => setCurrency(e.target.value.toUpperCase())}\n placeholder={tr('relationships.new.pricing.currencyPlaceholder', 'USD')}\n maxLength={3}\n className={inputCls}\n />\n </div>\n <div>\n <label htmlFor=\"rel-interval\" className={labelCls}>\n {tr('relationships.new.pricing.intervalLabel', 'Billing interval')}\n </label>\n <select\n id=\"rel-interval\"\n value={interval}\n onChange={(e) => setInterval(e.target.value as SubBillingInterval)}\n className={inputCls}\n >\n {INTERVALS.map((i) => (\n <option key={i} value={i}>\n {formatEnumLabel(i)}\n </option>\n ))}\n </select>\n </div>\n </div>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label htmlFor=\"rel-renews\" className={labelCls}>\n {tr('relationships.new.pricing.renewsOnLabel', 'Renews on')}\n </label>\n <input\n id=\"rel-renews\"\n type=\"date\"\n value={renewsAt}\n onChange={(e) => setRenewsAt(e.target.value)}\n className={inputCls}\n />\n </div>\n <label className=\"flex items-center gap-3 rounded-lg border border-border-subtle bg-bg-surface px-3 py-2.5 sm:mt-6\">\n <input\n type=\"checkbox\"\n checked={autoRenew}\n onChange={(e) => setAutoRenew(e.target.checked)}\n className=\"size-4 rounded border-border-subtle\"\n />\n <span className=\"text-sm text-text-primary\">\n {tr('relationships.new.pricing.autoRenews', 'Auto-renews')}\n </span>\n </label>\n </div>\n </div>\n </FormSection>\n\n {/* Notes */}\n <FormSection\n icon={<StickyNote className=\"h-4 w-4\" />}\n title={tr('relationships.new.notes.title', 'Notes')}\n description={tr(\n 'relationships.new.notes.description',\n 'Anything worth remembering about this relationship.'\n )}\n >\n <textarea\n id=\"rel-notes\"\n aria-label={tr('relationships.new.notes.title', 'Notes')}\n value={notes}\n onChange={(e) => setNotes(e.target.value)}\n rows={3}\n placeholder={tr(\n 'relationships.new.notes.placeholder',\n 'Anything worth remembering about this relationship…'\n )}\n className={inputCls}\n />\n </FormSection>\n\n <div className=\"flex flex-col gap-3 sm:flex-row\">\n <button\n type=\"submit\"\n disabled={create.isPending}\n className=\"rounded-lg bg-action-primary-bg px-5 py-2.5 text-sm font-medium text-action-primary-text hover:opacity-90 disabled:opacity-50\"\n >\n {create.isPending\n ? tr('relationships.new.creating', 'Creating…')\n : tr('relationships.new.submit', 'Create relationship')}\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo('/relationships')}\n className=\"rounded-lg border border-border-subtle px-5 py-2.5 text-sm font-medium text-text-primary hover:bg-bg-sunken\"\n >\n {tr('relationships.new.cancel', 'Cancel')}\n </button>\n </div>\n </form>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;AAwBA,IAAM,IAA+B;CACnC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,GAEM,IAAkC;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,GAEM,IAAgD;CACpD,cAAc;CACd,YAAY;CACZ,SAAS;CACT,UAAU;CACV,YAAY;CACZ,mBAAmB;CACnB,YAAY;CACZ,OAAO;AACT,GAEM,IACJ,0MACI,IAAW;AAGjB,SAAS,EAAY,EACnB,SACA,UACA,gBACA,eAMC;CACD,OACE,kBAAC,GAAD;EAAW,WAAU;EAAS,WAAU;YAAxC,CACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,QAAD;IAAM,WAAU;cACb;GACG,CAAA,GACN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,MAAD;KAAI,WAAU;eAA2C;IAAU,CAAA,GACnE,kBAAC,KAAD;KAAG,WAAU;eAAsC;IAAe,CAAA,CAC/D;KACF;MACL,kBAAC,OAAD;GAAK,WAAU;GAAQ;EAAc,CAAA,CAC5B;;AAEf;AAEA,SAAgB,IAAsB;CACpC,IAAM,IAAK,EAAM,GACX,EAAE,kBAAe,EAAiB,GAClC,IAAS,EAAsB,GAC/B,IAAa,EAAa,EAAE,YAAY;EAAE,OAAO;EAAK,QAAQ;CAAE,EAAE,CAAC,GAEnE,CAAC,GAAO,KAAY,EAAS,EAAE,GAC/B,CAAC,GAAM,KAAW,EAA8B,cAAc,GAC9D,CAAC,GAAY,KAAiB,EAAS,EAAE,GACzC,CAAC,GAAQ,KAAa,EAAS,EAAE,GACjC,CAAC,GAAQ,KAAa,EAAS,EAAE,GACjC,CAAC,GAAU,KAAe,EAAS,KAAK,GACxC,CAAC,GAAU,KAAe,EAA6B,SAAS,GAChE,CAAC,GAAU,KAAe,EAAS,EAAE,GACrC,CAAC,GAAW,KAAgB,EAAS,EAAI,GACzC,CAAC,GAAO,KAAY,EAAS,EAAE,GAC/B,CAAC,GAAW,KAAgB,EAAwB,IAAI,GAExD,IAAS,EAAS,KAAc,KAAA,CAAS,GACzC,IAAY,EAAW,MAAM,SAAS,CAAC,GACvC,IAAQ,EAAO,QAAQ,CAAC;CA2C9B,OAXI,EAAW,UAEX,kBAAC,GAAD;EAAY,OAAO,EAAG,2BAA2B,kBAAkB;YACjE,kBAAC,GAAD;GACE,SAAS,EAAG,mCAAmC,uCAAuC;GACtF,eAAe,KAAK,EAAW,QAAQ;EACxC,CAAA;CACS,CAAA,IAKd,kBAAC,GAAD;EACE,OAAO,EAAG,2BAA2B,kBAAkB;EACvD,aAAa,EACX,iCACA,4CACF;EACA,SACE,kBAAC,UAAD;GACE,MAAK;GACL,eAAe,EAAW,gBAAgB;GAC1C,WAAU;aAHZ;IAKE,kBAAC,GAAD,EAAW,WAAU,UAAW,CAAA;IAAC;IAAE,EAAG,0BAA0B,MAAM;GAChE;;YAbZ,CAgBE,kBAAC,GAAD;GAAa,WAAU;aACpB,EACC,6BACA,wMACF;EACW,CAAA,GAEb,kBAAC,QAAD;GAAM,WAjEY,MAAuB;IAG3C,IAFA,EAAE,eAAe,GACjB,EAAa,IAAI,GACb,CAAC,EAAM,KAAK,GAAG;KACjB,EAAa,EAAG,0CAA0C,sBAAsB,CAAC;KACjF;IACF;IACA,IAAM,IAAoC;KACxC,OAAO,EAAM,KAAK;KAClB;KACA;KACA;KACA,UAAU,EAAS,KAAK,KAAK;KAC7B,GAAI,IAAa,EAAE,cAAW,IAAI,CAAC;KACnC,GAAI,IAAS,EAAE,UAAO,IAAI,CAAC;KAC3B,GAAI,IAAS,EAAE,QAAQ,OAAO,CAAM,EAAE,IAAI,CAAC;KAC3C,GAAI,IAAW,EAAE,UAAU,IAAI,KAAK,CAAQ,EAAE,YAAY,EAAE,IAAI,CAAC;KACjE,GAAI,EAAM,KAAK,IAAI,EAAE,OAAO,EAAM,KAAK,EAAE,IAAI,CAAC;IAChD;IACA,EAAO,OAAO,GAAO;KACnB,YAAY,MAAQ,EAAW,kBAAkB,EAAI,IAAI;KACzD,UAAU,MACR,EACE,aAAe,QACX,EAAI,UACJ,EAAG,2BAA2B,gCAAgC,CACpE;IACJ,CAAC;GACH;GAqCkC,WAAU;aAAxC;IACG,KACC,kBAAC,OAAD;KAAK,WAAU;eACZ;IACE,CAAA;IAIP,kBAAC,GAAD;KACE,MAAM,kBAAC,GAAD,EAAK,WAAU,UAAW,CAAA;KAChC,OAAO,EAAG,kCAAkC,QAAQ;KACpD,aAAa,EACX,wCACA,oDACF;eAEA,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;OAAO,SAAQ;OAAY,WAAW;iBAAtC;QACG,EAAG,uCAAuC,OAAO;QAAG;QACrD,kBAAC,QAAD;SAAM,WAAU;mBAAyB;QAAO,CAAA;OAC3C;UACP,kBAAC,SAAD;OACE,IAAG;OACH,MAAK;OACL,OAAO;OACP,WAAW,MAAM,EAAS,EAAE,OAAO,KAAK;OACxC,aAAa,EACX,6CACA,sCACF;OACA,WAAW;OACX,UAAA;MACD,CAAA,CACE,EAAA,CAAA,GACL,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,SAAD;QAAO,SAAQ;QAAW,WAAW;kBAClC,EAAG,sCAAsC,MAAM;OAC3C,CAAA,GACP,kBAAC,UAAD;QACE,IAAG;QACH,OAAO;QACP,WAAW,MAAM,EAAQ,EAAE,OAAO,KAA4B;QAC9D,WAAW;kBAEV,EAAM,KAAK,MACV,kBAAC,UAAD;SAAgB,OAAO;mBACpB,EAAG,EAAS,IAAI,EAAgB,CAAC,CAAC;QAC7B,GAFK,CAEL,CACT;OACK,CAAA,CACL;QACF;;IACM,CAAA;IAGb,kBAAC,GAAD;KACE,MAAM,kBAAC,GAAD,EAAW,WAAU,UAAW,CAAA;KACtC,OAAO,EAAG,wCAAwC,iBAAiB;KACnE,aAAa,EACX,8CACA,6EACF;eAEA,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;OAAO,SAAQ;OAAe,WAAW;iBACtC,EAAG,gDAAgD,UAAU;MACzD,CAAA,GACP,kBAAC,UAAD;OACE,IAAG;OACH,OAAO;OACP,WAAW,MAAM;QAEf,AADA,EAAc,EAAE,OAAO,KAAK,GAC5B,EAAU,EAAE;OACd;OACA,WAAW;iBAPb,CASE,kBAAC,UAAD;QAAQ,OAAM;kBACX,EAAG,+CAA+C,UAAU;OACvD,CAAA,GACP,EAAU,KAAK,MACd,kBAAC,UAAD;QAAmB,OAAO,EAAE;kBACzB,EAAE;OACG,GAFK,EAAE,EAEP,CACT,CACK;QACL,EAAA,CAAA,GACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;OAAO,SAAQ;OAAW,WAAW;iBAClC,EAAG,4CAA4C,MAAM;MACjD,CAAA,GACP,kBAAC,UAAD;OACE,IAAG;OACH,OAAO;OACP,WAAW,MAAM,EAAU,EAAE,OAAO,KAAK;OACzC,WAAW;OACX,UAAU,CAAC,KAAc,EAAM,WAAW;iBAL5C,CAOE,kBAAC,UAAD;QAAQ,OAAM;kBACX,IACG,EAAM,WAAW,IACf,EAAG,0CAA0C,oBAAoB,IACjE,EAAG,2CAA2C,UAAU,IAC1D,EACE,sDACA,yBACF;OACE,CAAA,GACP,EAAM,KAAK,MACV,kBAAC,UAAD;QAAoB,OAAO,EAAG;kBAC3B,EAAG;OACE,GAFK,EAAG,EAER,CACT,CACK;QACL,EAAA,CAAA,CACF;;IACM,CAAA;IAGb,kBAAC,GAAD;KACE,MAAM,kBAAC,GAAD,EAAQ,WAAU,UAAW,CAAA;KACnC,OAAO,EAAG,mCAAmC,mBAAmB;KAChE,aAAa,EACX,yCACA,yEACF;eAEA,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;SAAO,SAAQ;SAAa,WAAW;mBACpC,EAAG,yCAAyC,QAAQ;QAChD,CAAA,GACP,kBAAC,SAAD;SACE,IAAG;SACH,MAAK;SACL,KAAI;SACJ,MAAK;SACL,OAAO;SACP,WAAW,MAAM,EAAU,EAAE,OAAO,KAAK;SACzC,aAAa,EAAG,+CAA+C,MAAM;SACrE,WAAW;QACZ,CAAA,CACE,EAAA,CAAA;QACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;SAAO,SAAQ;SAAe,WAAW;mBACtC,EAAG,2CAA2C,UAAU;QACpD,CAAA,GACP,kBAAC,SAAD;SACE,IAAG;SACH,MAAK;SACL,OAAO;SACP,WAAW,MAAM,EAAY,EAAE,OAAO,MAAM,YAAY,CAAC;SACzD,aAAa,EAAG,iDAAiD,KAAK;SACtE,WAAW;SACX,WAAW;QACZ,CAAA,CACE,EAAA,CAAA;QACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;SAAO,SAAQ;SAAe,WAAW;mBACtC,EAAG,2CAA2C,kBAAkB;QAC5D,CAAA,GACP,kBAAC,UAAD;SACE,IAAG;SACH,OAAO;SACP,WAAW,MAAM,EAAY,EAAE,OAAO,KAA2B;SACjE,WAAW;mBAEV,EAAU,KAAK,MACd,kBAAC,UAAD;UAAgB,OAAO;oBACpB,EAAgB,CAAC;SACZ,GAFK,CAEL,CACT;QACK,CAAA,CACL,EAAA,CAAA;OACF;UACL,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;QAAO,SAAQ;QAAa,WAAW;kBACpC,EAAG,2CAA2C,WAAW;OACrD,CAAA,GACP,kBAAC,SAAD;QACE,IAAG;QACH,MAAK;QACL,OAAO;QACP,WAAW,MAAM,EAAY,EAAE,OAAO,KAAK;QAC3C,WAAW;OACZ,CAAA,CACE,EAAA,CAAA,GACL,kBAAC,SAAD;QAAO,WAAU;kBAAjB,CACE,kBAAC,SAAD;SACE,MAAK;SACL,SAAS;SACT,WAAW,MAAM,EAAa,EAAE,OAAO,OAAO;SAC9C,WAAU;QACX,CAAA,GACD,kBAAC,QAAD;SAAM,WAAU;mBACb,EAAG,wCAAwC,aAAa;QACrD,CAAA,CACD;SACJ;QACF;;IACM,CAAA;IAGb,kBAAC,GAAD;KACE,MAAM,kBAAC,GAAD,EAAY,WAAU,UAAW,CAAA;KACvC,OAAO,EAAG,iCAAiC,OAAO;KAClD,aAAa,EACX,uCACA,qDACF;eAEA,kBAAC,YAAD;MACE,IAAG;MACH,cAAY,EAAG,iCAAiC,OAAO;MACvD,OAAO;MACP,WAAW,MAAM,EAAS,EAAE,OAAO,KAAK;MACxC,MAAM;MACN,aAAa,EACX,uCACA,qDACF;MACA,WAAW;KACZ,CAAA;IACU,CAAA;IAEb,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,UAAD;MACE,MAAK;MACL,UAAU,EAAO;MACjB,WAAU;gBAET,EAAO,YACJ,EAAG,8BAA8B,WAAW,IAC5C,EAAG,4BAA4B,qBAAqB;KAClD,CAAA,GACR,kBAAC,UAAD;MACE,MAAK;MACL,eAAe,EAAW,gBAAgB;MAC1C,WAAU;gBAET,EAAG,4BAA4B,QAAQ;KAClC,CAAA,CACL;;GACD;IACI;;AAEhB"}
@@ -1 +1 @@
1
- {"version":3,"file":"RelationshipsListPage.js","names":[],"sources":["../../../../src/subscriberbot/pages/relationships/RelationshipsListPage.tsx"],"sourcesContent":["/**\n * Relationships list\n * @module subscriberbot/pages/relationships\n *\n * The core CRUDL list — every recurring relationship (subscription /\n * membership / license / contract) in one paginated, filterable view.\n * Data comes from `subListRelationships` (a SubRelationshipConnection).\n */\n\nimport { useMemo, useState } from 'react';\nimport { Plus, Search, Repeat2, ChevronRight } from 'lucide-react';\nimport { GlassCard, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { EmptyState } from '../../components/EmptyState';\nimport { LoadingView, ErrorView } from '../../components/StateViews';\nimport { MiniProgress } from '../../components';\nimport { useSubscriberBot } from '../../context/SubscriberBotContext';\nimport { useRelationships } from '../../hooks/useSubscriberBotApi';\nimport { cn } from '../../utils/cn';\nimport {\n formatCurrency,\n formatDate,\n formatEnumLabel,\n formatIntervalSuffix,\n} from '../../utils/formatters';\nimport { useTr } from '../../hooks/useTr';\nimport type { SubRelationshipKind, SubRelationshipStatus } from '../../types';\n\nconst PAGE_SIZE = 20;\n\nconst STATUSES: SubRelationshipStatus[] = [\n 'ACTIVE',\n 'TRIAL',\n 'PAUSED',\n 'PAST_DUE',\n 'LAPSED',\n 'EXPIRED',\n 'CANCELLED',\n];\n\nconst KINDS: SubRelationshipKind[] = [\n 'SUBSCRIPTION',\n 'MEMBERSHIP',\n 'LICENSE',\n 'CONTRACT',\n 'NEWSLETTER',\n 'RECURRING_PAYMENT',\n 'ENROLLMENT',\n 'TRIAL',\n];\n\nconst STATUS_KEY: Record<SubRelationshipStatus, string> = {\n ACTIVE: 'relationships.statuses.active',\n TRIAL: 'relationships.statuses.trial',\n PAUSED: 'relationships.statuses.paused',\n PAST_DUE: 'relationships.statuses.pastDue',\n LAPSED: 'relationships.statuses.lapsed',\n EXPIRED: 'relationships.statuses.expired',\n CANCELLED: 'relationships.statuses.cancelled',\n};\n\nconst KIND_KEY: Record<SubRelationshipKind, string> = {\n SUBSCRIPTION: 'relationships.kinds.subscription',\n MEMBERSHIP: 'relationships.kinds.membership',\n LICENSE: 'relationships.kinds.license',\n CONTRACT: 'relationships.kinds.contract',\n NEWSLETTER: 'relationships.kinds.newsletter',\n RECURRING_PAYMENT: 'relationships.kinds.recurringPayment',\n ENROLLMENT: 'relationships.kinds.enrollment',\n TRIAL: 'relationships.kinds.trial',\n};\n\nconst selectCls =\n 'rounded-lg border border-border-subtle bg-bg-surface px-3 py-2.5 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]';\n\n/** Map a 0–100 health score onto a MiniProgress tone. */\nfunction healthTone(\n score: number | null | undefined\n): 'positive' | 'accent' | 'warning' | 'negative' {\n if (score == null) return 'accent';\n if (score >= 66) return 'positive';\n if (score >= 33) return 'warning';\n return 'negative';\n}\n\nexport function RelationshipsListPage() {\n const tr = useTr();\n const { navigateTo } = useSubscriberBot();\n const [page, setPage] = useState(0);\n const [statusFilter, setStatusFilter] = useState<'' | SubRelationshipStatus>('');\n const [kindFilter, setKindFilter] = useState<'' | SubRelationshipKind>('');\n const [search, setSearch] = useState('');\n const [searchInput, setSearchInput] = useState('');\n\n const { data, isLoading, isError, refetch, isFetching } = useRelationships({\n status: statusFilter || undefined,\n kind: kindFilter || undefined,\n search: search || undefined,\n pagination: { limit: PAGE_SIZE, offset: page * PAGE_SIZE },\n });\n\n const items = useMemo(() => data?.items ?? [], [data]);\n const hasMore = data?.pageInfo.hasMore ?? false;\n\n const submitSearch = (e: React.FormEvent) => {\n e.preventDefault();\n setSearch(searchInput.trim());\n setPage(0);\n };\n\n return (\n <PageLayout\n title={tr('relationships.title', 'Relationships')}\n description={tr(\n 'relationships.description',\n 'Every subscription, membership, license and contract you track'\n )}\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/relationships/new')}\n className=\"inline-flex items-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90\"\n >\n <Plus className=\"h-4 w-4\" /> {tr('relationships.addRelationship', 'Add relationship')}\n </button>\n }\n >\n <PagePurpose className=\"mb-4\">\n {tr(\n 'relationships.purpose',\n 'This is the fundamental object of Subscriber Bot. Filter by lifecycle and kind, open any row to manage its plan, payment, entitlements, assets and renewals, or advance its lifecycle.'\n )}\n </PagePurpose>\n\n {/* Toolbar — search + filters, responsive */}\n <GlassCard treatment=\"plain\" className=\"p-3 sm:p-4\">\n <div className=\"flex flex-col gap-3 md:flex-row md:items-center\">\n <form onSubmit={submitSearch} className=\"relative flex-1 min-w-0\">\n <Search className=\"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <input\n type=\"text\"\n aria-label={tr('relationships.searchPlaceholder', 'Search relationships by label…')}\n placeholder={tr('relationships.searchPlaceholder', 'Search relationships by label…')}\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2.5 pl-10 pr-3 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </form>\n <div className=\"flex flex-wrap gap-2 sm:flex-nowrap\">\n <select\n aria-label={tr('relationships.filters.kindLabel', 'Filter by kind')}\n value={kindFilter}\n onChange={(e) => {\n setKindFilter(e.target.value as '' | SubRelationshipKind);\n setPage(0);\n }}\n className={cn(selectCls, 'flex-1 sm:flex-none')}\n >\n <option value=\"\">{tr('relationships.filters.allKinds', 'All kinds')}</option>\n {KINDS.map((k) => (\n <option key={k} value={k}>\n {tr(KIND_KEY[k], formatEnumLabel(k))}\n </option>\n ))}\n </select>\n <select\n aria-label={tr('relationships.filters.statusLabel', 'Filter by status')}\n value={statusFilter}\n onChange={(e) => {\n setStatusFilter(e.target.value as '' | SubRelationshipStatus);\n setPage(0);\n }}\n className={cn(selectCls, 'flex-1 sm:flex-none')}\n >\n <option value=\"\">{tr('relationships.filters.allStatuses', 'All statuses')}</option>\n {STATUSES.map((s) => (\n <option key={s} value={s}>\n {tr(STATUS_KEY[s], formatEnumLabel(s))}\n </option>\n ))}\n </select>\n </div>\n </div>\n </GlassCard>\n\n {isLoading ? (\n <LoadingView label={tr('relationships.loading', 'Loading relationships…')} />\n ) : isError ? (\n <ErrorView\n message={tr('relationships.error', 'Could not load relationships.')}\n onRetry={() => void refetch()}\n />\n ) : items.length === 0 ? (\n <div className=\"mt-6\">\n <EmptyState\n illustration=\"empty-data\"\n icon={<Repeat2 className=\"h-12 w-12\" />}\n title={tr('relationships.emptyTitle', 'No relationships found')}\n description={\n search\n ? tr(\n 'relationships.emptyDescriptionSearch',\n 'No relationships match \"{{search}}\".',\n { search }\n )\n : tr(\n 'relationships.emptyDescription',\n 'Add your first recurring relationship to start tracking it.'\n )\n }\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/relationships/new')}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90\"\n >\n {tr('relationships.addRelationship', 'Add relationship')}\n </button>\n }\n />\n </div>\n ) : (\n <>\n {/* Portfolio table — scrolls horizontally on small screens, never the page */}\n <GlassCard treatment=\"plain\" className=\"mt-4 overflow-hidden p-0\">\n <div className=\"overflow-x-auto\">\n <div className=\"min-w-[720px]\">\n <div className=\"grid grid-cols-[minmax(0,2.4fr)_1fr_1fr_1fr_1fr_1.3fr] gap-4 border-b border-border-seam bg-bg-sunken/60 px-4 py-2.5 text-xs font-medium uppercase tracking-wide text-text-secondary\">\n <span>{tr('relationships.table.subscription', 'Subscription')}</span>\n <span>{tr('relationships.table.kind', 'Kind')}</span>\n <span>{tr('relationships.table.status', 'Status')}</span>\n <span className=\"text-right\">{tr('relationships.table.amount', 'Amount')}</span>\n <span className=\"text-right\">\n {tr('relationships.table.renewsOn', 'Renews on')}\n </span>\n <span>{tr('relationships.table.health', 'Health')}</span>\n </div>\n <div className=\"divide-y divide-border-subtle\">\n {items.map((r) => {\n const score = r.healthScore;\n return (\n <button\n key={r.id}\n type=\"button\"\n onClick={() => navigateTo(`/relationships/${r.id}`)}\n className=\"group grid w-full grid-cols-[minmax(0,2.4fr)_1fr_1fr_1fr_1fr_1.3fr] items-center gap-4 px-4 py-3.5 text-left transition-colors hover:bg-bg-sunken\"\n >\n <div className=\"flex min-w-0 items-center gap-2\">\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-semibold text-text-primary\">\n {r.label}\n </p>\n {r.provider?.name && (\n <p className=\"truncate text-xs text-text-secondary\">\n {r.provider.name}\n </p>\n )}\n </div>\n </div>\n <span>\n <span className=\"inline-flex items-center rounded-md bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary\">\n {tr(KIND_KEY[r.kind], formatEnumLabel(r.kind))}\n </span>\n </span>\n <span>\n <StatusBadge status={r.status} />\n </span>\n <span className=\"text-right text-sm font-semibold tabular-nums text-text-primary\">\n {formatCurrency(r.amount, r.currency)}\n <span className=\"text-xs font-normal text-text-secondary\">\n {formatIntervalSuffix(r.interval)}\n </span>\n </span>\n <span className=\"text-right text-xs text-text-secondary\">\n {r.renewsAt ? formatDate(r.renewsAt) : '—'}\n </span>\n <span className=\"flex items-center gap-2\">\n {score != null ? (\n <>\n <MiniProgress\n value={score}\n max={100}\n tone={healthTone(score)}\n className=\"w-16 shrink-0 sm:w-20\"\n />\n <span className=\"text-xs tabular-nums text-text-secondary\">\n {score}\n </span>\n </>\n ) : (\n <span className=\"text-xs text-text-secondary\">—</span>\n )}\n <ChevronRight className=\"ml-auto h-4 w-4 shrink-0 text-text-secondary opacity-0 transition-opacity group-hover:opacity-100\" />\n </span>\n </button>\n );\n })}\n </div>\n </div>\n </div>\n </GlassCard>\n\n <div className=\"mt-4 flex items-center justify-between\">\n <p className=\"text-xs text-text-secondary\">\n {tr('relationships.pagination.page', 'Page {{page}}', { page: page + 1 })}\n {isFetching ? ` · ${tr('relationships.pagination.refreshing', 'refreshing…')}` : ''}\n </p>\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n disabled={page === 0}\n onClick={() => setPage((p) => Math.max(0, p - 1))}\n className={cn(\n 'rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium',\n page === 0\n ? 'cursor-not-allowed text-text-secondary opacity-50'\n : 'text-text-primary hover:bg-bg-sunken'\n )}\n >\n {tr('relationships.pagination.previous', 'Previous')}\n </button>\n <button\n type=\"button\"\n disabled={!hasMore}\n onClick={() => setPage((p) => p + 1)}\n className={cn(\n 'rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium',\n !hasMore\n ? 'cursor-not-allowed text-text-secondary opacity-50'\n : 'text-text-primary hover:bg-bg-sunken'\n )}\n >\n {tr('relationships.pagination.next', 'Next')}\n </button>\n </div>\n </div>\n </>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"RelationshipsListPage.js","names":[],"sources":["../../../../src/subscriberbot/pages/relationships/RelationshipsListPage.tsx"],"sourcesContent":["/**\n * Relationships list\n * @module subscriberbot/pages/relationships\n *\n * The core CRUDL list — every recurring relationship (subscription /\n * membership / license / contract) in one paginated, filterable view.\n * Data comes from `subListRelationships` (a SubRelationshipConnection).\n */\n\nimport { useMemo, useState } from 'react';\nimport { Plus, Search, Repeat2, ChevronRight } from 'lucide-react';\nimport { GlassCard, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { EmptyState } from '../../components/EmptyState';\nimport { LoadingView, ErrorView } from '../../components/StateViews';\nimport { MiniProgress } from '../../components';\nimport { useSubscriberBot } from '../../context/SubscriberBotContext';\nimport { useRelationships } from '../../hooks/useSubscriberBotApi';\nimport { cn } from '../../utils/cn';\nimport {\n formatCurrency,\n formatDate,\n formatEnumLabel,\n formatIntervalSuffix,\n} from '../../utils/formatters';\nimport { useTr } from '../../hooks/useTr';\nimport type { SubRelationshipKind, SubRelationshipStatus } from '../../types';\n\nconst PAGE_SIZE = 20;\n\nconst STATUSES: SubRelationshipStatus[] = [\n 'ACTIVE',\n 'TRIAL',\n 'PAUSED',\n 'PAST_DUE',\n 'LAPSED',\n 'EXPIRED',\n 'CANCELLED',\n];\n\nconst KINDS: SubRelationshipKind[] = [\n 'SUBSCRIPTION',\n 'MEMBERSHIP',\n 'LICENSE',\n 'CONTRACT',\n 'NEWSLETTER',\n 'RECURRING_PAYMENT',\n 'ENROLLMENT',\n 'TRIAL',\n];\n\nconst STATUS_KEY: Record<SubRelationshipStatus, string> = {\n ACTIVE: 'relationships.statuses.active',\n TRIAL: 'relationships.statuses.trial',\n PAUSED: 'relationships.statuses.paused',\n PAST_DUE: 'relationships.statuses.pastDue',\n LAPSED: 'relationships.statuses.lapsed',\n EXPIRED: 'relationships.statuses.expired',\n CANCELLED: 'relationships.statuses.cancelled',\n};\n\nconst KIND_KEY: Record<SubRelationshipKind, string> = {\n SUBSCRIPTION: 'relationships.kinds.subscription',\n MEMBERSHIP: 'relationships.kinds.membership',\n LICENSE: 'relationships.kinds.license',\n CONTRACT: 'relationships.kinds.contract',\n NEWSLETTER: 'relationships.kinds.newsletter',\n RECURRING_PAYMENT: 'relationships.kinds.recurringPayment',\n ENROLLMENT: 'relationships.kinds.enrollment',\n TRIAL: 'relationships.kinds.trial',\n};\n\nconst selectCls =\n 'rounded-lg border border-border-subtle bg-bg-surface px-3 py-2.5 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]';\n\n/** Map a 0–100 health score onto a MiniProgress tone. */\nfunction healthTone(\n score: number | null | undefined\n): 'positive' | 'accent' | 'warning' | 'negative' {\n if (score == null) return 'accent';\n if (score >= 66) return 'positive';\n if (score >= 33) return 'warning';\n return 'negative';\n}\n\nexport function RelationshipsListPage() {\n const tr = useTr();\n const { navigateTo } = useSubscriberBot();\n const [page, setPage] = useState(0);\n const [statusFilter, setStatusFilter] = useState<'' | SubRelationshipStatus>('');\n const [kindFilter, setKindFilter] = useState<'' | SubRelationshipKind>('');\n const [search, setSearch] = useState('');\n const [searchInput, setSearchInput] = useState('');\n\n const { data, isLoading, isError, refetch, isFetching } = useRelationships({\n status: statusFilter || undefined,\n kind: kindFilter || undefined,\n search: search || undefined,\n pagination: { limit: PAGE_SIZE, offset: page * PAGE_SIZE },\n });\n\n const items = useMemo(() => data?.items ?? [], [data]);\n const hasMore = data?.pageInfo.hasMore ?? false;\n\n const submitSearch = (e: React.FormEvent) => {\n e.preventDefault();\n setSearch(searchInput.trim());\n setPage(0);\n };\n\n return (\n <PageLayout\n title={tr('relationships.title', 'Relationships')}\n description={tr(\n 'relationships.description',\n 'Every subscription, membership, license and contract you track'\n )}\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/relationships/new')}\n className=\"inline-flex items-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90\"\n >\n <Plus className=\"h-4 w-4\" /> {tr('relationships.addRelationship', 'Add relationship')}\n </button>\n }\n >\n <PagePurpose className=\"mb-4\">\n {tr(\n 'relationships.purpose',\n 'This is the fundamental object of Subscriber Bot. Filter by lifecycle and kind, open any row to manage its plan, payment, entitlements, assets and renewals, or advance its lifecycle.'\n )}\n </PagePurpose>\n\n {/* Toolbar — search + filters, responsive */}\n <GlassCard treatment=\"plain\" className=\"p-3 sm:p-4\">\n <div className=\"flex flex-col gap-3 md:flex-row md:items-center\">\n <form onSubmit={submitSearch} className=\"relative flex-1 min-w-0\">\n <Search className=\"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <input\n type=\"text\"\n aria-label={tr('relationships.searchPlaceholder', 'Search relationships by label…')}\n placeholder={tr('relationships.searchPlaceholder', 'Search relationships by label…')}\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2.5 pl-10 pr-3 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </form>\n <div className=\"flex flex-wrap gap-2 sm:flex-nowrap\">\n <select\n aria-label={tr('relationships.filters.kindLabel', 'Filter by kind')}\n value={kindFilter}\n onChange={(e) => {\n setKindFilter(e.target.value as '' | SubRelationshipKind);\n setPage(0);\n }}\n className={cn(selectCls, 'flex-1 sm:flex-none')}\n >\n <option value=\"\">{tr('relationships.filters.allKinds', 'All kinds')}</option>\n {KINDS.map((k) => (\n <option key={k} value={k}>\n {tr(KIND_KEY[k], formatEnumLabel(k))}\n </option>\n ))}\n </select>\n <select\n aria-label={tr('relationships.filters.statusLabel', 'Filter by status')}\n value={statusFilter}\n onChange={(e) => {\n setStatusFilter(e.target.value as '' | SubRelationshipStatus);\n setPage(0);\n }}\n className={cn(selectCls, 'flex-1 sm:flex-none')}\n >\n <option value=\"\">{tr('relationships.filters.allStatuses', 'All statuses')}</option>\n {STATUSES.map((s) => (\n <option key={s} value={s}>\n {tr(STATUS_KEY[s], formatEnumLabel(s))}\n </option>\n ))}\n </select>\n </div>\n </div>\n </GlassCard>\n\n {isLoading ? (\n <LoadingView label={tr('relationships.loading', 'Loading relationships…')} />\n ) : isError ? (\n <ErrorView\n message={tr('relationships.error', 'Could not load relationships.')}\n onRetry={() => void refetch()}\n />\n ) : items.length === 0 ? (\n <div className=\"mt-6\">\n <EmptyState\n illustration=\"empty-data\"\n icon={<Repeat2 className=\"h-12 w-12\" />}\n title={tr('relationships.emptyTitle', 'No relationships found')}\n description={\n search\n ? tr(\n 'relationships.emptyDescriptionSearch',\n 'No relationships match \"{{search}}\".',\n { search }\n )\n : tr(\n 'relationships.emptyDescription',\n 'Add your first recurring relationship to start tracking it.'\n )\n }\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/relationships/new')}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90\"\n >\n {tr('relationships.addRelationship', 'Add relationship')}\n </button>\n }\n />\n </div>\n ) : (\n <>\n {/* Portfolio table — scrolls horizontally on small screens, never the page */}\n <GlassCard treatment=\"plain\" className=\"mt-4 overflow-hidden p-0\">\n <div className=\"overflow-x-auto\">\n <div className=\"min-w-[720px]\">\n <div className=\"grid grid-cols-[minmax(0,2.4fr)_1fr_1fr_1fr_1fr_1.3fr] gap-4 border-b border-border-seam bg-bg-sunken/60 px-4 py-2.5 text-xs font-medium uppercase tracking-wide text-text-secondary\">\n <span>{tr('relationships.table.subscription', 'Subscription')}</span>\n <span>{tr('relationships.table.kind', 'Kind')}</span>\n <span>{tr('relationships.table.status', 'Status')}</span>\n <span className=\"text-right\">{tr('relationships.table.amount', 'Amount')}</span>\n <span className=\"text-right\">\n {tr('relationships.table.renewsOn', 'Renews on')}\n </span>\n <span>{tr('relationships.table.health', 'Health')}</span>\n </div>\n <div className=\"divide-y divide-border-subtle\">\n {items.map((r) => {\n const score = r.healthScore;\n return (\n <button\n key={r.id}\n type=\"button\"\n onClick={() => navigateTo(`/relationships/${r.id}`)}\n className=\"group grid w-full grid-cols-[minmax(0,2.4fr)_1fr_1fr_1fr_1fr_1.3fr] items-center gap-4 px-4 py-3.5 text-left transition-colors hover:bg-bg-sunken\"\n >\n <div className=\"flex min-w-0 items-center gap-2\">\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-semibold text-text-primary\">\n {r.label}\n </p>\n {r.provider?.name && (\n <p className=\"truncate text-xs text-text-secondary\">\n {r.provider.name}\n </p>\n )}\n </div>\n </div>\n <span>\n <span className=\"inline-flex items-center rounded-md bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary\">\n {tr(KIND_KEY[r.kind], formatEnumLabel(r.kind))}\n </span>\n </span>\n <span>\n <StatusBadge status={r.status} />\n </span>\n <span className=\"text-right text-sm font-semibold tabular-nums text-text-primary\">\n {formatCurrency(r.amount, r.currency)}\n <span className=\"text-xs font-normal text-text-secondary\">\n {formatIntervalSuffix(r.interval)}\n </span>\n </span>\n <span className=\"text-right text-xs text-text-secondary\">\n {r.renewsAt ? formatDate(r.renewsAt) : '—'}\n </span>\n <span className=\"flex items-center gap-2\">\n {score != null ? (\n <>\n <MiniProgress\n value={score}\n max={100}\n tone={healthTone(score)}\n className=\"w-16 shrink-0 sm:w-20\"\n />\n <span className=\"text-xs tabular-nums text-text-secondary\">\n {score}\n </span>\n </>\n ) : (\n <span className=\"text-xs text-text-secondary\">—</span>\n )}\n <ChevronRight className=\"ml-auto h-4 w-4 shrink-0 text-text-secondary opacity-0 transition-opacity group-hover:opacity-100\" />\n </span>\n </button>\n );\n })}\n </div>\n </div>\n </div>\n </GlassCard>\n\n <div className=\"mt-4 flex items-center justify-between\">\n <p className=\"text-xs text-text-secondary\">\n {tr('relationships.pagination.page', 'Page {{page}}', { page: page + 1 })}\n {isFetching ? ` · ${tr('relationships.pagination.refreshing', 'refreshing…')}` : ''}\n </p>\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n disabled={page === 0}\n onClick={() => setPage((p) => Math.max(0, p - 1))}\n className={cn(\n 'rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium',\n page === 0\n ? 'cursor-not-allowed text-text-secondary opacity-50'\n : 'text-text-primary hover:bg-bg-sunken'\n )}\n >\n {tr('relationships.pagination.previous', 'Previous')}\n </button>\n <button\n type=\"button\"\n disabled={!hasMore}\n onClick={() => setPage((p) => p + 1)}\n className={cn(\n 'rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium',\n !hasMore\n ? 'cursor-not-allowed text-text-secondary opacity-50'\n : 'text-text-primary hover:bg-bg-sunken'\n )}\n >\n {tr('relationships.pagination.next', 'Next')}\n </button>\n </div>\n </div>\n </>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"createSandboxAssistantTransport.js","names":[],"sources":["../../../src/subscriberbot/services/createSandboxAssistantTransport.ts"],"sourcesContent":["/**\n * subscriberbot adapter for the shared fe-libs AssistantWidget transport.\n *\n * The sandbox lifecycle + poll/stream loop now lives in\n * `@burdenoff/fe-libs/shared/assistant` (one implementation for all products);\n * this is a thin wrapper. The exported name/shape are unchanged so app-shell\n * imports don't move. The public return type is a LOCALLY-declared structural\n * mirror — never re-export fe-libs types (vite-plugin-dts path rewriting).\n */\n\nimport { useSandboxAssistantTransport as useSharedTransport } from '@burdenoff/fe-libs/shared/assistant';\nimport { gatherPageContext } from '#subscriberbot/utils/pageContext';\n\ninterface AssistantSendArgs {\n prompt: string;\n onProgress: (partialText: string) => void;\n signal: AbortSignal;\n}\n\nexport interface AssistantTransport {\n sendPrompt: (args: AssistantSendArgs) => Promise<{ text: string }>;\n prewarm?: (level?: 'probe' | 'full') => void;\n suspend?: () => void;\n}\n\nexport function useSandboxAssistantTransport(): AssistantTransport {\n return useSharedTransport({\n product: 'subscriberbot',\n gatherPageContext: gatherPageContext,\n enableCredits: true,\n });\n}\n"],"mappings":";;;AAyBA,SAAgB,IAAmD;AACjE,QAAO,EAAmB;EACxB,SAAS;EACU;EACnB,eAAe;EAChB,CAAC"}
1
+ {"version":3,"file":"createSandboxAssistantTransport.js","names":[],"sources":["../../../src/subscriberbot/services/createSandboxAssistantTransport.ts"],"sourcesContent":["/**\n * subscriberbot adapter for the shared fe-libs AssistantWidget transport.\n *\n * The sandbox lifecycle + poll/stream loop now lives in\n * `@burdenoff/fe-libs/shared/assistant` (one implementation for all products);\n * this is a thin wrapper. The exported name/shape are unchanged so app-shell\n * imports don't move. The public return type is a LOCALLY-declared structural\n * mirror — never re-export fe-libs types (vite-plugin-dts path rewriting).\n */\n\nimport { useSandboxAssistantTransport as useSharedTransport } from '@burdenoff/fe-libs/shared/assistant';\nimport { gatherPageContext } from '#subscriberbot/utils/pageContext';\n\ninterface AssistantSendArgs {\n prompt: string;\n onProgress: (partialText: string) => void;\n signal: AbortSignal;\n}\n\nexport interface AssistantTransport {\n sendPrompt: (args: AssistantSendArgs) => Promise<{ text: string }>;\n prewarm?: (level?: 'probe' | 'full') => void;\n suspend?: () => void;\n}\n\nexport function useSandboxAssistantTransport(): AssistantTransport {\n return useSharedTransport({\n product: 'subscriberbot',\n gatherPageContext: gatherPageContext,\n enableCredits: true,\n });\n}\n"],"mappings":";;;AAyBA,SAAgB,IAAmD;CACjE,OAAO,EAAmB;EACxB,SAAS;EACU;EACnB,eAAe;CACjB,CAAC;AACH"}
@@ -1 +1 @@
1
- {"version":3,"file":"subscriberbotStore.js","names":[],"sources":["../../../src/subscriberbot/store/subscriberbotStore.ts"],"sourcesContent":["/**\n * SubscriberBot Zustand Store\n * @module subscriberbot/store\n */\n\nimport { create } from 'zustand';\nimport { devtools, persist } from 'zustand/middleware';\nimport { createProfileScopedStorage } from '@burdenoff/fe-libs/shared/utils';\nimport type { ViewMode } from '../types';\n\n// ============================================================================\n// State Interface\n// ============================================================================\n\ninterface SubscriberBotState {\n // View state\n viewMode: ViewMode;\n activeSection: string;\n sidebarCollapsed: boolean;\n\n // Search & filters\n searchQuery: string;\n categoryFilter: string;\n\n // Selected entities\n selectedCartId: string | null;\n selectedOrderId: string | null;\n\n // Actions\n setViewMode: (mode: ViewMode) => void;\n setActiveSection: (section: string) => void;\n setSearchQuery: (query: string) => void;\n setCategoryFilter: (category: string) => void;\n setSelectedCartId: (cartId: string | null) => void;\n setSelectedOrderId: (orderId: string | null) => void;\n toggleSidebar: () => void;\n reset: () => void;\n}\n\n// ============================================================================\n// Initial State\n// ============================================================================\n\nconst initialState = {\n viewMode: 'grid' as ViewMode,\n activeSection: 'dashboard',\n sidebarCollapsed: false,\n\n searchQuery: '',\n categoryFilter: '',\n\n selectedCartId: null,\n selectedOrderId: null,\n};\n\n// ============================================================================\n// Store\n// ============================================================================\n\nexport const useSubscriberBotStore = create<SubscriberBotState>()(\n devtools(\n persist(\n (set) => ({\n ...initialState,\n\n // View actions\n setViewMode: (mode) => set({ viewMode: mode }),\n setActiveSection: (section) => set({ activeSection: section }),\n toggleSidebar: () => set((state) => ({ sidebarCollapsed: !state.sidebarCollapsed })),\n\n // Search & filter actions\n setSearchQuery: (query) => set({ searchQuery: query }),\n setCategoryFilter: (category) => set({ categoryFilter: category }),\n\n // Selection actions\n setSelectedCartId: (cartId) => set({ selectedCartId: cartId }),\n setSelectedOrderId: (orderId) => set({ selectedOrderId: orderId }),\n\n // Reset\n reset: () => set(initialState),\n }),\n {\n name: 'burdenoff-subscriberbot-storage',\n storage: createProfileScopedStorage(),\n partialize: (state) => ({\n viewMode: state.viewMode,\n sidebarCollapsed: state.sidebarCollapsed,\n activeSection: state.activeSection,\n }),\n }\n ),\n { name: 'SubscriberBot Store', enabled: import.meta.env.DEV }\n )\n);\n"],"mappings":";;;;AA2CA,IAAM,IAAe;CACnB,UAAU;CACV,eAAe;CACf,kBAAkB;CAElB,aAAa;CACb,gBAAgB;CAEhB,gBAAgB;CAChB,iBAAiB;CAClB,EAMY,IAAwB,GAA4B,CAC/D,EACE,GACG,OAAS;CACR,GAAG;CAGH,cAAc,MAAS,EAAI,EAAE,UAAU,GAAM,CAAC;CAC9C,mBAAmB,MAAY,EAAI,EAAE,eAAe,GAAS,CAAC;CAC9D,qBAAqB,GAAK,OAAW,EAAE,kBAAkB,CAAC,EAAM,kBAAkB,EAAE;CAGpF,iBAAiB,MAAU,EAAI,EAAE,aAAa,GAAO,CAAC;CACtD,oBAAoB,MAAa,EAAI,EAAE,gBAAgB,GAAU,CAAC;CAGlE,oBAAoB,MAAW,EAAI,EAAE,gBAAgB,GAAQ,CAAC;CAC9D,qBAAqB,MAAY,EAAI,EAAE,iBAAiB,GAAS,CAAC;CAGlE,aAAa,EAAI,EAAa;CAC/B,GACD;CACE,MAAM;CACN,SAAS,GAA4B;CACrC,aAAa,OAAW;EACtB,UAAU,EAAM;EAChB,kBAAkB,EAAM;EACxB,eAAe,EAAM;EACtB;CACF,CACF,EACD;CAAE,MAAM;CAAuB,SAAA;CAA8B,CAC9D,CACF"}
1
+ {"version":3,"file":"subscriberbotStore.js","names":[],"sources":["../../../src/subscriberbot/store/subscriberbotStore.ts"],"sourcesContent":["/**\n * SubscriberBot Zustand Store\n * @module subscriberbot/store\n */\n\nimport { create } from 'zustand';\nimport { devtools, persist } from 'zustand/middleware';\nimport { createProfileScopedStorage } from '@burdenoff/fe-libs/shared/utils';\nimport type { ViewMode } from '../types';\n\n// ============================================================================\n// State Interface\n// ============================================================================\n\ninterface SubscriberBotState {\n // View state\n viewMode: ViewMode;\n activeSection: string;\n sidebarCollapsed: boolean;\n\n // Search & filters\n searchQuery: string;\n categoryFilter: string;\n\n // Selected entities\n selectedCartId: string | null;\n selectedOrderId: string | null;\n\n // Actions\n setViewMode: (mode: ViewMode) => void;\n setActiveSection: (section: string) => void;\n setSearchQuery: (query: string) => void;\n setCategoryFilter: (category: string) => void;\n setSelectedCartId: (cartId: string | null) => void;\n setSelectedOrderId: (orderId: string | null) => void;\n toggleSidebar: () => void;\n reset: () => void;\n}\n\n// ============================================================================\n// Initial State\n// ============================================================================\n\nconst initialState = {\n viewMode: 'grid' as ViewMode,\n activeSection: 'dashboard',\n sidebarCollapsed: false,\n\n searchQuery: '',\n categoryFilter: '',\n\n selectedCartId: null,\n selectedOrderId: null,\n};\n\n// ============================================================================\n// Store\n// ============================================================================\n\nexport const useSubscriberBotStore = create<SubscriberBotState>()(\n devtools(\n persist(\n (set) => ({\n ...initialState,\n\n // View actions\n setViewMode: (mode) => set({ viewMode: mode }),\n setActiveSection: (section) => set({ activeSection: section }),\n toggleSidebar: () => set((state) => ({ sidebarCollapsed: !state.sidebarCollapsed })),\n\n // Search & filter actions\n setSearchQuery: (query) => set({ searchQuery: query }),\n setCategoryFilter: (category) => set({ categoryFilter: category }),\n\n // Selection actions\n setSelectedCartId: (cartId) => set({ selectedCartId: cartId }),\n setSelectedOrderId: (orderId) => set({ selectedOrderId: orderId }),\n\n // Reset\n reset: () => set(initialState),\n }),\n {\n name: 'burdenoff-subscriberbot-storage',\n storage: createProfileScopedStorage(),\n partialize: (state) => ({\n viewMode: state.viewMode,\n sidebarCollapsed: state.sidebarCollapsed,\n activeSection: state.activeSection,\n }),\n }\n ),\n { name: 'SubscriberBot Store', enabled: import.meta.env.DEV }\n )\n);\n"],"mappings":";;;;AA2CA,IAAM,IAAe;CACnB,UAAU;CACV,eAAe;CACf,kBAAkB;CAElB,aAAa;CACb,gBAAgB;CAEhB,gBAAgB;CAChB,iBAAiB;AACnB,GAMa,IAAwB,EAA2B,EAC9D,EACE,GACG,OAAS;CACR,GAAG;CAGH,cAAc,MAAS,EAAI,EAAE,UAAU,EAAK,CAAC;CAC7C,mBAAmB,MAAY,EAAI,EAAE,eAAe,EAAQ,CAAC;CAC7D,qBAAqB,GAAK,OAAW,EAAE,kBAAkB,CAAC,EAAM,iBAAiB,EAAE;CAGnF,iBAAiB,MAAU,EAAI,EAAE,aAAa,EAAM,CAAC;CACrD,oBAAoB,MAAa,EAAI,EAAE,gBAAgB,EAAS,CAAC;CAGjE,oBAAoB,MAAW,EAAI,EAAE,gBAAgB,EAAO,CAAC;CAC7D,qBAAqB,MAAY,EAAI,EAAE,iBAAiB,EAAQ,CAAC;CAGjE,aAAa,EAAI,CAAY;AAC/B,IACA;CACE,MAAM;CACN,SAAS,EAA2B;CACpC,aAAa,OAAW;EACtB,UAAU,EAAM;EAChB,kBAAkB,EAAM;EACxB,eAAe,EAAM;CACvB;AACF,CACF,GACA;CAAE,MAAM;CAAuB,SAAA;AAA6B,CAC9D,CACF"}
@@ -212,6 +212,7 @@ export interface SubRelationship {
212
212
  plan?: SubPlan | null;
213
213
  entitlements?: SubEntitlement[];
214
214
  assets?: SubAsset[];
215
+ invoices?: SubInvoice[];
215
216
  renewalEvents?: SubRenewalEvent[];
216
217
  }
217
218
  export interface SubInboxMessage {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/subscriberbot/types/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/subscriberbot/types/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"cn.js","names":[],"sources":["../../../src/subscriberbot/utils/cn.ts"],"sourcesContent":["/**\n * Class name utility\n * @module subscriberbot/utils\n */\n\nimport { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n"],"mappings":";;;AAQA,SAAgB,EAAG,GAAG,GAA8B;AAClD,QAAO,EAAQ,EAAK,EAAO,CAAC"}
1
+ {"version":3,"file":"cn.js","names":[],"sources":["../../../src/subscriberbot/utils/cn.ts"],"sourcesContent":["/**\n * Class name utility\n * @module subscriberbot/utils\n */\n\nimport { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n"],"mappings":";;;AAQA,SAAgB,EAAG,GAAG,GAA8B;CAClD,OAAO,EAAQ,EAAK,CAAM,CAAC;AAC7B"}
@@ -1 +1 @@
1
- {"version":3,"file":"formatters.js","names":[],"sources":["../../../src/subscriberbot/utils/formatters.ts"],"sourcesContent":["/**\n * Formatting utilities for the Subscriber Bot microfrontend\n * @module subscriberbot/utils/formatters\n *\n * Subscriber Bot is a global product — relationships are billed in many\n * currencies. Formatting is therefore currency-aware (each Relationship /\n * Invoice / Plan carries its own ISO currency code).\n */\n\n/**\n * Format an amount as currency using the relationship/invoice's own ISO code.\n *\n * @param amount - The numeric amount to format\n * @param currency - ISO 4217 currency code (e.g. \"USD\", \"EUR\", \"INR\")\n * @param options - Optional Intl.NumberFormat overrides\n * @returns Formatted currency string (e.g. \"$12.00\")\n *\n * @example\n * formatCurrency(12, 'USD') // => \"$12.00\"\n * formatCurrency(999, 'INR', { minimumFractionDigits: 0 }) // => \"₹999\"\n */\nexport function formatCurrency(\n amount: number,\n currency = 'USD',\n options?: Partial<Intl.NumberFormatOptions>\n): string {\n try {\n return new Intl.NumberFormat(undefined, {\n style: 'currency',\n currency: currency || 'USD',\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n ...options,\n }).format(amount);\n } catch {\n // Unknown/invalid currency code → fall back to a plain number + code.\n return `${amount.toFixed(2)} ${currency}`;\n }\n}\n\n/**\n * Format a date string or Date object into a human-readable date.\n *\n * @param date - ISO date string or Date object\n * @param options - Optional Intl.DateTimeFormat options\n * @returns Formatted date string (e.g. \"15 Jan 2026\")\n */\nexport function formatDate(\n date: string | Date | null | undefined,\n options?: Partial<Intl.DateTimeFormatOptions>\n): string {\n if (!date) return '—';\n const d = typeof date === 'string' ? new Date(date) : date;\n if (Number.isNaN(d.getTime())) return '—';\n return new Intl.DateTimeFormat(undefined, {\n day: 'numeric',\n month: 'short',\n year: 'numeric',\n ...options,\n }).format(d);\n}\n\n/**\n * Format a date-time into a date + time string.\n */\nexport function formatDateTime(\n date: string | Date | null | undefined,\n options?: Partial<Intl.DateTimeFormatOptions>\n): string {\n if (!date) return '—';\n const d = typeof date === 'string' ? new Date(date) : date;\n if (Number.isNaN(d.getTime())) return '—';\n return new Intl.DateTimeFormat(undefined, {\n day: 'numeric',\n month: 'short',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n ...options,\n }).format(d);\n}\n\n/**\n * Format a date into a relative time string (e.g. \"2 hours ago\", \"in 3 days\").\n *\n * @param date - ISO date string or Date object\n * @returns Human-readable relative time string\n */\nexport function formatRelativeTime(date: string | Date | null | undefined): string {\n if (!date) return '—';\n const d = typeof date === 'string' ? new Date(date) : date;\n if (Number.isNaN(d.getTime())) return '—';\n\n const now = new Date();\n const diffMs = d.getTime() - now.getTime();\n const future = diffMs >= 0;\n const absSeconds = Math.floor(Math.abs(diffMs) / 1000);\n const minutes = Math.floor(absSeconds / 60);\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n const weeks = Math.floor(days / 7);\n const months = Math.floor(days / 30);\n const years = Math.floor(days / 365);\n\n const phrase = (value: number, unit: string): string => {\n const label = `${value} ${unit}${value !== 1 ? 's' : ''}`;\n return future ? `in ${label}` : `${label} ago`;\n };\n\n if (absSeconds < 60) return future ? 'soon' : 'just now';\n if (minutes < 60) return phrase(minutes, 'min');\n if (hours < 24) return phrase(hours, 'hour');\n if (days < 7) return phrase(days, 'day');\n if (weeks < 4) return phrase(weeks, 'week');\n if (months < 12) return phrase(months, 'month');\n return phrase(years, 'year');\n}\n\n/**\n * Format a number with locale grouping.\n */\nexport function formatNumber(value: number, options?: Partial<Intl.NumberFormatOptions>): string {\n return new Intl.NumberFormat(undefined, options).format(value);\n}\n\n/**\n * Turn an ENUM_LIKE_TOKEN into a human \"Enum Like Token\" label.\n */\nexport function formatEnumLabel(value: string): string {\n return value\n .toLowerCase()\n .replace(/_/g, ' ')\n .replace(/\\b\\w/g, (char) => char.toUpperCase());\n}\n\n/**\n * Format a billing interval enum into a short suffix (e.g. \"MONTHLY\" → \"/mo\").\n */\nexport function formatIntervalSuffix(interval: string): string {\n switch (interval) {\n case 'DAILY':\n return '/day';\n case 'WEEKLY':\n return '/wk';\n case 'MONTHLY':\n return '/mo';\n case 'QUARTERLY':\n return '/qtr';\n case 'YEARLY':\n return '/yr';\n case 'LIFETIME':\n return ' lifetime';\n case 'USAGE_BASED':\n return ' usage';\n case 'FREE':\n return '';\n default:\n return '';\n }\n}\n"],"mappings":";AAqBA,SAAgB,EACd,GACA,IAAW,OACX,GACQ;AACR,KAAI;AACF,SAAO,IAAI,KAAK,aAAa,KAAA,GAAW;GACtC,OAAO;GACP,UAAU,KAAY;GACtB,uBAAuB;GACvB,uBAAuB;GACvB,GAAG;GACJ,CAAC,CAAC,OAAO,EAAO;SACX;AAEN,SAAO,GAAG,EAAO,QAAQ,EAAE,CAAC,GAAG;;;AAWnC,SAAgB,EACd,GACA,GACQ;AACR,KAAI,CAAC,EAAM,QAAO;CAClB,IAAM,IAAI,OAAO,KAAS,WAAW,IAAI,KAAK,EAAK,GAAG;AAEtD,QADI,OAAO,MAAM,EAAE,SAAS,CAAC,GAAS,MAC/B,IAAI,KAAK,eAAe,KAAA,GAAW;EACxC,KAAK;EACL,OAAO;EACP,MAAM;EACN,GAAG;EACJ,CAAC,CAAC,OAAO,EAAE;;AAMd,SAAgB,EACd,GACA,GACQ;AACR,KAAI,CAAC,EAAM,QAAO;CAClB,IAAM,IAAI,OAAO,KAAS,WAAW,IAAI,KAAK,EAAK,GAAG;AAEtD,QADI,OAAO,MAAM,EAAE,SAAS,CAAC,GAAS,MAC/B,IAAI,KAAK,eAAe,KAAA,GAAW;EACxC,KAAK;EACL,OAAO;EACP,MAAM;EACN,MAAM;EACN,QAAQ;EACR,GAAG;EACJ,CAAC,CAAC,OAAO,EAAE;;AASd,SAAgB,EAAmB,GAAgD;AACjF,KAAI,CAAC,EAAM,QAAO;CAClB,IAAM,IAAI,OAAO,KAAS,WAAW,IAAI,KAAK,EAAK,GAAG;AACtD,KAAI,OAAO,MAAM,EAAE,SAAS,CAAC,CAAE,QAAO;CAEtC,IAAM,oBAAM,IAAI,MAAM,EAChB,IAAS,EAAE,SAAS,GAAG,EAAI,SAAS,EACpC,IAAS,KAAU,GACnB,IAAa,KAAK,MAAM,KAAK,IAAI,EAAO,GAAG,IAAK,EAChD,IAAU,KAAK,MAAM,IAAa,GAAG,EACrC,IAAQ,KAAK,MAAM,IAAU,GAAG,EAChC,IAAO,KAAK,MAAM,IAAQ,GAAG,EAC7B,IAAQ,KAAK,MAAM,IAAO,EAAE,EAC5B,IAAS,KAAK,MAAM,IAAO,GAAG,EAC9B,IAAQ,KAAK,MAAM,IAAO,IAAI,EAE9B,KAAU,GAAe,MAAyB;EACtD,IAAM,IAAQ,GAAG,EAAM,GAAG,IAAO,MAAU,IAAU,KAAN;AAC/C,SAAO,IAAS,MAAM,MAAU,GAAG,EAAM;;AAS3C,QANI,IAAa,KAAW,IAAS,SAAS,aAC1C,IAAU,KAAW,EAAO,GAAS,MAAM,GAC3C,IAAQ,KAAW,EAAO,GAAO,OAAO,GACxC,IAAO,IAAU,EAAO,GAAM,MAAM,GACpC,IAAQ,IAAU,EAAO,GAAO,OAAO,GACvC,IAAS,KAAW,EAAO,GAAQ,QAAQ,GACxC,EAAO,GAAO,OAAO;;AAM9B,SAAgB,EAAa,GAAe,GAAqD;AAC/F,QAAO,IAAI,KAAK,aAAa,KAAA,GAAW,EAAQ,CAAC,OAAO,EAAM;;AAMhE,SAAgB,EAAgB,GAAuB;AACrD,QAAO,EACJ,aAAa,CACb,QAAQ,MAAM,IAAI,CAClB,QAAQ,UAAU,MAAS,EAAK,aAAa,CAAC;;AAMnD,SAAgB,EAAqB,GAA0B;AAC7D,SAAQ,GAAR;EACE,KAAK,QACH,QAAO;EACT,KAAK,SACH,QAAO;EACT,KAAK,UACH,QAAO;EACT,KAAK,YACH,QAAO;EACT,KAAK,SACH,QAAO;EACT,KAAK,WACH,QAAO;EACT,KAAK,cACH,QAAO;EACT,KAAK,OACH,QAAO;EACT,QACE,QAAO"}
1
+ {"version":3,"file":"formatters.js","names":[],"sources":["../../../src/subscriberbot/utils/formatters.ts"],"sourcesContent":["/**\n * Formatting utilities for the Subscriber Bot microfrontend\n * @module subscriberbot/utils/formatters\n *\n * Subscriber Bot is a global product — relationships are billed in many\n * currencies. Formatting is therefore currency-aware (each Relationship /\n * Invoice / Plan carries its own ISO currency code).\n */\n\n/**\n * Format an amount as currency using the relationship/invoice's own ISO code.\n *\n * @param amount - The numeric amount to format\n * @param currency - ISO 4217 currency code (e.g. \"USD\", \"EUR\", \"INR\")\n * @param options - Optional Intl.NumberFormat overrides\n * @returns Formatted currency string (e.g. \"$12.00\")\n *\n * @example\n * formatCurrency(12, 'USD') // => \"$12.00\"\n * formatCurrency(999, 'INR', { minimumFractionDigits: 0 }) // => \"₹999\"\n */\nexport function formatCurrency(\n amount: number,\n currency = 'USD',\n options?: Partial<Intl.NumberFormatOptions>\n): string {\n try {\n return new Intl.NumberFormat(undefined, {\n style: 'currency',\n currency: currency || 'USD',\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n ...options,\n }).format(amount);\n } catch {\n // Unknown/invalid currency code → fall back to a plain number + code.\n return `${amount.toFixed(2)} ${currency}`;\n }\n}\n\n/**\n * Format a date string or Date object into a human-readable date.\n *\n * @param date - ISO date string or Date object\n * @param options - Optional Intl.DateTimeFormat options\n * @returns Formatted date string (e.g. \"15 Jan 2026\")\n */\nexport function formatDate(\n date: string | Date | null | undefined,\n options?: Partial<Intl.DateTimeFormatOptions>\n): string {\n if (!date) return '—';\n const d = typeof date === 'string' ? new Date(date) : date;\n if (Number.isNaN(d.getTime())) return '—';\n return new Intl.DateTimeFormat(undefined, {\n day: 'numeric',\n month: 'short',\n year: 'numeric',\n ...options,\n }).format(d);\n}\n\n/**\n * Format a date-time into a date + time string.\n */\nexport function formatDateTime(\n date: string | Date | null | undefined,\n options?: Partial<Intl.DateTimeFormatOptions>\n): string {\n if (!date) return '—';\n const d = typeof date === 'string' ? new Date(date) : date;\n if (Number.isNaN(d.getTime())) return '—';\n return new Intl.DateTimeFormat(undefined, {\n day: 'numeric',\n month: 'short',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n ...options,\n }).format(d);\n}\n\n/**\n * Format a date into a relative time string (e.g. \"2 hours ago\", \"in 3 days\").\n *\n * @param date - ISO date string or Date object\n * @returns Human-readable relative time string\n */\nexport function formatRelativeTime(date: string | Date | null | undefined): string {\n if (!date) return '—';\n const d = typeof date === 'string' ? new Date(date) : date;\n if (Number.isNaN(d.getTime())) return '—';\n\n const now = new Date();\n const diffMs = d.getTime() - now.getTime();\n const future = diffMs >= 0;\n const absSeconds = Math.floor(Math.abs(diffMs) / 1000);\n const minutes = Math.floor(absSeconds / 60);\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n const weeks = Math.floor(days / 7);\n const months = Math.floor(days / 30);\n const years = Math.floor(days / 365);\n\n const phrase = (value: number, unit: string): string => {\n const label = `${value} ${unit}${value !== 1 ? 's' : ''}`;\n return future ? `in ${label}` : `${label} ago`;\n };\n\n if (absSeconds < 60) return future ? 'soon' : 'just now';\n if (minutes < 60) return phrase(minutes, 'min');\n if (hours < 24) return phrase(hours, 'hour');\n if (days < 7) return phrase(days, 'day');\n if (weeks < 4) return phrase(weeks, 'week');\n if (months < 12) return phrase(months, 'month');\n return phrase(years, 'year');\n}\n\n/**\n * Format a number with locale grouping.\n */\nexport function formatNumber(value: number, options?: Partial<Intl.NumberFormatOptions>): string {\n return new Intl.NumberFormat(undefined, options).format(value);\n}\n\n/**\n * Turn an ENUM_LIKE_TOKEN into a human \"Enum Like Token\" label.\n */\nexport function formatEnumLabel(value: string): string {\n return value\n .toLowerCase()\n .replace(/_/g, ' ')\n .replace(/\\b\\w/g, (char) => char.toUpperCase());\n}\n\n/**\n * Format a billing interval enum into a short suffix (e.g. \"MONTHLY\" → \"/mo\").\n */\nexport function formatIntervalSuffix(interval: string): string {\n switch (interval) {\n case 'DAILY':\n return '/day';\n case 'WEEKLY':\n return '/wk';\n case 'MONTHLY':\n return '/mo';\n case 'QUARTERLY':\n return '/qtr';\n case 'YEARLY':\n return '/yr';\n case 'LIFETIME':\n return ' lifetime';\n case 'USAGE_BASED':\n return ' usage';\n case 'FREE':\n return '';\n default:\n return '';\n }\n}\n"],"mappings":";AAqBA,SAAgB,EACd,GACA,IAAW,OACX,GACQ;CACR,IAAI;EACF,OAAO,IAAI,KAAK,aAAa,KAAA,GAAW;GACtC,OAAO;GACP,UAAU,KAAY;GACtB,uBAAuB;GACvB,uBAAuB;GACvB,GAAG;EACL,CAAC,EAAE,OAAO,CAAM;CAClB,QAAQ;EAEN,OAAO,GAAG,EAAO,QAAQ,CAAC,EAAE,GAAG;CACjC;AACF;AASA,SAAgB,EACd,GACA,GACQ;CACR,IAAI,CAAC,GAAM,OAAO;CAClB,IAAM,IAAI,OAAO,KAAS,WAAW,IAAI,KAAK,CAAI,IAAI;CAEtD,OADI,OAAO,MAAM,EAAE,QAAQ,CAAC,IAAU,MAC/B,IAAI,KAAK,eAAe,KAAA,GAAW;EACxC,KAAK;EACL,OAAO;EACP,MAAM;EACN,GAAG;CACL,CAAC,EAAE,OAAO,CAAC;AACb;AAKA,SAAgB,EACd,GACA,GACQ;CACR,IAAI,CAAC,GAAM,OAAO;CAClB,IAAM,IAAI,OAAO,KAAS,WAAW,IAAI,KAAK,CAAI,IAAI;CAEtD,OADI,OAAO,MAAM,EAAE,QAAQ,CAAC,IAAU,MAC/B,IAAI,KAAK,eAAe,KAAA,GAAW;EACxC,KAAK;EACL,OAAO;EACP,MAAM;EACN,MAAM;EACN,QAAQ;EACR,GAAG;CACL,CAAC,EAAE,OAAO,CAAC;AACb;AAQA,SAAgB,EAAmB,GAAgD;CACjF,IAAI,CAAC,GAAM,OAAO;CAClB,IAAM,IAAI,OAAO,KAAS,WAAW,IAAI,KAAK,CAAI,IAAI;CACtD,IAAI,OAAO,MAAM,EAAE,QAAQ,CAAC,GAAG,OAAO;CAEtC,IAAM,oBAAM,IAAI,KAAK,GACf,IAAS,EAAE,QAAQ,IAAI,EAAI,QAAQ,GACnC,IAAS,KAAU,GACnB,IAAa,KAAK,MAAM,KAAK,IAAI,CAAM,IAAI,GAAI,GAC/C,IAAU,KAAK,MAAM,IAAa,EAAE,GACpC,IAAQ,KAAK,MAAM,IAAU,EAAE,GAC/B,IAAO,KAAK,MAAM,IAAQ,EAAE,GAC5B,IAAQ,KAAK,MAAM,IAAO,CAAC,GAC3B,IAAS,KAAK,MAAM,IAAO,EAAE,GAC7B,IAAQ,KAAK,MAAM,IAAO,GAAG,GAE7B,KAAU,GAAe,MAAyB;EACtD,IAAM,IAAQ,GAAG,EAAM,GAAG,IAAO,MAAU,IAAU,KAAN;EAC/C,OAAO,IAAS,MAAM,MAAU,GAAG,EAAM;CAC3C;CAQA,OANI,IAAa,KAAW,IAAS,SAAS,aAC1C,IAAU,KAAW,EAAO,GAAS,KAAK,IAC1C,IAAQ,KAAW,EAAO,GAAO,MAAM,IACvC,IAAO,IAAU,EAAO,GAAM,KAAK,IACnC,IAAQ,IAAU,EAAO,GAAO,MAAM,IACtC,IAAS,KAAW,EAAO,GAAQ,OAAO,IACvC,EAAO,GAAO,MAAM;AAC7B;AAKA,SAAgB,EAAa,GAAe,GAAqD;CAC/F,OAAO,IAAI,KAAK,aAAa,KAAA,GAAW,CAAO,EAAE,OAAO,CAAK;AAC/D;AAKA,SAAgB,EAAgB,GAAuB;CACrD,OAAO,EACJ,YAAY,EACZ,QAAQ,MAAM,GAAG,EACjB,QAAQ,UAAU,MAAS,EAAK,YAAY,CAAC;AAClD;AAKA,SAAgB,EAAqB,GAA0B;CAC7D,QAAQ,GAAR;EACE,KAAK,SACH,OAAO;EACT,KAAK,UACH,OAAO;EACT,KAAK,WACH,OAAO;EACT,KAAK,aACH,OAAO;EACT,KAAK,UACH,OAAO;EACT,KAAK,YACH,OAAO;EACT,KAAK,eACH,OAAO;EACT,KAAK,QACH,OAAO;EACT,SACE,OAAO;CACX;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"navigation.js","names":[],"sources":["../../../src/subscriberbot/utils/navigation.ts"],"sourcesContent":["/**\n * Navigation utilities for the SubscriberBot microfrontend\n * @module subscriberbot/utils\n */\n\n/**\n * Join basePath with a relative path, correctly handling slashes\n *\n * @param basePath - The base path (e.g., '/' or '/subscriberbot')\n * @param relativePath - The relative path (e.g., 'carts/new' or '/carts/new')\n * @returns The joined path (e.g., '/subscriberbot/carts/new')\n *\n * @example\n * joinPath('/', 'carts/new') // => '/carts/new'\n * joinPath('/', '/carts/new') // => '/carts/new'\n * joinPath('/subscriberbot', 'orders') // => '/subscriberbot/orders'\n * joinPath('/subscriberbot/', 'orders') // => '/subscriberbot/orders'\n * joinPath('/subscriberbot', '') // => '/subscriberbot'\n */\nexport function joinPath(basePath: string, relativePath: string): string {\n // Remove trailing slash from base\n const cleanBase = basePath.endsWith('/') ? basePath.slice(0, -1) : basePath;\n\n // Handle empty relative path (go to base)\n if (!relativePath || relativePath === '') {\n return cleanBase || '/';\n }\n\n // Ensure relative path starts with /\n const cleanPath = relativePath.startsWith('/') ? relativePath : `/${relativePath}`;\n\n // Join them\n return cleanBase + cleanPath;\n}\n"],"mappings":";AAmBA,SAAgB,EAAS,GAAkB,GAA8B;CAEvE,IAAM,IAAY,EAAS,SAAS,IAAI,GAAG,EAAS,MAAM,GAAG,GAAG,GAAG;AAWnE,QARI,CAAC,KAAgB,MAAiB,KAC7B,KAAa,MAOf,KAHW,EAAa,WAAW,IAAI,GAAG,IAAe,IAAI"}
1
+ {"version":3,"file":"navigation.js","names":[],"sources":["../../../src/subscriberbot/utils/navigation.ts"],"sourcesContent":["/**\n * Navigation utilities for the SubscriberBot microfrontend\n * @module subscriberbot/utils\n */\n\n/**\n * Join basePath with a relative path, correctly handling slashes\n *\n * @param basePath - The base path (e.g., '/' or '/subscriberbot')\n * @param relativePath - The relative path (e.g., 'carts/new' or '/carts/new')\n * @returns The joined path (e.g., '/subscriberbot/carts/new')\n *\n * @example\n * joinPath('/', 'carts/new') // => '/carts/new'\n * joinPath('/', '/carts/new') // => '/carts/new'\n * joinPath('/subscriberbot', 'orders') // => '/subscriberbot/orders'\n * joinPath('/subscriberbot/', 'orders') // => '/subscriberbot/orders'\n * joinPath('/subscriberbot', '') // => '/subscriberbot'\n */\nexport function joinPath(basePath: string, relativePath: string): string {\n // Remove trailing slash from base\n const cleanBase = basePath.endsWith('/') ? basePath.slice(0, -1) : basePath;\n\n // Handle empty relative path (go to base)\n if (!relativePath || relativePath === '') {\n return cleanBase || '/';\n }\n\n // Ensure relative path starts with /\n const cleanPath = relativePath.startsWith('/') ? relativePath : `/${relativePath}`;\n\n // Join them\n return cleanBase + cleanPath;\n}\n"],"mappings":";AAmBA,SAAgB,EAAS,GAAkB,GAA8B;CAEvE,IAAM,IAAY,EAAS,SAAS,GAAG,IAAI,EAAS,MAAM,GAAG,EAAE,IAAI;CAWnE,OARI,CAAC,KAAgB,MAAiB,KAC7B,KAAa,MAOf,KAHW,EAAa,WAAW,GAAG,IAAI,IAAe,IAAI;AAItE"}
@@ -1 +1 @@
1
- {"version":3,"file":"pageContext.js","names":[],"sources":["../../../src/subscriberbot/utils/pageContext.ts"],"sourcesContent":["interface ConversationContextShape {\n entityType?: string;\n entityId?: string;\n activeTab?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface PageContext {\n currentUrl: string;\n currentPage: string;\n entityType?: string;\n entityId?: string;\n platform: string;\n version: string;\n viewportSize: string;\n userAgent: string;\n timestamp: string;\n}\n\nexport function gatherPageContext(): PageContext {\n const url = window.location.href;\n const pathSegments = window.location.pathname.split('/').filter(Boolean);\n const currentPage = pathSegments.slice(0, 3).join('/') || 'home';\n const entity = resolveSubscriberBotConversationContext(\n window.location.pathname,\n window.location.search\n );\n\n return {\n currentUrl: url,\n currentPage,\n entityType: entity.entityType,\n entityId: entity.entityId,\n platform: 'subscriberbot',\n version: import.meta.env.VITE_APP_VERSION ?? '2026.615.1',\n viewportSize: `${window.innerWidth}x${window.innerHeight}`,\n userAgent: navigator.userAgent,\n timestamp: new Date().toISOString(),\n };\n}\n\nfunction matchPath(pattern: RegExp, pathname: string): RegExpMatchArray | null {\n return pathname.match(pattern);\n}\n\nexport function resolveSubscriberBotConversationContext(\n pathname: string,\n search: string\n): ConversationContextShape {\n const params = new URLSearchParams(search);\n const directMatches: Array<[RegExp, string]> = [\n [/^\\/subscriberbot\\/relationships\\/([^/]+)$/, 'SUBSCRIBERBOT_RELATIONSHIP'],\n [/^\\/subscriberbot\\/providers\\/([^/]+)$/, 'SUBSCRIBERBOT_PROVIDER'],\n [/^\\/subscriberbot\\/agents\\/([^/]+)$/, 'SUBSCRIBERBOT_AGENT'],\n [/^\\/subscriberbot\\/invoices\\/([^/]+)$/, 'SUBSCRIBERBOT_INVOICE'],\n [/^\\/subscriberbot\\/workflows\\/([^/]+)$/, 'SUBSCRIBERBOT_WORKFLOW'],\n ];\n\n for (const [pattern, entityType] of directMatches) {\n const match = matchPath(pattern, pathname);\n if (match) {\n return {\n entityType,\n entityId: match[1],\n metadata: {\n routePattern: pattern.source,\n },\n };\n }\n }\n\n const activeTab =\n params.get('tab') ??\n (() => {\n const segments = pathname.split('/').filter(Boolean);\n return segments.length > 2 ? segments[segments.length - 1] : undefined;\n })();\n\n return {\n activeTab: activeTab ?? undefined,\n metadata: {\n ...(activeTab ? { activeTab } : {}),\n },\n };\n}\n"],"mappings":";AAmBA,SAAgB,IAAiC;CAC/C,IAAM,IAAM,OAAO,SAAS,MAEtB,IADe,OAAO,SAAS,SAAS,MAAM,IAAI,CAAC,OAAO,QAAQ,CACvC,MAAM,GAAG,EAAE,CAAC,KAAK,IAAI,IAAI,QACpD,IAAS,EACb,OAAO,SAAS,UAChB,OAAO,SAAS,OACjB;AAED,QAAO;EACL,YAAY;EACZ;EACA,YAAY,EAAO;EACnB,UAAU,EAAO;EACjB,UAAU;EACV,SAA6C;EAC7C,cAAc,GAAG,OAAO,WAAW,GAAG,OAAO;EAC7C,WAAW,UAAU;EACrB,4BAAW,IAAI,MAAM,EAAC,aAAa;EACpC;;AAGH,SAAS,EAAU,GAAiB,GAA2C;AAC7E,QAAO,EAAS,MAAM,EAAQ;;AAGhC,SAAgB,EACd,GACA,GAC0B;CAC1B,IAAM,IAAS,IAAI,gBAAgB,EAAO;AAS1C,MAAK,IAAM,CAAC,GAAS,MAR0B;EAC7C,CAAC,6CAA6C,6BAA6B;EAC3E,CAAC,yCAAyC,yBAAyB;EACnE,CAAC,sCAAsC,sBAAsB;EAC7D,CAAC,wCAAwC,wBAAwB;EACjE,CAAC,yCAAyC,yBAAyB;EACpE,EAEkD;EACjD,IAAM,IAAQ,EAAU,GAAS,EAAS;AAC1C,MAAI,EACF,QAAO;GACL;GACA,UAAU,EAAM;GAChB,UAAU,EACR,cAAc,EAAQ,QACvB;GACF;;CAIL,IAAM,IACJ,EAAO,IAAI,MAAM,WACV;EACL,IAAM,IAAW,EAAS,MAAM,IAAI,CAAC,OAAO,QAAQ;AACpD,SAAO,EAAS,SAAS,IAAI,EAAS,EAAS,SAAS,KAAK,KAAA;KAC3D;AAEN,QAAO;EACL,WAAW,KAAa,KAAA;EACxB,UAAU,EACR,GAAI,IAAY,EAAE,cAAW,GAAG,EAAE,EACnC;EACF"}
1
+ {"version":3,"file":"pageContext.js","names":[],"sources":["../../../src/subscriberbot/utils/pageContext.ts"],"sourcesContent":["interface ConversationContextShape {\n entityType?: string;\n entityId?: string;\n activeTab?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface PageContext {\n currentUrl: string;\n currentPage: string;\n entityType?: string;\n entityId?: string;\n platform: string;\n version: string;\n viewportSize: string;\n userAgent: string;\n timestamp: string;\n}\n\nexport function gatherPageContext(): PageContext {\n const url = window.location.href;\n const pathSegments = window.location.pathname.split('/').filter(Boolean);\n const currentPage = pathSegments.slice(0, 3).join('/') || 'home';\n const entity = resolveSubscriberBotConversationContext(\n window.location.pathname,\n window.location.search\n );\n\n return {\n currentUrl: url,\n currentPage,\n entityType: entity.entityType,\n entityId: entity.entityId,\n platform: 'subscriberbot',\n version: import.meta.env.VITE_APP_VERSION ?? '2026.615.1',\n viewportSize: `${window.innerWidth}x${window.innerHeight}`,\n userAgent: navigator.userAgent,\n timestamp: new Date().toISOString(),\n };\n}\n\nfunction matchPath(pattern: RegExp, pathname: string): RegExpMatchArray | null {\n return pathname.match(pattern);\n}\n\nexport function resolveSubscriberBotConversationContext(\n pathname: string,\n search: string\n): ConversationContextShape {\n const params = new URLSearchParams(search);\n const directMatches: Array<[RegExp, string]> = [\n [/^\\/subscriberbot\\/relationships\\/([^/]+)$/, 'SUBSCRIBERBOT_RELATIONSHIP'],\n [/^\\/subscriberbot\\/providers\\/([^/]+)$/, 'SUBSCRIBERBOT_PROVIDER'],\n [/^\\/subscriberbot\\/agents\\/([^/]+)$/, 'SUBSCRIBERBOT_AGENT'],\n [/^\\/subscriberbot\\/invoices\\/([^/]+)$/, 'SUBSCRIBERBOT_INVOICE'],\n [/^\\/subscriberbot\\/workflows\\/([^/]+)$/, 'SUBSCRIBERBOT_WORKFLOW'],\n ];\n\n for (const [pattern, entityType] of directMatches) {\n const match = matchPath(pattern, pathname);\n if (match) {\n return {\n entityType,\n entityId: match[1],\n metadata: {\n routePattern: pattern.source,\n },\n };\n }\n }\n\n const activeTab =\n params.get('tab') ??\n (() => {\n const segments = pathname.split('/').filter(Boolean);\n return segments.length > 2 ? segments[segments.length - 1] : undefined;\n })();\n\n return {\n activeTab: activeTab ?? undefined,\n metadata: {\n ...(activeTab ? { activeTab } : {}),\n },\n };\n}\n"],"mappings":";AAmBA,SAAgB,IAAiC;CAC/C,IAAM,IAAM,OAAO,SAAS,MAEtB,IADe,OAAO,SAAS,SAAS,MAAM,GAAG,EAAE,OAAO,OAC5C,EAAa,MAAM,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,QACpD,IAAS,EACb,OAAO,SAAS,UAChB,OAAO,SAAS,MAClB;CAEA,OAAO;EACL,YAAY;EACZ;EACA,YAAY,EAAO;EACnB,UAAU,EAAO;EACjB,UAAU;EACV,SAA6C;EAC7C,cAAc,GAAG,OAAO,WAAW,GAAG,OAAO;EAC7C,WAAW,UAAU;EACrB,4BAAW,IAAI,KAAK,GAAE,YAAY;CACpC;AACF;AAEA,SAAS,EAAU,GAAiB,GAA2C;CAC7E,OAAO,EAAS,MAAM,CAAO;AAC/B;AAEA,SAAgB,EACd,GACA,GAC0B;CAC1B,IAAM,IAAS,IAAI,gBAAgB,CAAM;CASzC,KAAK,IAAM,CAAC,GAAS,MAAe;EAPlC,CAAC,6CAA6C,4BAA4B;EAC1E,CAAC,yCAAyC,wBAAwB;EAClE,CAAC,sCAAsC,qBAAqB;EAC5D,CAAC,wCAAwC,uBAAuB;EAChE,CAAC,yCAAyC,wBAAwB;CAGhC,GAAe;EACjD,IAAM,IAAQ,EAAU,GAAS,CAAQ;EACzC,IAAI,GACF,OAAO;GACL;GACA,UAAU,EAAM;GAChB,UAAU,EACR,cAAc,EAAQ,OACxB;EACF;CAEJ;CAEA,IAAM,IACJ,EAAO,IAAI,KAAK,YACT;EACL,IAAM,IAAW,EAAS,MAAM,GAAG,EAAE,OAAO,OAAO;EACnD,OAAO,EAAS,SAAS,IAAI,EAAS,EAAS,SAAS,KAAK,KAAA;CAC/D,GAAG;CAEL,OAAO;EACL,WAAW,KAAa,KAAA;EACxB,UAAU,EACR,GAAI,IAAY,EAAE,aAAU,IAAI,CAAC,EACnC;CACF;AACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-subscriberbot",
3
- "version": "2026.1014.1",
3
+ "version": "2026.1023.2",
4
4
  "description": "Burdenoff SubscriberBot Microfrontend",
5
5
  "type": "module",
6
6
  "files": [