@orechio/platform-angular 0.5.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +134 -64
  2. package/fesm2022/orechio-platform-angular-account-account-client-mPl0tzMg.mjs +56 -0
  3. package/fesm2022/orechio-platform-angular-account-account-client-mPl0tzMg.mjs.map +1 -0
  4. package/fesm2022/orechio-platform-angular-account-forgot-password.page-L-Z-s49p.mjs +136 -0
  5. package/fesm2022/orechio-platform-angular-account-forgot-password.page-L-Z-s49p.mjs.map +1 -0
  6. package/fesm2022/orechio-platform-angular-account-initial-branch.page-C8a1eU3L.mjs +121 -0
  7. package/fesm2022/orechio-platform-angular-account-initial-branch.page-C8a1eU3L.mjs.map +1 -0
  8. package/fesm2022/orechio-platform-angular-account-resend-verification.page-C3lk1vNj.mjs +122 -0
  9. package/fesm2022/orechio-platform-angular-account-resend-verification.page-C3lk1vNj.mjs.map +1 -0
  10. package/fesm2022/orechio-platform-angular-account-token-password.page-1vn5XGVu.mjs +181 -0
  11. package/fesm2022/orechio-platform-angular-account-token-password.page-1vn5XGVu.mjs.map +1 -0
  12. package/fesm2022/orechio-platform-angular-account-verify-email.page-xulVDiOn.mjs +121 -0
  13. package/fesm2022/orechio-platform-angular-account-verify-email.page-xulVDiOn.mjs.map +1 -0
  14. package/fesm2022/orechio-platform-angular-account.mjs +106 -0
  15. package/fesm2022/orechio-platform-angular-account.mjs.map +1 -0
  16. package/fesm2022/orechio-platform-angular-billing-billing-format-0nlddK-x.mjs +194 -0
  17. package/fesm2022/orechio-platform-angular-billing-billing-format-0nlddK-x.mjs.map +1 -0
  18. package/fesm2022/orechio-platform-angular-billing-checkout.page-CHU_Drpu.mjs +186 -0
  19. package/fesm2022/orechio-platform-angular-billing-checkout.page-CHU_Drpu.mjs.map +1 -0
  20. package/fesm2022/orechio-platform-angular-billing-invoice.page-BVyWur3o.mjs +136 -0
  21. package/fesm2022/orechio-platform-angular-billing-invoice.page-BVyWur3o.mjs.map +1 -0
  22. package/fesm2022/orechio-platform-angular-billing-invoices.page-BiEm3hRf.mjs +105 -0
  23. package/fesm2022/orechio-platform-angular-billing-invoices.page-BiEm3hRf.mjs.map +1 -0
  24. package/fesm2022/orechio-platform-angular-billing-pix-panel.component-B608dQmc.mjs +81 -0
  25. package/fesm2022/orechio-platform-angular-billing-pix-panel.component-B608dQmc.mjs.map +1 -0
  26. package/fesm2022/orechio-platform-angular-billing-profile.page-Baa6uoM6.mjs +282 -0
  27. package/fesm2022/orechio-platform-angular-billing-profile.page-Baa6uoM6.mjs.map +1 -0
  28. package/fesm2022/orechio-platform-angular-billing-subscription.page-9NF8bWhu.mjs +160 -0
  29. package/fesm2022/orechio-platform-angular-billing-subscription.page-9NF8bWhu.mjs.map +1 -0
  30. package/fesm2022/orechio-platform-angular-billing.mjs +69 -0
  31. package/fesm2022/orechio-platform-angular-billing.mjs.map +1 -0
  32. package/fesm2022/orechio-platform-angular.mjs +62 -62
  33. package/fesm2022/orechio-platform-angular.mjs.map +1 -1
  34. package/package.json +9 -1
  35. package/types/orechio-platform-angular-account.d.ts +97 -0
  36. package/types/orechio-platform-angular-billing.d.ts +32 -0
