mitre-form-component 0.0.42 → 0.0.44

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.js CHANGED
@@ -1079,8 +1079,139 @@ var PhoneInputBase = ({
1079
1079
  };
1080
1080
  var PhoneInput2 = forwardRef2(PhoneInputBase);
1081
1081
 
1082
+ // src/components/ProductSelect/index.tsx
1083
+ import {
1084
+ forwardRef as forwardRef3
1085
+ } from "react";
1086
+
1087
+ // src/components/ProductSelect/styles.ts
1088
+ import styled6, { css as css5 } from "styled-components";
1089
+ var FormLabel3 = styled6.label`
1090
+ font-family: "Montserrat", sans-serif;
1091
+ font-style: normal;
1092
+ font-weight: 500;
1093
+ font-size: 1rem;
1094
+ color: ${(props) => props.$textColor || "var(--black)"};
1095
+ display: block;
1096
+ margin-bottom: 0.5rem;
1097
+ text-align: left;
1098
+ `;
1099
+ var Select = styled6.select`
1100
+ font-family: "Montserrat", sans-serif;
1101
+ font-style: normal;
1102
+ font-weight: 500;
1103
+ font-size: 1rem;
1104
+ line-height: 1.5rem;
1105
+ background: ${(props) => props.$backgroundColor || "var(--white)"};
1106
+ color: ${(props) => props.$textColor || "var(--black)"};
1107
+ padding: 0.5rem 3rem 0.5rem 0.5rem; /* Aumentado padding-right para 3rem */
1108
+ border-radius: 0.125rem;
1109
+ border: 1px solid ${(props) => props.$borderColor || "transparent"};
1110
+ display: block;
1111
+ height: 3.125rem;
1112
+ width: 100%;
1113
+ cursor: pointer;
1114
+
1115
+ /* Remover a seta padrão do navegador */
1116
+ -webkit-appearance: none;
1117
+ -moz-appearance: none;
1118
+ appearance: none;
1119
+
1120
+ /* Adicionar seta personalizada maior */
1121
+ background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6,9 12,15 18,9'%3e%3c/polyline%3e%3c/svg%3e");
1122
+ background-repeat: no-repeat;
1123
+ background-position: right 1rem center; /* Posicionado a 1rem da direita */
1124
+ background-size: 1.25rem; /* Tamanho da seta aumentado para 1.25rem */
1125
+
1126
+ &:focus {
1127
+ border-radius: 0.125rem;
1128
+ border: 2px solid ${(props) => props.$focusBorderColor || "var(--yellow-500)"};
1129
+ outline: none;
1130
+ }
1131
+
1132
+ /* Estilo para option disabled (placeholder) */
1133
+ option:disabled {
1134
+ color: var(--gray-100);
1135
+ font-weight: 800;
1136
+ }
1137
+
1138
+ /* Estilo para options normais */
1139
+ option:not(:disabled) {
1140
+ color: ${(props) => props.$textColor || "var(--black)"};
1141
+ font-weight: 500;
1142
+ }
1143
+ `;
1144
+ var FormErrorMessage3 = styled6.small`
1145
+ font-size: 0.75rem;
1146
+ line-height: 1.125rem;
1147
+ color: var(--red);
1148
+ margin-top: 0.25rem;
1149
+ display: block;
1150
+ `;
1151
+ var FormControl3 = styled6.div.withConfig({
1152
+ shouldForwardProp: (prop) => !["isInvalid"].includes(prop)
1153
+ })`
1154
+ ${FormLabel3} {
1155
+ ${(props) => props.isInvalid && css5`
1156
+ color: var(--red);
1157
+ `};
1158
+ }
1159
+
1160
+ ${Select} {
1161
+ ${(props) => props.isInvalid && css5`
1162
+ border: 1px solid var(--red);
1163
+ `};
1164
+
1165
+ &:focus {
1166
+ ${(props) => props.isInvalid && css5`
1167
+ border: 1px solid var(--red);
1168
+ `};
1169
+ }
1170
+ }
1171
+ `;
1172
+
1173
+ // src/components/ProductSelect/index.tsx
1174
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1175
+ var ProductSelectBase = ({
1176
+ id,
1177
+ label,
1178
+ error,
1179
+ showErrorMessage = true,
1180
+ labelTextColor,
1181
+ backgroundColor,
1182
+ borderColor,
1183
+ focusBorderColor,
1184
+ textColor,
1185
+ products,
1186
+ placeholder = "Selecione um produto",
1187
+ ...rest
1188
+ }, ref) => {
1189
+ return /* @__PURE__ */ jsxs5(FormControl3, { isInvalid: !!error, children: [
1190
+ !!label && /* @__PURE__ */ jsx5(FormLabel3, { htmlFor: id, $textColor: labelTextColor, children: label }),
1191
+ /* @__PURE__ */ jsxs5(
1192
+ Select,
1193
+ {
1194
+ id,
1195
+ ref,
1196
+ "aria-invalid": !!error && showErrorMessage ? "true" : "false",
1197
+ $backgroundColor: backgroundColor,
1198
+ $borderColor: borderColor,
1199
+ $focusBorderColor: focusBorderColor,
1200
+ $textColor: textColor,
1201
+ ...rest,
1202
+ children: [
1203
+ /* @__PURE__ */ jsx5("option", { value: "", disabled: true, children: placeholder }),
1204
+ products.map((product) => /* @__PURE__ */ jsx5("option", { value: product.id, children: product.name }, product.id))
1205
+ ]
1206
+ }
1207
+ ),
1208
+ !!error && showErrorMessage && /* @__PURE__ */ jsx5(FormErrorMessage3, { "data-testid": "error-message", children: typeof error === "string" ? error : error.message })
1209
+ ] });
1210
+ };
1211
+ var ProductSelect = forwardRef3(ProductSelectBase);
1212
+
1082
1213
  // src/components/Form/index.tsx
1083
- import { Fragment, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1214
+ import { Fragment, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1084
1215
  var phoneUtil = PhoneNumberUtil.getInstance();
1085
1216
  var isPhoneValid = (phone) => {
1086
1217
  try {
@@ -1090,7 +1221,7 @@ var isPhoneValid = (phone) => {
1090
1221
  return false;
1091
1222
  }
1092
1223
  };
1093
- var schema = yup.object().shape({
1224
+ var baseSchema = {
1094
1225
  name: yup.string().required("Nome \xE9 obrigat\xF3rio"),
1095
1226
  email: yup.string().required("Email \xE9 obrigat\xF3rio").email("Email inv\xE1lido"),
1096
1227
  phone: yup.object().shape({
@@ -1105,9 +1236,14 @@ var schema = yup.object().shape({
1105
1236
  inputValue: yup.string().required("Telefone \xE9 obrigat\xF3rio!"),
1106
1237
  dialCode: yup.string().required("C\xF3digo de pa\xEDs \xE9 obrigat\xF3rio")
1107
1238
  })
1239
+ };
1240
+ var schemaWithProduct = yup.object().shape({
1241
+ ...baseSchema,
1242
+ productId: yup.string().required("Produto \xE9 obrigat\xF3rio")
1108
1243
  });
1244
+ var schema = yup.object().shape(baseSchema);
1109
1245
  var MitreFormComponent = React3.forwardRef(({
1110
- productId,
1246
+ products,
1111
1247
  apiUrl,
1112
1248
  apiToken,
1113
1249
  showHeader = true,
@@ -1126,9 +1262,36 @@ var MitreFormComponent = React3.forwardRef(({
1126
1262
  const { error, handleError, clearError } = useError();
1127
1263
  const [successMessage, setSuccessMessage] = useState3("");
1128
1264
  const [formKey, setFormKey] = useState3(0);
1265
+ const [selectedProductId, setSelectedProductId] = useState3(null);
1266
+ const validateProducts = () => {
1267
+ if (!products) {
1268
+ return "Lista de produtos n\xE3o foi fornecida";
1269
+ }
1270
+ if (!Array.isArray(products)) {
1271
+ return "Lista de produtos deve ser um array";
1272
+ }
1273
+ if (products.length === 0) {
1274
+ return "Lista de produtos n\xE3o pode estar vazia";
1275
+ }
1276
+ for (let i = 0; i < products.length; i++) {
1277
+ const product = products[i];
1278
+ if (!product) {
1279
+ return `Produto na posi\xE7\xE3o ${i} \xE9 inv\xE1lido (nulo/undefined)`;
1280
+ }
1281
+ if (typeof product.id !== "number" || product.id <= 0) {
1282
+ return `Produto na posi\xE7\xE3o ${i} possui ID inv\xE1lido (deve ser um n\xFAmero positivo)`;
1283
+ }
1284
+ if (typeof product.name !== "string" || product.name.trim().length === 0) {
1285
+ return `Produto na posi\xE7\xE3o ${i} possui nome inv\xE1lido (deve ser uma string n\xE3o vazia)`;
1286
+ }
1287
+ }
1288
+ return null;
1289
+ };
1290
+ const productsValidationError = validateProducts();
1129
1291
  const [utm, setUtm] = useState3({ utm_source: "direto", createdAt: (/* @__PURE__ */ new Date()).toISOString() });
1292
+ const formSchema = products && products.length > 1 ? schemaWithProduct : schema;
1130
1293
  const { control, register, handleSubmit, formState: { errors }, reset, clearErrors } = useForm({
1131
- resolver: yupResolver(schema),
1294
+ resolver: yupResolver(formSchema),
1132
1295
  mode: "onSubmit"
1133
1296
  });
1134
1297
  React3.useEffect(() => {
@@ -1137,11 +1300,16 @@ var MitreFormComponent = React3.forwardRef(({
1137
1300
  setUtm(data);
1138
1301
  }, []);
1139
1302
  const resetForm = () => {
1140
- reset({
1303
+ const resetData = {
1141
1304
  name: "",
1142
1305
  email: "",
1143
1306
  phone: { phone: "", inputValue: "", dialCode: "" }
1144
- }, {
1307
+ };
1308
+ if (products && products.length > 1) {
1309
+ resetData.productId = "";
1310
+ setSelectedProductId(null);
1311
+ }
1312
+ reset(resetData, {
1145
1313
  keepErrors: false,
1146
1314
  keepDirty: false,
1147
1315
  keepTouched: false,
@@ -1154,23 +1322,36 @@ var MitreFormComponent = React3.forwardRef(({
1154
1322
  setFormKey((k) => k + 1);
1155
1323
  };
1156
1324
  const sendMessage = async (data) => {
1157
- const { name, email, phone } = data;
1325
+ const { name, email, phone, productId } = data;
1158
1326
  const phoneValue = phone.inputValue;
1159
1327
  const phoneDigitsOnly = phoneValue?.replace(/\D/g, "") || "";
1160
1328
  const message = "Gostaria de mais informa\xE7\xF5es sobre o produto";
1161
1329
  try {
1162
1330
  setIsLoading(true);
1163
- if (!productId || !apiToken) {
1331
+ if (!products || products.length === 0 || !apiToken) {
1164
1332
  throw new Error("Par\xE2metros obrigat\xF3rios n\xE3o informados");
1165
1333
  }
1334
+ let selectedProduct;
1335
+ if (products.length === 1) {
1336
+ selectedProduct = products[0];
1337
+ } else {
1338
+ if (!productId) {
1339
+ throw new Error("Produto deve ser selecionado");
1340
+ }
1341
+ const foundProduct = products.find((p) => p.id.toString() === productId);
1342
+ if (!foundProduct) {
1343
+ throw new Error("Produto selecionado n\xE3o encontrado");
1344
+ }
1345
+ selectedProduct = foundProduct;
1346
+ }
1166
1347
  const requestBody = {
1167
1348
  name,
1168
1349
  email,
1169
1350
  phone: phoneDigitsOnly,
1170
1351
  message,
1171
- productId,
1352
+ productId: selectedProduct.id.toString(),
1172
1353
  utm_source: utm.utm_source,
1173
- utm_campaing: utm.utm_campaign,
1354
+ utm_campaign: utm.utm_campaign,
1174
1355
  utm_medium: utm.utm_medium,
1175
1356
  utm_term: utm.utm_term
1176
1357
  };
@@ -1195,10 +1376,21 @@ var MitreFormComponent = React3.forwardRef(({
1195
1376
  setIsLoading(false);
1196
1377
  }
1197
1378
  };
1198
- return /* @__PURE__ */ jsxs5(Fragment, { children: [
1199
- /* @__PURE__ */ jsx5(global_default, {}),
1200
- /* @__PURE__ */ jsx5(GlobalStyles, {}),
1201
- error && /* @__PURE__ */ jsx5(
1379
+ if (productsValidationError) {
1380
+ console.error("Erro na valida\xE7\xE3o dos produtos:", productsValidationError);
1381
+ return /* @__PURE__ */ jsxs6(Fragment, { children: [
1382
+ /* @__PURE__ */ jsx6(global_default, {}),
1383
+ /* @__PURE__ */ jsx6(GlobalStyles, {}),
1384
+ /* @__PURE__ */ jsx6(FormContainer, { $backgroundColor: backgroundColor, $innerPadding: innerPadding, ref, children: /* @__PURE__ */ jsxs6(HeaderContainer, { children: [
1385
+ /* @__PURE__ */ jsx6(Title, { $textColor: textColor, children: "Erro no carregamento do formul\xE1rio!" }),
1386
+ /* @__PURE__ */ jsx6(Text, { $textColor: textColor, children: "N\xE3o foi poss\xEDvel carregar o formul\xE1rio. Tente novamente mais tarde." })
1387
+ ] }) })
1388
+ ] });
1389
+ }
1390
+ return /* @__PURE__ */ jsxs6(Fragment, { children: [
1391
+ /* @__PURE__ */ jsx6(global_default, {}),
1392
+ /* @__PURE__ */ jsx6(GlobalStyles, {}),
1393
+ error && /* @__PURE__ */ jsx6(
1202
1394
  Alert,
1203
1395
  {
1204
1396
  type: "error",
@@ -1208,7 +1400,7 @@ var MitreFormComponent = React3.forwardRef(({
1208
1400
  children: error.message
1209
1401
  }
1210
1402
  ),
1211
- successMessage && /* @__PURE__ */ jsx5(
1403
+ successMessage && /* @__PURE__ */ jsx6(
1212
1404
  Alert,
1213
1405
  {
1214
1406
  type: "success",
@@ -1218,13 +1410,30 @@ var MitreFormComponent = React3.forwardRef(({
1218
1410
  children: successMessage
1219
1411
  }
1220
1412
  ),
1221
- /* @__PURE__ */ jsxs5(FormContainer, { $backgroundColor: backgroundColor, $innerPadding: innerPadding, ref, children: [
1222
- showHeader && /* @__PURE__ */ jsxs5(HeaderContainer, { children: [
1223
- /* @__PURE__ */ jsx5(Title, { $textColor: textColor, children: "Atendimento por mensagem" }),
1224
- /* @__PURE__ */ jsx5(Text, { $textColor: textColor, children: "Informe seus dados e retornaremos a mensagem." })
1413
+ /* @__PURE__ */ jsxs6(FormContainer, { $backgroundColor: backgroundColor, $innerPadding: innerPadding, ref, children: [
1414
+ showHeader && /* @__PURE__ */ jsxs6(HeaderContainer, { children: [
1415
+ /* @__PURE__ */ jsx6(Title, { $textColor: textColor, children: "Atendimento por mensagem" }),
1416
+ /* @__PURE__ */ jsx6(Text, { $textColor: textColor, children: "Informe seus dados e retornaremos a mensagem." })
1225
1417
  ] }),
1226
- /* @__PURE__ */ jsxs5(Form, { $textColor: textColor, onSubmit: handleSubmit(sendMessage), noValidate: true, children: [
1227
- /* @__PURE__ */ jsx5(
1418
+ /* @__PURE__ */ jsxs6(Form, { $textColor: textColor, onSubmit: handleSubmit(sendMessage), noValidate: true, children: [
1419
+ products.length > 1 && /* @__PURE__ */ jsx6(
1420
+ ProductSelect,
1421
+ {
1422
+ id: "productId",
1423
+ label: "Produto de interesse *",
1424
+ placeholder: "Selecione um produto",
1425
+ ...register("productId"),
1426
+ error: errors.productId?.message,
1427
+ products,
1428
+ required: true,
1429
+ labelTextColor: textColor,
1430
+ backgroundColor: inputBackgroundColor,
1431
+ borderColor: inputBorderColor,
1432
+ focusBorderColor: inputFocusBorderColor,
1433
+ textColor: inputTextColor
1434
+ }
1435
+ ),
1436
+ /* @__PURE__ */ jsx6(
1228
1437
  Input2,
1229
1438
  {
1230
1439
  id: "name",
@@ -1242,7 +1451,7 @@ var MitreFormComponent = React3.forwardRef(({
1242
1451
  inputTextColor
1243
1452
  }
1244
1453
  ),
1245
- /* @__PURE__ */ jsx5(
1454
+ /* @__PURE__ */ jsx6(
1246
1455
  Input2,
1247
1456
  {
1248
1457
  id: "email",
@@ -1261,7 +1470,7 @@ var MitreFormComponent = React3.forwardRef(({
1261
1470
  inputTextColor
1262
1471
  }
1263
1472
  ),
1264
- /* @__PURE__ */ jsx5(
1473
+ /* @__PURE__ */ jsx6(
1265
1474
  Controller,
1266
1475
  {
1267
1476
  name: "phone",
@@ -1270,7 +1479,7 @@ var MitreFormComponent = React3.forwardRef(({
1270
1479
  shouldUnregister: true,
1271
1480
  render: ({ field }) => {
1272
1481
  const errorMsg = errors.phone?.inputValue?.message || errors.phone?.phone?.message || errors.phone?.message;
1273
- return /* @__PURE__ */ jsx5(
1482
+ return /* @__PURE__ */ jsx6(
1274
1483
  PhoneInput2,
1275
1484
  {
1276
1485
  id: "phone",
@@ -1293,12 +1502,12 @@ var MitreFormComponent = React3.forwardRef(({
1293
1502
  },
1294
1503
  formKey
1295
1504
  ),
1296
- /* @__PURE__ */ jsx5("h6", { children: "* Campos de preenchimento obrigat\xF3rio." }),
1297
- /* @__PURE__ */ jsx5(ButtonContainer, { children: /* @__PURE__ */ jsx5(Button2, { bgColor: buttonBackgroundColor, color: buttonTextColor, type: "submit", isSubmitting: loading, children: "Enviar mensagem" }) }),
1298
- /* @__PURE__ */ jsxs5("p", { children: [
1505
+ /* @__PURE__ */ jsx6("h6", { children: "* Campos de preenchimento obrigat\xF3rio." }),
1506
+ /* @__PURE__ */ jsx6(ButtonContainer, { children: /* @__PURE__ */ jsx6(Button2, { bgColor: buttonBackgroundColor, color: buttonTextColor, type: "submit", isSubmitting: loading, children: "Enviar mensagem" }) }),
1507
+ /* @__PURE__ */ jsxs6("p", { children: [
1299
1508
  "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",
1300
1509
  " ",
1301
- /* @__PURE__ */ jsx5(
1510
+ /* @__PURE__ */ jsx6(
1302
1511
  "a",
1303
1512
  {
1304
1513
  href: "https://www.mitrerealty.com.br/politica-de-privacidade",