mitre-form-component 0.1.4 → 2.0.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,17 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1258
1478
  inputPlaceholderColor = theme.colors.gray100,
1259
1479
  inputTextColor = theme.colors.black,
1260
1480
  showPreferenciaContato = false,
1261
- onSuccess,
1262
- onError
1481
+ idProdutoTerceiro,
1482
+ idEmpreendimento,
1483
+ naoCriarEvento
1263
1484
  }, ref) => {
1264
1485
  useMontserratFont();
1265
- const [loading, setIsLoading] = (0, import_react7.useState)(false);
1486
+ const [loading, setIsLoading] = (0, import_react8.useState)(false);
1266
1487
  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);
1488
+ const [successMessage, setSuccessMessage] = (0, import_react8.useState)("");
1489
+ const [formKey, setFormKey] = (0, import_react8.useState)(0);
1490
+ const [selectedProductId, setSelectedProductId] = (0, import_react8.useState)(null);
1491
+ const [actionModal, setActionModal] = (0, import_react8.useState)(null);
1270
1492
  const validateProducts = () => {
1271
1493
  if (!products) {
1272
1494
  return "Lista de produtos n\xE3o foi fornecida";
@@ -1291,14 +1513,60 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1291
1513
  }
1292
1514
  return null;
1293
1515
  };
1516
+ const env = resolveEnvironment(ambiente);
1517
+ const validateAmbienteConfig = () => {
1518
+ if (!env) {
1519
+ return `ambiente='${ambiente}' n\xE3o \xE9 reconhecido. Use 'homol' ou 'prod'.`;
1520
+ }
1521
+ if (!env.apiUrl || !env.apiToken) {
1522
+ return `Configura\xE7\xE3o interna do ambiente '${ambiente}' est\xE1 incompleta (apiUrl/apiToken).`;
1523
+ }
1524
+ return null;
1525
+ };
1526
+ const validateWhatsappConfig = () => {
1527
+ if (canal !== "whatsapp") return null;
1528
+ if (!env) return null;
1529
+ const raw = env.whatsappPhone?.trim() ?? "";
1530
+ if (!raw) {
1531
+ return `canal='whatsapp' exige whatsappPhone no ambiente '${ambiente}'.`;
1532
+ }
1533
+ const normalized = raw.startsWith("+") ? raw : `+${raw}`;
1534
+ if (!isPhoneValid(normalized)) {
1535
+ return `whatsappPhone do ambiente '${ambiente}' \xE9 inv\xE1lido (${JSON.stringify(env.whatsappPhone)}).`;
1536
+ }
1537
+ return null;
1538
+ };
1539
+ const validateChatConfig = () => {
1540
+ if (canal !== "chat") return null;
1541
+ if (!env) return null;
1542
+ const raw = env.chatUrl?.trim() ?? "";
1543
+ if (!raw) {
1544
+ return `canal='chat' exige chatUrl no ambiente '${ambiente}'.`;
1545
+ }
1546
+ try {
1547
+ const parsed = new URL(raw);
1548
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
1549
+ return `chatUrl do ambiente '${ambiente}' precisa ter protocolo http(s) (recebido: ${JSON.stringify(env.chatUrl)}).`;
1550
+ }
1551
+ } catch {
1552
+ return `chatUrl do ambiente '${ambiente}' n\xE3o \xE9 URL absoluta v\xE1lida (recebido: ${JSON.stringify(env.chatUrl)}).`;
1553
+ }
1554
+ return null;
1555
+ };
1294
1556
  const productsValidationError = validateProducts();
1295
- const [utm, setUtm] = (0, import_react7.useState)({ utm_source: "direto", createdAt: (/* @__PURE__ */ new Date()).toISOString() });
1557
+ const ambienteConfigError = validateAmbienteConfig();
1558
+ const whatsappConfigError = validateWhatsappConfig();
1559
+ const chatConfigError = validateChatConfig();
1560
+ const effectiveShowPreferenciaContato = canal === "whatsapp" || canal === "chat" ? false : showPreferenciaContato;
1561
+ const effectiveTitle = canal === "whatsapp" ? WHATSAPP_TITLE : canal === "chat" ? CHAT_TITLE : title;
1562
+ const effectiveSubtitle = canal === "whatsapp" ? WHATSAPP_SUBTITLE : canal === "chat" ? CHAT_SUBTITLE : subtitle;
1563
+ const [utm, setUtm] = (0, import_react8.useState)({ utm_source: "direto", createdAt: (/* @__PURE__ */ new Date()).toISOString() });
1296
1564
  const formSchema = products && products.length > 1 ? schemaWithProduct : schema;
