mitre-form-component 0.1.4 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +131 -28
- package/dist/index.cjs +439 -70
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +53 -3
- package/dist/index.d.ts +53 -3
- package/dist/index.js +427 -58
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -47,7 +47,7 @@ Embora o componente esteja pronto para uso, você pode personalizá-lo ao passar
|
|
|
47
47
|
Aqui está um exemplo de uso básico dentro do projeto:
|
|
48
48
|
|
|
49
49
|
```tsx
|
|
50
|
-
import { MitreFormComponent } from "mitre-form-component
|
|
50
|
+
import { MitreFormComponent } from "mitre-form-component";
|
|
51
51
|
|
|
52
52
|
// array de produtos
|
|
53
53
|
const products = JSON.parse(process.env.VITE_PRODUCT_ID!);
|
|
@@ -55,11 +55,11 @@ const products = JSON.parse(process.env.VITE_PRODUCT_ID!);
|
|
|
55
55
|
|
|
56
56
|
<MitreFormComponent
|
|
57
57
|
products={products}
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
ambiente="prod" //[Opcional] "homol" (padrão) | "prod". Define de onde sai apiUrl/apiToken/whatsappPhone/chatUrl (config interno).
|
|
59
|
+
canal="form" //[Opcional] "form" (padrão) | "chat" | "whatsapp". Ver "🔀 Modos de submit (canal)".
|
|
60
60
|
showHeader={true} //[Opcional] Se irá exibir ou não o cabeçalho
|
|
61
|
-
title="Atendimento por mensagem" //[Opcional] Título do formulário
|
|
62
|
-
subtitle="Informe seus dados e retornaremos a mensagem." //[Opcional] Subtítulo
|
|
61
|
+
title="Atendimento por mensagem" //[Opcional] Título do formulário (ignorado em canal=whatsapp/chat)
|
|
62
|
+
subtitle="Informe seus dados e retornaremos a mensagem." //[Opcional] Subtítulo (ignorado em canal=whatsapp/chat)
|
|
63
63
|
backgroundColor="#000" //[Opcional]
|
|
64
64
|
textColor="#ffffff" //[Opcional]
|
|
65
65
|
buttonBackgroundColor="#FF5733" //[Opcional]
|
|
@@ -70,9 +70,12 @@ const products = JSON.parse(process.env.VITE_PRODUCT_ID!);
|
|
|
70
70
|
inputFocusBorderColor="#76B" //[Opcional]
|
|
71
71
|
inputPlaceholderColor="#FFF" //[Opcional]
|
|
72
72
|
inputTextColor="#FFF" //[Opcional]
|
|
73
|
-
showPreferenciaContato={true} //[Opcional] Exibe campo de preferência de contato
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
showPreferenciaContato={true} //[Opcional] Exibe campo de preferência de contato (ignorado em canal=whatsapp/chat)
|
|
74
|
+
// idProdutoTerceiro={produto.idTerceiro} //[Opcional, quando canal !== "form"]
|
|
75
|
+
// idEmpreendimento={produto.id} //[Opcional, quando canal !== "form"]
|
|
76
|
+
// naoCriarEvento={false} //[Opcional] Override do default (que é true em chat/whatsapp).
|
|
77
|
+
onSuccess={(requestBody, leadId) => console.log('Formulário enviado com sucesso!', requestBody, leadId)} //[Opcional] Callback de sucesso, útil para tracking
|
|
78
|
+
onError={(error) => console.error('Erro ao enviar formulário:', error)} //[Opcional] Callback de erro
|
|
76
79
|
/>;
|
|
77
80
|
```
|
|
78
81
|
|
|
@@ -108,13 +111,13 @@ Este componente pode ser instalado em qualquer projeto React usando o gerenciado
|
|
|
108
111
|
|
|
109
112
|
```bash
|
|
110
113
|
# Usando npm
|
|
111
|
-
npm install mitre-form-component
|
|
114
|
+
npm install mitre-form-component
|
|
112
115
|
|
|
113
116
|
# Usando yarn
|
|
114
|
-
yarn add mitre-form-component
|
|
117
|
+
yarn add mitre-form-component
|
|
115
118
|
|
|
116
119
|
# Usando pnpm
|
|
117
|
-
pnpm add mitre-form-component
|
|
120
|
+
pnpm add mitre-form-component
|
|
118
121
|
```
|
|
119
122
|
|
|
120
123
|
Depois de instalar a biblioteca, você pode começar a usá-la diretamente no seu projeto.
|
|
@@ -128,11 +131,10 @@ O `MitreFormComponent` aceita as seguintes props:
|
|
|
128
131
|
- **`products`** (array): Array de objetos contendo os produtos disponíveis. Cada produto deve ter `id` (number) e `name` (string).
|
|
129
132
|
- Se o array contém apenas 1 produto: o formulário usa automaticamente esse produto
|
|
130
133
|
- Se o array contém múltiplos produtos: é exibido um seletor para o usuário escolher
|
|
131
|
-
- **`
|
|
132
|
-
- **`apiToken`** (string): Token de autenticação da API.
|
|
134
|
+
- **`ambiente`** (opcional, `"homol" | "prod"`): Define de qual config interno o componente lê `apiUrl`, `apiToken`, `whatsappPhone` e `chatUrl`. Padrão: `"homol"`. Ver §"🌐 Ambiente".
|
|
133
135
|
- **`showHeader`** (opcional, boolean): Controla se o cabeçalho será mostrado. Padrão: `true`.
|
|
134
|
-
- **`title`** (opcional, string): Título do formulário. Padrão: `"Atendimento por mensagem"`.
|
|
135
|
-
- **`subtitle`** (opcional, string): Subtítulo do formulário. Padrão: `"Informe seus dados e retornaremos a mensagem."`.
|
|
136
|
+
- **`title`** (opcional, string): Título do formulário. Padrão: `"Atendimento por mensagem"`. **Quando `canal="whatsapp"` esta prop é ignorada e o título é forçado para `"Fale com um corretor por WhatsApp"`; quando `canal="chat"` é forçado para `"Fale com um corretor por chat"`** (ver §"Modos de submit").
|
|
137
|
+
- **`subtitle`** (opcional, string): Subtítulo do formulário. Padrão: `"Informe seus dados e retornaremos a mensagem."`. **Quando `canal="whatsapp"` ou `canal="chat"` esta prop é ignorada e o subtítulo é forçado para `"Informe seus dados para contato."`** (ver §"Modos de submit").
|
|
136
138
|
- **`backgroundColor`** (opcional, string): Cor de fundo do formulário. Padrão: `#CECECE`.
|
|
137
139
|
- **`textColor`** (opcional, string): Cor dos textos do cabeçalho, do label dos inputs e do texto de privacidade. Padrão: `#2F2F2F`.
|
|
138
140
|
- **`buttonBackgroundColor`** (opcional, string): Define a cor de fundo do botão. Padrão: `#F6C76B`.
|
|
@@ -143,9 +145,13 @@ O `MitreFormComponent` aceita as seguintes props:
|
|
|
143
145
|
- **`inputFocusBorderColor`** (opcional, string): Cor da borda do input quando selecionado. Padrão: `#F6C76B`.
|
|
144
146
|
- **`inputPlaceholderColor`** (opcional, string): Cor do placeholder do input. Padrão: `#B6B6B6`.
|
|
145
147
|
- **`inputTextColor`** (opcional, string): Cor do texto do input. Padrão: `#2F2F2F`.
|
|
146
|
-
- **`showPreferenciaContato`** (opcional, boolean): Exibe um campo de seleção "Preferência de Contato" com as opções `Whatsapp`, `Email` e `Ligação`. Quando selecionado, o valor é enviado à API como `preferencia_contato`. Padrão: `false`.
|
|
147
|
-
- **`
|
|
148
|
-
- **`
|
|
148
|
+
- **`showPreferenciaContato`** (opcional, boolean): Exibe um campo de seleção "Preferência de Contato" com as opções `Whatsapp`, `Email` e `Ligação`. Quando selecionado, o valor é enviado à API como `preferencia_contato`. Padrão: `false`. **Quando `canal="whatsapp"` esta prop é ignorada e tratada como `false`**, e o componente injeta `preferencia_contato: "Whatsapp"` automaticamente no body do POST (ver §"Modos de submit").
|
|
149
|
+
- **`canal`** (opcional, `"form" | "chat" | "whatsapp"`): Define o comportamento do submit. `"form"` (padrão) preserva o comportamento histórico (apenas POST `/leads`). `"chat"` e `"whatsapp"` continuam fazendo o POST `/leads` e, em sucesso, abrem o atendimento em **nova aba**. Ver seção "🔀 Modos de submit (`canal`)" abaixo. Padrão: `"form"`.
|
|
150
|
+
- **`idProdutoTerceiro`** (opcional, `string | number`): Repassado no body do POST `/leads` e no `virtual_obj` (modo chat) quando `canal !== "form"`.
|
|
151
|
+
- **`idEmpreendimento`** (opcional, `string | number`): Repassado no body do POST `/leads` e no `virtual_obj` (modo chat) quando `canal !== "form"`.
|
|
152
|
+
- **`naoCriarEvento`** (opcional, boolean): Se `true`, envia `naoCriarEvento: true` no body do POST `/leads` (e no `virtual_obj` no modo chat) para instruir o CRM a não criar evento associado ao lead. **Default automático:** `true` quando `canal === "chat"` ou `canal === "whatsapp"` (paridade com o fluxo antigo do `atendimento.html`); `false` quando `canal === "form"`. Passe `false` explicitamente para forçar a criação do evento mesmo em chat/whatsapp.
|
|
153
|
+
- **`onSuccess`** (opcional, função): Callback executado quando o POST `/leads` retorna sucesso, em qualquer canal. Recebe `(requestBody, leadId)`. Útil para tracking (GTM, Analytics), redirect customizado ou logging. O componente continua exibindo a UI de sucesso (mensagem em `canal=form`, modal em `canal=whatsapp`/`canal=chat`) independente do callback.
|
|
154
|
+
- **`onError`** (opcional, função): Callback executado quando o POST `/leads` falha. Recebe `Error`. Útil para tracking de erro (Sentry, Datadog, GTM). O componente continua exibindo a UI de erro independente do callback.
|
|
149
155
|
|
|
150
156
|
---
|
|
151
157
|
|
|
@@ -193,22 +199,120 @@ O campo é opcional: se o usuário não selecionar nenhuma opção, `preferencia
|
|
|
193
199
|
O enum `PreferenciaContato` é exportado pela biblioteca para uso externo, se necessário:
|
|
194
200
|
|
|
195
201
|
```tsx
|
|
196
|
-
import { MitreFormComponent, PreferenciaContato } from "mitre-form-component
|
|
202
|
+
import { MitreFormComponent, PreferenciaContato } from "mitre-form-component";
|
|
197
203
|
|
|
198
204
|
<MitreFormComponent
|
|
199
205
|
products={products}
|
|
200
|
-
|
|
201
|
-
apiToken={process.env.NEXT_PUBLIC_REGISTER_LEADS_TOKEN!}
|
|
206
|
+
ambiente="prod"
|
|
202
207
|
showPreferenciaContato={true}
|
|
203
|
-
onSuccess={(requestBody) => {
|
|
204
|
-
// requestBody.preferencia_contato estará presente se o usuário selecionou uma opção
|
|
205
|
-
console.log(requestBody.preferencia_contato); // ex: "Whatsapp"
|
|
206
|
-
}}
|
|
207
208
|
/>
|
|
208
209
|
```
|
|
209
210
|
|
|
210
211
|
---
|
|
211
212
|
|
|
213
|
+
## 🌐 Ambiente
|
|
214
|
+
|
|
215
|
+
A partir da v2.0, o componente gerencia internamente `apiUrl`, `apiToken`, `whatsappPhone` e `chatUrl`. A landing **não passa mais essas props** — apenas escolhe o ambiente:
|
|
216
|
+
|
|
217
|
+
```tsx
|
|
218
|
+
<MitreFormComponent products={products} ambiente="prod" /> // produção
|
|
219
|
+
<MitreFormComponent products={products} ambiente="homol" /> // homologação (padrão)
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Os valores de cada ambiente vivem em `src/config/environments.ts`. Mudanças nessas URLs/tokens exigem nova versão da lib publicada no npm e atualização das landings consumidoras.
|
|
223
|
+
|
|
224
|
+
| Ambiente | apiUrl | chatUrl |
|
|
225
|
+
|---|---|---|
|
|
226
|
+
| `"homol"` | `https://leads-hml.mitrerealty.com.br/api-leads` | `https://crm-hml.mitrerealty.com.br/wcc/UserLoginSubmit.do` |
|
|
227
|
+
| `"prod"` | `https://leads.mitrerealty.com.br/api-leads` | `https://crm.mitrerealty.com.br/wcc/UserLoginSubmit.do` |
|
|
228
|
+
|
|
229
|
+
Se `ambiente` for um valor desconhecido ou se os campos resolvidos vierem vazios, o componente exibe a tela genérica de erro ("Erro no carregamento do formulário!") no lugar do form.
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## 🔀 Modos de submit (`canal`)
|
|
234
|
+
|
|
235
|
+
Por padrão (`canal="form"`), ao enviar o formulário o componente faz apenas o `POST /leads` e exibe uma mensagem de sucesso — o consumidor continua na mesma página. **Esse é o comportamento histórico e segue inalterado para todos os usos atuais.**
|
|
236
|
+
|
|
237
|
+
Para casos em que, após salvar o lead, o usuário precisa ser direcionado para um canal de atendimento (chat ou WhatsApp), o componente expõe a prop `canal` com mais dois modos: `"chat"` e `"whatsapp"`. Nesses dois modos:
|
|
238
|
+
|
|
239
|
+
- O `POST /leads` é feito normalmente.
|
|
240
|
+
- Em sucesso, é exibido um **modal de confirmação** ("Cadastro realizado! Clique abaixo para continuar...") e o clique no botão do modal abre o atendimento **em uma nova aba**, mantendo a landing page do consumidor aberta.
|
|
241
|
+
- Em caso de falha no POST `/leads`, é exibido um **modal de erro** ("Não foi possível completar seu contato.") e a segunda aba **não é aberta**.
|
|
242
|
+
- O número do WhatsApp e a URL do chat vêm da config interna do `ambiente` selecionado — não precisam ser passados como props.
|
|
243
|
+
|
|
244
|
+
O tipo `Canal` é exportado pela biblioteca:
|
|
245
|
+
|
|
246
|
+
```tsx
|
|
247
|
+
import { MitreFormComponent, type Canal } from "mitre-form-component";
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Modo `"chat"`
|
|
251
|
+
|
|
252
|
+
Após salvar o lead, o botão do modal de sucesso submete (em nova aba) um POST `application/x-www-form-urlencoded` para a `chatUrl` do ambiente, com um único campo `virtual_obj` contendo o JSON do lead acrescido de `externalOriginId`, `pagina`, `idProdutoTerceiro`/`idEmpreendimento` (se informados) e `naoCriarEvento` (quando o flag efetivo é `true`).
|
|
253
|
+
|
|
254
|
+
```tsx
|
|
255
|
+
<MitreFormComponent
|
|
256
|
+
products={products}
|
|
257
|
+
ambiente="prod"
|
|
258
|
+
canal="chat"
|
|
259
|
+
idProdutoTerceiro={produto.idTerceiro}
|
|
260
|
+
idEmpreendimento={produto.id}
|
|
261
|
+
/>
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Modo `"whatsapp"`
|
|
265
|
+
|
|
266
|
+
Após salvar o lead, o botão do modal de sucesso abre `https://api.whatsapp.com/send?phone=<whatsappPhone>&text=...` em nova aba. A mensagem pré-preenchida é fixa: `"Olá! Tenho interesse e gostaria de mais informações."`.
|
|
267
|
+
|
|
268
|
+
```tsx
|
|
269
|
+
<MitreFormComponent
|
|
270
|
+
products={products}
|
|
271
|
+
ambiente="prod"
|
|
272
|
+
canal="whatsapp"
|
|
273
|
+
/>
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Campos extras enviados ao `/leads`
|
|
277
|
+
|
|
278
|
+
Quando `canal !== "form"`, o componente injeta automaticamente os seguintes campos no body do `POST /leads`:
|
|
279
|
+
|
|
280
|
+
| Campo | Quando | Origem |
|
|
281
|
+
|---|---|---|
|
|
282
|
+
| `canal` | sempre que `canal !== "form"` | valor da prop |
|
|
283
|
+
| `pagina` | sempre que `canal !== "form"` | `window.location.href` no momento do submit |
|
|
284
|
+
| `is_chat` | sempre que `canal !== "form"` (paridade com `atendimento.html` legado) | constante `true` |
|
|
285
|
+
| `idProdutoTerceiro` | se a prop foi informada | valor da prop |
|
|
286
|
+
| `idEmpreendimento` | se a prop foi informada | valor da prop |
|
|
287
|
+
| `naoCriarEvento` | quando o flag efetivo é `true` (default em chat/whatsapp; ver prop `naoCriarEvento`) | constante `true` |
|
|
288
|
+
| `preferencia_contato` | apenas em `canal === "whatsapp"` | constante `"Whatsapp"` (em `canal === "whatsapp"` e `canal === "chat"` a prop `showPreferenciaContato` é ignorada e o select não é exibido) |
|
|
289
|
+
|
|
290
|
+
Esses campos são aceitos pelo backend `api-leads` sem nenhuma alteração — o `LeadDTO` possui `@JsonAlias` para os campos conhecidos e `@JsonAnySetter` para o restante.
|
|
291
|
+
|
|
292
|
+
### Textos fixos em `canal="whatsapp"` e `canal="chat"`
|
|
293
|
+
|
|
294
|
+
Quando `canal="whatsapp"` ou `canal="chat"`, os seguintes textos do formulário são forçados, independente das props passadas:
|
|
295
|
+
|
|
296
|
+
| Elemento | `canal="whatsapp"` | `canal="chat"` |
|
|
297
|
+
|---|---|---|
|
|
298
|
+
| Título (prop `title`) | `"Fale com um corretor por WhatsApp"` | `"Fale com um corretor por chat"` |
|
|
299
|
+
| Subtítulo (prop `subtitle`) | `"Informe seus dados para contato."` | `"Informe seus dados para contato."` |
|
|
300
|
+
| Texto do botão de submit | `"Entrar"` | `"Entrar"` |
|
|
301
|
+
|
|
302
|
+
Paridade com o fluxo legado `atendimento.html` (título e botão), com subtítulo unificado entre os canais.
|
|
303
|
+
|
|
304
|
+
### Validações
|
|
305
|
+
|
|
306
|
+
Em render-time o componente valida:
|
|
307
|
+
|
|
308
|
+
- **Ambiente**: se a prop `ambiente` for desconhecida, ou se a config interna resolvida não tiver `apiUrl`/`apiToken` → tela genérica de erro.
|
|
309
|
+
- **canal=chat**: a `chatUrl` do ambiente precisa ser URL absoluta com protocolo `http(s)`; caso contrário, tela genérica de erro.
|
|
310
|
+
- **canal=whatsapp**: o `whatsappPhone` do ambiente precisa ser número válido segundo `google-libphonenumber`; caso contrário, tela genérica de erro.
|
|
311
|
+
|
|
312
|
+
Todas essas validações rodam **antes do submit** e substituem a renderização do formulário pela tela "Erro no carregamento do formulário!" + `console.error` técnico.
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
212
316
|
## 🚨 Componente dentro de um `ErrorBoundary`
|
|
213
317
|
|
|
214
318
|
Recomendamos que o componente `MitreFormComponent` seja sempre utilizado dentro de um `ErrorBoundary` para garantir que a aplicação não quebre em caso de falha no carregamento do componente. Também é preciso usar dynamic do next/dynamics para a importação.
|
|
@@ -221,7 +325,7 @@ import dynamic from "next/dynamic";
|
|
|
221
325
|
import { ErrorBoundary } from "react-error-boundary";
|
|
222
326
|
const MitreFormComponent = dynamic(
|
|
223
327
|
() =>
|
|
224
|
-
import("mitre-form-component
|
|
328
|
+
import("mitre-form-component").then((mod) => mod.MitreFormComponent),
|
|
225
329
|
{ ssr: false }
|
|
226
330
|
);
|
|
227
331
|
|
|
@@ -231,8 +335,7 @@ const MitreFormComponent = dynamic(
|
|
|
231
335
|
{ id: 1, name: "Apartamento 2 quartos" },
|
|
232
336
|
{ id: 2, name: "Casa 3 quartos" }
|
|
233
337
|
]}
|
|
234
|
-
|
|
235
|
-
apiToken={process.env.NEXT_PUBLIC_REGISTER_LEADS_TOKEN!}
|
|
338
|
+
ambiente="prod"
|
|
236
339
|
/>
|
|
237
340
|
</ErrorBoundary>;
|
|
238
341
|
```
|