@orechio/platform-angular 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +13 -0
  2. package/fesm2022/{orechio-platform-angular-account-account-client-mPl0tzMg.mjs → orechio-platform-angular-account-account-client-BjRRo_f3.mjs} +4 -4
  3. package/fesm2022/{orechio-platform-angular-account-account-client-mPl0tzMg.mjs.map → orechio-platform-angular-account-account-client-BjRRo_f3.mjs.map} +1 -1
  4. package/fesm2022/{orechio-platform-angular-account-forgot-password.page-L-Z-s49p.mjs → orechio-platform-angular-account-forgot-password.page-dSIZ21HJ.mjs} +5 -5
  5. package/fesm2022/{orechio-platform-angular-account-forgot-password.page-L-Z-s49p.mjs.map → orechio-platform-angular-account-forgot-password.page-dSIZ21HJ.mjs.map} +1 -1
  6. package/fesm2022/{orechio-platform-angular-account-initial-branch.page-C8a1eU3L.mjs → orechio-platform-angular-account-initial-branch.page-vLp57syM.mjs} +10 -5
  7. package/fesm2022/orechio-platform-angular-account-initial-branch.page-vLp57syM.mjs.map +1 -0
  8. package/fesm2022/{orechio-platform-angular-account-resend-verification.page-C3lk1vNj.mjs → orechio-platform-angular-account-resend-verification.page-BO--Lmyi.mjs} +5 -5
  9. package/fesm2022/{orechio-platform-angular-account-resend-verification.page-C3lk1vNj.mjs.map → orechio-platform-angular-account-resend-verification.page-BO--Lmyi.mjs.map} +1 -1
  10. package/fesm2022/{orechio-platform-angular-account-token-password.page-1vn5XGVu.mjs → orechio-platform-angular-account-token-password.page-WfTzcecr.mjs} +5 -5
  11. package/fesm2022/{orechio-platform-angular-account-token-password.page-1vn5XGVu.mjs.map → orechio-platform-angular-account-token-password.page-WfTzcecr.mjs.map} +1 -1
  12. package/fesm2022/{orechio-platform-angular-account-verify-email.page-xulVDiOn.mjs → orechio-platform-angular-account-verify-email.page-DCVh128a.mjs} +5 -5
  13. package/fesm2022/{orechio-platform-angular-account-verify-email.page-xulVDiOn.mjs.map → orechio-platform-angular-account-verify-email.page-DCVh128a.mjs.map} +1 -1
  14. package/fesm2022/orechio-platform-angular-account.mjs +9 -9
  15. package/fesm2022/{orechio-platform-angular-billing-billing-format-C8QPXulm.mjs → orechio-platform-angular-billing-billing-format-CuDtE7fj.mjs} +6 -71
  16. package/fesm2022/orechio-platform-angular-billing-billing-format-CuDtE7fj.mjs.map +1 -0
  17. package/fesm2022/{orechio-platform-angular-billing-checkout.page-Dr6ZGDkd.mjs → orechio-platform-angular-billing-checkout.page-BhUYGMkL.mjs} +7 -6
  18. package/fesm2022/{orechio-platform-angular-billing-checkout.page-Dr6ZGDkd.mjs.map → orechio-platform-angular-billing-checkout.page-BhUYGMkL.mjs.map} +1 -1
  19. package/fesm2022/{orechio-platform-angular-billing-invoice.page-CWThsx-_.mjs → orechio-platform-angular-billing-invoice.page-CELLNkLd.mjs} +7 -6
  20. package/fesm2022/{orechio-platform-angular-billing-invoice.page-CWThsx-_.mjs.map → orechio-platform-angular-billing-invoice.page-CELLNkLd.mjs.map} +1 -1
  21. package/fesm2022/{orechio-platform-angular-billing-invoices.page-DytE1Lcz.mjs → orechio-platform-angular-billing-invoices.page-CfWDUFv6.mjs} +6 -5
  22. package/fesm2022/{orechio-platform-angular-billing-invoices.page-DytE1Lcz.mjs.map → orechio-platform-angular-billing-invoices.page-CfWDUFv6.mjs.map} +1 -1
  23. package/fesm2022/orechio-platform-angular-billing-orechio-platform-angular-billing-C8Q1JSAC.mjs +313 -0
  24. package/fesm2022/orechio-platform-angular-billing-orechio-platform-angular-billing-C8Q1JSAC.mjs.map +1 -0
  25. package/fesm2022/{orechio-platform-angular-billing-pix-panel.component-DrfNi22S.mjs → orechio-platform-angular-billing-pix-panel.component-BiNCJuB_.mjs} +5 -5
  26. package/fesm2022/{orechio-platform-angular-billing-pix-panel.component-DrfNi22S.mjs.map → orechio-platform-angular-billing-pix-panel.component-BiNCJuB_.mjs.map} +1 -1
  27. package/fesm2022/{orechio-platform-angular-billing-profile.page-DRkoYOZa.mjs → orechio-platform-angular-billing-profile.page-DufY3HDA.mjs} +6 -5
  28. package/fesm2022/{orechio-platform-angular-billing-profile.page-DRkoYOZa.mjs.map → orechio-platform-angular-billing-profile.page-DufY3HDA.mjs.map} +1 -1
  29. package/fesm2022/{orechio-platform-angular-billing-subscription.page-Dbk-Znvg.mjs → orechio-platform-angular-billing-subscription.page-Bi6w7yq_.mjs} +8 -5
  30. package/fesm2022/orechio-platform-angular-billing-subscription.page-Bi6w7yq_.mjs.map +1 -0
  31. package/fesm2022/orechio-platform-angular-billing.mjs +1 -68
  32. package/fesm2022/orechio-platform-angular-billing.mjs.map +1 -1
  33. package/fesm2022/orechio-platform-angular.mjs +15 -15
  34. package/package.json +1 -1
  35. package/types/orechio-platform-angular-billing.d.ts +67 -3
  36. package/types/orechio-platform-angular.d.ts +2 -2
  37. package/fesm2022/orechio-platform-angular-account-initial-branch.page-C8a1eU3L.mjs.map +0 -1
  38. package/fesm2022/orechio-platform-angular-billing-billing-format-C8QPXulm.mjs.map +0 -1
  39. package/fesm2022/orechio-platform-angular-billing-subscription.page-Dbk-Znvg.mjs.map +0 -1
@@ -1,7 +1,8 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { inject, signal, computed, ChangeDetectionStrategy, Component } from '@angular/core';
3
3
  import { RouterLink } from '@angular/router';
4
- import { d as data, B as BillingClient, a as BillingErrorComponent } from './orechio-platform-angular-billing-billing-format-C8QPXulm.mjs';
4
+ import { B as BillingClient, S as SubscriptionAccessState } from './orechio-platform-angular-billing-orechio-platform-angular-billing-C8Q1JSAC.mjs';
5
+ import { d as data, B as BillingErrorComponent } from './orechio-platform-angular-billing-billing-format-CuDtE7fj.mjs';
5
6
 
6
7
  const DIA = 24 * 60 * 60 * 1000;
7
8
  const EM_ABERTO = ['Created', 'Pending', 'Overdue'];
@@ -74,6 +75,7 @@ function situacao(assinatura, agora, emAberto) {
74
75
  }
75
76
  class SubscriptionPage {
76
77
  client = inject(BillingClient);
78
+ acesso = inject(SubscriptionAccessState);
77
79
  assinatura = signal(null, /* @ts-ignore */
78
80
  ...(ngDevMode ? [{ debugName: "assinatura" }] : /* istanbul ignore next */ []));
79
81
  /** Só preenchido em Grace/Suspended: `undefined` = ainda não respondeu; `null` = nenhuma aberta. */
@@ -96,6 +98,7 @@ class SubscriptionPage {
96
98
  this.client.getSubscription().subscribe({
97
99
  next: (assinatura) => {
98
100
  this.assinatura.set(assinatura);
101
+ this.acesso.atualizar(assinatura.status);
99
102
  if (emAtraso(assinatura))
100
103
  this.buscarFaturaEmAberto();
101
104
  },
@@ -108,8 +111,8 @@ class SubscriptionPage {
108
111
  error: (problema) => this.erro.set(problema),
109
112
  });
110
113
  }
111
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: SubscriptionPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
112
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: SubscriptionPage, isStandalone: true, selector: "orechio-billing-subscription", ngImport: i0, template: `
114
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: SubscriptionPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
115
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.3", type: SubscriptionPage, isStandalone: true, selector: "orechio-billing-subscription", ngImport: i0, template: `
113
116
  <section class="orechio-billing">
114
117
  <h1>Assinatura</h1>
115
118
 
@@ -131,7 +134,7 @@ class SubscriptionPage {
131
134
  </section>
132
135
  `, isInline: true, styles: [".orechio-billing{display:flex;flex-direction:column;gap:var(--orechio-space-3, .75rem);max-width:40rem;margin:0 auto;padding:var(--orechio-space-6, 1.5rem);color:var(--orechio-color-text, inherit);font-family:var(--orechio-font-body, inherit)}.orechio-billing form{display:flex;flex-direction:column;gap:var(--orechio-space-2, .5rem)}.orechio-billing__muted{color:var(--orechio-color-text-muted, #666)}.orechio-billing__error{color:var(--orechio-color-danger, #b00020)}.orechio-billing__acao{align-self:flex-start;display:inline-block;padding:var(--orechio-space-2, .5rem) var(--orechio-space-4, 1rem);border-radius:var(--orechio-radius, .375rem);background:var(--orechio-color-primary, #1a56db);color:var(--orechio-color-on-primary, #fff);font-weight:600;text-decoration:none}.orechio-billing__acao:hover,.orechio-billing__acao:focus-visible{background:var(--orechio-color-primary-hover, var(--orechio-color-primary, #1446b0))}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "component", type: BillingErrorComponent, selector: "orechio-billing-error", inputs: ["problema"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
133
136
  }
134
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: SubscriptionPage, decorators: [{
137
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: SubscriptionPage, decorators: [{
135
138
  type: Component,
136
139
  args: [{ selector: 'orechio-billing-subscription', standalone: true, imports: [RouterLink, BillingErrorComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: `
137
140
  <section class="orechio-billing">
@@ -157,4 +160,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImpor
157
160
  }] });
