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/dist/index.cjs CHANGED
@@ -36,7 +36,7 @@ __export(index_exports, {
36
36
  module.exports = __toCommonJS(index_exports);
37
37
 
38
38
  // src/components/Form/index.tsx
39
- var import_react7 = __toESM(require("react"), 1);
39
+ var import_react8 = __toESM(require("react"), 1);
40
40
 
41
41
  // src/components/hooks/useError.ts
42
42
  var import_react = require("react");
@@ -928,14 +928,181 @@ var Alert = ({
928
928
  );
929
929
  };
930
930
 
931
- // src/components/PhoneInput/index.tsx
931
+ // src/components/Modal/index.tsx
932
932
  var import_react5 = require("react");
933
+ var import_hi2 = require("react-icons/hi");
933
934
 
934
- // src/components/PhoneInput/styles.ts
935
+ // src/components/Modal/styles.ts
935
936
  var import_styled_components6 = __toESM(require("styled-components"), 1);
937
+ var fadeIn2 = import_styled_components6.keyframes`
938
+ from { opacity: 0; }
939
+ to { opacity: 1; }
940
+ `;
941
+ var slideIn = import_styled_components6.keyframes`
942
+ from { opacity: 0; transform: translateY(-20px) scale(0.96); }
943
+ to { opacity: 1; transform: translateY(0) scale(1); }
944
+ `;
945
+ var Overlay = import_styled_components6.default.div`
946
+ position: fixed;
947
+ inset: 0;
948
+ background: rgba(0, 0, 0, 0.55);
949
+ display: flex;
950
+ align-items: center;
951
+ justify-content: center;
952
+ z-index: 9999;
953
+ padding: 1rem;
954
+ animation: ${fadeIn2} 0.18s ease-out;
955
+ `;
956
+ var accentStyles = {
957
+ success: import_styled_components6.css`
958
+ color: ${theme.colors.green2};
959
+ `,
960
+ error: import_styled_components6.css`
961
+ color: ${theme.colors.red};
962
+ `
963
+ };
964
+ var Container = import_styled_components6.default.div`
965
+ position: relative;
966
+ background: ${theme.colors.white};
967
+ border-radius: 0.75rem;
968
+ box-shadow: ${theme.shadows.shadow500};
969
+ max-width: 420px;
970
+ width: 100%;
971
+ padding: 1.75rem 1.5rem 1.25rem;
972
+ font-family: ${theme.fonts.primary};
973
+ animation: ${slideIn} 0.22s ease-out;
974
+
975
+ &::before {
976
+ content: "";
977
+ display: block;
978
+ width: 56px;
979
+ height: 4px;
980
+ border-radius: 999px;
981
+ margin: 0 auto 1rem;
982
+ background: ${({ $type }) => $type === "success" ? theme.colors.green2 : theme.colors.red};
983
+ }
984
+
985
+ h2 {
986
+ margin: 0 0 0.5rem;
987
+ font-size: 1.25rem;
988
+ font-weight: 700;
989
+ text-align: center;
990
+ ${({ $type }) => accentStyles[$type]}
991
+ }
992
+
993
+ p {
994
+ margin: 0 0 1.5rem;
995
+ font-size: 0.95rem;
996
+ line-height: 1.45;
997
+ text-align: center;
998
+ color: ${theme.colors.black};
999
+ }
1000
+ `;
1001
+ var CloseButton = import_styled_components6.default.button`
1002
+ position: absolute;
1003
+ top: 0.5rem;
1004
+ right: 0.5rem;
1005
+ background: transparent;
1006
+ border: none;
1007
+ cursor: pointer;
1008
+ color: ${theme.colors.gray550};
1009
+ padding: 0.25rem;
1010
+ display: inline-flex;
1011
+ align-items: center;
1012
+ justify-content: center;
1013
+ border-radius: 999px;
1014
+ transition: background 0.15s, color 0.15s;
1015
+
1016
+ &:hover {
1017
+ background: ${theme.colors.gray300};
1018
+ color: ${theme.colors.black};
1019
+ }
1020
+
1021
+ svg {
1022
+ width: 1.1rem;
1023
+ height: 1.1rem;
1024
+ }
1025
+ `;
1026
+ var PrimaryButton = import_styled_components6.default.button`
1027
+ display: block;
1028
+ width: 100%;
1029
+ padding: 0.75rem 1rem;
1030
+ border: none;
1031
+ border-radius: 0.5rem;
1032
+ background: ${({ $bgColor }) => $bgColor || theme.colors.yellow500};
1033
+ color: ${({ $textColor }) => $textColor || theme.colors.black};
1034
+ font-family: ${theme.fonts.primary};
1035
+ font-size: 1rem;
1036
+ font-weight: 700;
1037
+ cursor: pointer;
1038
+ transition: filter 0.15s;
1039
+
1040
+ &:hover {
1041
+ filter: brightness(0.95);
1042
+ }
1043
+
1044
+ &:focus-visible {
1045
+ outline: 2px solid ${theme.colors.yellow400};
1046
+ outline-offset: 2px;
1047
+ }
1048
+ `;
1049
+
1050
+ // src/components/Modal/index.tsx
1051
+ var import_jsx_runtime4 = require("react/jsx-runtime");
1052
+ var Modal = ({
1053
+ type,
1054
+ title,
1055
+ message,
1056
+ primaryButtonText,
1057
+ onPrimaryAction,
1058
+ onClose,
1059
+ primaryButtonBgColor,
1060
+ primaryButtonTextColor
1061
+ }) => {
1062
+ const primaryButtonRef = (0, import_react5.useRef)(null);
1063
+ (0, import_react5.useEffect)(() => {
1064
+ primaryButtonRef.current?.focus();
1065
+ }, []);
1066
+ (0, import_react5.useEffect)(() => {
1067
+ const handleKey = (event) => {
1068
+ if (event.key === "Escape") {
1069
+ onClose();
1070
+ }
1071
+ };
1072
+ document.addEventListener("keydown", handleKey);
1073
+ return () => document.removeEventListener("keydown", handleKey);
1074
+ }, [onClose]);
1075
+ const handleOverlayClick = (event) => {
1076
+ if (event.target === event.currentTarget) {
1077
+ onClose();
1078
+ }
1079
+ };
1080
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Overlay, { onClick: handleOverlayClick, role: "dialog", "aria-modal": "true", "aria-label": title, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Container, { $type: type, children: [
1081
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CloseButton, { onClick: onClose, "aria-label": "Fechar", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_hi2.HiX, {}) }),
1082
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { children: title }),
1083
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { children: message }),
1084
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1085
+ PrimaryButton,
1086
+ {
1087
+ ref: primaryButtonRef,
1088
+ onClick: onPrimaryAction,
1089
+ $bgColor: primaryButtonBgColor,
1090
+ $textColor: primaryButtonTextColor,
1091
+ type: "button",
1092
+ children: primaryButtonText
1093
+ }
1094
+ )
1095
+ ] }) });
1096
+ };
1097
+
1098
+ // src/components/PhoneInput/index.tsx
1099
+ var import_react6 = require("react");
1100
+
1101
+ // src/components/PhoneInput/styles.ts
1102
+ var import_styled_components7 = __toESM(require("styled-components"), 1);
936
1103
  var import_react_international_phone = require("react-international-phone");