1297
1565
  const { control, register, handleSubmit, formState: { errors }, reset, clearErrors } = (0, import_react_hook_form.useForm)({
1298
1566
  resolver: (0, import_yup.yupResolver)(formSchema),
1299
1567
  mode: "onSubmit"
1300
1568
  });
1301
- import_react7.default.useEffect(() => {
1569
+ import_react8.default.useEffect(() => {
1302
1570
  if (!isBrowser()) return;
1303
1571
  const { data } = resolveUtmWithPriority(/* @__PURE__ */ new Date());
1304
1572
  setUtm(data);
@@ -1330,9 +1598,13 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1330
1598
  const phoneValue = phone.inputValue;
1331
1599
  const phoneDigitsOnly = phoneValue?.replace(/\D/g, "") || "";
1332
1600
  const message = "Gostaria de mais informa\xE7\xF5es sobre o produto";
1601
+ setActionModal(null);
1333
1602
  try {
1334
1603
  setIsLoading(true);
1335
- if (!products || products.length === 0 || !apiToken) {
1604
+ if (!env) {
1605
+ throw new Error("Ambiente n\xE3o resolvido");
1606
+ }
1607
+ if (!products || products.length === 0) {
1336
1608
  throw new Error("Par\xE2metros obrigat\xF3rios n\xE3o informados");
1337
1609
  }
1338
1610
  let selectedProduct;
@@ -1348,6 +1620,8 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1348
1620
  }
1349
1621
  selectedProduct = foundProduct;
1350
1622
  }
1623
+ const paginaAtual = typeof window !== "undefined" ? window.location.href : void 0;
1624
+ const naoCriarEventoEfetivo = canal !== "form" && (naoCriarEvento ?? true);
1351
1625
  const requestBody = {
1352
1626
  name,
1353
1627
  email,
@@ -1358,13 +1632,23 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1358
1632
  utm_campaign: utm.utm_campaign,
1359
1633
  utm_medium: utm.utm_medium,
1360
1634
  utm_term: utm.utm_term,
1361
- ...showPreferenciaContato && preferencia_contato ? { preferencia_contato } : {}
1635
+ ...canal === "whatsapp" ? { preferencia_contato: "Whatsapp" /* Whatsapp */ } : effectiveShowPreferenciaContato && preferencia_contato ? { preferencia_contato } : {},
1636
+ ...canal !== "form" ? {
1637
+ canal,
1638
+ ...paginaAtual ? { pagina: paginaAtual } : {},
1639
+ // Paridade com atendimento.html legado: o mesmo <form id="chat-form">
1640
+ // era usado para chat e whatsapp, portanto is_chat=true ia em ambos.
1641
+ is_chat: true,
1642
+ ...idProdutoTerceiro !== void 0 ? { idProdutoTerceiro } : {},
1643
+ ...idEmpreendimento !== void 0 ? { idEmpreendimento } : {},
1644
+ ...naoCriarEventoEfetivo ? { naoCriarEvento: true } : {}
1645
+ } : {}
1362
1646
  };
1363
- const response = await fetch(`${apiUrl}/leads`, {
1647
+ const response = await fetch(`${env.apiUrl}/leads`, {
1364
1648
  method: "POST",
1365
1649
  headers: {
1366
1650
  "Content-Type": "application/json",
1367
- Authorization: `Basic ${apiToken}`
1651
+ Authorization: `Basic ${env.apiToken}`
1368
1652
  },
1369
1653
  body: JSON.stringify(requestBody)
1370
1654
  });
@@ -1373,26 +1657,61 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1373
1657
  }
1374
1658
  const responseData = await response.json();
1375
1659
  const leadId = responseData.leadId || responseData.id || "";
1376
- setSuccessMessage("Mensagem enviada com sucesso!");
1377
1660
  resetForm();
1378
- onSuccess?.(requestBody, leadId);
1661
+ if (canal === "whatsapp") {
1662
+ setActionModal({
1663
+ kind: "success",
1664
+ canal: "whatsapp",
1665
+ targetUrl: buildWhatsappUrl(env.whatsappPhone)
1666
+ });
1667
+ } else if (canal === "chat") {
1668
+ const virtualObj = {
1669
+ ...requestBody,
1670
+ externalOriginId: leadId,
1671
+ ...paginaAtual ? { pagina: paginaAtual } : {},
1672
+ ...idProdutoTerceiro !== void 0 ? { idProdutoTerceiro } : {},
1673
+ ...idEmpreendimento !== void 0 ? { idEmpreendimento } : {},
1674
+ ...naoCriarEventoEfetivo ? { naoCriarEvento: true } : {}
1675
+ };
1676
+ setActionModal({
1677
+ kind: "success",
1678
+ canal: "chat",
1679
+ chatUrl: env.chatUrl,
1680
+ virtualObj
1681
+ });
1682
+ } else {
1683
+ setSuccessMessage("Mensagem enviada com sucesso!");
1684
+ }
1379
1685
  } catch (err) {
1380
- const error2 = err instanceof Error ? err : new Error("Erro desconhecido");
1381
- handleError(err);
1382
- onError?.(error2);
1686
+ if (canal === "whatsapp" || canal === "chat") {
1687
+ setActionModal({ kind: "error" });
1688
+ } else {
1689
+ handleError(err);
1690
+ }
1383
1691
  } finally {
1384
1692
  setIsLoading(false);
1385
1693
  }
1386
1694
  };
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." })
1695
+ if (productsValidationError || ambienteConfigError || whatsappConfigError || chatConfigError) {
1696
+ if (productsValidationError) {
1697
+ console.error("Erro na valida\xE7\xE3o dos produtos:", productsValidationError);
1698
+ }
1699
+ if (ambienteConfigError) {
1700
+ console.error("Erro na valida\xE7\xE3o do ambiente:", ambienteConfigError);
1701
+ }
1702
+ if (whatsappConfigError) {
1703
+ console.error("Erro na valida\xE7\xE3o do canal whatsapp:", whatsappConfigError);
1704
+ }
1705
+ if (chatConfigError) {
1706
+ console.error("Erro na valida\xE7\xE3o do canal chat:", chatConfigError);
1707
+ }
1708
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FormContainer, { $backgroundColor: backgroundColor, $innerPadding: innerPadding, ref, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(HeaderContainer, { children: [
1709
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Title, { $textColor: textColor, children: "Erro no carregamento do formul\xE1rio!" }),
1710
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Subtitle, { $textColor: textColor, children: "N\xE3o foi poss\xEDvel carregar o formul\xE1rio. Tente novamente mais tarde." })
1392
1711
  ] }) });
1393
1712
  }