@@ -0,0 +1,105 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, signal, computed, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { RouterLink } from '@angular/router';
4
+ import { B as BillingClient, S as STATUS_DA_FATURA, m as moeda, d as data, a as BillingErrorComponent } from './orechio-platform-angular-billing-billing-format-0nlddK-x.mjs';
5
+
6
+ const TAMANHO_DA_PAGINA = 20;
7
+ class InvoicesPage {
8
+ client = inject(BillingClient);
9
+ status = STATUS_DA_FATURA;
10
+ moeda = moeda;
11
+ data = data;
12
+ pagina = signal(null, /* @ts-ignore */
13
+ ...(ngDevMode ? [{ debugName: "pagina" }] : /* istanbul ignore next */ []));
14
+ erro = signal(null, /* @ts-ignore */
15
+ ...(ngDevMode ? [{ debugName: "erro" }] : /* istanbul ignore next */ []));
16
+ temProxima = computed(() => {
17
+ const p = this.pagina();
18
+ return !!p && p.page * p.pageSize < p.total;
19
+ }, /* @ts-ignore */
20
+ ...(ngDevMode ? [{ debugName: "temProxima" }] : /* istanbul ignore next */ []));
21
+ ngOnInit() {
22
+ this.carregar(1);
23
+ }
24
+ carregar(pagina) {
25
+ this.client.listInvoices(pagina, TAMANHO_DA_PAGINA).subscribe({
26
+ next: (resultado) => this.pagina.set(resultado),
27
+ error: (problema) => this.erro.set(problema),
28
+ });
29
+ }
30
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: InvoicesPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
31
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: InvoicesPage, isStandalone: true, selector: "orechio-billing-invoices", ngImport: i0, template: `
32
+ <section class="orechio-billing">
33
+ <h1>Faturas</h1>
34
+
35
+ @if (erro(); as problema) {
36
+ <orechio-billing-error [problema]="problema" />
37
+ } @else if (pagina(); as p) {
38
+ @if (p.invoices.length === 0) {
39
+ <p class="orechio-billing__muted">Nenhuma fatura ainda.</p>
40
+ } @else {
41
+ <ul>
42
+ @for (fatura of p.invoices; track fatura.id) {
43
+ <li>
44
+ <a [routerLink]="fatura.id">Fatura {{ fatura.number }}</a>
45
+ — {{ status[fatura.status] }} — {{ moeda(fatura.amount) }} — vence em {{ data(fatura.dueDate) }}
46
+ </li>
47
+ }
48
+ </ul>
49
+
50
+ <nav>
51
+ @if (p.page > 1) {
52
+ <button type="button" (click)="carregar(p.page - 1)">Anteriores</button>
53
+ }
54
+ @if (temProxima()) {
55
+ <button type="button" (click)="carregar(p.page + 1)">Próximas</button>
56
+ }
57
+ </nav>
58
+ }
59
+ <a routerLink="..">Voltar para a assinatura</a>
60
+ } @else {
61
+ <p class="orechio-billing__muted">Carregando…</p>
62
+ }
63
+ </section>
64
+ `, 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)}\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 });
65
+ }
66
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: InvoicesPage, decorators: [{
67
+ type: Component,
68
+ args: [{ selector: 'orechio-billing-invoices', standalone: true, imports: [RouterLink, BillingErrorComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: `
69
+ <section class="orechio-billing">
70
+ <h1>Faturas</h1>
71
+
72
+ @if (erro(); as problema) {
73
+ <orechio-billing-error [problema]="problema" />
74
+ } @else if (pagina(); as p) {
75
+ @if (p.invoices.length === 0) {
76
+ <p class="orechio-billing__muted">Nenhuma fatura ainda.</p>
77
+ } @else {
78
+ <ul>
79
+ @for (fatura of p.invoices; track fatura.id) {
80
+ <li>
81
+ <a [routerLink]="fatura.id">Fatura {{ fatura.number }}</a>
82
+ — {{ status[fatura.status] }} — {{ moeda(fatura.amount) }} — vence em {{ data(fatura.dueDate) }}
83
+ </li>
84
+ }
85
+ </ul>
86
+
87
+ <nav>
88
+ @if (p.page > 1) {
89
+ <button type="button" (click)="carregar(p.page - 1)">Anteriores</button>
90
+ }
91
+ @if (temProxima()) {
92
+ <button type="button" (click)="carregar(p.page + 1)">Próximas</button>
93
+ }
94
+ </nav>
95
+ }
96
+ <a routerLink="..">Voltar para a assinatura</a>
97
+ } @else {
98
+ <p class="orechio-billing__muted">Carregando…</p>
99
+ }
100
+ </section>
101
+ `, 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)}\n"] }]
102
+ }] });
103
+
104
+ export { InvoicesPage };
105
+ //# sourceMappingURL=orechio-platform-angular-billing-invoices.page-BiEm3hRf.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orechio-platform-angular-billing-invoices.page-BiEm3hRf.mjs","sources":["../../../projects/platform-angular/billing/src/pages/invoices.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, STATUS_DA_FATURA, data, moeda } from '../billing-format';\r\nimport { InvoicesPage as PaginaDeFaturas } from '../billing-models';\r\n\r\nconst TAMANHO_DA_PAGINA = 20;\r\n\r\n@Component({\r\n selector: 'orechio-billing-invoices',\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>Faturas</h1>\r\n\r\n @if (erro(); as problema) {\r\n <orechio-billing-error [problema]=\"problema\" />\r\n } @else if (pagina(); as p) {\r\n @if (p.invoices.length === 0) {\r\n <p class=\"orechio-billing__muted\">Nenhuma fatura ainda.</p>\r\n } @else {\r\n <ul>\r\n @for (fatura of p.invoices; track fatura.id) {\r\n <li>\r\n <a [routerLink]=\"fatura.id\">Fatura {{ fatura.number }}</a>\r\n — {{ status[fatura.status] }} — {{ moeda(fatura.amount) }} — vence em {{ data(fatura.dueDate) }}\r\n </li>\r\n }\r\n </ul>\r\n\r\n <nav>\r\n @if (p.page > 1) {\r\n <button type=\"button\" (click)=\"carregar(p.page - 1)\">Anteriores</button>\r\n }\r\n @if (temProxima()) {\r\n <button type=\"button\" (click)=\"carregar(p.page + 1)\">Próximas</button>\r\n }\r\n </nav>\r\n }\r\n <a routerLink=\"..\">Voltar para a assinatura</a>\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 InvoicesPage implements OnInit {\r\n private readonly client = inject(BillingClient);\r\n\r\n protected readonly status = STATUS_DA_FATURA;\r\n protected readonly moeda = moeda;\r\n protected readonly data = data;\r\n protected readonly pagina = signal<PaginaDeFaturas | null>(null);\r\n protected readonly erro = signal<ProblemDetails | null>(null);\r\n protected readonly temProxima = computed(() => {\r\n const p = this.pagina();\r\n return !!p && p.page * p.pageSize < p.total;\r\n });\r\n\r\n ngOnInit(): void {\r\n this.carregar(1);\r\n }\r\n\r\n protected carregar(pagina: number): void {\r\n this.client.listInvoices(pagina, TAMANHO_DA_PAGINA).subscribe({\r\n next: (resultado) => this.pagina.set(resultado),\r\n error: (problema: ProblemDetails) => this.erro.set(problema),\r\n });\r\n }\r\n}\r\n"],"names":[],"mappings":";;;;;AAQA,MAAM,iBAAiB,GAAG,EAAE;MA2Cf,YAAY,CAAA;AACN,IAAA,MAAM,GAAG,MAAM,CAAC,aAAa,CAAC;IAE5B,MAAM,GAAG,gBAAgB;IACzB,KAAK,GAAG,KAAK;IACb,IAAI,GAAG,IAAI;IACX,MAAM,GAAG,MAAM,CAAyB,IAAI;+EAAC;IAC7C,IAAI,GAAG,MAAM,CAAwB,IAAI;6EAAC;AAC1C,IAAA,UAAU,GAAG,QAAQ,CAAC,MAAK;AAC5C,QAAA,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE;AACvB,QAAA,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,KAAK;IAC7C,CAAC;mFAAC;IAEF,QAAQ,GAAA;AACN,QAAA,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IAClB;AAEU,IAAA,QAAQ,CAAC,MAAc,EAAA;QAC/B,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,SAAS,CAAC;AAC5D,YAAA,IAAI,EAAE,CAAC,SAAS,KAAK,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;AAC/C,YAAA,KAAK,EAAE,CAAC,QAAwB,KAAK,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC7D,SAAA,CAAC;IACJ;uGAtBW,YAAY,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAZ,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAY,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,0BAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EApCb,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCT,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,ydAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAnCS,UAAU,kPAAE,qBAAqB,EAAA,QAAA,EAAA,uBAAA,EAAA,MAAA,EAAA,CAAA,UAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAsChC,YAAY,EAAA,UAAA,EAAA,CAAA;kBAzCxB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,0BAA0B,EAAA,UAAA,EACxB,IAAI,EAAA,OAAA,EACP,CAAC,UAAU,EAAE,qBAAqB,CAAC,EAAA,eAAA,EAC3B,uBAAuB,CAAC,MAAM,EAAA,QAAA,EACrC,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,ydAAA,CAAA,EAAA;;;;;"}
@@ -0,0 +1,81 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, signal, ChangeDetectionStrategy, Component } from '@angular/core';
3
+
4
+ /**
5
+ * O QR e o copia-e-cola, como a Platform os devolveu. O `encodedImage` é PNG em base64
6
+ * (ASAAS); o `payload` é o código que o app do banco aceita colado.
7
+ */
8
+ class PixPanelComponent {
9
+ pix = input.required(/* @ts-ignore */
10
+ ...(ngDevMode ? [{ debugName: "pix" }] : /* istanbul ignore next */ []));
11
+ /** Página de pagamento do ASAAS, aberta em nova aba; sem ela, o link não aparece. */
12
+ invoiceUrl = input(null, /* @ts-ignore */
13
+ ...(ngDevMode ? [{ debugName: "invoiceUrl" }] : /* istanbul ignore next */ []));
14
+ copiado = signal(false, /* @ts-ignore */
15
+ ...(ngDevMode ? [{ debugName: "copiado" }] : /* istanbul ignore next */ []));
16
+ semAreaDeTransferencia = signal(false, /* @ts-ignore */
17
+ ...(ngDevMode ? [{ debugName: "semAreaDeTransferencia" }] : /* istanbul ignore next */ []));
18
+ copiar() {
19
+ const areaDeTransferencia = globalThis.navigator?.clipboard;
20
+ if (!areaDeTransferencia) {
21
+ this.semAreaDeTransferencia.set(true);
22
+ return;
23
+ }
24
+ areaDeTransferencia.writeText(this.pix().payload).then(() => this.copiado.set(true), () => this.semAreaDeTransferencia.set(true));
25
+ }
26
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: PixPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
27
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: PixPanelComponent, isStandalone: true, selector: "orechio-billing-pix", inputs: { pix: { classPropertyName: "pix", publicName: "pix", isSignal: true, isRequired: true, transformFunction: null }, invoiceUrl: { classPropertyName: "invoiceUrl", publicName: "invoiceUrl", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
28
+ <div class="orechio-billing-pix">
29
+ <img data-qr [src]="'data:image/png;base64,' + pix().encodedImage" alt="QR Code PIX" width="240" height="240" />
30
+
31
+ <p>Ou copie o código PIX e cole no app do seu banco:</p>
32
+ <code class="orechio-billing-pix__codigo">{{ pix().payload }}</code>
33
+ <button type="button" data-copiar (click)="copiar()">
34
+ {{ copiado() ? 'Código copiado' : 'Copiar código' }}
35
+ </button>
36
+ @if (semAreaDeTransferencia()) {
37
+ <p class="orechio-billing-pix__aviso">Selecione o código acima e copie manualmente.</p>
38
+ }
39
+
40
+ @if (pix().expirationDate; as validade) {
41
+ <p class="orechio-billing-pix__aviso">Válido até {{ validade }}.</p>
42
+ }
43
+
44
+ @if (invoiceUrl(); as url) {
45
+ <a data-invoice-url [href]="url" target="_blank" rel="noopener noreferrer">
46
+ Pagar pelo site do ASAAS
47
+ </a>
48
+ }
49
+ </div>
50
+ `, isInline: true, styles: [".orechio-billing-pix{display:flex;flex-direction:column;align-items:flex-start;gap:var(--orechio-space-2, .5rem)}.orechio-billing-pix__codigo{word-break:break-all}.orechio-billing-pix__aviso{color:var(--orechio-color-text-muted, #666)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
51
+ }
52
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: PixPanelComponent, decorators: [{
53
+ type: Component,
54
+ args: [{ selector: 'orechio-billing-pix', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: `
55
+ <div class="orechio-billing-pix">
56
+ <img data-qr [src]="'data:image/png;base64,' + pix().encodedImage" alt="QR Code PIX" width="240" height="240" />
57
+
58
+ <p>Ou copie o código PIX e cole no app do seu banco:</p>
59
+ <code class="orechio-billing-pix__codigo">{{ pix().payload }}</code>
60
+ <button type="button" data-copiar (click)="copiar()">
61
+ {{ copiado() ? 'Código copiado' : 'Copiar código' }}
62
+ </button>
63
+ @if (semAreaDeTransferencia()) {
64
+ <p class="orechio-billing-pix__aviso">Selecione o código acima e copie manualmente.</p>
65
+ }
66
+
67
+ @if (pix().expirationDate; as validade) {
68
+ <p class="orechio-billing-pix__aviso">Válido até {{ validade }}.</p>
69
+ }
70
+
71
+ @if (invoiceUrl(); as url) {
72
+ <a data-invoice-url [href]="url" target="_blank" rel="noopener noreferrer">
73
+ Pagar pelo site do ASAAS
74
+ </a>
75
+ }
76
+ </div>
77
+ `, styles: [".orechio-billing-pix{display:flex;flex-direction:column;align-items:flex-start;gap:var(--orechio-space-2, .5rem)}.orechio-billing-pix__codigo{word-break:break-all}.orechio-billing-pix__aviso{color:var(--orechio-color-text-muted, #666)}\n"] }]
78
+ }], propDecorators: { pix: [{ type: i0.Input, args: [{ isSignal: true, alias: "pix", required: true }] }], invoiceUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "invoiceUrl", required: false }] }] } });
79
+
80
+ export { PixPanelComponent as P };
81
+ //# sourceMappingURL=orechio-platform-angular-billing-pix-panel.component-B608dQmc.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orechio-platform-angular-billing-pix-panel.component-B608dQmc.mjs","sources":["../../../projects/platform-angular/billing/src/pix-panel.component.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, input, signal } from '@angular/core';\r\nimport { PixData } from './billing-models';\r\n\r\n/**\r\n * O QR e o copia-e-cola, como a Platform os devolveu. O `encodedImage` é PNG em base64\r\n * (ASAAS); o `payload` é o código que o app do banco aceita colado.\r\n */\r\n@Component({\r\n selector: 'orechio-billing-pix',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n template: `\r\n <div class=\"orechio-billing-pix\">\r\n <img data-qr [src]=\"'data:image/png;base64,' + pix().encodedImage\" alt=\"QR Code PIX\" width=\"240\" height=\"240\" />\r\n\r\n <p>Ou copie o código PIX e cole no app do seu banco:</p>\r\n <code class=\"orechio-billing-pix__codigo\">{{ pix().payload }}</code>\r\n <button type=\"button\" data-copiar (click)=\"copiar()\">\r\n {{ copiado() ? 'Código copiado' : 'Copiar código' }}\r\n </button>\r\n @if (semAreaDeTransferencia()) {\r\n <p class=\"orechio-billing-pix__aviso\">Selecione o código acima e copie manualmente.</p>\r\n }\r\n\r\n @if (pix().expirationDate; as validade) {\r\n <p class=\"orechio-billing-pix__aviso\">Válido até {{ validade }}.</p>\r\n }\r\n\r\n @if (invoiceUrl(); as url) {\r\n <a data-invoice-url [href]=\"url\" target=\"_blank\" rel=\"noopener noreferrer\">\r\n Pagar pelo site do ASAAS\r\n </a>\r\n }\r\n </div>\r\n `,\r\n styles: `\r\n .orechio-billing-pix { display: flex; flex-direction: column; align-items: flex-start; gap: var(--orechio-space-2, 0.5rem); }\r\n .orechio-billing-pix__codigo { word-break: break-all; }\r\n .orechio-billing-pix__aviso { color: var(--orechio-color-text-muted, #666); }\r\n `,\r\n})\r\nexport class PixPanelComponent {\r\n readonly pix = input.required<PixData>();\r\n /** Página de pagamento do ASAAS, aberta em nova aba; sem ela, o link não aparece. */\r\n readonly invoiceUrl = input<string | null | undefined>(null);\r\n\r\n protected readonly copiado = signal(false);\r\n protected readonly semAreaDeTransferencia = signal(false);\r\n\r\n protected copiar(): void {\r\n const areaDeTransferencia = globalThis.navigator?.clipboard;\r\n if (!areaDeTransferencia) {\r\n this.semAreaDeTransferencia.set(true);\r\n return;\r\n }\r\n\r\n areaDeTransferencia.writeText(this.pix().payload).then(\r\n () => this.copiado.set(true),\r\n () => this.semAreaDeTransferencia.set(true),\r\n );\r\n }\r\n}\r\n"],"names":[],"mappings":";;;AAGA;;;AAGG;MAmCU,iBAAiB,CAAA;IACnB,GAAG,GAAG,KAAK,CAAC,QAAQ;4EAAW;;IAE/B,UAAU,GAAG,KAAK,CAA4B,IAAI;mFAAC;IAEzC,OAAO,GAAG,MAAM,CAAC,KAAK;gFAAC;IACvB,sBAAsB,GAAG,MAAM,CAAC,KAAK;+FAAC;IAE/C,MAAM,GAAA;AACd,QAAA,MAAM,mBAAmB,GAAG,UAAU,CAAC,SAAS,EAAE,SAAS;QAC3D,IAAI,CAAC,mBAAmB,EAAE;AACxB,YAAA,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,IAAI,CAAC;YACrC;QACF;AAEA,QAAA,mBAAmB,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CACpD,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAC5B,MAAM,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,IAAI,CAAC,CAC5C;IACH;uGAnBW,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAjB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,iBAAiB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,qBAAA,EAAA,MAAA,EAAA,EAAA,GAAA,EAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA9BlB,CAAA;;;;;;;;;;;;;;;;;;;;;;;AAuBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,+OAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAOU,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAlC7B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,qBAAqB,cACnB,IAAI,EAAA,eAAA,EACC,uBAAuB,CAAC,MAAM,EAAA,QAAA,EACrC,CAAA;;;;;;;;;;;;;;;;;;;;;;;AAuBT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,+OAAA,CAAA,EAAA;;;;;"}
@@ -0,0 +1,282 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, signal, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { NgTemplateOutlet } from '@angular/common';
4
+ import * as i1 from '@angular/forms';
5
+ import { FormsModule } from '@angular/forms';
6
+ import { Router, ActivatedRoute, RouterLink } from '@angular/router';
7
+ import { B as BillingClient, a as BillingErrorComponent } from './orechio-platform-angular-billing-billing-format-0nlddK-x.mjs';
8
+
9
+ function doPerfil(perfil) {
10
+ return {
11
+ documentType: perfil.documentType ?? 'Cnpj',
12
+ documentNumber: perfil.documentNumber ?? '',
13
+ legalName: perfil.legalName ?? '',
14
+ tradeName: perfil.tradeName ?? '',
15
+ billingEmail: perfil.billingEmail ?? '',
16
+ phone: perfil.phone ?? '',
17
+ mobilePhone: perfil.mobilePhone ?? '',
18
+ postalCode: perfil.postalCode ?? '',
19
+ street: perfil.street ?? '',
20
+ number: perfil.number ?? '',
21
+ complement: perfil.complement ?? '',
22
+ neighborhood: perfil.neighborhood ?? '',
23
+ city: perfil.city ?? '',
24
+ state: perfil.state ?? '',
25
+ };
26
+ }
27
+ /** Campo opcional vazio vai como `null`, que é o que a Platform espera nos `string?`. */
28
+ function opcional(valor) {
29
+ const limpo = valor.trim();
30
+ return limpo ? limpo : null;
31
+ }
32
+ /**
33
+ * Perfil de cobrança (ADR-021 §3.5, item 2). Cria com `POST profile`; edita por partes, como a
34
+ * Platform: `PATCH profile/contact` e `PATCH profile/address` — não existe PUT.
35
+ */
36
+ class ProfilePage {
37
+ client = inject(BillingClient);
38
+ router = inject(Router);
39
+ route = inject(ActivatedRoute);
40
+ form = doPerfil({});
41
+ perfil = signal(null, /* @ts-ignore */
42
+ ...(ngDevMode ? [{ debugName: "perfil" }] : /* istanbul ignore next */ []));
43
+ travado = signal(false, /* @ts-ignore */
44
+ ...(ngDevMode ? [{ debugName: "travado" }] : /* istanbul ignore next */ []));
45
+ enviando = signal(false, /* @ts-ignore */
46
+ ...(ngDevMode ? [{ debugName: "enviando" }] : /* istanbul ignore next */ []));
47
+ salvo = signal(false, /* @ts-ignore */
48
+ ...(ngDevMode ? [{ debugName: "salvo" }] : /* istanbul ignore next */ []));
49
+ erro = signal(null, /* @ts-ignore */
50
+ ...(ngDevMode ? [{ debugName: "erro" }] : /* istanbul ignore next */ []));
51
+ ngOnInit() {
52
+ this.carregar();
53
+ }
54
+ criar() {
55
+ this.enviar(this.client.createProfile({ ...this.contato(), ...this.endereco() }), () => {
56
+ // Quem veio do pagamento volta para ele: foi o checkout que mandou para cá.
57
+ if (this.route.snapshot.queryParamMap.get('next') === 'checkout') {
58
+ void this.router.navigate(['../checkout'], { relativeTo: this.route });
59
+ return;
60
+ }
61
+ this.carregar();
62
+ });
63
+ }
64
+ salvarContato() {
65
+ this.enviar(this.client.updateProfileContact(this.contato()), () => this.salvo.set(true));
66
+ }
67
+ salvarEndereco() {
68
+ this.enviar(this.client.updateProfileAddress(this.endereco()), () => this.salvo.set(true));
69
+ }
70
+ carregar() {
71
+ this.client.getProfile().subscribe({
72
+ next: (perfil) => {
73
+ this.form = doPerfil(perfil);
74
+ this.travado.set(perfil.isDocumentLocked === true);
75
+ this.perfil.set(perfil);
76
+ },
77
+ error: (problema) => this.erro.set(problema),
78
+ });
79
+ }
80
+ enviar(chamada, depois) {
81
+ if (this.enviando())
82
+ return;
83
+ this.enviando.set(true);
84
+ this.salvo.set(false);
85
+ this.erro.set(null);
86
+ chamada.subscribe({
87
+ next: () => {
88
+ this.enviando.set(false);
89
+ depois();
90
+ },
91
+ error: (problema) => {
92
+ this.enviando.set(false);
93
+ this.erro.set(problema);
94
+ },
95
+ });
96
+ }
97
+ contato() {
98
+ return {
99
+ documentType: this.form.documentType,
100
+ documentNumber: this.form.documentNumber.trim(),
101
+ legalName: this.form.legalName.trim(),
102
+ tradeName: opcional(this.form.tradeName),
103
+ billingEmail: this.form.billingEmail.trim(),
104
+ phone: opcional(this.form.phone),
105
+ mobilePhone: opcional(this.form.mobilePhone),
106
+ };
107
+ }
108
+ endereco() {
109
+ return {
110
+ postalCode: this.form.postalCode.trim(),
111
+ street: this.form.street.trim(),
112
+ number: this.form.number.trim(),
113
+ complement: opcional(this.form.complement),
114
+ neighborhood: this.form.neighborhood.trim(),
115
+ city: this.form.city.trim(),
116
+ state: this.form.state.trim().toUpperCase(),
117
+ };
118
+ }
119
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: ProfilePage, deps: [], target: i0.ɵɵFactoryTarget.Component });
120
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: ProfilePage, isStandalone: true, selector: "orechio-billing-profile", ngImport: i0, template: `
121
+ <section class="orechio-billing">
122
+ <h1>Dados de cobrança</h1>
123
+
124
+ @if (perfil(); as p) {
125
+ @if (!p.exists) {
126
+ <p class="orechio-billing__muted">
127
+ Informe os dados que vão na cobrança. O CPF ou CNPJ é exigido pelo emissor do PIX.
128
+ </p>
129
+ <form data-criar (ngSubmit)="criar()">
130
+ <ng-container *ngTemplateOutlet="contato" />
131
+ <ng-container *ngTemplateOutlet="endereco" />
132
+ <button type="submit" [disabled]="enviando()">{{ enviando() ? 'Salvando…' : 'Salvar' }}</button>
133
+ </form>
134
+ } @else {
135
+ <form data-contato (ngSubmit)="salvarContato()">
136
+ <h2>Contato</h2>
137
+ <ng-container *ngTemplateOutlet="contato" />
138
+ <button type="submit" [disabled]="enviando()">Salvar contato</button>
139
+ </form>
140
+
141
+ <form data-endereco (ngSubmit)="salvarEndereco()">
142
+ <h2>Endereço</h2>
143
+ <ng-container *ngTemplateOutlet="endereco" />
144
+ <button type="submit" [disabled]="enviando()">Salvar endereço</button>
145
+ </form>
146
+ }
147
+
148
+ @if (salvo()) {
149
+ <p role="status">Dados salvos.</p>
150
+ }
151
+ <a routerLink="..">Voltar para a assinatura</a>
152
+ } @else if (!erro()) {
153
+ <p class="orechio-billing__muted">Carregando…</p>
154
+ }
155
+
156
+ @if (erro(); as problema) {
157
+ <orechio-billing-error [problema]="problema" />
158
+ }
159
+ </section>
160
+
161
+ <ng-template #contato>
162
+ <label>Tipo de documento
163
+ <select name="documentType" [(ngModel)]="form.documentType" [disabled]="travado()">
164
+ <option value="Cpf">CPF</option>
165
+ <option value="Cnpj">CNPJ</option>
166
+ </select>
167
+ </label>
168
+ <label>{{ form.documentType === 'Cpf' ? 'CPF' : 'CNPJ' }}
169
+ <input name="documentNumber" inputmode="numeric" [(ngModel)]="form.documentNumber" [disabled]="travado()" required />
170
+ </label>
171
+ <label>{{ form.documentType === 'Cpf' ? 'Nome completo' : 'Razão social' }}
172
+ <input name="legalName" [(ngModel)]="form.legalName" [disabled]="travado()" required />
173
+ </label>
174
+ <label>Nome fantasia (opcional)
175
+ <input name="tradeName" [(ngModel)]="form.tradeName" />
176
+ </label>
177
+ <label>E-mail de cobrança
178
+ <input name="billingEmail" type="email" autocomplete="email" [(ngModel)]="form.billingEmail" required />
179
+ </label>
180
+ <label>Telefone (opcional)
181
+ <input name="phone" type="tel" [(ngModel)]="form.phone" />
182
+ </label>
183
+ <label>Celular (opcional)
184
+ <input name="mobilePhone" type="tel" [(ngModel)]="form.mobilePhone" />
185
+ </label>
186
+ </ng-template>
187
+
188
+ <ng-template #endereco>
189
+ <label>CEP <input name="postalCode" inputmode="numeric" autocomplete="postal-code" [(ngModel)]="form.postalCode" required /></label>
190
+ <label>Rua <input name="street" autocomplete="address-line1" [(ngModel)]="form.street" required /></label>
191
+ <label>Número <input name="number" [(ngModel)]="form.number" required /></label>
192
+ <label>Complemento (opcional) <input name="complement" autocomplete="address-line2" [(ngModel)]="form.complement" /></label>
193
+ <label>Bairro <input name="neighborhood" [(ngModel)]="form.neighborhood" required /></label>
194
+ <label>Cidade <input name="city" autocomplete="address-level2" [(ngModel)]="form.city" required /></label>
195
+ <label>UF <input name="state" maxlength="2" autocomplete="address-level1" [(ngModel)]="form.state" required /></label>
196
+ </ng-template>
197
+ `, 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)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple]):not([ngNoCva])[formControlName],select:not([multiple]):not([ngNoCva])[formControl],select:not([multiple]):not([ngNoCva])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { 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 });
198
+ }
199
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: ProfilePage, decorators: [{
200
+ type: Component,
201
+ args: [{ selector: 'orechio-billing-profile', standalone: true, imports: [FormsModule, NgTemplateOutlet, RouterLink, BillingErrorComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: `
202
+ <section class="orechio-billing">
203
+ <h1>Dados de cobrança</h1>
204
+
205
+ @if (perfil(); as p) {
206
+ @if (!p.exists) {
207
+ <p class="orechio-billing__muted">
208
+ Informe os dados que vão na cobrança. O CPF ou CNPJ é exigido pelo emissor do PIX.
209
+ </p>
210
+ <form data-criar (ngSubmit)="criar()">
211
+ <ng-container *ngTemplateOutlet="contato" />
212
+ <ng-container *ngTemplateOutlet="endereco" />
213
+ <button type="submit" [disabled]="enviando()">{{ enviando() ? 'Salvando…' : 'Salvar' }}</button>
214
+ </form>
215
+ } @else {
216
+ <form data-contato (ngSubmit)="salvarContato()">
217
+ <h2>Contato</h2>
218
+ <ng-container *ngTemplateOutlet="contato" />
219
+ <button type="submit" [disabled]="enviando()">Salvar contato</button>
220
+ </form>
221
+
222
+ <form data-endereco (ngSubmit)="salvarEndereco()">
223
+ <h2>Endereço</h2>
224
+ <ng-container *ngTemplateOutlet="endereco" />
225
+ <button type="submit" [disabled]="enviando()">Salvar endereço</button>
226
+ </form>
227
+ }
228
+
229
+ @if (salvo()) {
230
+ <p role="status">Dados salvos.</p>
231
+ }
232
+ <a routerLink="..">Voltar para a assinatura</a>
233
+ } @else if (!erro()) {
234
+ <p class="orechio-billing__muted">Carregando…</p>
235
+ }
236
+
237
+ @if (erro(); as problema) {
238
+ <orechio-billing-error [problema]="problema" />
239
+ }
240
+ </section>
241
+
242
+ <ng-template #contato>
243
+ <label>Tipo de documento
244
+ <select name="documentType" [(ngModel)]="form.documentType" [disabled]="travado()">
245
+ <option value="Cpf">CPF</option>
246
+ <option value="Cnpj">CNPJ</option>
247
+ </select>
248
+ </label>
249
+ <label>{{ form.documentType === 'Cpf' ? 'CPF' : 'CNPJ' }}
250
+ <input name="documentNumber" inputmode="numeric" [(ngModel)]="form.documentNumber" [disabled]="travado()" required />
251
+ </label>
252
+ <label>{{ form.documentType === 'Cpf' ? 'Nome completo' : 'Razão social' }}
253
+ <input name="legalName" [(ngModel)]="form.legalName" [disabled]="travado()" required />
254
+ </label>
255
+ <label>Nome fantasia (opcional)
256
+ <input name="tradeName" [(ngModel)]="form.tradeName" />
257
+ </label>
258
+ <label>E-mail de cobrança
259
+ <input name="billingEmail" type="email" autocomplete="email" [(ngModel)]="form.billingEmail" required />
260
+ </label>
261
+ <label>Telefone (opcional)
262
+ <input name="phone" type="tel" [(ngModel)]="form.phone" />
263
+ </label>
264
+ <label>Celular (opcional)
265
+ <input name="mobilePhone" type="tel" [(ngModel)]="form.mobilePhone" />
266
+ </label>
267
+ </ng-template>
268
+
269
+ <ng-template #endereco>
270
+ <label>CEP <input name="postalCode" inputmode="numeric" autocomplete="postal-code" [(ngModel)]="form.postalCode" required /></label>
271
+ <label>Rua <input name="street" autocomplete="address-line1" [(ngModel)]="form.street" required /></label>
272
+ <label>Número <input name="number" [(ngModel)]="form.number" required /></label>
273
+ <label>Complemento (opcional) <input name="complement" autocomplete="address-line2" [(ngModel)]="form.complement" /></label>
274
+ <label>Bairro <input name="neighborhood" [(ngModel)]="form.neighborhood" required /></label>
275
+ <label>Cidade <input name="city" autocomplete="address-level2" [(ngModel)]="form.city" required /></label>
276
+ <label>UF <input name="state" maxlength="2" autocomplete="address-level1" [(ngModel)]="form.state" required /></label>
277
+ </ng-template>
278
+ `, 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)}\n"] }]
279
+ }] });
280
+
281
+ export { ProfilePage };
282
+ //# sourceMappingURL=orechio-platform-angular-billing-profile.page-Baa6uoM6.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orechio-platform-angular-billing-profile.page-Baa6uoM6.mjs","sources":["../../../projects/platform-angular/billing/src/pages/profile.page.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, OnInit, inject, signal } from '@angular/core';\r\nimport { NgTemplateOutlet } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { ActivatedRoute, Router, RouterLink } from '@angular/router';\r\nimport { Observable } from 'rxjs';\r\nimport { ProblemDetails } from '@orechio/platform-angular';\r\nimport { BillingClient } from '../billing-client';\r\nimport { BillingErrorComponent } from '../billing-error.component';\r\nimport { ESTILO_BASE } from '../billing-format';\r\nimport {\r\n BillingAddressRequest,\r\n BillingContactRequest,\r\n BillingProfile,\r\n DocumentType,\r\n} from '../billing-models';\r\n\r\ninterface Formulario {\r\n documentType: DocumentType;\r\n documentNumber: string;\r\n legalName: string;\r\n tradeName: string;\r\n billingEmail: string;\r\n phone: string;\r\n mobilePhone: string;\r\n postalCode: string;\r\n street: string;\r\n number: string;\r\n complement: string;\r\n neighborhood: string;\r\n city: string;\r\n state: string;\r\n}\r\n\r\nfunction doPerfil(perfil: BillingProfile): Formulario {\r\n return {\r\n documentType: perfil.documentType ?? 'Cnpj',\r\n documentNumber: perfil.documentNumber ?? '',\r\n legalName: perfil.legalName ?? '',\r\n tradeName: perfil.tradeName ?? '',\r\n billingEmail: perfil.billingEmail ?? '',\r\n phone: perfil.phone ?? '',\r\n mobilePhone: perfil.mobilePhone ?? '',\r\n postalCode: perfil.postalCode ?? '',\r\n street: perfil.street ?? '',\r\n number: perfil.number ?? '',\r\n complement: perfil.complement ?? '',\r\n neighborhood: perfil.neighborhood ?? '',\r\n city: perfil.city ?? '',\r\n state: perfil.state ?? '',\r\n };\r\n}\r\n\r\n/** Campo opcional vazio vai como `null`, que é o que a Platform espera nos `string?`. */\r\nfunction opcional(valor: string): string | null {\r\n const limpo = valor.trim();\r\n return limpo ? limpo : null;\r\n}\r\n\r\n/**\r\n * Perfil de cobrança (ADR-021 §3.5, item 2). Cria com `POST profile`; edita por partes, como a\r\n * Platform: `PATCH profile/contact` e `PATCH profile/address` — não existe PUT.\r\n */\r\n@Component({\r\n selector: 'orechio-billing-profile',\r\n standalone: true,\r\n imports: [FormsModule, NgTemplateOutlet, RouterLink, BillingErrorComponent],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n template: `\r\n <section class=\"orechio-billing\">\r\n <h1>Dados de cobrança</h1>\r\n\r\n @if (perfil(); as p) {\r\n @if (!p.exists) {\r\n <p class=\"orechio-billing__muted\">\r\n Informe os dados que vão na cobrança. O CPF ou CNPJ é exigido pelo emissor do PIX.\r\n </p>\r\n <form data-criar (ngSubmit)=\"criar()\">\r\n <ng-container *ngTemplateOutlet=\"contato\" />\r\n <ng-container *ngTemplateOutlet=\"endereco\" />\r\n <button type=\"submit\" [disabled]=\"enviando()\">{{ enviando() ? 'Salvando…' : 'Salvar' }}</button>\r\n </form>\r\n } @else {\r\n <form data-contato (ngSubmit)=\"salvarContato()\">\r\n <h2>Contato</h2>\r\n <ng-container *ngTemplateOutlet=\"contato\" />\r\n <button type=\"submit\" [disabled]=\"enviando()\">Salvar contato</button>\r\n </form>\r\n\r\n <form data-endereco (ngSubmit)=\"salvarEndereco()\">\r\n <h2>Endereço</h2>\r\n <ng-container *ngTemplateOutlet=\"endereco\" />\r\n <button type=\"submit\" [disabled]=\"enviando()\">Salvar endereço</button>\r\n </form>\r\n }\r\n\r\n @if (salvo()) {\r\n <p role=\"status\">Dados salvos.</p>\r\n }\r\n <a routerLink=\"..\">Voltar para a assinatura</a>\r\n } @else if (!erro()) {\r\n <p class=\"orechio-billing__muted\">Carregando…</p>\r\n }\r\n\r\n @if (erro(); as problema) {\r\n <orechio-billing-error [problema]=\"problema\" />\r\n }\r\n </section>\r\n\r\n <ng-template #contato>\r\n <label>Tipo de documento\r\n <select name=\"documentType\" [(ngModel)]=\"form.documentType\" [disabled]=\"travado()\">\r\n <option value=\"Cpf\">CPF</option>\r\n <option value=\"Cnpj\">CNPJ</option>\r\n </select>\r\n </label>\r\n <label>{{ form.documentType === 'Cpf' ? 'CPF' : 'CNPJ' }}\r\n <input name=\"documentNumber\" inputmode=\"numeric\" [(ngModel)]=\"form.documentNumber\" [disabled]=\"travado()\" required />\r\n </label>\r\n <label>{{ form.documentType === 'Cpf' ? 'Nome completo' : 'Razão social' }}\r\n <input name=\"legalName\" [(ngModel)]=\"form.legalName\" [disabled]=\"travado()\" required />\r\n </label>\r\n <label>Nome fantasia (opcional)\r\n <input name=\"tradeName\" [(ngModel)]=\"form.tradeName\" />\r\n </label>\r\n <label>E-mail de cobrança\r\n <input name=\"billingEmail\" type=\"email\" autocomplete=\"email\" [(ngModel)]=\"form.billingEmail\" required />\r\n </label>\r\n <label>Telefone (opcional)\r\n <input name=\"phone\" type=\"tel\" [(ngModel)]=\"form.phone\" />\r\n </label>\r\n <label>Celular (opcional)\r\n <input name=\"mobilePhone\" type=\"tel\" [(ngModel)]=\"form.mobilePhone\" />\r\n </label>\r\n </ng-template>\r\n\r\n <ng-template #endereco>\r\n <label>CEP <input name=\"postalCode\" inputmode=\"numeric\" autocomplete=\"postal-code\" [(ngModel)]=\"form.postalCode\" required /></label>\r\n <label>Rua <input name=\"street\" autocomplete=\"address-line1\" [(ngModel)]=\"form.street\" required /></label>\r\n <label>Número <input name=\"number\" [(ngModel)]=\"form.number\" required /></label>\r\n <label>Complemento (opcional) <input name=\"complement\" autocomplete=\"address-line2\" [(ngModel)]=\"form.complement\" /></label>\r\n <label>Bairro <input name=\"neighborhood\" [(ngModel)]=\"form.neighborhood\" required /></label>\r\n <label>Cidade <input name=\"city\" autocomplete=\"address-level2\" [(ngModel)]=\"form.city\" required /></label>\r\n <label>UF <input name=\"state\" maxlength=\"2\" autocomplete=\"address-level1\" [(ngModel)]=\"form.state\" required /></label>\r\n </ng-template>\r\n `,\r\n styles: ESTILO_BASE,\r\n})\r\nexport class ProfilePage implements OnInit {\r\n private readonly client = inject(BillingClient);\r\n private readonly router = inject(Router);\r\n private readonly route = inject(ActivatedRoute);\r\n\r\n protected form: Formulario = doPerfil({} as BillingProfile);\r\n protected readonly perfil = signal<BillingProfile | null>(null);\r\n protected readonly travado = signal(false);\r\n protected readonly enviando = signal(false);\r\n protected readonly salvo = signal(false);\r\n protected readonly erro = signal<ProblemDetails | null>(null);\r\n\r\n ngOnInit(): void {\r\n this.carregar();\r\n }\r\n\r\n protected criar(): void {\r\n this.enviar(this.client.createProfile({ ...this.contato(), ...this.endereco() }), () => {\r\n // Quem veio do pagamento volta para ele: foi o checkout que mandou para cá.\r\n if (this.route.snapshot.queryParamMap.get('next') === 'checkout') {\r\n void this.router.navigate(['../checkout'], { relativeTo: this.route });\r\n return;\r\n }\r\n this.carregar();\r\n });\r\n }\r\n\r\n protected salvarContato(): void {\r\n this.enviar(this.client.updateProfileContact(this.contato()), () => this.salvo.set(true));\r\n }\r\n\r\n protected salvarEndereco(): void {\r\n this.enviar(this.client.updateProfileAddress(this.endereco()), () => this.salvo.set(true));\r\n }\r\n\r\n private carregar(): void {\r\n this.client.getProfile().subscribe({\r\n next: (perfil) => {\r\n this.form = doPerfil(perfil);\r\n this.travado.set(perfil.isDocumentLocked === true);\r\n this.perfil.set(perfil);\r\n },\r\n error: (problema: ProblemDetails) => this.erro.set(problema),\r\n });\r\n }\r\n\r\n private enviar(chamada: Observable<unknown>, depois: () => void): void {\r\n if (this.enviando()) return;\r\n this.enviando.set(true);\r\n this.salvo.set(false);\r\n this.erro.set(null);\r\n\r\n chamada.subscribe({\r\n next: () => {\r\n this.enviando.set(false);\r\n depois();\r\n },\r\n error: (problema: ProblemDetails) => {\r\n this.enviando.set(false);\r\n this.erro.set(problema);\r\n },\r\n });\r\n }\r\n\r\n private contato(): BillingContactRequest {\r\n return {\r\n documentType: this.form.documentType,\r\n documentNumber: this.form.documentNumber.trim(),\r\n legalName: this.form.legalName.trim(),\r\n tradeName: opcional(this.form.tradeName),\r\n billingEmail: this.form.billingEmail.trim(),\r\n phone: opcional(this.form.phone),\r\n mobilePhone: opcional(this.form.mobilePhone),\r\n };\r\n }\r\n\r\n private endereco(): BillingAddressRequest {\r\n return {\r\n postalCode: this.form.postalCode.trim(),\r\n street: this.form.street.trim(),\r\n number: this.form.number.trim(),\r\n complement: opcional(this.form.complement),\r\n neighborhood: this.form.neighborhood.trim(),\r\n city: this.form.city.trim(),\r\n state: this.form.state.trim().toUpperCase(),\r\n };\r\n }\r\n}\r\n"],"names":[],"mappings":"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"}