937
1104
  var import_style = require("react-international-phone/style.css");
938
- var FormLabel3 = import_styled_components6.default.label`
1105
+ var FormLabel3 = import_styled_components7.default.label`
939
1106
  font-family: ${theme.fonts.primary};
940
1107
  font-style: normal;
941
1108
  font-weight: 500;
@@ -945,7 +1112,7 @@ var FormLabel3 = import_styled_components6.default.label`
945
1112
  margin-bottom: 0.5rem;
946
1113
  text-align: left;
947
1114
  `;
948
- var StyledPhoneInput = (0, import_styled_components6.default)(import_react_international_phone.PhoneInput)`
1115
+ var StyledPhoneInput = (0, import_styled_components7.default)(import_react_international_phone.PhoneInput)`
949
1116
  width: 100%;
950
1117
  height: 3.125rem;
951
1118
  background: ${(props) => props.$backgroundColor || theme.colors.white};
@@ -1059,24 +1226,24 @@ var StyledPhoneInput = (0, import_styled_components6.default)(import_react_inter
1059
1226
  }
1060
1227
  }
1061
1228
  `;
1062
- var FormErrorMessage3 = import_styled_components6.default.small`
1229
+ var FormErrorMessage3 = import_styled_components7.default.small`
1063
1230
  font-size: 0.75rem;
1064
1231
  line-height: 1.125rem;
1065
1232
  color: ${theme.colors.red};
1066
1233
  margin-top: 0.25rem;
1067
1234
  display: block;
1068
1235
  `;