158
161
 
159
162
  export { SubscriptionPage };
160
- //# sourceMappingURL=orechio-platform-angular-billing-subscription.page-Dbk-Znvg.mjs.map
163
+ //# sourceMappingURL=orechio-platform-angular-billing-subscription.page-Bi6w7yq_.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orechio-platform-angular-billing-subscription.page-Bi6w7yq_.mjs","sources":["../../../projects/platform-angular/billing/src/pages/subscription.page.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, OnInit, computed, inject, signal } from '@angular/core';\r\nimport { RouterLink } from '@angular/router';\r\nimport { ProblemDetails } from '@orechio/platform-angular';\r\nimport { BillingClient } from '../billing-client';\r\nimport { BillingErrorComponent } from '../billing-error.component';\r\nimport { ESTILO_BASE, data } from '../billing-format';\r\nimport { InvoiceListItem, InvoiceStatus, Subscription } from '../billing-models';\r\nimport { SubscriptionAccessState } from '../subscription-access.state';\r\n\r\nconst DIA = 24 * 60 * 60 * 1000;\r\nconst EM_ABERTO: InvoiceStatus[] = ['Created', 'Pending', 'Overdue'];\r\n\r\nconst emAtraso = (assinatura: Subscription) =>\r\n assinatura.status === 'Grace' || assinatura.status === 'Suspended';\r\n\r\ninterface Situacao {\r\n titulo: string;\r\n detalhe: string;\r\n acao: { texto: string; link: string };\r\n}\r\n\r\n/**\r\n * A ação de cada estado segue o que a Platform aceita: o checkout serve `Trial`,\r\n * `PendingPayment` e, desde a BILLING-2b, `Grace` e `Suspended` — mas só sem fatura aberta\r\n * (`Created|Pending|Overdue`; com ela, `checkout.open_invoice_exists`). Em carência e suspensão\r\n * a ação depende disso: fatura aberta → o detalhe dela; nenhuma → o checkout. Cancelada e\r\n * expirada não têm ação de pagamento nesta versão: reativar é v2 (ADR-021 §3.5).\r\n */\r\nfunction situacao(assinatura: Subscription, agora: number, emAberto: InvoiceListItem | null): Situacao {\r\n const pagar = { texto: 'Pagar agora', link: 'checkout' };\r\n const faturas = { texto: 'Ver faturas', link: 'invoices' };\r\n const acaoDeAtraso = emAberto\r\n ? { texto: 'Pagar fatura em aberto', link: `invoices/${emAberto.id}` }\r\n : { texto: 'Pagar', link: 'checkout' };\r\n const orientacao = emAberto ? 'Pague a fatura em aberto' : 'Faça o pagamento';\r\n\r\n switch (assinatura.status) {\r\n case 'Trial': {\r\n const dias = Math.max(0, Math.ceil((Date.parse(assinatura.trialEndsAt) - agora) / DIA));\r\n const restante =\r\n dias === 0 ? 'O período de teste termina hoje.'\r\n : dias === 1 ? 'Falta 1 dia para o fim do período de teste.'\r\n : `Faltam ${dias} dias para o fim do período de teste.`;\r\n return { titulo: 'Período de teste', detalhe: restante, acao: { texto: 'Assinar agora', link: 'checkout' } };\r\n }\r\n case 'PendingPayment':\r\n return {\r\n titulo: 'Pagamento pendente',\r\n detalhe: 'A assinatura começa assim que o primeiro pagamento for confirmado.',\r\n acao: pagar,\r\n };\r\n case 'Active':\r\n return {\r\n titulo: 'Assinatura ativa',\r\n detalhe: assinatura.currentPeriodEndsAt\r\n ? `Próxima renovação em ${data(assinatura.currentPeriodEndsAt)}.`\r\n : 'Tudo em dia.',\r\n acao: faturas,\r\n };\r\n case 'Grace':\r\n return {\r\n titulo: 'Pagamento em atraso',\r\n detalhe: assinatura.graceEndsAt\r\n ? `O acesso continua até ${data(assinatura.graceEndsAt)}. ${orientacao} para não ter o acesso suspenso.`\r\n : `${orientacao} para não ter o acesso suspenso.`,\r\n acao: acaoDeAtraso,\r\n };\r\n case 'Suspended':\r\n return {\r\n titulo: 'Assinatura suspensa',\r\n detalhe: `O acesso foi suspenso por falta de pagamento. ${orientacao} para voltar a usar.`,\r\n acao: acaoDeAtraso,\r\n };\r\n case 'Cancelled':\r\n return {\r\n titulo: 'Assinatura cancelada',\r\n detalhe: assinatura.cancelEffectiveAt\r\n ? `O cancelamento vale a partir de ${data(assinatura.cancelEffectiveAt)}. Para reativar, fale com o suporte.`\r\n : 'Para reativar, fale com o suporte.',\r\n acao: faturas,\r\n };\r\n case 'Expired':\r\n return {\r\n titulo: 'Assinatura expirada',\r\n detalhe: 'Para voltar a assinar, fale com o suporte.',\r\n acao: faturas,\r\n };\r\n }\r\n}\r\n\r\n@Component({\r\n selector: 'orechio-billing-subscription',\r\n standalone: true,\r\n imports: [RouterLink, BillingErrorComponent],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n template: `\r\n <section class=\"orechio-billing\">\r\n <h1>Assinatura</h1>\r\n\r\n @if (erro(); as problema) {\r\n <orechio-billing-error [problema]=\"problema\" />\r\n } @else if (atual(); as s) {\r\n <h2>{{ s.titulo }}</h2>\r\n <p>{{ s.detalhe }}</p>\r\n <a data-acao class=\"orechio-billing__acao\" [routerLink]=\"s.acao.link\">{{ s.acao.texto }}</a>\r\n\r\n <nav class=\"orechio-billing__muted\">\r\n <a routerLink=\"profile\">Dados de cobrança</a>\r\n ·\r\n <a routerLink=\"invoices\">Faturas</a>\r\n </nav>\r\n } @else {\r\n <p class=\"orechio-billing__muted\">Carregando…</p>\r\n }\r\n </section>\r\n `,\r\n styles: ESTILO_BASE,\r\n})\r\nexport class SubscriptionPage implements OnInit {\r\n private readonly client = inject(BillingClient);\r\n private readonly acesso = inject(SubscriptionAccessState);\r\n\r\n private readonly assinatura = signal<Subscription | null>(null);\r\n /** Só preenchido em Grace/Suspended: `undefined` = ainda não respondeu; `null` = nenhuma aberta. */\r\n private readonly emAberto = signal<InvoiceListItem | null | undefined>(undefined);\r\n protected readonly erro = signal<ProblemDetails | null>(null);\r\n protected readonly atual = computed(() => {\r\n const assinatura = this.assinatura();\r\n if (!assinatura) return null;\r\n\r\n const aberta = this.emAberto();\r\n // Sem a resposta das faturas não se sabe o destino da ação: não se adivinha.\r\n if (emAtraso(assinatura) && aberta === undefined) return null;\r\n\r\n return situacao(assinatura, Date.now(), aberta ?? null);\r\n });\r\n\r\n ngOnInit(): void {\r\n this.client.getSubscription().subscribe({\r\n next: (assinatura) => {\r\n this.assinatura.set(assinatura);\r\n this.acesso.atualizar(assinatura.status);\r\n if (emAtraso(assinatura)) this.buscarFaturaEmAberto();\r\n },\r\n error: (problema: ProblemDetails) => this.erro.set(problema),\r\n });\r\n }\r\n\r\n private buscarFaturaEmAberto(): void {\r\n this.client.listInvoices().subscribe({\r\n next: (pagina) => this.emAberto.set(pagina.invoices.find((f) => EM_ABERTO.includes(f.status)) ?? null),\r\n error: (problema: ProblemDetails) => this.erro.set(problema),\r\n });\r\n }\r\n}\r\n"],"names":[],"mappings":"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"}
@@ -1,69 +1,2 @@
1
- import { InjectionToken } from '@angular/core';
2
-
3
- const ORECHIO_BILLING_CONFIG = new InjectionToken('ORECHIO_BILLING_CONFIG');
4
- function provideOrechioBilling(options = {}) {
5
- const bruto = options.basePath ?? '/api/billing';
6
- // Mesma regra do `BillingRoutePrefix` do BFF, no mesmo momento: na composição. Uma URL
7
- // absoluta aqui levaria a cobrança para fora do domínio do produto, onde o cookie de sessão
8
- // não vai junto.
9
- if (!bruto.startsWith('/') || bruto.startsWith('//')) {
10
- throw new Error(`provideOrechioBilling: \`basePath\` precisa ser um caminho same-origin começando com '/': '${bruto}'.`);
11
- }
12
- const config = { basePath: bruto.replace(/\/+$/, '') };
13
- return [{ provide: ORECHIO_BILLING_CONFIG, useValue: config }];
14
- }
15
-
16
- /**
17
- * As rotas de cobrança. O host as monta em `/billing` — é para lá que os e-mails de cobrança
18
- * da Platform apontam (`{base}/billing`, ADR-021 §3.2):
19
- *
20
- * <pre>
21
- * { path: 'billing', children: ORECHIO_BILLING_ROUTES }
22
- * </pre>
23
- *
24
- * Os caminhos ENTRE as telas são fixos (a situação leva a `checkout` e `invoices`, o
25
- * pagamento sem perfil leva a `profile`). Todas com `loadComponent`, como as de conta.
26
- */
27
- const ORECHIO_BILLING_ROUTES = [
28
- {
29
- path: '',
30
- pathMatch: 'full',
31
- title: 'Assinatura',
32
- loadComponent: () => import('./orechio-platform-angular-billing-subscription.page-Dbk-Znvg.mjs').then((m) => m.SubscriptionPage),
33
- },
34
- {
35
- path: 'profile',
36
- title: 'Dados de cobrança',
37
- loadComponent: () => import('./orechio-platform-angular-billing-profile.page-DRkoYOZa.mjs').then((m) => m.ProfilePage),
38
- },
39
- {
40
- path: 'checkout',
41
- title: 'Pagar assinatura',
42
- loadComponent: () => import('./orechio-platform-angular-billing-checkout.page-Dr6ZGDkd.mjs').then((m) => m.CheckoutPage),
43
- },
44
- {
45
- path: 'invoices',
46
- title: 'Faturas',
47
- loadComponent: () => import('./orechio-platform-angular-billing-invoices.page-DytE1Lcz.mjs').then((m) => m.InvoicesPage),
48
- },
49
- {
50
- path: 'invoices/:id',
51
- title: 'Fatura',
52
- loadComponent: () => import('./orechio-platform-angular-billing-invoice.page-CWThsx-_.mjs').then((m) => m.InvoicePage),
53
- },
54
- ];
55
-
56
- /*
57
- * Public API Surface of @orechio/platform-angular/billing
58
- *
59
- * BILLING-3 — as telas de cobrança do titular (ADR-021 §3.5). Mesmo contrato do entry
60
- * `account`: `BillingClient` e as páginas NÃO são exportados. As telas são alcançadas por
61
- * `ORECHIO_BILLING_ROUTES`, e os caminhos entre elas só valem montados juntos.
62
- */
63
-
64
- /**
65
- * Generated bundle index. Do not edit.
66
- */
67
-
68
- export { ORECHIO_BILLING_CONFIG, ORECHIO_BILLING_ROUTES, provideOrechioBilling };
1
+ export { O as ORECHIO_BILLING_CONFIG, a as ORECHIO_BILLING_ROUTES, b as OrechioSubscriptionNotice, p as provideOrechioBilling, r as requireSubscriptionAccess, s as subscriptionAccessInterceptor } from './orechio-platform-angular-billing-orechio-platform-angular-billing-C8Q1JSAC.mjs';
69
2
  //# sourceMappingURL=orechio-platform-angular-billing.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"orechio-platform-angular-billing.mjs","sources":["../../../projects/platform-angular/billing/src/billing-config.ts","../../../projects/platform-angular/billing/src/billing.routes.ts","../../../projects/platform-angular/billing/src/public-api.ts","../../../projects/platform-angular/billing/src/orechio-platform-angular-billing.ts"],"sourcesContent":["import { InjectionToken, Provider } from '@angular/core';\r\n\r\nexport interface OrechioBillingConfig {\r\n /**\r\n * Prefixo do BFF de cobrança (`MapOrechioBillingEndpoints`), same-origin. O BFF lê a sessão\r\n * do host e fala com a Platform; o browser nunca vê token nem fala com a Platform.\r\n */\r\n basePath: string;\r\n}\r\n\r\nexport const ORECHIO_BILLING_CONFIG = new InjectionToken<OrechioBillingConfig>(\r\n 'ORECHIO_BILLING_CONFIG',\r\n);\r\n\r\nexport interface OrechioBillingOptions {\r\n /** Default `/api/billing`, o mesmo `BillingRoutePrefix` default do BFF. */\r\n basePath?: string;\r\n}\r\n\r\nexport function provideOrechioBilling(options: OrechioBillingOptions = {}): Provider[] {\r\n const bruto = options.basePath ?? '/api/billing';\r\n\r\n // Mesma regra do `BillingRoutePrefix` do BFF, no mesmo momento: na composição. Uma URL\r\n // absoluta aqui levaria a cobrança para fora do domínio do produto, onde o cookie de sessão\r\n // não vai junto.\r\n if (!bruto.startsWith('/') || bruto.startsWith('//')) {\r\n throw new Error(\r\n `provideOrechioBilling: \\`basePath\\` precisa ser um caminho same-origin começando com '/': '${bruto}'.`,\r\n );\r\n }\r\n\r\n const config: OrechioBillingConfig = { basePath: bruto.replace(/\\/+$/, '') };\r\n return [{ provide: ORECHIO_BILLING_CONFIG, useValue: config }];\r\n}\r\n","import { Routes } from '@angular/router';\r\n\r\n/**\r\n * As rotas de cobrança. O host as monta em `/billing` — é para lá que os e-mails de cobrança\r\n * da Platform apontam (`{base}/billing`, ADR-021 §3.2):\r\n *\r\n * <pre>\r\n * { path: 'billing', children: ORECHIO_BILLING_ROUTES }\r\n * </pre>\r\n *\r\n * Os caminhos ENTRE as telas são fixos (a situação leva a `checkout` e `invoices`, o\r\n * pagamento sem perfil leva a `profile`). Todas com `loadComponent`, como as de conta.\r\n */\r\nexport const ORECHIO_BILLING_ROUTES: Routes = [\r\n {\r\n path: '',\r\n pathMatch: 'full',\r\n title: 'Assinatura',\r\n loadComponent: () => import('./pages/subscription.page').then((m) => m.SubscriptionPage),\r\n },\r\n {\r\n path: 'profile',\r\n title: 'Dados de cobrança',\r\n loadComponent: () => import('./pages/profile.page').then((m) => m.ProfilePage),\r\n },\r\n {\r\n path: 'checkout',\r\n title: 'Pagar assinatura',\r\n loadComponent: () => import('./pages/checkout.page').then((m) => m.CheckoutPage),\r\n },\r\n {\r\n path: 'invoices',\r\n title: 'Faturas',\r\n loadComponent: () => import('./pages/invoices.page').then((m) => m.InvoicesPage),\r\n },\r\n {\r\n path: 'invoices/:id',\r\n title: 'Fatura',\r\n loadComponent: () => import('./pages/invoice.page').then((m) => m.InvoicePage),\r\n },\r\n];\r\n","/*\r\n * Public API Surface of @orechio/platform-angular/billing\r\n *\r\n * BILLING-3 — as telas de cobrança do titular (ADR-021 §3.5). Mesmo contrato do entry\r\n * `account`: `BillingClient` e as páginas NÃO são exportados. As telas são alcançadas por\r\n * `ORECHIO_BILLING_ROUTES`, e os caminhos entre elas só valem montados juntos.\r\n */\r\n\r\nexport type { OrechioBillingConfig, OrechioBillingOptions } from './billing-config';\r\nexport { ORECHIO_BILLING_CONFIG, provideOrechioBilling } from './billing-config';\r\n\r\nexport { ORECHIO_BILLING_ROUTES } from './billing.routes';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;MAUa,sBAAsB,GAAG,IAAI,cAAc,CACtD,wBAAwB;AAQpB,SAAU,qBAAqB,CAAC,OAAA,GAAiC,EAAE,EAAA;AACvE,IAAA,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,IAAI,cAAc;;;;AAKhD,IAAA,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;AACpD,QAAA,MAAM,IAAI,KAAK,CACb,8FAA8F,KAAK,CAAA,EAAA,CAAI,CACxG;IACH;AAEA,IAAA,MAAM,MAAM,GAAyB,EAAE,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;IAC5E,OAAO,CAAC,EAAE,OAAO,EAAE,sBAAsB,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AAChE;;AC/BA;;;;;;;;;;AAUG;AACI,MAAM,sBAAsB,GAAW;AAC5C,IAAA;AACE,QAAA,IAAI,EAAE,EAAE;AACR,QAAA,SAAS,EAAE,MAAM;AACjB,QAAA,KAAK,EAAE,YAAY;AACnB,QAAA,aAAa,EAAE,MAAM,OAAO,mEAA2B,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,gBAAgB,CAAC;AACzF,KAAA;AACD,IAAA;AACE,QAAA,IAAI,EAAE,SAAS;AACf,QAAA,KAAK,EAAE,mBAAmB;AAC1B,QAAA,aAAa,EAAE,MAAM,OAAO,8DAAsB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC;AAC/E,KAAA;AACD,IAAA;AACE,QAAA,IAAI,EAAE,UAAU;AAChB,QAAA,KAAK,EAAE,kBAAkB;AACzB,QAAA,aAAa,EAAE,MAAM,OAAO,+DAAuB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC;AACjF,KAAA;AACD,IAAA;AACE,QAAA,IAAI,EAAE,UAAU;AAChB,QAAA,KAAK,EAAE,SAAS;AAChB,QAAA,aAAa,EAAE,MAAM,OAAO,+DAAuB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC;AACjF,KAAA;AACD,IAAA;AACE,QAAA,IAAI,EAAE,cAAc;AACpB,QAAA,KAAK,EAAE,QAAQ;AACf,QAAA,aAAa,EAAE,MAAM,OAAO,8DAAsB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC;AAC/E,KAAA;;;ACvCH;;;;;;AAMG;;ACNH;;AAEG;;;;"}