1394
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1395
- error && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1713
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
1714
+ error && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1396
1715
  Alert,
1397
1716
  {
1398
1717
  type: "error",
@@ -1402,7 +1721,7 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1402
1721
  children: error.message
1403
1722
  }
1404
1723
  ),
1405
- successMessage && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1724
+ successMessage && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1406
1725
  Alert,
1407
1726
  {
1408
1727
  type: "success",
@@ -1412,13 +1731,58 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1412
1731
  children: successMessage
1413
1732
  }
1414
1733
  ),
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 })
1734
+ actionModal?.kind === "error" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1735
+ Modal,
1736
+ {
1737
+ type: "error",
1738
+ title: MODAL_ERROR_TITLE,
1739
+ message: MODAL_ERROR_MESSAGE,
1740
+ primaryButtonText: MODAL_ERROR_BUTTON_TEXT,
1741
+ onPrimaryAction: () => setActionModal(null),
1742
+ onClose: () => setActionModal(null),
1743
+ primaryButtonBgColor: buttonBackgroundColor,
1744
+ primaryButtonTextColor: buttonTextColor
1745
+ }
1746
+ ),
1747
+ actionModal?.kind === "success" && actionModal.canal === "whatsapp" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1748
+ Modal,
1749
+ {
1750
+ type: "success",
1751
+ title: MODAL_SUCCESS_TITLE,
1752
+ message: MODAL_SUCCESS_MESSAGE_WHATSAPP,
1753
+ primaryButtonText: MODAL_SUCCESS_BUTTON_WHATSAPP,
1754
+ onPrimaryAction: () => {
1755
+ window.open(actionModal.targetUrl, "_blank", "noopener,noreferrer");
1756
+ setActionModal(null);
1757
+ },
1758
+ onClose: () => setActionModal(null),
1759
+ primaryButtonBgColor: buttonBackgroundColor,
1760
+ primaryButtonTextColor: buttonTextColor
1761
+ }
1762
+ ),
1763
+ actionModal?.kind === "success" && actionModal.canal === "chat" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1764
+ Modal,
1765
+ {
1766
+ type: "success",
1767
+ title: MODAL_SUCCESS_TITLE,
1768
+ message: MODAL_SUCCESS_MESSAGE_CHAT,
1769
+ primaryButtonText: MODAL_SUCCESS_BUTTON_CHAT,
1770
+ onPrimaryAction: () => {
1771
+ submitChatInNewTab(actionModal.chatUrl, actionModal.virtualObj);
1772
+ setActionModal(null);
1773
+ },
1774
+ onClose: () => setActionModal(null),
1775
+ primaryButtonBgColor: buttonBackgroundColor,
1776
+ primaryButtonTextColor: buttonTextColor
1777
+ }
1778
+ ),
1779
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(FormContainer, { $backgroundColor: backgroundColor, $innerPadding: innerPadding, ref, children: [
1780
+ showHeader && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(HeaderContainer, { children: [
1781
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Title, { $textColor: textColor, children: effectiveTitle }),
1782
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Subtitle, { $textColor: textColor, children: effectiveSubtitle })
1419
1783
  ] }),
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)(
1784
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Form, { $textColor: textColor, onSubmit: handleSubmit(sendMessage), noValidate: true, children: [
1785
+ products.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1422
1786
  ProductSelect,
1423
1787
  {
1424
1788
  id: "productId",
@@ -1435,7 +1799,7 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1435
1799
  textColor: inputTextColor
1436
1800
  }
1437
1801
  ),
1438
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1802
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1439
1803
  Input2,
1440
1804
  {
1441
1805
  id: "name",
@@ -1453,7 +1817,7 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1453
1817
  inputTextColor
1454
1818
  }
1455
1819
  ),
1456
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1820
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1457
1821
  Input2,
1458
1822
  {
1459
1823
  id: "email",
@@ -1472,7 +1836,7 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1472
1836
  inputTextColor
1473
1837
  }
1474
1838
  ),
