@orechio/platform-angular 0.7.1 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/fesm2022/{orechio-platform-angular-billing-billing-format-0nlddK-x.mjs → orechio-platform-angular-billing-billing-format-DFY2U19Y.mjs} +111 -2
  2. package/fesm2022/orechio-platform-angular-billing-billing-format-DFY2U19Y.mjs.map +1 -0
  3. package/fesm2022/{orechio-platform-angular-billing-checkout.page-CHU_Drpu.mjs → orechio-platform-angular-billing-checkout.page-CNl0PPiE.mjs} +5 -5
  4. package/fesm2022/{orechio-platform-angular-billing-checkout.page-CHU_Drpu.mjs.map → orechio-platform-angular-billing-checkout.page-CNl0PPiE.mjs.map} +1 -1
  5. package/fesm2022/{orechio-platform-angular-billing-invoice.page-BVyWur3o.mjs → orechio-platform-angular-billing-invoice.page-CLojIJkf.mjs} +5 -5
  6. package/fesm2022/{orechio-platform-angular-billing-invoice.page-BVyWur3o.mjs.map → orechio-platform-angular-billing-invoice.page-CLojIJkf.mjs.map} +1 -1
  7. package/fesm2022/{orechio-platform-angular-billing-invoices.page-BiEm3hRf.mjs → orechio-platform-angular-billing-invoices.page-COsCT5NY.mjs} +4 -4
  8. package/fesm2022/{orechio-platform-angular-billing-invoices.page-BiEm3hRf.mjs.map → orechio-platform-angular-billing-invoices.page-COsCT5NY.mjs.map} +1 -1
  9. package/fesm2022/{orechio-platform-angular-billing-pix-panel.component-B608dQmc.mjs → orechio-platform-angular-billing-pix-panel.component-fdORTehK.mjs} +5 -3
  10. package/fesm2022/orechio-platform-angular-billing-pix-panel.component-fdORTehK.mjs.map +1 -0
  11. package/fesm2022/{orechio-platform-angular-billing-profile.page-Baa6uoM6.mjs → orechio-platform-angular-billing-profile.page-DHjsB3jJ.mjs} +50 -23
  12. package/fesm2022/orechio-platform-angular-billing-profile.page-DHjsB3jJ.mjs.map +1 -0
  13. package/fesm2022/{orechio-platform-angular-billing-subscription.page-9NF8bWhu.mjs → orechio-platform-angular-billing-subscription.page-Cotupt22.mjs} +6 -6
  14. package/fesm2022/orechio-platform-angular-billing-subscription.page-Cotupt22.mjs.map +1 -0
  15. package/fesm2022/orechio-platform-angular-billing.mjs +5 -5
  16. package/fesm2022/orechio-platform-angular.mjs +8 -4
  17. package/fesm2022/orechio-platform-angular.mjs.map +1 -1
  18. package/package.json +1 -1
  19. package/types/orechio-platform-angular.d.ts +8 -4
  20. package/fesm2022/orechio-platform-angular-billing-billing-format-0nlddK-x.mjs.map +0 -1
  21. package/fesm2022/orechio-platform-angular-billing-pix-panel.component-B608dQmc.mjs.map +0 -1
  22. package/fesm2022/orechio-platform-angular-billing-profile.page-Baa6uoM6.mjs.map +0 -1
  23. package/fesm2022/orechio-platform-angular-billing-subscription.page-9NF8bWhu.mjs.map +0 -1
@@ -4,18 +4,19 @@ import { NgTemplateOutlet } from '@angular/common';
4
4
  import * as i1 from '@angular/forms';
5
5
  import { FormsModule } from '@angular/forms';
6
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';
7
+ import { m as mascararCep, b as mascararTelefone, c as mascararDocumento, B as BillingClient, e as mascararCpf, f as mascararCnpj, s as soDigitos, a as BillingErrorComponent } from './orechio-platform-angular-billing-billing-format-DFY2U19Y.mjs';
8
8
 