1
+ {"version":3,"file":"orechio-platform-angular-billing.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -32,10 +32,10 @@ class SessionStore {
32
32
  clear() {
33
33
  this.state.set(null);
34
34
  }
35
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: SessionStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
36
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: SessionStore, providedIn: 'root' });
35
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: SessionStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
36
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: SessionStore, providedIn: 'root' });
37
37
  }
38
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: SessionStore, decorators: [{
38
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: SessionStore, decorators: [{
39
39
  type: Injectable,
40
40
  args: [{ providedIn: 'root' }]
41
41
  }] });
@@ -122,10 +122,10 @@ class AuthClient {
122
122
  .post(this.url(this.config.auth.logout), {})
123
123
  .pipe(finalize(() => this.session.clear()));
124
124
  }
125
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: AuthClient, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
126
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: AuthClient, providedIn: 'root' });
125
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: AuthClient, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
126
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: AuthClient, providedIn: 'root' });
127
127
  }
128
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: AuthClient, decorators: [{
128
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: AuthClient, decorators: [{
129
129
  type: Injectable,
130
130
  args: [{ providedIn: 'root' }]
131
131
  }] });
@@ -270,8 +270,8 @@ class BranchSelector {
270
270
  fragment(branch) {
271
271
  return branch.id.slice(0, 8);
272
272
  }
273
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: BranchSelector, deps: [], target: i0.ɵɵFactoryTarget.Component });
274
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: BranchSelector, isStandalone: true, selector: "orechio-branch-selector", inputs: { branches: { classPropertyName: "branches", publicName: "branches", isSignal: true, isRequired: true, transformFunction: null }, busy: { classPropertyName: "busy", publicName: "busy", isSignal: true, isRequired: false, transformFunction: null }, legend: { classPropertyName: "legend", publicName: "legend", isSignal: true, isRequired: false, transformFunction: null }, confirmLabel: { classPropertyName: "confirmLabel", publicName: "confirmLabel", isSignal: true, isRequired: false, transformFunction: null }, emptyLabel: { classPropertyName: "emptyLabel", publicName: "emptyLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selected" }, ngImport: i0, template: `
273
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: BranchSelector, deps: [], target: i0.ɵɵFactoryTarget.Component });
274
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.3", type: BranchSelector, isStandalone: true, selector: "orechio-branch-selector", inputs: { branches: { classPropertyName: "branches", publicName: "branches", isSignal: true, isRequired: true, transformFunction: null }, busy: { classPropertyName: "busy", publicName: "busy", isSignal: true, isRequired: false, transformFunction: null }, legend: { classPropertyName: "legend", publicName: "legend", isSignal: true, isRequired: false, transformFunction: null }, confirmLabel: { classPropertyName: "confirmLabel", publicName: "confirmLabel", isSignal: true, isRequired: false, transformFunction: null }, emptyLabel: { classPropertyName: "emptyLabel", publicName: "emptyLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selected" }, ngImport: i0, template: `
275
275
  @if (branches().length === 0) {
276
276
  <p class="orechio-branch-selector__empty" role="status">{{ emptyLabel() }}</p>
277
277
  } @else {
@@ -306,7 +306,7 @@ class BranchSelector {
306
306
  }
307
307
  `, isInline: true, styles: [".orechio-branch-selector__option{display:flex;align-items:center;margin:.25rem 0}.orechio-branch-selector__option input[type=radio]{width:auto;height:auto;margin:0 .5rem 0 0}.orechio-branch-selector__hint{font-size:.85em;opacity:.7;white-space:pre}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
308
308
  }
309
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: BranchSelector, decorators: [{
309
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: BranchSelector, decorators: [{
310
310
  type: Component,
311
311
  args: [{ selector: 'orechio-branch-selector', changeDetection: ChangeDetectionStrategy.OnPush, template: `
312
312
  @if (branches().length === 0) {
@@ -412,10 +412,10 @@ class RefreshCoordinator {
412
412
  }));
413
413
  return this.inFlight$;
414
414
  }