1069
- var FormControl3 = import_styled_components6.default.div.withConfig({
1236
+ var FormControl3 = import_styled_components7.default.div.withConfig({
1070
1237
  shouldForwardProp: (prop) => !["isInvalid"].includes(prop)
1071
1238
  })`
1072
1239
  ${FormLabel3} {
1073
- ${(props) => props.isInvalid && import_styled_components6.css`
1240
+ ${(props) => props.isInvalid && import_styled_components7.css`
1074
1241
  color: ${theme.colors.red};
1075
1242
  `};
1076
1243
  }
1077
1244
 
1078
1245
  ${StyledPhoneInput} {
1079
- ${(props) => props.isInvalid && import_styled_components6.css`
1246
+ ${(props) => props.isInvalid && import_styled_components7.css`
1080
1247
  border: 1px solid ${theme.colors.red};
1081
1248
 
1082
1249
  &:not(:focus)::placeholder {
@@ -1086,7 +1253,7 @@ var FormControl3 = import_styled_components6.default.div.withConfig({
1086
1253
  `};
1087
1254
 
1088
1255
  .react-international-phone-input-container {
1089
- ${(props) => props.isInvalid && import_styled_components6.css`
1256
+ ${(props) => props.isInvalid && import_styled_components7.css`
1090
1257
  border: 1px solid ${theme.colors.red};
1091
1258
 
1092
1259
  &:not(:focus)::placeholder {
@@ -1097,7 +1264,7 @@ var FormControl3 = import_styled_components6.default.div.withConfig({
1097
1264
  }
1098
1265
 
1099
1266
  .react-international-phone-country-selector-button {
1100
- ${(props) => props.isInvalid && import_styled_components6.css`
1267
+ ${(props) => props.isInvalid && import_styled_components7.css`
1101
1268
  border-right: 1px solid ${theme.colors.red};
1102
1269
  `};
1103
1270
  }
@@ -1105,7 +1272,7 @@ var FormControl3 = import_styled_components6.default.div.withConfig({
1105
1272
  `;
1106
1273
 
1107
1274
  // src/components/PhoneInput/index.tsx
1108
- var import_jsx_runtime4 = require("react/jsx-runtime");
1275
+ var import_jsx_runtime5 = require("react/jsx-runtime");
1109
1276
  var PhoneInputBase = ({
1110
1277
  id,
1111
1278
  label,
@@ -1120,9 +1287,9 @@ var PhoneInputBase = ({
1120
1287
  value,
1121
1288
  ...rest
1122
1289
  }, ref) => {
1123
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(FormControl3, { isInvalid: !!error, children: [
1124
- !!label && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FormLabel3, { htmlFor: id, $textColor: labelTextColor, children: label }),
1125
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1290
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(FormControl3, { isInvalid: !!error, children: [
1291
+ !!label && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(FormLabel3, { htmlFor: id, $textColor: labelTextColor, children: label }),
1292
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1126
1293
  StyledPhoneInput,
1127
1294
  {
1128
1295
  ref,
@@ -1156,14 +1323,14 @@ var PhoneInputBase = ({
1156
1323
  $textColor: inputTextColor
1157
1324
  }
1158
1325
  ),
1159
- !!error && showErrorMessage && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FormErrorMessage3, { "data-testid": "error-message", children: typeof error === "string" ? error : error?.message })
1326
+ !!error && showErrorMessage && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(FormErrorMessage3, { "data-testid": "error-message", children: typeof error === "string" ? error : error?.message })
1160
1327
  ] });
1161
1328
  };
1162
- var PhoneInput2 = (0, import_react5.forwardRef)(PhoneInputBase);
1329
+ var PhoneInput2 = (0, import_react6.forwardRef)(PhoneInputBase);
1163
1330
 
1164
1331
  // src/components/ProductSelect/index.tsx
1165
- var import_react6 = require("react");
1166
- var import_jsx_runtime5 = require("react/jsx-runtime");
1332
+ var import_react7 = require("react");
1333
+ var import_jsx_runtime6 = require("react/jsx-runtime");
1167
1334
  var ProductSelectBase = ({
1168
1335
  id,
1169
1336
  label,
@@ -1178,9 +1345,9 @@ var ProductSelectBase = ({
1178
1345
  placeholder = "Selecione um produto",
1179
1346
  ...rest
1180
1347
  }, ref) => {
1181
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(FormControl, { isInvalid: !!error, children: [
1182
- !!label && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(FormLabel, { htmlFor: id, $textColor: labelTextColor, children: label }),
1183
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1348
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(FormControl, { isInvalid: !!error, children: [
1349
+ !!label && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FormLabel, { htmlFor: id, $textColor: labelTextColor, children: label }),
1350
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1184
1351
  Select,
1185
1352
  {
1186
1353
  id,
@@ -1192,18 +1359,37 @@ var ProductSelectBase = ({
1192
1359
  $textColor: textColor,
1193
1360
  ...rest,
1194
1361
  children: [
1195
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "", disabled: true, children: placeholder }),
1196
- products.map((product) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: product.id, children: product.name }, product.id))
1362
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: "", disabled: true, children: placeholder }),
1363
+ products.map((product) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: product.id, children: product.name }, product.id))
1197
1364
  ]
1198
1365
  }
1199
1366
  ),
1200
- !!error && showErrorMessage && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(FormErrorMessage, { "data-testid": "error-message", children: typeof error === "string" ? error : error.message })
1367
+ !!error && showErrorMessage && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FormErrorMessage, { "data-testid": "error-message", children: typeof error === "string" ? error : error.message })
1201
1368
  ] });
1202
1369
  };
1203
- var ProductSelect = (0, import_react6.forwardRef)(ProductSelectBase);
1370
+ var ProductSelect = (0, import_react7.forwardRef)(ProductSelectBase);
1371
+
1372
+ // src/config/environments.ts
1373
+ var ENVIRONMENTS = {
1374
+ homol: {
1375
+ apiUrl: "https://leads-hml.mitrerealty.com.br/api-leads",
1376
+ apiToken: "TEFORElOR19NSVRSRTptZlFXZnhvUHdNbWVZY0FidkF0QWJ3Q2RFYWtKckJBOXg5cGNsOTBvS1V0N2ZsU0d4TEtNdEZZd3k0NFlEc0c3",
1377
+ whatsappPhone: "551148100601",
1378
+ chatUrl: "https://crm-hml.mitrerealty.com.br/wcc/UserLoginSubmit.do"
1379
+ },
1380
+ prod: {
1381
+ apiUrl: "https://leads.mitrerealty.com.br/api-leads",
1382
+ apiToken: "TEFORElOR19NSVRSRTptZlFXZnhvUHdNbWVZY0FidkF0QWJ3Q2RFYWtKckJBOXg5cGNsOTBvS1V0N2ZsU0d4TEtNdEZZd3k0NFlEc0c3",
1383
+ whatsappPhone: "551148100601",
1384
+ chatUrl: "https://crm.mitrerealty.com.br/wcc/UserLoginSubmit.do"
1385
+ }
1386
+ };
1387
+ var resolveEnvironment = (ambiente = "homol") => {
1388
+ return ENVIRONMENTS[ambiente] ?? null;
1389
+ };
1204
1390
 
1205
1391
  // src/components/Form/index.tsx
1206
- var import_jsx_runtime6 = require("react/jsx-runtime");
1392
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1207
1393
  var phoneUtil = import_google_libphonenumber.PhoneNumberUtil.getInstance();
1208
1394
  var PreferenciaContato = /* @__PURE__ */ ((PreferenciaContato2) => {
1209
1395
  PreferenciaContato2["Whatsapp"] = "Whatsapp";
@@ -1211,6 +1397,40 @@ var PreferenciaContato = /* @__PURE__ */ ((PreferenciaContato2) => {
1211
1397
  PreferenciaContato2["Ligacao"] = "Liga\xE7\xE3o";
1212
1398
  return PreferenciaContato2;
1213
1399
  })(PreferenciaContato || {});
1400
+ var WHATSAPP_MESSAGE = "Ol\xE1! Tenho interesse e gostaria de mais informa\xE7\xF5es.";
1401
+ var WHATSAPP_TITLE = "Fale com um corretor por WhatsApp";
1402
+ var WHATSAPP_SUBTITLE = "Informe seus dados para contato.";
1403
+ var WHATSAPP_BUTTON_TEXT = "Entrar";
1404
+ var CHAT_TITLE = "Fale com um corretor por chat";
1405
+ var CHAT_SUBTITLE = "Informe seus dados para contato.";
1406
+ var CHAT_BUTTON_TEXT = "Entrar";
1407
+ var MODAL_ERROR_TITLE = "N\xE3o foi poss\xEDvel completar seu contato";
1408
+ var MODAL_ERROR_MESSAGE = "Por favor, tente novamente em alguns instantes.";
1409
+ var MODAL_ERROR_BUTTON_TEXT = "OK";
1410
+ var MODAL_SUCCESS_TITLE = "Cadastro realizado!";
1411
+ var MODAL_SUCCESS_MESSAGE_WHATSAPP = "Clique abaixo para continuar pelo WhatsApp.";
1412
+ var MODAL_SUCCESS_BUTTON_WHATSAPP = "Abrir WhatsApp";
1413
+ var MODAL_SUCCESS_MESSAGE_CHAT = "Clique abaixo para iniciar o atendimento.";
1414
+ var MODAL_SUCCESS_BUTTON_CHAT = "Iniciar atendimento";
1415
+ function buildWhatsappUrl(phone) {
1416
+ const digits = phone.replace(/\D/g, "");
1417
+ const text = encodeURIComponent(WHATSAPP_MESSAGE);
1418
+ return `https://api.whatsapp.com/send?phone=${digits}&text=${text}`;
1419
+ }
1420
+ function submitChatInNewTab(chatUrl, virtualObj) {
1421
+ const form = document.createElement("form");
1422
+ form.method = "POST";
1423
+ form.action = chatUrl;
1424
+ form.target = "_blank";
1425
+ const input = document.createElement("input");
1426
+ input.type = "hidden";
1427
+ input.name = "virtual_obj";
1428
+ input.value = JSON.stringify(virtualObj);
1429
+ form.appendChild(input);
1430
+ document.body.appendChild(form);
1431
+ form.submit();
1432
+ document.body.removeChild(form);
1433
+ }
1214
1434
  var isPhoneValid = (phone) => {
1215
1435
  try {
1216
1436
  return phoneUtil.isValidNumber(phoneUtil.parseAndKeepRawInput(phone));
@@ -1240,10 +1460,10 @@ var schemaWithProduct = yup.object().shape({
1240
1460
  productId: yup.string().required("Produto \xE9 obrigat\xF3rio")
1241
1461
  });
1242
1462
  var schema = yup.object().shape(baseSchema);
1243
- var MitreFormComponent = import_react7.default.forwardRef(({
1463
+ var MitreFormComponent = import_react8.default.forwardRef(({
1244
1464
  products,
1245
- apiUrl,
1246
- apiToken,
1465
+ ambiente = "homol",
1466
+ canal = "form",
1247
1467
  showHeader = true,
1248
1468
  title = "Atendimento por mensagem",
1249
1469
  subtitle = "Informe seus dados e retornaremos a mensagem.",
@@ -1258,15 +1478,19 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1258
1478
  inputPlaceholderColor = theme.colors.gray100,
1259
1479
  inputTextColor = theme.colors.black,
1260
1480
  showPreferenciaContato = false,
1481
+ idProdutoTerceiro,
1482
+ idEmpreendimento,
1483
+ naoCriarEvento,
1261
1484
  onSuccess,
1262
1485
  onError
1263
1486
  }, ref) => {
1264
1487
  useMontserratFont();
1265
- const [loading, setIsLoading] = (0, import_react7.useState)(false);
1488
+ const [loading, setIsLoading] = (0, import_react8.useState)(false);
1266
1489
  const { error, handleError, clearError } = useError();
1267
- const [successMessage, setSuccessMessage] = (0, import_react7.useState)("");
1268
- const [formKey, setFormKey] = (0, import_react7.useState)(0);
1269
- const [selectedProductId, setSelectedProductId] = (0, import_react7.useState)(null);
1490
+ const [successMessage, setSuccessMessage] = (0, import_react8.useState)("");
1491
+ const [formKey, setFormKey] = (0, import_react8.useState)(0);
1492
+ const [selectedProductId, setSelectedProductId] = (0, import_react8.useState)(null);
1493
+ const [actionModal, setActionModal] = (0, import_react8.useState)(null);
1270
1494
  const validateProducts = () => {
1271
1495
  if (!products) {
1272
1496
  return "Lista de produtos n\xE3o foi fornecida";
@@ -1291,14 +1515,60 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1291
1515
  }
1292
1516
  return null;
1293
1517
  };
1518
+ const env = resolveEnvironment(ambiente);
1519
+ const validateAmbienteConfig = () => {
1520
+ if (!env) {
1521
+ return `ambiente='${ambiente}' n\xE3o \xE9 reconhecido. Use 'homol' ou 'prod'.`;
1522
+ }
1523
+ if (!env.apiUrl || !env.apiToken) {
1524
+ return `Configura\xE7\xE3o interna do ambiente '${ambiente}' est\xE1 incompleta (apiUrl/apiToken).`;
1525
+ }
1526
+ return null;
1527
+ };
1528
+ const validateWhatsappConfig = () => {
1529
+ if (canal !== "whatsapp") return null;
1530
+ if (!env) return null;
1531
+ const raw = env.whatsappPhone?.trim() ?? "";
1532
+ if (!raw) {
1533
+ return `canal='whatsapp' exige whatsappPhone no ambiente '${ambiente}'.`;
1534
+ }
1535
+ const normalized = raw.startsWith("+") ? raw : `+${raw}`;
1536
+ if (!isPhoneValid(normalized)) {
1537
+ return `whatsappPhone do ambiente '${ambiente}' \xE9 inv\xE1lido (${JSON.stringify(env.whatsappPhone)}).`;
1538
+ }
1539
+ return null;
1540
+ };
1541
+ const validateChatConfig = () => {
1542
+ if (canal !== "chat") return null;
1543
+ if (!env) return null;
1544
+ const raw = env.chatUrl?.trim() ?? "";
1545
+ if (!raw) {
1546
+ return `canal='chat' exige chatUrl no ambiente '${ambiente}'.`;
1547
+ }
1548
+ try {
1549
+ const parsed = new URL(raw);
1550
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
1551
+ return `chatUrl do ambiente '${ambiente}' precisa ter protocolo http(s) (recebido: ${JSON.stringify(env.chatUrl)}).`;
1552
+ }
1553
+ } catch {
1554
+ return `chatUrl do ambiente '${ambiente}' n\xE3o \xE9 URL absoluta v\xE1lida (recebido: ${JSON.stringify(env.chatUrl)}).`;
1555
+ }
1556
+ return null;
1557
+ };
1294
1558
  const productsValidationError = validateProducts();
1295
- const [utm, setUtm] = (0, import_react7.useState)({ utm_source: "direto", createdAt: (/* @__PURE__ */ new Date()).toISOString() });
1559
+ const ambienteConfigError = validateAmbienteConfig();
1560
+ const whatsappConfigError = validateWhatsappConfig();
1561
+ const chatConfigError = validateChatConfig();
1562
+ const effectiveShowPreferenciaContato = canal === "whatsapp" || canal === "chat" ? false : showPreferenciaContato;
1563
+ const effectiveTitle = canal === "whatsapp" ? WHATSAPP_TITLE : canal === "chat" ? CHAT_TITLE : title;
1564
+ const effectiveSubtitle = canal === "whatsapp" ? WHATSAPP_SUBTITLE : canal === "chat" ? CHAT_SUBTITLE : subtitle;
1565
+ const [utm, setUtm] = (0, import_react8.useState)({ utm_source: "direto", createdAt: (/* @__PURE__ */ new Date()).toISOString() });
1296
1566
  const formSchema = products && products.length > 1 ? schemaWithProduct : schema;
1297
1567
  const { control, register, handleSubmit, formState: { errors }, reset, clearErrors } = (0, import_react_hook_form.useForm)({
1298
1568
  resolver: (0, import_yup.yupResolver)(formSchema),
1299
1569
  mode: "onSubmit"
1300
1570
  });
1301
- import_react7.default.useEffect(() => {
1571
+ import_react8.default.useEffect(() => {
1302
1572
  if (!isBrowser()) return;
1303
1573
  const { data } = resolveUtmWithPriority(/* @__PURE__ */ new Date());
1304
1574
  setUtm(data);
@@ -1330,9 +1600,13 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1330
1600
  const phoneValue = phone.inputValue;
1331
1601
  const phoneDigitsOnly = phoneValue?.replace(/\D/g, "") || "";
1332
1602
  const message = "Gostaria de mais informa\xE7\xF5es sobre o produto";
1603
+ setActionModal(null);
1333
1604
  try {
1334
1605
  setIsLoading(true);
1335
- if (!products || products.length === 0 || !apiToken) {
1606
+ if (!env) {
1607
+ throw new Error("Ambiente n\xE3o resolvido");
1608
+ }
1609
+ if (!products || products.length === 0) {
1336
1610
  throw new Error("Par\xE2metros obrigat\xF3rios n\xE3o informados");
1337
1611
  }
1338
1612
  let selectedProduct;
@@ -1348,6 +1622,8 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1348
1622
  }
1349
1623
  selectedProduct = foundProduct;
1350
1624
  }
1625
+ const paginaAtual = typeof window !== "undefined" ? window.location.href : void 0;
1626
+ const naoCriarEventoEfetivo = canal !== "form" && (naoCriarEvento ?? true);
1351
1627
  const requestBody = {
1352
1628
  name,
1353
1629
  email,
@@ -1358,13 +1634,23 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1358
1634
  utm_campaign: utm.utm_campaign,
1359
1635
  utm_medium: utm.utm_medium,
1360
1636
  utm_term: utm.utm_term,
1361
- ...showPreferenciaContato && preferencia_contato ? { preferencia_contato } : {}
1637
+ ...canal === "whatsapp" ? { preferencia_contato: "Whatsapp" /* Whatsapp */ } : effectiveShowPreferenciaContato && preferencia_contato ? { preferencia_contato } : {},
1638
+ ...canal !== "form" ? {
1639
+ canal,
1640
+ ...paginaAtual ? { pagina: paginaAtual } : {},
1641
+ // Paridade com atendimento.html legado: o mesmo <form id="chat-form">
1642
+ // era usado para chat e whatsapp, portanto is_chat=true ia em ambos.
1643
+ is_chat: true,
1644
+ ...idProdutoTerceiro !== void 0 ? { idProdutoTerceiro } : {},
1645
+ ...idEmpreendimento !== void 0 ? { idEmpreendimento } : {},
1646
+ ...naoCriarEventoEfetivo ? { naoCriarEvento: true } : {}
1647
+ } : {}
1362
1648
  };
1363
- const response = await fetch(`${apiUrl}/leads`, {
1649
+ const response = await fetch(`${env.apiUrl}/leads`, {
1364
1650
  method: "POST",
1365
1651
  headers: {
1366
1652
  "Content-Type": "application/json",
1367
- Authorization: `Basic ${apiToken}`
1653
+ Authorization: `Basic ${env.apiToken}`
1368
1654
  },
1369
1655
  body: JSON.stringify(requestBody)
1370
1656
  });
@@ -1373,26 +1659,64 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1373
1659
  }
1374
1660
  const responseData = await response.json();
1375
1661
  const leadId = responseData.leadId || responseData.id || "";
1376
- setSuccessMessage("Mensagem enviada com sucesso!");
1377
1662
  resetForm();
1378
1663
  onSuccess?.(requestBody, leadId);
1664
+ if (canal === "whatsapp") {
1665
+ setActionModal({
1666
+ kind: "success",
1667
+ canal: "whatsapp",
1668
+ targetUrl: buildWhatsappUrl(env.whatsappPhone)
1669
+ });
1670
+ } else if (canal === "chat") {
1671
+ const virtualObj = {
1672
+ ...requestBody,
1673
+ externalOriginId: leadId,
1674
+ ...paginaAtual ? { pagina: paginaAtual } : {},
1675
+ ...idProdutoTerceiro !== void 0 ? { idProdutoTerceiro } : {},
1676
+ ...idEmpreendimento !== void 0 ? { idEmpreendimento } : {},
1677
+ ...naoCriarEventoEfetivo ? { naoCriarEvento: true } : {}
1678
+ };
1679
+ setActionModal({
1680
+ kind: "success",
1681
+ canal: "chat",
1682
+ chatUrl: env.chatUrl,
1683
+ virtualObj
1684
+ });
1685
+ } else {
1686
+ setSuccessMessage("Mensagem enviada com sucesso!");
1687
+ }
1379
1688
  } catch (err) {
1380
1689
  const error2 = err instanceof Error ? err : new Error("Erro desconhecido");
1381
- handleError(err);
1690
+ if (canal === "whatsapp" || canal === "chat") {
1691
+ setActionModal({ kind: "error" });
1692
+ } else {
1693
+ handleError(err);
1694
+ }
1382
1695
  onError?.(error2);
1383
1696
  } finally {
1384
1697
  setIsLoading(false);
1385
1698
  }
1386
1699
  };
1387
- if (productsValidationError) {
1388
- console.error("Erro na valida\xE7\xE3o dos produtos:", productsValidationError);
1389
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FormContainer, { $backgroundColor: backgroundColor, $innerPadding: innerPadding, ref, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(HeaderContainer, { children: [
1390
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Title, { $textColor: textColor, children: "Erro no carregamento do formul\xE1rio!" }),
1391
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Subtitle, { $textColor: textColor, children: "N\xE3o foi poss\xEDvel carregar o formul\xE1rio. Tente novamente mais tarde." })
1700
+ if (productsValidationError || ambienteConfigError || whatsappConfigError || chatConfigError) {
1701
+ if (productsValidationError) {
1702
+ console.error("Erro na valida\xE7\xE3o dos produtos:", productsValidationError);
1703
+ }
1704
+ if (ambienteConfigError) {
1705
+ console.error("Erro na valida\xE7\xE3o do ambiente:", ambienteConfigError);
1706
+ }
1707
+ if (whatsappConfigError) {
1708
+ console.error("Erro na valida\xE7\xE3o do canal whatsapp:", whatsappConfigError);
1709
+ }
1710
+ if (chatConfigError) {
1711
+ console.error("Erro na valida\xE7\xE3o do canal chat:", chatConfigError);
1712
+ }
1713
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FormContainer, { $backgroundColor: backgroundColor, $innerPadding: innerPadding, ref, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(HeaderContainer, { children: [
1714
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Title, { $textColor: textColor, children: "Erro no carregamento do formul\xE1rio!" }),
1715
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Subtitle, { $textColor: textColor, children: "N\xE3o foi poss\xEDvel carregar o formul\xE1rio. Tente novamente mais tarde." })
1392
1716
  ] }) });
1393
1717
  }
1394
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1395
- error && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1718
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
1719
+ error && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1396
1720
  Alert,
1397
1721
  {
1398
1722
  type: "error",
@@ -1402,7 +1726,7 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1402
1726
  children: error.message
1403
1727
  }
1404
1728
  ),
1405
- successMessage && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1729
+ successMessage && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1406
1730
  Alert,
1407
1731
  {
1408
1732
  type: "success",
@@ -1412,13 +1736,58 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1412
1736
  children: successMessage
1413
1737
  }
1414
1738
  ),
1415
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(FormContainer, { $backgroundColor: backgroundColor, $innerPadding: innerPadding, ref, children: [
1416
- showHeader && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(HeaderContainer, { children: [
1417
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Title, { $textColor: textColor, children: title }),
1418
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Subtitle, { $textColor: textColor, children: subtitle })
1739
+ actionModal?.kind === "error" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1740
+ Modal,
1741
+ {
1742
+ type: "error",
1743
+ title: MODAL_ERROR_TITLE,
1744
+ message: MODAL_ERROR_MESSAGE,
1745
+ primaryButtonText: MODAL_ERROR_BUTTON_TEXT,
1746
+ onPrimaryAction: () => setActionModal(null),
1747
+ onClose: () => setActionModal(null),
1748
+ primaryButtonBgColor: buttonBackgroundColor,
1749
+ primaryButtonTextColor: buttonTextColor
1750
+ }
1751
+ ),
1752
+ actionModal?.kind === "success" && actionModal.canal === "whatsapp" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1753
+ Modal,
1754
+ {
1755
+ type: "success",
1756
+ title: MODAL_SUCCESS_TITLE,
1757
+ message: MODAL_SUCCESS_MESSAGE_WHATSAPP,
1758
+ primaryButtonText: MODAL_SUCCESS_BUTTON_WHATSAPP,
1759
+ onPrimaryAction: () => {
1760
+ window.open(actionModal.targetUrl, "_blank", "noopener,noreferrer");
1761
+ setActionModal(null);
1762
+ },
1763
+ onClose: () => setActionModal(null),
1764
+ primaryButtonBgColor: buttonBackgroundColor,
1765
+ primaryButtonTextColor: buttonTextColor
1766
+ }
1767
+ ),
1768
+ actionModal?.kind === "success" && actionModal.canal === "chat" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1769
+ Modal,
1770
+ {
1771
+ type: "success",
1772
+ title: MODAL_SUCCESS_TITLE,
1773
+ message: MODAL_SUCCESS_MESSAGE_CHAT,
1774
+ primaryButtonText: MODAL_SUCCESS_BUTTON_CHAT,
1775
+ onPrimaryAction: () => {
1776
+ submitChatInNewTab(actionModal.chatUrl, actionModal.virtualObj);
1777
+ setActionModal(null);
1778
+ },
1779
+ onClose: () => setActionModal(null),
1780
+ primaryButtonBgColor: buttonBackgroundColor,
1781
+ primaryButtonTextColor: buttonTextColor
1782
+ }
1783
+ ),
1784
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(FormContainer, { $backgroundColor: backgroundColor, $innerPadding: innerPadding, ref, children: [
1785
+ showHeader && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(HeaderContainer, { children: [
1786
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Title, { $textColor: textColor, children: effectiveTitle }),
1787
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Subtitle, { $textColor: textColor, children: effectiveSubtitle })
1419
1788
  ] }),
1420
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Form, { $textColor: textColor, onSubmit: handleSubmit(sendMessage), noValidate: true, children: [
1421
- products.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1789
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Form, { $textColor: textColor, onSubmit: handleSubmit(sendMessage), noValidate: true, children: [
1790
+ products.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1422
1791
  ProductSelect,
1423
1792
  {
1424
1793
  id: "productId",
@@ -1435,7 +1804,7 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1435
1804
  textColor: inputTextColor
1436
1805
  }
1437
1806
  ),
1438
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1807
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1439
1808
  Input2,
1440
1809
  {
1441
1810
  id: "name",
@@ -1453,7 +1822,7 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1453
1822
  inputTextColor
1454
1823
  }
1455
1824
  ),
1456
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1825
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1457
1826
  Input2,
1458
1827
  {
1459
1828
  id: "email",
@@ -1472,7 +1841,7 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1472
1841
  inputTextColor
1473
1842
  }
1474
1843
  ),
1475
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1844
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1476
1845
  import_react_hook_form.Controller,
1477
1846
  {
1478
1847
  name: "phone",
@@ -1481,7 +1850,7 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1481
1850
  shouldUnregister: true,
1482
1851
  render: ({ field }) => {
1483
1852
  const errorMsg = errors.phone?.inputValue?.message || errors.phone?.phone?.message || errors.phone?.message;
1484
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1853
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1485
1854
  PhoneInput2,
1486
1855
  {
1487
1856
  id: "phone",
@@ -1504,9 +1873,9 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1504
1873
  },
1505
1874
  formKey
1506
1875
  ),
1507
- showPreferenciaContato && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(FormControl, { isInvalid: !!errors.preferencia_contato, children: [
1508
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FormLabel, { htmlFor: "preferencia_contato", $textColor: textColor, children: "Prefer\xEAncia de Contato" }),
1509
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1876
+ effectiveShowPreferenciaContato && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(FormControl, { isInvalid: !!errors.preferencia_contato, children: [
1877
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FormLabel, { htmlFor: "preferencia_contato", $textColor: textColor, children: "Prefer\xEAncia de Contato" }),
1878
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1510
1879
  Select,
1511
1880
  {
1512
1881
  id: "preferencia_contato",
@@ -1517,19 +1886,19 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1517
1886
  $focusBorderColor: inputFocusBorderColor,
1518
1887
  $textColor: inputTextColor,
1519
1888
  children: [
1520
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: "", disabled: true, children: "Selecione uma op\xE7\xE3o" }),
1521
- Object.values(PreferenciaContato).map((op) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: op, children: op }, op))
1889
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: "", disabled: true, children: "Selecione uma op\xE7\xE3o" }),
1890
+ Object.values(PreferenciaContato).map((op) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: op, children: op }, op))
1522
1891
  ]
1523
1892
  }
1524
1893
  ),
1525
- errors.preferencia_contato && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FormErrorMessage, { children: errors.preferencia_contato.message })
1894
+ errors.preferencia_contato && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FormErrorMessage, { children: errors.preferencia_contato.message })
1526
1895
  ] }),
1527
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h6", { children: "* Campos de preenchimento obrigat\xF3rio." }),
1528
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ButtonContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Button2, { bgColor: buttonBackgroundColor, color: buttonTextColor, type: "submit", isSubmitting: loading, children: "Enviar mensagem" }) }),
1529
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { children: [
1896
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h6", { children: "* Campos de preenchimento obrigat\xF3rio." }),
1897
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ButtonContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Button2, { bgColor: buttonBackgroundColor, color: buttonTextColor, type: "submit", isSubmitting: loading, children: canal === "whatsapp" ? WHATSAPP_BUTTON_TEXT : canal === "chat" ? CHAT_BUTTON_TEXT : "Enviar mensagem" }) }),
1898
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { children: [
1530
1899
  "A Mitre Realty respeita a sua privacidade e utiliza os seus dados pessoais para contat\xE1-lo por e-mail ou telefone aqui registrados. Para saber mais, acesse a nossa",
1531
1900
  " ",
1532
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1901
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1533
1902
  "a",
1534
1903
  {
1535
1904
  href: "https://www.mitrerealty.com.br/politica-de-privacidade",