9
9
  function doPerfil(perfil) {
10
+ const tipo = perfil.documentType ?? 'Cnpj';
10
11
  return {
11
- documentType: perfil.documentType ?? 'Cnpj',
12
- documentNumber: perfil.documentNumber ?? '',
12
+ documentType: tipo,
13
+ documentNumber: mascararDocumento(tipo, perfil.documentNumber ?? ''),
13
14
  legalName: perfil.legalName ?? '',
14
15
  tradeName: perfil.tradeName ?? '',
15
16
  billingEmail: perfil.billingEmail ?? '',
16
- phone: perfil.phone ?? '',
17
- mobilePhone: perfil.mobilePhone ?? '',
18
- postalCode: perfil.postalCode ?? '',
17
+ phone: mascararTelefone(perfil.phone ?? ''),
18
+ mobilePhone: mascararTelefone(perfil.mobilePhone ?? ''),
19
+ postalCode: mascararCep(perfil.postalCode ?? ''),
19
20
  street: perfil.street ?? '',
20
21
  number: perfil.number ?? '',
21
22
  complement: perfil.complement ?? '',
@@ -51,6 +52,32 @@ class ProfilePage {
51
52
  ngOnInit() {
52
53
  this.carregar();
53
54
  }
55
+ /**
56
+ * Máscara ao digitar: o campo é reescrito pela máscara e o formulário guarda o texto
57
+ * mascarado. Sem `ngModel` de propósito — com ele, digitar um caractere que a máscara
58
+ * descarta deixaria o valor do modelo igual ao anterior, e o campo continuaria mostrando
59
+ * o caractere digitado.
60
+ */
61
+ mascarar(campo, evento) {
62
+ const entrada = evento.target;
63
+ const mascarado = this.mascara(campo)(entrada.value);
64
+ entrada.value = mascarado;
65
+ this.form[campo] = mascarado;
66
+ }
67
+ trocarTipo(tipo) {
68
+ this.form.documentType = tipo;
69
+ this.form.documentNumber = mascararDocumento(tipo, this.form.documentNumber);
70
+ }
71
+ mascara(campo) {
72
+ switch (campo) {
73
+ case 'documentNumber':
74
+ return this.form.documentType === 'Cpf' ? mascararCpf : mascararCnpj;
75
+ case 'postalCode':
76
+ return mascararCep;
77
+ default:
78
+ return mascararTelefone;
79
+ }
80
+ }
54
81
  criar() {
55
82
  this.enviar(this.client.createProfile({ ...this.contato(), ...this.endereco() }), () => {
56
83
  // Quem veio do pagamento volta para ele: foi o checkout que mandou para cá.
@@ -97,17 +124,17 @@ class ProfilePage {
97
124
  contato() {
98
125
  return {
99
126
  documentType: this.form.documentType,
100
- documentNumber: this.form.documentNumber.trim(),
127
+ documentNumber: soDigitos(this.form.documentNumber),
101
128
  legalName: this.form.legalName.trim(),
102
129
  tradeName: opcional(this.form.tradeName),
103
130
  billingEmail: this.form.billingEmail.trim(),
104
- phone: opcional(this.form.phone),
105
- mobilePhone: opcional(this.form.mobilePhone),
131
+ phone: opcional(soDigitos(this.form.phone)),
132
+ mobilePhone: opcional(soDigitos(this.form.mobilePhone)),
106
133
  };
107
134
  }
108
135
  endereco() {
109
136
  return {
110
- postalCode: this.form.postalCode.trim(),
137
+ postalCode: soDigitos(this.form.postalCode),
111
138
  street: this.form.street.trim(),
112
139
  number: this.form.number.trim(),
113
140
  complement: opcional(this.form.complement),
@@ -160,13 +187,13 @@ class ProfilePage {
160
187
 
161
188
  <ng-template #contato>
162
189
  <label>Tipo de documento
163
- <select name="documentType" [(ngModel)]="form.documentType" [disabled]="travado()">
190
+ <select name="documentType" [ngModel]="form.documentType" (ngModelChange)="trocarTipo($event)" [disabled]="travado()">
164
191
  <option value="Cpf">CPF</option>
165
192
  <option value="Cnpj">CNPJ</option>
166
193
  </select>
167
194
  </label>
168
195
  <label>{{ form.documentType === 'Cpf' ? 'CPF' : 'CNPJ' }}
169
- <input name="documentNumber" inputmode="numeric" [(ngModel)]="form.documentNumber" [disabled]="travado()" required />
196
+ <input name="documentNumber" inputmode="numeric" [value]="form.documentNumber" (input)="mascarar('documentNumber', $event)" [disabled]="travado()" required />
170
197
  </label>
171
198
  <label>{{ form.documentType === 'Cpf' ? 'Nome completo' : 'Razão social' }}
172
199
  <input name="legalName" [(ngModel)]="form.legalName" [disabled]="travado()" required />
@@ -178,15 +205,15 @@ class ProfilePage {
178
205
  <input name="billingEmail" type="email" autocomplete="email" [(ngModel)]="form.billingEmail" required />
179
206
  </label>
180
207
  <label>Telefone (opcional)
181
- <input name="phone" type="tel" [(ngModel)]="form.phone" />
208
+ <input name="phone" type="tel" [value]="form.phone" (input)="mascarar('phone', $event)" />
182
209
  </label>
183
210
  <label>Celular (opcional)
184
- <input name="mobilePhone" type="tel" [(ngModel)]="form.mobilePhone" />
211
+ <input name="mobilePhone" type="tel" [value]="form.mobilePhone" (input)="mascarar('mobilePhone', $event)" />
185
212
  </label>
186
213
  </ng-template>
187
214
 
188
215
  <ng-template #endereco>
189
- <label>CEP <input name="postalCode" inputmode="numeric" autocomplete="postal-code" [(ngModel)]="form.postalCode" required /></label>
216
+ <label>CEP <input name="postalCode" inputmode="numeric" autocomplete="postal-code" [value]="form.postalCode" (input)="mascarar('postalCode', $event)" required /></label>
190
217
  <label>Rua <input name="street" autocomplete="address-line1" [(ngModel)]="form.street" required /></label>
191
218
  <label>Número <input name="number" [(ngModel)]="form.number" required /></label>
192
219
  <label>Complemento (opcional) <input name="complement" autocomplete="address-line2" [(ngModel)]="form.complement" /></label>
@@ -194,7 +221,7 @@ class ProfilePage {
194
221
  <label>Cidade <input name="city" autocomplete="address-level2" [(ngModel)]="form.city" required /></label>
195
222
  <label>UF <input name="state" maxlength="2" autocomplete="address-level1" [(ngModel)]="form.state" required /></label>
196
223
  </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 });
224
+ `, 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: "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
225
  }
199
226
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: ProfilePage, decorators: [{
200
227
  type: Component,
@@ -241,13 +268,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImpor
241
268
 
242
269
  <ng-template #contato>
243
270
  <label>Tipo de documento
244
- <select name="documentType" [(ngModel)]="form.documentType" [disabled]="travado()">
271
+ <select name="documentType" [ngModel]="form.documentType" (ngModelChange)="trocarTipo($event)" [disabled]="travado()">
245
272
  <option value="Cpf">CPF</option>
246
273
  <option value="Cnpj">CNPJ</option>
247
274
  </select>
248
275
  </label>
249
276
  <label>{{ form.documentType === 'Cpf' ? 'CPF' : 'CNPJ' }}
250
- <input name="documentNumber" inputmode="numeric" [(ngModel)]="form.documentNumber" [disabled]="travado()" required />
277
+ <input name="documentNumber" inputmode="numeric" [value]="form.documentNumber" (input)="mascarar('documentNumber', $event)" [disabled]="travado()" required />
251
278
  </label>
252
279
  <label>{{ form.documentType === 'Cpf' ? 'Nome completo' : 'Razão social' }}
253
280
  <input name="legalName" [(ngModel)]="form.legalName" [disabled]="travado()" required />
@@ -259,15 +286,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImpor
259
286
  <input name="billingEmail" type="email" autocomplete="email" [(ngModel)]="form.billingEmail" required />
260
287
  </label>
261
288
  <label>Telefone (opcional)
262
- <input name="phone" type="tel" [(ngModel)]="form.phone" />
289
+ <input name="phone" type="tel" [value]="form.phone" (input)="mascarar('phone', $event)" />
263
290
  </label>
264
291
  <label>Celular (opcional)
265
- <input name="mobilePhone" type="tel" [(ngModel)]="form.mobilePhone" />
292
+ <input name="mobilePhone" type="tel" [value]="form.mobilePhone" (input)="mascarar('mobilePhone', $event)" />
266
293
  </label>
267
294
  </ng-template>
268
295
 
269
296
  <ng-template #endereco>
270
- <label>CEP <input name="postalCode" inputmode="numeric" autocomplete="postal-code" [(ngModel)]="form.postalCode" required /></label>
297
+ <label>CEP <input name="postalCode" inputmode="numeric" autocomplete="postal-code" [value]="form.postalCode" (input)="mascarar('postalCode', $event)" required /></label>
271
298
  <label>Rua <input name="street" autocomplete="address-line1" [(ngModel)]="form.street" required /></label>
272
299
  <label>Número <input name="number" [(ngModel)]="form.number" required /></label>
273
300
  <label>Complemento (opcional) <input name="complement" autocomplete="address-line2" [(ngModel)]="form.complement" /></label>
@@ -275,8 +302,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImpor
275
302
  <label>Cidade <input name="city" autocomplete="address-level2" [(ngModel)]="form.city" required /></label>
276
303
  <label>UF <input name="state" maxlength="2" autocomplete="address-level1" [(ngModel)]="form.state" required /></label>
277
304
  </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"] }]
305
+ `, 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"] }]
279
306
  }] });
280
307
 
281
308
  export { ProfilePage };
282
- //# sourceMappingURL=orechio-platform-angular-billing-profile.page-Baa6uoM6.mjs.map
309
+ //# sourceMappingURL=orechio-platform-angular-billing-profile.page-DHjsB3jJ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orechio-platform-angular-billing-profile.page-DHjsB3jJ.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 {\r\n ESTILO_BASE,\r\n mascararCep,\r\n mascararCpf,\r\n mascararCnpj,\r\n mascararDocumento,\r\n mascararTelefone,\r\n soDigitos,\r\n} 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\n/** Os campos que levam máscara, e qual máscara cada um leva (o documento depende do tipo). */\r\ntype CampoMascarado = 'documentNumber' | 'phone' | 'mobilePhone' | 'postalCode';\r\n\r\nfunction doPerfil(perfil: BillingProfile): Formulario {\r\n const tipo = perfil.documentType ?? 'Cnpj';\r\n return {\r\n documentType: tipo,\r\n documentNumber: mascararDocumento(tipo, perfil.documentNumber ?? ''),\r\n legalName: perfil.legalName ?? '',\r\n tradeName: perfil.tradeName ?? '',\r\n billingEmail: perfil.billingEmail ?? '',\r\n phone: mascararTelefone(perfil.phone ?? ''),\r\n mobilePhone: mascararTelefone(perfil.mobilePhone ?? ''),\r\n postalCode: mascararCep(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\" (ngModelChange)=\"trocarTipo($event)\" [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\" [value]=\"form.documentNumber\" (input)=\"mascarar('documentNumber', $event)\" [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\" [value]=\"form.phone\" (input)=\"mascarar('phone', $event)\" />\r\n </label>\r\n <label>Celular (opcional)\r\n <input name=\"mobilePhone\" type=\"tel\" [value]=\"form.mobilePhone\" (input)=\"mascarar('mobilePhone', $event)\" />\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\" [value]=\"form.postalCode\" (input)=\"mascarar('postalCode', $event)\" 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 /**\r\n * Máscara ao digitar: o campo é reescrito pela máscara e o formulário guarda o texto\r\n * mascarado. Sem `ngModel` de propósito — com ele, digitar um caractere que a máscara\r\n * descarta deixaria o valor do modelo igual ao anterior, e o campo continuaria mostrando\r\n * o caractere digitado.\r\n */\r\n protected mascarar(campo: CampoMascarado, evento: Event): void {\r\n const entrada = evento.target as HTMLInputElement;\r\n const mascarado = this.mascara(campo)(entrada.value);\r\n entrada.value = mascarado;\r\n this.form[campo] = mascarado;\r\n }\r\n\r\n protected trocarTipo(tipo: DocumentType): void {\r\n this.form.documentType = tipo;\r\n this.form.documentNumber = mascararDocumento(tipo, this.form.documentNumber);\r\n }\r\n\r\n private mascara(campo: CampoMascarado): (valor: string) => string {\r\n switch (campo) {\r\n case 'documentNumber':\r\n return this.form.documentType === 'Cpf' ? mascararCpf : mascararCnpj;\r\n case 'postalCode':\r\n return mascararCep;\r\n default:\r\n return mascararTelefone;\r\n }\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: soDigitos(this.form.documentNumber),\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(soDigitos(this.form.phone)),\r\n mobilePhone: opcional(soDigitos(this.form.mobilePhone)),\r\n };\r\n }\r\n\r\n private endereco(): BillingAddressRequest {\r\n return {\r\n postalCode: soDigitos(this.form.postalCode),\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":";;;;;;;;AA4CA,SAAS,QAAQ,CAAC,MAAsB,EAAA;AACtC,IAAA,MAAM,IAAI,GAAG,MAAM,CAAC,YAAY,IAAI,MAAM;IAC1C,OAAO;AACL,QAAA,YAAY,EAAE,IAAI;QAClB,cAAc,EAAE,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,cAAc,IAAI,EAAE,CAAC;AACpE,QAAA,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE;AACjC,QAAA,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE;AACjC,QAAA,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,EAAE;QACvC,KAAK,EAAE,gBAAgB,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;QAC3C,WAAW,EAAE,gBAAgB,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;QACvD,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC;AAChD,QAAA,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE;AAC3B,QAAA,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE;AAC3B,QAAA,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,EAAE;AACnC,QAAA,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,EAAE;AACvC,QAAA,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE;AACvB,QAAA,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE;KAC1B;AACH;AAEA;AACA,SAAS,QAAQ,CAAC,KAAa,EAAA;AAC7B,IAAA,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE;IAC1B,OAAO,KAAK,GAAG,KAAK,GAAG,IAAI;AAC7B;AAEA;;;AAGG;MAsFU,WAAW,CAAA;AACL,IAAA,MAAM,GAAG,MAAM,CAAC,aAAa,CAAC;AAC9B,IAAA,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;AACvB,IAAA,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC;AAErC,IAAA,IAAI,GAAe,QAAQ,CAAC,EAAoB,CAAC;IACxC,MAAM,GAAG,MAAM,CAAwB,IAAI;+EAAC;IAC5C,OAAO,GAAG,MAAM,CAAC,KAAK;gFAAC;IACvB,QAAQ,GAAG,MAAM,CAAC,KAAK;iFAAC;IACxB,KAAK,GAAG,MAAM,CAAC,KAAK;8EAAC;IACrB,IAAI,GAAG,MAAM,CAAwB,IAAI;6EAAC;IAE7D,QAAQ,GAAA;QACN,IAAI,CAAC,QAAQ,EAAE;IACjB;AAEA;;;;;AAKG;IACO,QAAQ,CAAC,KAAqB,EAAE,MAAa,EAAA;AACrD,QAAA,MAAM,OAAO,GAAG,MAAM,CAAC,MAA0B;AACjD,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;AACpD,QAAA,OAAO,CAAC,KAAK,GAAG,SAAS;AACzB,QAAA,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,SAAS;IAC9B;AAEU,IAAA,UAAU,CAAC,IAAkB,EAAA;AACrC,QAAA,IAAI,CAAC,IAAI,CAAC,YAAY,GAAG,IAAI;AAC7B,QAAA,IAAI,CAAC,IAAI,CAAC,cAAc,GAAG,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC;IAC9E;AAEQ,IAAA,OAAO,CAAC,KAAqB,EAAA;QACnC,QAAQ,KAAK;AACX,YAAA,KAAK,gBAAgB;AACnB,gBAAA,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,KAAK,KAAK,GAAG,WAAW,GAAG,YAAY;AACtE,YAAA,KAAK,YAAY;AACf,gBAAA,OAAO,WAAW;AACpB,YAAA;AACE,gBAAA,OAAO,gBAAgB;;IAE7B;IAEU,KAAK,GAAA;QACb,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,MAAK;;AAErF,YAAA,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,UAAU,EAAE;AAChE,gBAAA,KAAK,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,aAAa,CAAC,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;gBACtE;YACF;YACA,IAAI,CAAC,QAAQ,EAAE;AACjB,QAAA,CAAC,CAAC;IACJ;IAEU,aAAa,GAAA;QACrB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC3F;IAEU,cAAc,GAAA;QACtB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC5F;IAEQ,QAAQ,GAAA;AACd,QAAA,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,SAAS,CAAC;AACjC,YAAA,IAAI,EAAE,CAAC,MAAM,KAAI;AACf,gBAAA,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC;gBAC5B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,KAAK,IAAI,CAAC;AAClD,gBAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;YACzB,CAAC;AACD,YAAA,KAAK,EAAE,CAAC,QAAwB,KAAK,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC7D,SAAA,CAAC;IACJ;IAEQ,MAAM,CAAC,OAA4B,EAAE,MAAkB,EAAA;QAC7D,IAAI,IAAI,CAAC,QAAQ,EAAE;YAAE;AACrB,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;AACvB,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;AACrB,QAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;QAEnB,OAAO,CAAC,SAAS,CAAC;YAChB,IAAI,EAAE,MAAK;AACT,gBAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;AACxB,gBAAA,MAAM,EAAE;YACV,CAAC;AACD,YAAA,KAAK,EAAE,CAAC,QAAwB,KAAI;AAClC,gBAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;AACxB,gBAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;YACzB,CAAC;AACF,SAAA,CAAC;IACJ;IAEQ,OAAO,GAAA;QACb,OAAO;AACL,YAAA,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY;YACpC,cAAc,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC;YACnD,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE;YACrC,SAAS,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;YACxC,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;YAC3C,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3C,WAAW,EAAE,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;SACxD;IACH;IAEQ,QAAQ,GAAA;QACd,OAAO;YACL,UAAU,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC;YAC3C,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;YAC/B,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;YAC/B,UAAU,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC;YAC1C,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;YAC3C,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YAC3B,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE;SAC5C;IACH;uGAnHW,WAAW,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAX,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,WAAW,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,yBAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAhFZ,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6ET,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,o6BAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EA/ES,WAAW,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,aAAA,EAAA,QAAA,EAAA,8CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,cAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,uBAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,wSAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,0BAAA,EAAA,QAAA,EAAA,0JAAA,EAAA,MAAA,EAAA,CAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,sGAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,iBAAA,EAAA,QAAA,EAAA,wIAAA,EAAA,MAAA,EAAA,CAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,4EAAA,EAAA,MAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,qDAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,SAAA,EAAA,gBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,MAAA,EAAA,QAAA,EAAA,yEAAA,EAAA,MAAA,EAAA,CAAA,eAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,gBAAgB,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,yBAAA,EAAA,kBAAA,EAAA,0BAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,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;;2FAkF/D,WAAW,EAAA,UAAA,EAAA,CAAA;kBArFvB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,yBAAyB,cACvB,IAAI,EAAA,OAAA,EACP,CAAC,WAAW,EAAE,gBAAgB,EAAE,UAAU,EAAE,qBAAqB,CAAC,EAAA,eAAA,EAC1D,uBAAuB,CAAC,MAAM,EAAA,QAAA,EACrC,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6ET,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,o6BAAA,CAAA,EAAA;;;;;"}
@@ -1,7 +1,7 @@
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-0nlddK-x.mjs';
4
+ import { d as data, B as BillingClient, a as BillingErrorComponent } from './orechio-platform-angular-billing-billing-format-DFY2U19Y.mjs';
5
5
 
6
6
  const DIA = 24 * 60 * 60 * 1000;
7
7
  const EM_ABERTO = ['Created', 'Pending', 'Overdue'];
@@ -118,7 +118,7 @@ class SubscriptionPage {
118
118
  } @else if (atual(); as s) {
119
119
  <h2>{{ s.titulo }}</h2>
120
120
  <p>{{ s.detalhe }}</p>
121
- <a data-acao [routerLink]="s.acao.link">{{ s.acao.texto }}</a>
121
+ <a data-acao class="orechio-billing__acao" [routerLink]="s.acao.link">{{ s.acao.texto }}</a>
122
122
 
123
123
  <nav class="orechio-billing__muted">
124
124
  <a routerLink="profile">Dados de cobrança</a>
@@ -129,7 +129,7 @@ class SubscriptionPage {
129
129
  <p class="orechio-billing__muted">Carregando…</p>
130
130
  }
131
131
  </section>
132
- `, 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 });
132
+ `, 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
133
  }
134
134
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: SubscriptionPage, decorators: [{
135
135
  type: Component,
@@ -142,7 +142,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImpor
142
142
  } @else if (atual(); as s) {
143
143
  <h2>{{ s.titulo }}</h2>
144
144
  <p>{{ s.detalhe }}</p>
145
- <a data-acao [routerLink]="s.acao.link">{{ s.acao.texto }}</a>
145
+ <a data-acao class="orechio-billing__acao" [routerLink]="s.acao.link">{{ s.acao.texto }}</a>
146
146
 
147
147
  <nav class="orechio-billing__muted">
148
148
  <a routerLink="profile">Dados de cobrança</a>
@@ -153,8 +153,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImpor
153
153
  <p class="orechio-billing__muted">Carregando…</p>
154
154
  }
155
155
  </section>
156
- `, 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"] }]
156
+ `, 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"] }]
157
157
  }] });
158
158
 
159
159
  export { SubscriptionPage };
160
- //# sourceMappingURL=orechio-platform-angular-billing-subscription.page-9NF8bWhu.mjs.map
160
+ //# sourceMappingURL=orechio-platform-angular-billing-subscription.page-Cotupt22.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orechio-platform-angular-billing-subscription.page-Cotupt22.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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"}
@@ -29,27 +29,27 @@ const ORECHIO_BILLING_ROUTES = [
29
29
  path: '',
30
30
  pathMatch: 'full',
31
31
  title: 'Assinatura',
32
- loadComponent: () => import('./orechio-platform-angular-billing-subscription.page-9NF8bWhu.mjs').then((m) => m.SubscriptionPage),
32
+ loadComponent: () => import('./orechio-platform-angular-billing-subscription.page-Cotupt22.mjs').then((m) => m.SubscriptionPage),
33
33
  },
34
34
  {
35
35
  path: 'profile',
36
36
  title: 'Dados de cobrança',
37
- loadComponent: () => import('./orechio-platform-angular-billing-profile.page-Baa6uoM6.mjs').then((m) => m.ProfilePage),
37
+ loadComponent: () => import('./orechio-platform-angular-billing-profile.page-DHjsB3jJ.mjs').then((m) => m.ProfilePage),
38
38
  },
39
39
  {
40
40
  path: 'checkout',
41
41
  title: 'Pagar assinatura',
42
- loadComponent: () => import('./orechio-platform-angular-billing-checkout.page-CHU_Drpu.mjs').then((m) => m.CheckoutPage),
42
+ loadComponent: () => import('./orechio-platform-angular-billing-checkout.page-CNl0PPiE.mjs').then((m) => m.CheckoutPage),
43
43
  },
44
44
  {
45
45
  path: 'invoices',
46
46
  title: 'Faturas',
47
- loadComponent: () => import('./orechio-platform-angular-billing-invoices.page-BiEm3hRf.mjs').then((m) => m.InvoicesPage),
47
+ loadComponent: () => import('./orechio-platform-angular-billing-invoices.page-COsCT5NY.mjs').then((m) => m.InvoicesPage),
48
48
  },
49
49
  {
50
50
  path: 'invoices/:id',
51
51
  title: 'Fatura',
52
- loadComponent: () => import('./orechio-platform-angular-billing-invoice.page-BVyWur3o.mjs').then((m) => m.InvoicePage),
52
+ loadComponent: () => import('./orechio-platform-angular-billing-invoice.page-CLojIJkf.mjs').then((m) => m.InvoicePage),
53
53
  },
54
54
  ];
55
55
 
@@ -52,8 +52,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImpor
52
52
  * class contains zero hardcoded URLs, so it works unmodified against
53
53
  * Portal's /api/auth/{login,me,refresh,logout} (envelope-wrapped
54
54
  * `{ user: UserInfo }` responses, unwrapped via config.auth.unwrapUser) and
55
- * Store's /api/auth/{login,refresh,logout} (no `me`, unwrapped responses)
56
- * alike.
55
+ * the cookie-session hosts' /api/auth/{login,session,refresh,logout,select-branch}
56
+ * (unwrapped responses; `session` is configured as `me`) alike. Those hosts are
57
+ * Store, Moveis and any host mounting Orechio.Platform.Bff.Account 0.3.0
58
+ * (ADR-022), which serves exactly this contract.
57
59
  */
58
60
  class AuthClient {
59
61
  http = inject(HttpClient);
@@ -71,8 +73,10 @@ class AuthClient {
71
73
  }
72
74
  /**
73
75
  * Reads the current session. Uses the configured `me` endpoint (GET) when
74
- * present (Portal); falls back to `refresh` (POST) when it isn't (Store,
75
- * which has no dedicated session-read endpoint and bootstraps via refresh).
76
+ * present (Portal; Store and Moveis via `/api/auth/session`; and the
77
+ * Orechio.Platform.Bff.Account 0.3.0 session routes, ADR-022) — a read that
78
+ * neither rotates the session nor its cookies. Falls back to `refresh` (POST)
79
+ * only for a host that configures no `me`, which then bootstraps via refresh.
76
80
  */
77
81
  initSession() {
78
82
  if (this.config.auth.me) {