1475
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1839
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1476
1840
  import_react_hook_form.Controller,
1477
1841
  {
1478
1842
  name: "phone",
@@ -1481,7 +1845,7 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1481
1845
  shouldUnregister: true,
1482
1846
  render: ({ field }) => {
1483
1847
  const errorMsg = errors.phone?.inputValue?.message || errors.phone?.phone?.message || errors.phone?.message;
1484
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1848
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1485
1849
  PhoneInput2,
1486
1850
  {
1487
1851
  id: "phone",
@@ -1504,9 +1868,9 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1504
1868
  },
1505
1869
  formKey
1506
1870
  ),
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)(
1871
+ effectiveShowPreferenciaContato && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(FormControl, { isInvalid: !!errors.preferencia_contato, children: [
1872
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FormLabel, { htmlFor: "preferencia_contato", $textColor: textColor, children: "Prefer\xEAncia de Contato" }),
1873
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1510
1874
  Select,
1511
1875
  {
1512
1876
  id: "preferencia_contato",
@@ -1517,19 +1881,19 @@ var MitreFormComponent = import_react7.default.forwardRef(({
1517
1881
  $focusBorderColor: inputFocusBorderColor,
1518
1882
  $textColor: inputTextColor,
1519
1883
  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))
1884
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: "", disabled: true, children: "Selecione uma op\xE7\xE3o" }),
1885
+ Object.values(PreferenciaContato).map((op) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: op, children: op }, op))
1522
1886
  ]
1523
1887
  }
1524
1888
  ),
1525
- errors.preferencia_contato && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FormErrorMessage, { children: errors.preferencia_contato.message })
1889
+ errors.preferencia_contato && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FormErrorMessage, { children: errors.preferencia_contato.message })
1526
1890
  ] }),
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: [
1891
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h6", { children: "* Campos de preenchimento obrigat\xF3rio." }),
1892
+ /* @__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" }) }),
1893
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { children: [
1530
1894
  "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
1895
  " ",
1532
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1896
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1533
1897
  "a",
1534
1898
  {
1535
1899
  href: "https://www.mitrerealty.com.br/politica-de-privacidade",