415
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: RefreshCoordinator, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
416
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: RefreshCoordinator, providedIn: 'root' });
415
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: RefreshCoordinator, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
416
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: RefreshCoordinator, providedIn: 'root' });
417
417
  }
418
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: RefreshCoordinator, decorators: [{
418
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: RefreshCoordinator, decorators: [{
419
419
  type: Injectable,
420
420
  args: [{ providedIn: 'root' }]
421
421
  }] });
@@ -547,10 +547,10 @@ class CapabilityDirective {
547
547
  this.hasView = false;
548
548
  }
549
549
  }
550
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: CapabilityDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
551
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.2", type: CapabilityDirective, isStandalone: true, selector: "[orxCapability]", inputs: { orxCapability: "orxCapability", has: ["orxCapabilityHas", "has"] }, ngImport: i0 });
550
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: CapabilityDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
551
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.2.3", type: CapabilityDirective, isStandalone: true, selector: "[orxCapability]", inputs: { orxCapability: "orxCapability", has: ["orxCapabilityHas", "has"] }, ngImport: i0 });
552
552
  }
553
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: CapabilityDirective, decorators: [{
553
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: CapabilityDirective, decorators: [{
554
554
  type: Directive,
555
555
  args: [{
556
556
  selector: '[orxCapability]',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orechio/platform-angular",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^22.1.0",
6
6
  "@angular/core": "^22.1.0",
@@ -1,5 +1,8 @@
1
- import { InjectionToken, Provider } from '@angular/core';
2
- import { Routes } from '@angular/router';
1
+ import * as i0 from '@angular/core';
2
+ import { InjectionToken, Provider, OnInit } from '@angular/core';
3
+ import { Routes, CanActivateFn } from '@angular/router';
4
+ import { HttpInterceptorFn } from '@angular/common/http';
5
+ import { Observable } from 'rxjs';
3
6
 
4
7
  interface OrechioBillingConfig {
5
8
  /**
@@ -7,11 +10,15 @@ interface OrechioBillingConfig {
7
10
  * do host e fala com a Platform; o browser nunca vê token nem fala com a Platform.
8
11
  */
9
12
  basePath: string;
13
+ /** Rota da tela de assinatura no produto, para onde a faixa, o aviso e a guarda levam. */
14
+ uiRoute: string;
10
15
  }
11
16
  declare const ORECHIO_BILLING_CONFIG: InjectionToken<OrechioBillingConfig>;
12
17
  interface OrechioBillingOptions {
13
18
  /** Default `/api/billing`, o mesmo `BillingRoutePrefix` default do BFF. */
14
19
  basePath?: string;
20
+ /** Default `/billing` (ADR-021 §3.2). Caminho começando com `/`, nunca `//`. */
21
+ uiRoute?: string;
15
22
  }
16
23
  declare function provideOrechioBilling(options?: OrechioBillingOptions): Provider[];
17
24
 
@@ -28,5 +35,62 @@ declare function provideOrechioBilling(options?: OrechioBillingOptions): Provide
28
35
  */
29
36
  declare const ORECHIO_BILLING_ROUTES: Routes;
30
37
 
31
- export { ORECHIO_BILLING_CONFIG, ORECHIO_BILLING_ROUTES, provideOrechioBilling };
38
+ /**
39
+ * Trata as recusas de assinatura do backend do produto (Orechio.Platform.Client 1.6.0). O token
40
+ * da sessão pode estar atrasado em relação ao pagamento, então a primeira resposta é renovar a
41
+ * sessão e repetir o pedido uma vez. Se continuar recusado, suspensa abre o aviso e expirada leva
42
+ * à assinatura. Nunca desloga, e o erro devolvido é sempre o original.
43
+ */
44
+ declare const subscriptionAccessInterceptor: HttpInterceptorFn;
45
+
46
+ /**
47
+ * Expirada vai para a tela da assinatura. Qualquer outra situação entra, inclusive quando a
48
+ * leitura falhou: falha da cobrança nunca tranca (ADR-036), e a barreira de servidor continua
49
+ * valendo. Aplique nas rotas do produto, não nas de `/billing`.
50
+ */
51
+ declare const requireSubscriptionAccess: CanActivateFn;
52
+
53
+ /**
54
+ * Os formatos que o BFF repassa sem remontar: os DTOs do Commerce da Platform, em camelCase.
55
+ * Cada tipo aponta o DTO de origem; nenhum campo existe aqui que não exista lá.
56
+ */
57
+ /** `SubscriptionStatus` (Commerce.Domain.Subscriptions). */
58
+ type SubscriptionStatus = 'Trial' | 'PendingPayment' | 'Active' | 'Grace' | 'Cancelled' | 'Suspended' | 'Expired';
59
+
60
+ /**
61
+ * A situação da assinatura que a faixa, a guarda e o interceptor compartilham. Interno ao
62
+ * entry: não é exportado. A leitura acontece uma vez por aplicação; a tela de situação
63
+ * atualiza o estado com o que ela já carregou.
64
+ */
65
+ declare class SubscriptionAccessState {
66
+ private readonly client;
67
+ private leitura?;
68
+ /** `null` enquanto desconhecida, inclusive quando a leitura falhou. */
69
+ readonly status: i0.WritableSignal<SubscriptionStatus | null>;
70
+ readonly avisoAberto: i0.WritableSignal<boolean>;
71
+ /** Lê a situação uma única vez. Falha da cobrança vira `null`, e a próxima chamada tenta de novo. */
72
+ carregar(): Observable<SubscriptionStatus | null>;
73
+ atualizar(status: SubscriptionStatus): void;
74
+ abrirAviso(): void;
75
+ fecharAviso(): void;
76
+ static ɵfac: i0.ɵɵFactoryDeclaration<SubscriptionAccessState, never>;
77
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
78
+ }
79
+
80
+ /**
81
+ * A faixa fixa da assinatura suspensa e o aviso de gravação recusada. Ponha a tag uma vez no
82
+ * layout do produto. O texto é fixo: nada do corpo do erro vai para a tela.
83
+ */
84
+ declare class OrechioSubscriptionNotice implements OnInit {
85
+ protected readonly estado: SubscriptionAccessState;
86
+ protected readonly uiRoute: string;
87
+ private readonly router;
88
+ private readonly destroyRef;
89
+ ngOnInit(): void;
90
+ protected irParaAssinatura(): void;
91
+ static ɵfac: i0.ɵɵFactoryDeclaration<OrechioSubscriptionNotice, never>;
92
+ static ɵcmp: i0.ɵɵComponentDeclaration<OrechioSubscriptionNotice, "orechio-subscription-notice", never, {}, {}, never, never, true, never>;
93
+ }
94
+
95
+ export { ORECHIO_BILLING_CONFIG, ORECHIO_BILLING_ROUTES, OrechioSubscriptionNotice, provideOrechioBilling, requireSubscriptionAccess, subscriptionAccessInterceptor };
32
96
  export type { OrechioBillingConfig, OrechioBillingOptions };
@@ -91,7 +91,7 @@ declare class SessionStore<TUser extends SessionUser = SessionUser> {
91
91
  set(user: TUser): void;
92
92
  clear(): void;
93
93
  static ɵfac: i0.ɵɵFactoryDeclaration<SessionStore<any>, never>;
94
- static ɵprov: i0.ɵɵInjectableDeclaration<SessionStore<any>>;
94
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
95
95
  }
96
96
 
97
97
  /**
@@ -152,7 +152,7 @@ declare class AuthClient<TUser extends SessionUser = SessionUser> {
152
152
  */
153
153
  logout(): Observable<void>;
154
154
  static ɵfac: i0.ɵɵFactoryDeclaration<AuthClient<any>, never>;
155
- static ɵprov: i0.ɵɵInjectableDeclaration<AuthClient<any>>;
155
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
156
156
  }
157
157
 
158
158
  /**
@@ -1 +0,0 @@
1
- {"version":3,"file":"orechio-platform-angular-account-initial-branch.page-C8a1eU3L.mjs","sources":["../../../projects/platform-angular/account/src/pages/initial-branch.page.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, inject, signal } from '@angular/core';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { Router } from '@angular/router';\r\nimport { ProblemDetails } from '@orechio/platform-angular';\r\nimport { AccountClient } from '../account-client';\r\nimport { ORECHIO_ACCOUNT_CONFIG } from '../account-config';\r\n\r\n@Component({\r\n selector: 'orechio-account-initial-branch',\r\n standalone: true,\r\n imports: [FormsModule],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n template: `\r\n <section class=\"orechio-account\">\r\n <ng-content select=\"[orechioAccountBrand]\"></ng-content>\r\n\r\n <h1>Configure sua primeira {{ rotulo }}</h1>\r\n <p class=\"orechio-account__muted\">\r\n É onde seus lançamentos vão nascer. Dá para criar outras depois.\r\n </p>\r\n\r\n <form (ngSubmit)=\"enviar()\">\r\n <label for=\"orechio-account-branch-name\">Nome da {{ rotulo }}</label>\r\n <input\r\n id=\"orechio-account-branch-name\"\r\n name=\"nome\"\r\n type=\"text\"\r\n autocomplete=\"organization\"\r\n [(ngModel)]=\"nome\"\r\n [disabled]=\"enviando()\"\r\n required\r\n />\r\n\r\n @if (erro()) {\r\n <p class=\"orechio-account__error\">{{ mensagemDeErro() }}</p>\r\n }\r\n\r\n <button type=\"submit\" [disabled]=\"enviando() || !nome.trim()\">\r\n {{ enviando() ? 'Criando…' : 'Concluir' }}\r\n </button>\r\n </form>\r\n </section>\r\n `,\r\n styles: `\r\n .orechio-account {\r\n display: flex;\r\n flex-direction: column;\r\n gap: var(--orechio-space-3, 0.75rem);\r\n max-width: 28rem;\r\n margin: 0 auto;\r\n padding: var(--orechio-space-6, 1.5rem);\r\n color: var(--orechio-color-text, inherit);\r\n font-family: var(--orechio-font-body, inherit);\r\n }\r\n .orechio-account form { display: flex; flex-direction: column; gap: var(--orechio-space-2, 0.5rem); }\r\n .orechio-account__muted { color: var(--orechio-color-text-muted, #666); }\r\n .orechio-account__error { color: var(--orechio-color-danger, #b00020); }\r\n `,\r\n})\r\nexport class InitialBranchPage {\r\n private readonly router = inject(Router);\r\n private readonly client = inject(AccountClient);\r\n private readonly config = inject(ORECHIO_ACCOUNT_CONFIG);\r\n\r\n protected readonly rotulo = this.config.branchLabel;\r\n protected nome = '';\r\n protected readonly enviando = signal(false);\r\n protected readonly erro = signal<ProblemDetails | null>(null);\r\n\r\n protected mensagemDeErro(): string {\r\n const code = this.erro()?.code;\r\n if (code === 'onboarding.branch_already_exists') return `Esta ${this.rotulo} já foi criada.`;\r\n if (code === 'session.missing') return 'Sua sessão expirou. Abra o link do e-mail novamente.';\r\n if (code === 'onboarding.not_in_provisioning') return 'Este passo já foi concluído.';\r\n if (code === 'rate_limit_exceeded') return 'Muitas tentativas. Aguarde alguns minutos.';\r\n if (code?.startsWith('branch.')) return 'Escolha um nome válido.';\r\n return 'Não foi possível concluir. Tente novamente.';\r\n }\r\n\r\n protected enviar(): void {\r\n const nome = this.nome.trim();\r\n if (!nome || this.enviando()) return;\r\n\r\n this.enviando.set(true);\r\n this.erro.set(null);\r\n\r\n this.client.createInitialBranch(nome).subscribe({\r\n next: async (resultado) => {\r\n // O pacote entrega o resultado e sai. Quem decide para onde ir é o host —\r\n // `nextStep` é repassado inteiro, sem interpretação (ADR-019 §3).\r\n const destino = this.config.onCompleted(resultado);\r\n await this.router.navigateByUrl(destino, { replaceUrl: true });\r\n },\r\n error: (problema: ProblemDetails) => {\r\n this.erro.set(problema);\r\n this.enviando.set(false);\r\n },\r\n });\r\n }\r\n}\r\n"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"orechio-platform-angular-billing-billing-format-C8QPXulm.mjs","sources":["../../../projects/platform-angular/billing/src/billing-client.ts","../../../projects/platform-angular/billing/src/billing-errors.ts","../../../projects/platform-angular/billing/src/billing-error.component.ts","../../../projects/platform-angular/billing/src/billing-format.ts"],"sourcesContent":["import { HttpClient, HttpErrorResponse, HttpParams } from '@angular/common/http';\r\nimport { Injectable, inject } from '@angular/core';\r\nimport { Observable, catchError, throwError } from 'rxjs';\r\nimport { ProblemDetails, normalizeProblemDetails } from '@orechio/platform-angular';\r\nimport { ORECHIO_BILLING_CONFIG } from './billing-config';\r\nimport {\r\n BillingAddressRequest,\r\n BillingContactRequest,\r\n BillingCycle,\r\n BillingProfile,\r\n CheckoutResult,\r\n CreateBillingProfileRequest,\r\n InvoiceDetail,\r\n InvoicesPage,\r\n Plan,\r\n PricingPreview,\r\n RefreshedPayment,\r\n Subscription,\r\n} from './billing-models';\r\n\r\n/**\r\n * O cliente do BFF de cobrança (`Orechio.Platform.Bff.Account` 0.2.0,\r\n * `MapOrechioBillingEndpoints`). Same-origin, só com o BFF do host — mesmo desenho do\r\n * `AccountClient`, e o erro sai pelo mesmo `normalizeProblemDetails`.\r\n */\r\n@Injectable({ providedIn: 'root' })\r\nexport class BillingClient {\r\n private readonly http = inject(HttpClient);\r\n private readonly config = inject(ORECHIO_BILLING_CONFIG);\r\n\r\n getSubscription(): Observable<Subscription> {\r\n return this.falha(this.http.get<Subscription>(this.url('/subscription')));\r\n }\r\n\r\n getProfile(): Observable<BillingProfile> {\r\n return this.falha(this.http.get<BillingProfile>(this.url('/profile')));\r\n }\r\n\r\n createProfile(request: CreateBillingProfileRequest): Observable<{ id: string }> {\r\n return this.falha(this.http.post<{ id: string }>(this.url('/profile'), request));\r\n }\r\n\r\n updateProfileContact(request: BillingContactRequest): Observable<void> {\r\n return this.falha(this.http.patch<void>(this.url('/profile/contact'), request));\r\n }\r\n\r\n updateProfileAddress(request: BillingAddressRequest): Observable<void> {\r\n return this.falha(this.http.patch<void>(this.url('/profile/address'), request));\r\n }\r\n\r\n listPlans(): Observable<Plan[]> {\r\n return this.falha(this.http.get<Plan[]>(this.url('/plans')));\r\n }\r\n\r\n previewPricing(planId: string, branchCount: number, cycle: BillingCycle): Observable<PricingPreview> {\r\n const params = new HttpParams({ fromObject: { planId, branchCount, cycle } });\r\n return this.falha(this.http.get<PricingPreview>(this.url('/pricing/preview'), { params }));\r\n }\r\n\r\n /**\r\n * Checkout PIX. O corpo é o `CheckoutRequest` da Platform (`cycle`, `method`), sem\r\n * `applicationId`: com o token de produto, a Platform usa o app do token.\r\n */\r\n checkout(cycle: BillingCycle): Observable<CheckoutResult> {\r\n return this.falha(this.http.post<CheckoutResult>(this.url('/checkout'), { cycle, method: 'pix' }));\r\n }\r\n\r\n listInvoices(page = 1, pageSize = 20): Observable<InvoicesPage> {\r\n const params = new HttpParams({ fromObject: { page, pageSize } });\r\n return this.falha(this.http.get<InvoicesPage>(this.url('/invoices'), { params }));\r\n }\r\n\r\n getInvoice(id: string): Observable<InvoiceDetail> {\r\n return this.falha(this.http.get<InvoiceDetail>(this.url(`/invoices/${encodeURIComponent(id)}`)));\r\n }\r\n\r\n refreshInvoicePix(id: string): Observable<RefreshedPayment> {\r\n return this.falha(this.http.post<RefreshedPayment>(this.url(`/invoices/${encodeURIComponent(id)}/refresh`), null));\r\n }\r\n\r\n private url(path: string): string {\r\n return `${this.config.basePath}${path}`;\r\n }\r\n\r\n private falha<T>(chamada: Observable<T>): Observable<T> {\r\n return chamada.pipe(\r\n catchError((error: HttpErrorResponse) =>\r\n throwError((): ProblemDetails => normalizeProblemDetails(error)),\r\n ),\r\n );\r\n }\r\n}\r\n","import { ProblemDetails } from '@orechio/platform-angular';\r\n\r\nexport interface MensagemDeErro {\r\n texto: string;\r\n /** Só para code desconhecido: é o que o suporte cruza com o log dos dois lados. */\r\n correlationId?: string;\r\n}\r\n\r\nconst ENDERECO_INCOMPLETO = 'Preencha o endereço completo.';\r\nconst DOCUMENTO_INVALIDO = 'CPF ou CNPJ inválido.';\r\nconst DOCUMENTO_TRAVADO =\r\n 'O documento e o nome já foram usados em uma cobrança e não podem mais ser alterados.';\r\nconst PLANO_INDISPONIVEL = 'O plano da assinatura não está disponível. Fale com o suporte.';\r\nconst SO_O_TITULAR = 'Só o titular da conta pode ver e pagar a cobrança.';\r\n\r\n/**\r\n * Os codes que as rotas de cobrança da Platform e do BFF emitem de fato\r\n * (`Commerce*Endpoints`, handlers de `Billing/`, value objects de perfil,\r\n * `PermissionAuthorization`, `Bff.Account`).\r\n */\r\nconst MENSAGENS: Record<string, string> = {\r\n 'session.missing': 'Sua sessão expirou. Entre novamente para continuar.',\r\n 'platform.unavailable':\r\n 'O serviço de cobrança está indisponível no momento. Tente novamente em instantes.',\r\n 'http.0': 'Sem conexão com o servidor. Verifique sua internet e tente novamente.',\r\n rate_limit_exceeded: 'Muitas tentativas. Aguarde alguns minutos e tente novamente.',\r\n\r\n 'access.platform_only': SO_O_TITULAR,\r\n 'permission.denied': SO_O_TITULAR,\r\n\r\n 'subscription.not_found': 'Nenhuma assinatura encontrada para esta conta.',\r\n\r\n 'billing_profile.not_found': 'Cadastre os dados de cobrança antes de pagar.',\r\n 'billing_profile.already_exists': 'Os dados de cobrança já estão cadastrados.',\r\n 'billing_profile.legal_name_required': 'Informe o nome completo ou a razão social.',\r\n 'billing_profile.billing_email_required': 'Informe o e-mail de cobrança.',\r\n 'billing_profile.billing_email_invalid': 'Informe um e-mail de cobrança válido.',\r\n 'billing_profile.mobile_phone_too_long': 'O celular informado é longo demais.',\r\n 'billing_profile.document_type_locked': DOCUMENTO_TRAVADO,\r\n 'billing_profile.document_number_locked': DOCUMENTO_TRAVADO,\r\n 'billing_profile.legal_name_locked': DOCUMENTO_TRAVADO,\r\n 'tax_document.value_required': 'Informe o CPF ou o CNPJ.',\r\n 'tax_document.length_invalid': DOCUMENTO_INVALIDO,\r\n 'tax_document.checksum_invalid': DOCUMENTO_INVALIDO,\r\n 'address.postal_code_invalid': 'CEP inválido.',\r\n 'address.state_invalid': 'UF inválida. Use a sigla do estado, como SP.',\r\n 'address.street_required': ENDERECO_INCOMPLETO,\r\n 'address.number_required': ENDERECO_INCOMPLETO,\r\n 'address.neighborhood_required': ENDERECO_INCOMPLETO,\r\n 'address.city_required': ENDERECO_INCOMPLETO,\r\n\r\n 'checkout.subscription_not_eligible':\r\n 'Não há pagamento de assinatura a fazer agora. Veja as faturas em aberto.',\r\n 'checkout.open_invoice_exists':\r\n 'Já existe uma fatura em aberto. Pague a fatura em aberto em vez de gerar uma nova cobrança.',\r\n 'checkout.pending_other_method':\r\n 'Já existe uma cobrança em aberto por outro meio de pagamento. Veja as faturas.',\r\n 'checkout.credit_card_not_supported': 'Pagamento por cartão ainda não está disponível.',\r\n 'checkout.invoice_in_inconsistent_state':\r\n 'A cobrança anterior ficou incompleta. Tente novamente em alguns minutos.',\r\n 'billing.cycle_invalid': 'Escolha um ciclo de cobrança válido.',\r\n 'pricing_preview.cycle_invalid': 'Escolha um ciclo de cobrança válido.',\r\n 'plan.not_found': PLANO_INDISPONIVEL,\r\n 'plan.not_available': PLANO_INDISPONIVEL,\r\n 'subscription.plan_inactive': PLANO_INDISPONIVEL,\r\n\r\n 'invoice.not_found': 'Fatura não encontrada.',\r\n 'invoice.payment_unavailable':\r\n 'Esta cobrança não está mais disponível para pagamento. Fale com o suporte.',\r\n 'invoice.refresh_not_allowed': 'Esta fatura não está mais em aberto.',\r\n 'invoice.refresh_pix_only': 'Só é possível gerar QR para faturas PIX.',\r\n 'invoice.no_external_payment':\r\n 'Esta fatura ainda não tem cobrança gerada. Tente novamente em alguns minutos.',\r\n};\r\n\r\nconst GENERICA =\r\n 'Não foi possível concluir a operação. Tente novamente; se continuar, informe o código de atendimento ao suporte.';\r\n\r\n/**\r\n * O texto de tela para um erro do BFF, escolhido por `code`. O corpo do erro (`message`) nunca\r\n * vira texto: ele é escrito para log, não para o cliente.\r\n */\r\nexport function mensagemDeErro(problema: ProblemDetails): MensagemDeErro {\r\n const conhecida = MENSAGENS[problema.code];\r\n if (conhecida) return { texto: conhecida };\r\n\r\n return problema.correlationId\r\n ? { texto: GENERICA, correlationId: problema.correlationId }\r\n : { texto: GENERICA };\r\n}\r\n","import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\r\nimport { ProblemDetails } from '@orechio/platform-angular';\r\nimport { mensagemDeErro } from './billing-errors';\r\n\r\n@Component({\r\n selector: 'orechio-billing-error',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n template: `\r\n <div class=\"orechio-billing__error\" role=\"alert\">\r\n <p>{{ mensagem().texto }}</p>\r\n @if (mensagem().correlationId; as id) {\r\n <p>Código de atendimento: <code>{{ id }}</code></p>\r\n }\r\n </div>\r\n `,\r\n styles: `.orechio-billing__error { color: var(--orechio-color-danger, #b00020); }`,\r\n})\r\nexport class BillingErrorComponent {\r\n readonly problema = input.required<ProblemDetails>();\r\n protected readonly mensagem = computed(() => mensagemDeErro(this.problema()));\r\n}\r\n","import { InvoiceStatus } from './billing-models';\r\n\r\nconst MOEDA = new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' });\r\n\r\nexport function moeda(valor: number): string {\r\n return MOEDA.format(valor);\r\n}\r\n\r\nexport function data(iso: string | null | undefined): string {\r\n return iso ? new Date(iso).toLocaleDateString('pt-BR') : '';\r\n}\r\n\r\n/**\r\n * O vencimento para a tela: \"02/10/2026\". É uma DATA, sem hora: a Platform a manda como meia-noite\r\n * UTC (\"2026-10-02T00:00:00Z\") ou \"2026-10-02\", e passar por `new Date()` a deslocaria para o dia\r\n * anterior no fuso do navegador (Manaus, Brasília). Lê os 10 primeiros caracteres AAAA-MM-DD e\r\n * formata por PARTES DO TEXTO. Formato inesperado volta como veio.\r\n */\r\nexport function dataDoVencimento(valor: string): string {\r\n const partes = /^(\\d{4})-(\\d{2})-(\\d{2})(?![\\d])/.exec(valor.trim());\r\n if (!partes) return valor;\r\n const [, ano, mes, dia] = partes;\r\n return `${dia}/${mes}/${ano}`;\r\n}\r\n\r\nconst FUSO_DE_BRASILIA = 'America/Sao_Paulo';\r\nconst SUFIXO_DE_BRASILIA = '(horário de Brasília)';\r\n\r\n/** \"AAAA-MM-DD HH:mm[:ss]\" — o `expirationDate` do ASAAS: sem fuso, já em horário de Brasília. */\r\nconst SEM_FUSO = /^(\\d{4})-(\\d{2})-(\\d{2})[ T](\\d{2}):(\\d{2})(?::(\\d{2})(?:\\.\\d+)?)?$/;\r\n/** O mesmo, com fuso explícito: `Z` ou `±hh:mm` / `±hhmm`. */\r\nconst COM_FUSO = /^\\d{4}-\\d{2}-\\d{2}[ T]\\d{2}:\\d{2}(?::\\d{2}(?:\\.\\d+)?)?(?:Z|[+-]\\d{2}:?\\d{2})$/i;\r\n\r\n/**\r\n * A validade do PIX para a tela: \"02/10/2026 às 23:59 (horário de Brasília)\".\r\n *\r\n * O valor do ASAAS NÃO passa por `new Date()`: sem fuso, o construtor o leria no fuso do\r\n * navegador e a hora exibida se deslocaria. Ele é formatado por PARTES DO TEXTO. Só o valor\r\n * com fuso explícito é convertido (para America/Sao_Paulo). Formato não reconhecido volta como\r\n * veio — nunca \"Invalid Date\".\r\n */\r\nexport function validadeDoPix(valor: string): string {\r\n const texto = valor.trim();\r\n\r\n const semFuso = SEM_FUSO.exec(texto);\r\n if (semFuso) {\r\n const [, ano, mes, dia, hora, minuto] = semFuso;\r\n return dataValida(+ano, +mes, +dia, +hora, +minuto)\r\n ? `${dia}/${mes}/${ano} às ${hora}:${minuto} ${SUFIXO_DE_BRASILIA}`\r\n : valor;\r\n }\r\n\r\n if (COM_FUSO.test(texto)) {\r\n const instante = new Date(texto.replace(' ', 'T'));\r\n if (Number.isNaN(instante.getTime())) return valor;\r\n\r\n const partes = Object.fromEntries(\r\n new Intl.DateTimeFormat('pt-BR', {\r\n timeZone: FUSO_DE_BRASILIA,\r\n day: '2-digit',\r\n month: '2-digit',\r\n year: 'numeric',\r\n hour: '2-digit',\r\n minute: '2-digit',\r\n hourCycle: 'h23',\r\n })\r\n .formatToParts(instante)\r\n .map((parte) => [parte.type, parte.value]),\r\n );\r\n return `${partes['day']}/${partes['month']}/${partes['year']} às ${partes['hour']}:${partes['minute']} ${SUFIXO_DE_BRASILIA}`;\r\n }\r\n\r\n return valor;\r\n}\r\n\r\nfunction dataValida(ano: number, mes: number, dia: number, hora: number, minuto: number): boolean {\r\n if (mes < 1 || mes > 12 || hora > 23 || minuto > 59 || dia < 1) return false;\r\n return dia <= new Date(Date.UTC(ano, mes, 0)).getUTCDate();\r\n}\r\n\r\n// ── máscaras (perfil de cobrança) ────────────────────────────────────────────\r\n\r\nexport function soDigitos(valor: string): string {\r\n return valor.replace(/\\D/g, '');\r\n}\r\n\r\n/** Junta os grupos de dígitos com os separadores, parando no primeiro grupo vazio. */\r\nfunction agrupar(digitos: string, grupos: readonly number[], separadores: readonly string[]): string {\r\n let saida = '';\r\n let posicao = 0;\r\n for (let i = 0; i < grupos.length; i++) {\r\n const grupo = digitos.slice(posicao, posicao + grupos[i]);\r\n if (!grupo) break;\r\n saida += (i === 0 ? '' : separadores[i - 1]) + grupo;\r\n posicao += grupos[i];\r\n }\r\n return saida;\r\n}\r\n\r\n/** CPF `000.000.000-00`, progressivo enquanto se digita. */\r\nexport function mascararCpf(valor: string): string {\r\n return agrupar(soDigitos(valor).slice(0, 11), [3, 3, 3, 2], ['.', '.', '-']);\r\n}\r\n\r\n/** CNPJ `00.000.000/0000-00`, progressivo enquanto se digita. */\r\nexport function mascararCnpj(valor: string): string {\r\n return agrupar(soDigitos(valor).slice(0, 14), [2, 3, 3, 4, 2], ['.', '.', '/', '-']);\r\n}\r\n\r\n/** O documento conforme o tipo escolhido. */\r\nexport function mascararDocumento(tipo: 'Cpf' | 'Cnpj', valor: string): string {\r\n return tipo === 'Cpf' ? mascararCpf(valor) : mascararCnpj(valor);\r\n}\r\n\r\n/** CEP `00000-000`. */\r\nexport function mascararCep(valor: string): string {\r\n return agrupar(soDigitos(valor).slice(0, 8), [5, 3], ['-']);\r\n}\r\n\r\n/** Telefone `(00) 0000-0000` (10 dígitos) ou celular `(00) 00000-0000` (11). */\r\nexport function mascararTelefone(valor: string): string {\r\n const digitos = soDigitos(valor).slice(0, 11);\r\n if (!digitos) return '';\r\n\r\n const ddd = digitos.slice(0, 2);\r\n if (digitos.length <= 2) return `(${ddd}`;\r\n\r\n const numero = digitos.slice(2);\r\n const tamanhoDoPrimeiroBloco = digitos.length > 10 ? 5 : 4;\r\n const corpo =\r\n numero.length > tamanhoDoPrimeiroBloco\r\n ? `${numero.slice(0, tamanhoDoPrimeiroBloco)}-${numero.slice(tamanhoDoPrimeiroBloco)}`\r\n : numero;\r\n return `(${ddd}) ${corpo}`;\r\n}\r\n\r\nexport const STATUS_DA_FATURA: Record<InvoiceStatus, string> = {\r\n Created: 'Em emissão',\r\n Pending: 'Em aberto',\r\n Paid: 'Paga',\r\n Overdue: 'Vencida',\r\n Refunded: 'Estornada',\r\n Cancelled: 'Cancelada',\r\n};\r\n\r\nexport const ESTILO_BASE = `\r\n .orechio-billing {\r\n display: flex;\r\n flex-direction: column;\r\n gap: var(--orechio-space-3, 0.75rem);\r\n max-width: 40rem;\r\n margin: 0 auto;\r\n padding: var(--orechio-space-6, 1.5rem);\r\n color: var(--orechio-color-text, inherit);\r\n font-family: var(--orechio-font-body, inherit);\r\n }\r\n .orechio-billing form { display: flex; flex-direction: column; gap: var(--orechio-space-2, 0.5rem); }\r\n .orechio-billing__muted { color: var(--orechio-color-text-muted, #666); }\r\n .orechio-billing__error { color: var(--orechio-color-danger, #b00020); }\r\n .orechio-billing__acao {\r\n align-self: flex-start;\r\n display: inline-block;\r\n padding: var(--orechio-space-2, 0.5rem) var(--orechio-space-4, 1rem);\r\n border-radius: var(--orechio-radius, 0.375rem);\r\n background: var(--orechio-color-primary, #1a56db);\r\n color: var(--orechio-color-on-primary, #fff);\r\n font-weight: 600;\r\n text-decoration: none;\r\n }\r\n .orechio-billing__acao:hover,\r\n .orechio-billing__acao:focus-visible {\r\n background: var(--orechio-color-primary-hover, var(--orechio-color-primary, #1446b0));\r\n }\r\n`;\r\n"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"orechio-platform-angular-billing-subscription.page-Dbk-Znvg.mjs","sources":["../../../projects/platform-angular/billing/src/pages/subscription.page.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, OnInit, computed, inject, signal } from '@angular/core';\r\nimport { RouterLink } from '@angular/router';\r\nimport { ProblemDetails } from '@orechio/platform-angular';\r\nimport { BillingClient } from '../billing-client';\r\nimport { BillingErrorComponent } from '../billing-error.component';\r\nimport { ESTILO_BASE, data } from '../billing-format';\r\nimport { InvoiceListItem, InvoiceStatus, Subscription } from '../billing-models';\r\n\r\nconst DIA = 24 * 60 * 60 * 1000;\r\nconst EM_ABERTO: InvoiceStatus[] = ['Created', 'Pending', 'Overdue'];\r\n\r\nconst emAtraso = (assinatura: Subscription) =>\r\n assinatura.status === 'Grace' || assinatura.status === 'Suspended';\r\n\r\ninterface Situacao {\r\n titulo: string;\r\n detalhe: string;\r\n acao: { texto: string; link: string };\r\n}\r\n\r\n/**\r\n * A ação de cada estado segue o que a Platform aceita: o checkout serve `Trial`,\r\n * `PendingPayment` e, desde a BILLING-2b, `Grace` e `Suspended` — mas só sem fatura aberta\r\n * (`Created|Pending|Overdue`; com ela, `checkout.open_invoice_exists`). Em carência e suspensão\r\n * a ação depende disso: fatura aberta → o detalhe dela; nenhuma → o checkout. Cancelada e\r\n * expirada não têm ação de pagamento nesta versão: reativar é v2 (ADR-021 §3.5).\r\n */\r\nfunction situacao(assinatura: Subscription, agora: number, emAberto: InvoiceListItem | null): Situacao {\r\n const pagar = { texto: 'Pagar agora', link: 'checkout' };\r\n const faturas = { texto: 'Ver faturas', link: 'invoices' };\r\n const acaoDeAtraso = emAberto\r\n ? { texto: 'Pagar fatura em aberto', link: `invoices/${emAberto.id}` }\r\n : { texto: 'Pagar', link: 'checkout' };\r\n const orientacao = emAberto ? 'Pague a fatura em aberto' : 'Faça o pagamento';\r\n\r\n switch (assinatura.status) {\r\n case 'Trial': {\r\n const dias = Math.max(0, Math.ceil((Date.parse(assinatura.trialEndsAt) - agora) / DIA));\r\n const restante =\r\n dias === 0 ? 'O período de teste termina hoje.'\r\n : dias === 1 ? 'Falta 1 dia para o fim do período de teste.'\r\n : `Faltam ${dias} dias para o fim do período de teste.`;\r\n return { titulo: 'Período de teste', detalhe: restante, acao: { texto: 'Assinar agora', link: 'checkout' } };\r\n }\r\n case 'PendingPayment':\r\n return {\r\n titulo: 'Pagamento pendente',\r\n detalhe: 'A assinatura começa assim que o primeiro pagamento for confirmado.',\r\n acao: pagar,\r\n };\r\n case 'Active':\r\n return {\r\n titulo: 'Assinatura ativa',\r\n detalhe: assinatura.currentPeriodEndsAt\r\n ? `Próxima renovação em ${data(assinatura.currentPeriodEndsAt)}.`\r\n : 'Tudo em dia.',\r\n acao: faturas,\r\n };\r\n case 'Grace':\r\n return {\r\n titulo: 'Pagamento em atraso',\r\n detalhe: assinatura.graceEndsAt\r\n ? `O acesso continua até ${data(assinatura.graceEndsAt)}. ${orientacao} para não ter o acesso suspenso.`\r\n : `${orientacao} para não ter o acesso suspenso.`,\r\n acao: acaoDeAtraso,\r\n };\r\n case 'Suspended':\r\n return {\r\n titulo: 'Assinatura suspensa',\r\n detalhe: `O acesso foi suspenso por falta de pagamento. ${orientacao} para voltar a usar.`,\r\n acao: acaoDeAtraso,\r\n };\r\n case 'Cancelled':\r\n return {\r\n titulo: 'Assinatura cancelada',\r\n detalhe: assinatura.cancelEffectiveAt\r\n ? `O cancelamento vale a partir de ${data(assinatura.cancelEffectiveAt)}. Para reativar, fale com o suporte.`\r\n : 'Para reativar, fale com o suporte.',\r\n acao: faturas,\r\n };\r\n case 'Expired':\r\n return {\r\n titulo: 'Assinatura expirada',\r\n detalhe: 'Para voltar a assinar, fale com o suporte.',\r\n acao: faturas,\r\n };\r\n }\r\n}\r\n\r\n@Component({\r\n selector: 'orechio-billing-subscription',\r\n standalone: true,\r\n imports: [RouterLink, BillingErrorComponent],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n template: `\r\n <section class=\"orechio-billing\">\r\n <h1>Assinatura</h1>\r\n\r\n @if (erro(); as problema) {\r\n <orechio-billing-error [problema]=\"problema\" />\r\n } @else if (atual(); as s) {\r\n <h2>{{ s.titulo }}</h2>\r\n <p>{{ s.detalhe }}</p>\r\n <a data-acao class=\"orechio-billing__acao\" [routerLink]=\"s.acao.link\">{{ s.acao.texto }}</a>\r\n\r\n <nav class=\"orechio-billing__muted\">\r\n <a routerLink=\"profile\">Dados de cobrança</a>\r\n ·\r\n <a routerLink=\"invoices\">Faturas</a>\r\n </nav>\r\n } @else {\r\n <p class=\"orechio-billing__muted\">Carregando…</p>\r\n }\r\n </section>\r\n `,\r\n styles: ESTILO_BASE,\r\n})\r\nexport class SubscriptionPage implements OnInit {\r\n private readonly client = inject(BillingClient);\r\n\r\n private readonly assinatura = signal<Subscription | null>(null);\r\n /** Só preenchido em Grace/Suspended: `undefined` = ainda não respondeu; `null` = nenhuma aberta. */\r\n private readonly emAberto = signal<InvoiceListItem | null | undefined>(undefined);\r\n protected readonly erro = signal<ProblemDetails | null>(null);\r\n protected readonly atual = computed(() => {\r\n const assinatura = this.assinatura();\r\n if (!assinatura) return null;\r\n\r\n const aberta = this.emAberto();\r\n // Sem a resposta das faturas não se sabe o destino da ação: não se adivinha.\r\n if (emAtraso(assinatura) && aberta === undefined) return null;\r\n\r\n return situacao(assinatura, Date.now(), aberta ?? null);\r\n });\r\n\r\n ngOnInit(): void {\r\n this.client.getSubscription().subscribe({\r\n next: (assinatura) => {\r\n this.assinatura.set(assinatura);\r\n if (emAtraso(assinatura)) this.buscarFaturaEmAberto();\r\n },\r\n error: (problema: ProblemDetails) => this.erro.set(problema),\r\n });\r\n }\r\n\r\n private buscarFaturaEmAberto(): void {\r\n this.client.listInvoices().subscribe({\r\n next: (pagina) => this.emAberto.set(pagina.invoices.find((f) => EM_ABERTO.includes(f.status)) ?? null),\r\n error: (problema: ProblemDetails) => this.erro.set(problema),\r\n });\r\n }\r\n}\r\n"],"names":[],"mappings":"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"}