@visiion/forms-library 1.4.17 → 1.4.19

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.esm.js CHANGED
@@ -19858,7 +19858,7 @@ var AddressInput = function (_a) {
19858
19858
  var component = _a[_i];
19859
19859
  var types = component.types;
19860
19860
  if (types.includes("street_number"))
19861
- addressComponents.numero = parseInt(component.long_name, 10);
19861
+ addressComponents.numero = component.long_name;
19862
19862
  if (types.includes("route"))
19863
19863
  addressComponents.calle = component.long_name;
19864
19864
  if (types.includes("administrative_area_level_1")) {
@@ -23183,4 +23183,1267 @@ var GenericForm = function (_a) {
23183
23183
  return formContent;
23184
23184
  };
23185
23185
 
23186
- export { AddressInput, Alert, CheckboxInput, Checklist, Common, DatePicker, DynamicInput, GenericForm, GoogleMaps, InputWrapper, NavigationButton, RadioInput, RadioOption, RutInput, SelectInput, StatusScreen, SubtitleInput, SwornDeclaration, TextInput, TextInputField, TextareaInput, clean as cleanRut, commonValidations, createValidationSchema, formatRut, maskRut, useMiDt, validateOnlyNumbersAndLetters, validate as validateRut };
23186
+ // se convierte tags a mayúsculas excepto (h) que debe preservarse
23187
+ var convertTagsToUppercase$1 = function (text) {
23188
+ return text.replace(/\(([a-z]\d*)\)/g, function (match, tag) {
23189
+ if (tag === 'h')
23190
+ return match; // se preserva (h) minúscula
23191
+ return "(".concat(tag.toUpperCase(), ")");
23192
+ });
23193
+ };
23194
+ var SelectorComponent = function (_a) {
23195
+ var value = _a.value, onChange = _a.onChange, options = _a.options, placeholder = _a.placeholder;
23196
+ var _b = useState(false), isOpen = _b[0], setIsOpen = _b[1];
23197
+ var dropdownRef = useRef(null);
23198
+ // Encontrar la opción seleccionada
23199
+ // Comparar normalizando los tags a mayúsculas para ambos valores
23200
+ var selectedOption = options.find(function (option) { return convertTagsToUppercase$1(option.texto_visible) === convertTagsToUppercase$1(value); });
23201
+ // Cerrar dropdown al hacer click fuera
23202
+ useEffect(function () {
23203
+ var handleClickOutside = function (event) {
23204
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
23205
+ setIsOpen(false);
23206
+ }
23207
+ };
23208
+ document.addEventListener('mousedown', handleClickOutside);
23209
+ return function () {
23210
+ document.removeEventListener('mousedown', handleClickOutside);
23211
+ };
23212
+ }, []);
23213
+ return (jsxs("div", { className: "relative", ref: dropdownRef, children: [jsx("button", { type: "button", onClick: function () { return setIsOpen(!isOpen); }, className: "w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-left focus:border-sky-500 focus:outline-none focus:ring-2 focus:ring-sky-500", children: selectedOption ? convertTagsToUppercase$1(selectedOption.texto_visible) : placeholder }), isOpen && (jsx("div", { className: "absolute z-50 mt-1 max-h-60 w-full overflow-auto rounded-md border border-gray-300 bg-white shadow-lg", children: options.map(function (option) { return (jsx("button", { type: "button", onClick: function () {
23214
+ onChange(option.texto_visible);
23215
+ setIsOpen(false);
23216
+ }, className: "w-full px-3 py-2 text-left hover:bg-gray-100 focus:bg-gray-100 focus:outline-none", children: convertTagsToUppercase$1(option.texto_visible) }, option.id)); }) }))] }));
23217
+ };
23218
+
23219
+ // se convierte tags dentro del texto (excepto el tag principal H/h)
23220
+ var convertInnerTagsToUppercase = function (text) {
23221
+ return text.replace(/\(([a-z]\d*)\)/g, function (match, tag) {
23222
+ // si el tag es 'h' solo (sin número), no convertir
23223
+ if (tag === 'h')
23224
+ return match;
23225
+ return "(".concat(tag.toUpperCase(), ")");
23226
+ });
23227
+ };
23228
+ var MultiSelectorComponent = function (_a) {
23229
+ var value = _a.value, onChange = _a.onChange, options = _a.options, placeholder = _a.placeholder;
23230
+ var _b = useState(false), isOpen = _b[0], setIsOpen = _b[1];
23231
+ var dropdownRef = useRef(null);
23232
+ // se parsean los valores seleccionados (separados por " y ")
23233
+ var parseSelectedValues = function (val) {
23234
+ if (!val || val.trim() === '')
23235
+ return [];
23236
+ return val
23237
+ .split(' y ')
23238
+ .map(function (v) { return v.trim(); })
23239
+ .filter(Boolean);
23240
+ };
23241
+ var selectedValues = parseSelectedValues(value);
23242
+ // se verifica si una opción está seleccionada
23243
+ var isSelected = function (option) {
23244
+ var normalizedOption = convertInnerTagsToUppercase(option.texto_visible);
23245
+ return selectedValues.some(function (sv) { return convertInnerTagsToUppercase(sv) === normalizedOption; });
23246
+ };
23247
+ // se maneja el toggle de una opción
23248
+ var handleToggle = function (option) {
23249
+ var newSelected;
23250
+ if (isSelected(option)) {
23251
+ // se remueve
23252
+ newSelected = selectedValues.filter(function (sv) {
23253
+ return convertInnerTagsToUppercase(sv) !== convertInnerTagsToUppercase(option.texto_visible);
23254
+ });
23255
+ }
23256
+ else {
23257
+ // se agrega
23258
+ newSelected = __spreadArray(__spreadArray([], selectedValues, true), [option.texto_visible], false);
23259
+ }
23260
+ // se ordena según el orden de las opciones
23261
+ var sortedSelected = newSelected.sort(function (a, b) {
23262
+ var _a, _b;
23263
+ var optA = options.find(function (o) { return convertInnerTagsToUppercase(o.texto_visible) === convertInnerTagsToUppercase(a); });
23264
+ var optB = options.find(function (o) { return convertInnerTagsToUppercase(o.texto_visible) === convertInnerTagsToUppercase(b); });
23265
+ return ((_a = optA === null || optA === void 0 ? void 0 : optA.orden) !== null && _a !== void 0 ? _a : 0) - ((_b = optB === null || optB === void 0 ? void 0 : optB.orden) !== null && _b !== void 0 ? _b : 0);
23266
+ });
23267
+ // se unen con " y "
23268
+ onChange(sortedSelected.join(' y '));
23269
+ };
23270
+ // se cierra dropdown al hacer click fuera
23271
+ useEffect(function () {
23272
+ var handleClickOutside = function (event) {
23273
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
23274
+ setIsOpen(false);
23275
+ }
23276
+ };
23277
+ document.addEventListener('mousedown', handleClickOutside);
23278
+ return function () {
23279
+ document.removeEventListener('mousedown', handleClickOutside);
23280
+ };
23281
+ }, []);
23282
+ // se muestra el texto de selección
23283
+ var displayText = selectedValues.length > 0
23284
+ ? selectedValues.map(function (v) { return convertInnerTagsToUppercase(v); }).join(' y ')
23285
+ : placeholder;
23286
+ return (jsxs("div", { className: "relative", ref: dropdownRef, children: [jsx("button", { type: "button", onClick: function () { return setIsOpen(!isOpen); }, className: "w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-left focus:border-sky-500 focus:outline-none focus:ring-2 focus:ring-sky-500", children: jsxs("div", { className: "flex items-center justify-between", children: [jsx("span", { className: selectedValues.length === 0 ? 'text-gray-400' : '', children: displayText }), jsx("span", { className: "ml-2 text-xs text-gray-500", children: selectedValues.length > 0 && "(".concat(selectedValues.length, ")") })] }) }), isOpen && (jsx("div", { className: "absolute z-50 mt-1 max-h-60 w-full overflow-auto rounded-md border border-gray-300 bg-white shadow-lg", children: options.map(function (option) {
23287
+ var selected = isSelected(option);
23288
+ return (jsx("button", { type: "button", onClick: function () { return handleToggle(option); }, className: "flex w-full items-center px-3 py-2 text-left hover:bg-gray-100 focus:bg-gray-100 focus:outline-none ".concat(selected ? 'bg-sky-50' : ''), children: jsxs("div", { className: "flex flex-1 items-center", children: [jsx("div", { className: "mr-2 flex h-4 w-4 flex-shrink-0 items-center justify-center rounded border-2 ".concat(selected ? 'border-sky-600 bg-sky-600' : 'border-gray-300'), children: selected && (jsx("svg", { className: "h-3 w-3 text-white", fill: "none", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", viewBox: "0 0 24 24", stroke: "currentColor", children: jsx("path", { d: "M5 13l4 4L19 7" }) })) }), jsx("span", { children: convertInnerTagsToUppercase(option.texto_visible) })] }) }, option.id));
23289
+ }) }))] }));
23290
+ };
23291
+
23292
+ // Función auxiliar para convertir tags a mayúsculas
23293
+ var convertTagsToUppercase = function (text) {
23294
+ return text.replace(/\(([a-z]\d*)\)/g, function (_, tag) { return "(".concat(tag.toUpperCase(), ")"); });
23295
+ };
23296
+ var TextComponent = function (_a) {
23297
+ var label = _a.label, value = _a.value, onChange = _a.onChange, placeholder = _a.placeholder, _b = _a.rows, rows = _b === void 0 ? 3 : _b;
23298
+ // Manejar cambios en el textarea y convertir tags a mayúsculas
23299
+ var handleChange = function (e) {
23300
+ var newValue = e.target.value;
23301
+ var normalizedValue = convertTagsToUppercase(newValue);
23302
+ onChange(normalizedValue);
23303
+ };
23304
+ return (jsxs("div", { className: "space-y-4", children: [jsx("label", { className: "inline-block px-2 py-1 text-sm font-medium rounded ".concat(value ? 'text-green-800 bg-green-100' : 'text-orange-800'), style: value ? {} : { backgroundColor: 'rgb(254, 238, 221)' }, children: label }), jsx("textarea", { value: value, onChange: handleChange, placeholder: placeholder, className: "w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200 hover:border-gray-400 resize-none", rows: rows })] }));
23305
+ };
23306
+
23307
+ // Función para detectar el tipo de período según el formato de valores presentes
23308
+ var detectDateType = function (valor) {
23309
+ if (!valor)
23310
+ return 'dia';
23311
+ var first = valor.split('|').map(function (p) { return p.split(' - ')[0].trim(); }).find(Boolean) || '';
23312
+ if (/^\d{2}\/\d{2}\/\d{4}$/.test(first))
23313
+ return 'dia';
23314
+ if (/^\d{2}\/\d{4}$/.test(first))
23315
+ return 'mes';
23316
+ if (/^\d{4}$/.test(first))
23317
+ return 'año';
23318
+ return 'dia';
23319
+ };
23320
+ // Función para formatear fecha a YYYY-MM-DD
23321
+ var formatDateToYYYYMMDD = function (date) {
23322
+ if (!date)
23323
+ return '';
23324
+ var parts = date.split('/');
23325
+ if (parts.length === 3) {
23326
+ return "".concat(parts[2], "-").concat(parts[1].padStart(2, '0'), "-").concat(parts[0].padStart(2, '0'));
23327
+ }
23328
+ return date;
23329
+ };
23330
+ // Función para formatear fecha a dd/mm/yyyy
23331
+ var formatDateToDDMMYYYY = function (date) {
23332
+ if (!date)
23333
+ return '';
23334
+ // Si ya está en formato dd/mm/yyyy, devolverlo tal como está
23335
+ if (/^\d{2}\/\d{2}\/\d{4}$/.test(date)) {
23336
+ return date;
23337
+ }
23338
+ // Si está en formato YYYY-MM-DD, convertir a dd/mm/yyyy
23339
+ if (/^\d{4}-\d{2}-\d{2}$/.test(date)) {
23340
+ var parts = date.split('-');
23341
+ return "".concat(parts[2], "/").concat(parts[1], "/").concat(parts[0]);
23342
+ }
23343
+ return date;
23344
+ };
23345
+ // Mes: MM/YYYY <-> YYYY-MM
23346
+ var formatMonthToYYYYMM = function (mmYYYY) {
23347
+ if (!mmYYYY)
23348
+ return '';
23349
+ var _a = mmYYYY.split('/'), mm = _a[0], yyyy = _a[1];
23350
+ if (mm && yyyy)
23351
+ return "".concat(yyyy, "-").concat(mm.padStart(2, '0'));
23352
+ return mmYYYY;
23353
+ };
23354
+ var formatMonthToMMYYYY = function (yyyyMM) {
23355
+ if (!yyyyMM)
23356
+ return '';
23357
+ var _a = yyyyMM.split('-'), yyyy = _a[0], mm = _a[1];
23358
+ if (yyyy && mm)
23359
+ return "".concat(mm, "/").concat(yyyy);
23360
+ return yyyyMM;
23361
+ };
23362
+ // Comparador genérico para rangos
23363
+ var toComparable = function (v, tipo) {
23364
+ if (!v)
23365
+ return '';
23366
+ if (tipo === 'dia')
23367
+ return formatDateToYYYYMMDD(v);
23368
+ if (tipo === 'mes')
23369
+ return formatMonthToYYYYMM(v);
23370
+ return v; // año ya está en YYYY
23371
+ };
23372
+ var isValidRange = function (desde, hasta, tipo) {
23373
+ if (!desde || !hasta)
23374
+ return true;
23375
+ return toComparable(desde, tipo) <= toComparable(hasta, tipo);
23376
+ };
23377
+ // Función para parsear períodos
23378
+ var parsePeriods = function (valor) {
23379
+ if (!valor)
23380
+ return [{ desde: '', hasta: '' }];
23381
+ var periods = valor.split('|').map(function (period) {
23382
+ var parts = period.split(' - ');
23383
+ return {
23384
+ desde: parts[0] || '',
23385
+ hasta: parts[1] || ''
23386
+ };
23387
+ });
23388
+ return periods.length > 0 ? periods : [{ desde: '', hasta: '' }];
23389
+ };
23390
+ // Función para formatear períodos para reemplazo
23391
+ var formatPeriodsForReplacement = function (valor) {
23392
+ if (!valor)
23393
+ return '';
23394
+ // Si el valor no contiene '|' ni ' - ', es una fecha única
23395
+ if (!valor.includes('|') && !valor.includes(' - ')) {
23396
+ return valor; // Devolver la fecha tal como está
23397
+ }
23398
+ var periods = parsePeriods(valor);
23399
+ var validPeriods = periods.filter(function (p) { return p.desde && p.hasta; });
23400
+ if (validPeriods.length === 0)
23401
+ return '';
23402
+ // se formatea especial para:
23403
+ // - día: "del 01 de febrero del 2024 al 25 de marzo del 2024"
23404
+ // - mes: "de marzo del 2024 a mayo del 2024"
23405
+ var dayPattern = /^\d{2}\/\d{2}\/\d{4}$/;
23406
+ var monthPattern = /^\d{2}\/\d{4}$/;
23407
+ var monthNames = [
23408
+ 'enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio',
23409
+ 'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre'
23410
+ ];
23411
+ var formatLongDay = function (ddmmyyyy) {
23412
+ var _a = ddmmyyyy.split('/'), dd = _a[0], mm = _a[1], yyyy = _a[2];
23413
+ var monthIdx = Math.max(0, Math.min(11, Number(mm) - 1));
23414
+ var monthName = monthNames[monthIdx] || mm;
23415
+ return "".concat(dd, " de ").concat(monthName, " del ").concat(yyyy);
23416
+ };
23417
+ var formatLongMonth = function (mmyyyy) {
23418
+ var _a = mmyyyy.split('/'), mm = _a[0], yyyy = _a[1];
23419
+ var monthIdx = Math.max(0, Math.min(11, Number(mm) - 1));
23420
+ var monthName = monthNames[monthIdx] || mm;
23421
+ return "".concat(monthName, " del ").concat(yyyy);
23422
+ };
23423
+ var periodStrings = validPeriods.map(function (p) {
23424
+ var isDayRange = dayPattern.test(p.desde) && dayPattern.test(p.hasta);
23425
+ if (isDayRange) {
23426
+ return "del ".concat(formatLongDay(p.desde), " al ").concat(formatLongDay(p.hasta));
23427
+ }
23428
+ var isMonthRange = monthPattern.test(p.desde) && monthPattern.test(p.hasta);
23429
+ if (isMonthRange) {
23430
+ return "de ".concat(formatLongMonth(p.desde), " a ").concat(formatLongMonth(p.hasta));
23431
+ }
23432
+ var isYearRange = /^\d{4}$/.test(p.desde) && /^\d{4}$/.test(p.hasta);
23433
+ if (isYearRange) {
23434
+ return "desde el ".concat(p.desde, " al ").concat(p.hasta);
23435
+ }
23436
+ return "".concat(p.desde, " al ").concat(p.hasta);
23437
+ });
23438
+ if (periodStrings.length === 1) {
23439
+ return periodStrings[0];
23440
+ }
23441
+ else if (periodStrings.length === 2) {
23442
+ return "".concat(periodStrings[0], " y ").concat(periodStrings[1]);
23443
+ }
23444
+ else {
23445
+ var lastPeriod = periodStrings.pop();
23446
+ return "".concat(periodStrings.join(', '), " y ").concat(lastPeriod);
23447
+ }
23448
+ };
23449
+ var PeriodComponent = function (_a) {
23450
+ var label = _a.label, value = _a.value, onChange = _a.onChange;
23451
+ // Estados internos del componente
23452
+ var _b = useState('dia'), dateType = _b[0], setDateType = _b[1];
23453
+ // se inicializa el tipo una sola vez a partir del valor inicial; luego solo cambia por acción del usuario
23454
+ var initializedTypeRef = useRef(false);
23455
+ useEffect(function () {
23456
+ if (!initializedTypeRef.current) {
23457
+ var detectedType = detectDateType(value);
23458
+ setDateType(detectedType);
23459
+ initializedTypeRef.current = true;
23460
+ }
23461
+ }, [value]);
23462
+ // Handlers internos
23463
+ var handleTypeChange = function (newType) {
23464
+ setDateType(newType);
23465
+ onChange(''); // Limpiar el valor al cambiar tipo
23466
+ };
23467
+ // se maneja mediante rangos para todos los tipos (día, mes, año)
23468
+ var periods = parsePeriods(value);
23469
+ // detección de rangos duplicados (según tipo actual)
23470
+ var comparableRanges = periods.map(function (p) { return "".concat(toComparable(p.desde, dateType), "|").concat(toComparable(p.hasta, dateType)); });
23471
+ var seenKeys = new Set();
23472
+ var duplicateFlags = comparableRanges.map(function (key) {
23473
+ // evita marcar como duplicado si el rango está incompleto
23474
+ if (!key || key === '|' || key.startsWith('|') || key.endsWith('|'))
23475
+ return false;
23476
+ var isDup = seenKeys.has(key);
23477
+ seenKeys.add(key);
23478
+ return isDup;
23479
+ });
23480
+ var addPeriod = function () {
23481
+ var newPeriods = __spreadArray(__spreadArray([], periods, true), [{ desde: '', hasta: '' }], false);
23482
+ var newValor = newPeriods.map(function (p) { return "".concat(p.desde, " - ").concat(p.hasta); }).join('|');
23483
+ onChange(newValor);
23484
+ };
23485
+ var removePeriod = function (index) {
23486
+ var newPeriods = periods.filter(function (_, i) { return i !== index; });
23487
+ var newValor = newPeriods.map(function (p) { return "".concat(p.desde, " - ").concat(p.hasta); }).join('|');
23488
+ onChange(newValor);
23489
+ };
23490
+ var updatePeriod = function (index, field, value) {
23491
+ var _a;
23492
+ var newPeriods = __spreadArray([], periods, true);
23493
+ newPeriods[index] = __assign(__assign({}, newPeriods[index]), (_a = {}, _a[field] = value, _a));
23494
+ var newValor = newPeriods.map(function (p) { return "".concat(p.desde, " - ").concat(p.hasta); }).join('|');
23495
+ onChange(newValor);
23496
+ };
23497
+ // validaciones para habilitar/deshabilitar agregar rango
23498
+ var isPeriodComplete = function (p) { return !!(p.desde && p.hasta && isValidRange(p.desde, p.hasta, dateType)); };
23499
+ var lastPeriod = periods[periods.length - 1] || { desde: '', hasta: '' };
23500
+ var allRangesOrderValid = periods.every(function (p) { return !p.desde || !p.hasta || isValidRange(p.desde, p.hasta, dateType); })
23501
+ && periods.every(function (p, idx) { return idx === 0 || !periods[idx - 1].hasta || !p.desde || isValidRange(periods[idx - 1].hasta, p.desde, dateType); });
23502
+ var canAddAnother = isPeriodComplete(lastPeriod) && !duplicateFlags[periods.length - 1] && allRangesOrderValid;
23503
+ return (jsxs("div", { className: "space-y-4", children: [jsxs("label", { className: "inline-block px-2 py-1 text-sm font-medium rounded ".concat(value ? 'text-green-800 bg-green-100' : 'text-orange-800'), style: value ? {} : { backgroundColor: 'rgb(254, 238, 221)' }, children: ["(", label, ")"] }), jsxs("div", { className: "flex gap-2", children: [jsx("button", { type: "button", onClick: function () { return handleTypeChange('dia'); }, className: "px-3 py-2 text-sm rounded-md border transition-colors ".concat(dateType === 'dia'
23504
+ ? 'bg-gray-300 text-gray-900 border-gray-500 shadow-sm'
23505
+ : 'bg-gray-100 text-gray-700 border-gray-300 hover:bg-gray-200'), children: "D\u00EDa" }), jsx("button", { type: "button", onClick: function () { return handleTypeChange('mes'); }, className: "px-3 py-2 text-sm rounded-md border transition-colors ".concat(dateType === 'mes'
23506
+ ? 'bg-gray-300 text-gray-900 border-gray-500 shadow-sm'
23507
+ : 'bg-gray-100 text-gray-700 border-gray-300 hover:bg-gray-200'), children: "Mes" }), jsx("button", { type: "button", onClick: function () { return handleTypeChange('año'); }, className: "px-3 py-2 text-sm rounded-md border transition-colors ".concat(dateType === 'año'
23508
+ ? 'bg-gray-300 text-gray-900 border-gray-500 shadow-sm'
23509
+ : 'bg-gray-100 text-gray-700 border-gray-300 hover:bg-gray-200'), children: "A\u00F1o" })] }), (dateType === 'dia' || dateType === 'mes') && (jsxs(Fragment$1, { children: [periods.map(function (period, index) {
23510
+ var _a;
23511
+ return (jsxs("div", { className: "space-y-2", children: [jsxs("div", { className: "flex items-center gap-3", children: [jsx("div", { className: "flex-1", children: jsx("input", { type: dateType === 'mes' ? 'month' : 'date', min: (function () {
23512
+ var _a;
23513
+ if (index === 0)
23514
+ return undefined;
23515
+ var prevHasta = ((_a = periods[index - 1]) === null || _a === void 0 ? void 0 : _a.hasta) || '';
23516
+ if (!prevHasta)
23517
+ return undefined;
23518
+ return dateType === 'mes' ? formatMonthToYYYYMM(prevHasta) : formatDateToYYYYMMDD(prevHasta);
23519
+ })(), max: (function () {
23520
+ var today = new Date();
23521
+ if (dateType === 'mes') {
23522
+ var yyyy = today.getFullYear();
23523
+ var mm = String(today.getMonth() + 1).padStart(2, '0');
23524
+ return "".concat(yyyy, "-").concat(mm);
23525
+ }
23526
+ else {
23527
+ var yyyy = today.getFullYear();
23528
+ var mm = String(today.getMonth() + 1).padStart(2, '0');
23529
+ var dd = String(today.getDate()).padStart(2, '0');
23530
+ return "".concat(yyyy, "-").concat(mm, "-").concat(dd);
23531
+ }
23532
+ })(), value: dateType === 'mes'
23533
+ ? (period.desde ? formatMonthToYYYYMM(period.desde) : '')
23534
+ : (period.desde ? formatDateToYYYYMMDD(period.desde) : ''), onChange: function (e) {
23535
+ var newDesde = dateType === 'mes'
23536
+ ? formatMonthToMMYYYY(e.target.value)
23537
+ : formatDateToDDMMYYYY(e.target.value);
23538
+ updatePeriod(index, 'desde', newDesde);
23539
+ }, className: "w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200 hover:border-gray-400" }) }), jsx("span", { className: "text-sm text-gray-600 font-medium", children: "al" }), jsx("div", { className: "flex-1", children: jsxs("div", { className: "relative", children: [jsx("input", { type: dateType === 'mes' ? 'month' : 'date', min: period.desde ? (dateType === 'mes' ? formatMonthToYYYYMM(period.desde) : formatDateToYYYYMMDD(period.desde)) : undefined, max: index === periods.length - 1 ? (function () {
23540
+ var today = new Date();
23541
+ if (dateType === 'mes') {
23542
+ var yyyy = today.getFullYear();
23543
+ var mm = String(today.getMonth() + 1).padStart(2, '0');
23544
+ return "".concat(yyyy, "-").concat(mm);
23545
+ }
23546
+ else {
23547
+ var yyyy = today.getFullYear();
23548
+ var mm = String(today.getMonth() + 1).padStart(2, '0');
23549
+ var dd = String(today.getDate()).padStart(2, '0');
23550
+ return "".concat(yyyy, "-").concat(mm, "-").concat(dd);
23551
+ }
23552
+ })() : undefined, value: dateType === 'mes'
23553
+ ? (period.hasta ? formatMonthToYYYYMM(period.hasta) : '')
23554
+ : (period.hasta ? formatDateToYYYYMMDD(period.hasta) : ''), onChange: function (e) {
23555
+ var newHasta = dateType === 'mes'
23556
+ ? formatMonthToMMYYYY(e.target.value)
23557
+ : formatDateToDDMMYYYY(e.target.value);
23558
+ updatePeriod(index, 'hasta', newHasta);
23559
+ }, className: "w-full px-3 py-2 pr-10 border rounded-lg focus:outline-none focus:ring-2 focus:border-transparent transition-all duration-200 hover:border-gray-400 ".concat(period.desde && period.hasta && !isValidRange(period.desde, period.hasta, dateType)
23560
+ ? 'border-red-500 focus:ring-red-500'
23561
+ : 'border-gray-300 focus:ring-blue-500') }), periods.length > 1 && (jsx("button", { type: "button", onClick: function () { return removePeriod(index); }, className: "absolute right-2 top-1/2 transform -translate-y-1/2 text-red-500 hover:text-red-700 transition-colors", title: "Eliminar per\u00EDodo", children: jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) }))] }) })] }), index > 0 && ((_a = periods[index - 1]) === null || _a === void 0 ? void 0 : _a.hasta) && period.desde && !isValidRange(periods[index - 1].hasta, period.desde, dateType) && (jsx("p", { className: "text-xs text-red-600", children: "El inicio debe ser posterior o igual al final del rango anterior" })), duplicateFlags[index] && (jsx("p", { className: "text-xs text-red-600", children: "El rango est\u00E1 duplicado" })), period.desde && period.hasta && !isValidRange(period.desde, period.hasta, dateType) && (jsx("p", { className: "text-xs text-red-600", children: "La fecha final debe ser posterior a la fecha inicial" }))] }, index));
23562
+ }), jsx("div", { className: "w-full", children: jsx("button", { type: "button", onClick: addPeriod, disabled: !canAddAnother, className: "w-full px-3 py-2 text-sm border rounded-md transition-colors ".concat(canAddAnother
23563
+ ? 'bg-gray-100 text-gray-700 border-gray-300 hover:bg-gray-200'
23564
+ : 'bg-gray-200 text-gray-400 border-gray-300 cursor-not-allowed'), title: !canAddAnother ? 'Completa y corrige el rango actual antes de agregar otro' : '', children: "+ Agregar rango" }) })] })), dateType === 'año' && (jsxs(Fragment$1, { children: [periods.map(function (period, index) {
23565
+ var _a;
23566
+ return (jsxs("div", { className: "space-y-2", children: [jsxs("div", { className: "flex items-center gap-3", children: [jsx("div", { className: "flex-1", children: jsx("input", { type: "number", min: (function () {
23567
+ var _a;
23568
+ if (index === 0)
23569
+ return '1900';
23570
+ var prevHasta = ((_a = periods[index - 1]) === null || _a === void 0 ? void 0 : _a.hasta) || '';
23571
+ return prevHasta || '1900';
23572
+ })(), max: new Date().getFullYear().toString(), value: period.desde || '', onChange: function (e) {
23573
+ var value = e.target.value;
23574
+ var numValue = Number(value);
23575
+ var currentYear = new Date().getFullYear();
23576
+ // se valida que no sea mayor al año actual
23577
+ if (value && numValue > currentYear) {
23578
+ return; // no actualizar si supera el año actual
23579
+ }
23580
+ updatePeriod(index, 'desde', value);
23581
+ }, className: "w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200 hover:border-gray-400" }) }), jsx("span", { className: "text-sm text-gray-600 font-medium", children: "al" }), jsx("div", { className: "flex-1", children: jsxs("div", { className: "relative", children: [jsx("input", { type: "number", min: period.desde || '1900', max: index === periods.length - 1 ? new Date().getFullYear().toString() : '2100', value: period.hasta || '', onChange: function (e) {
23582
+ var value = e.target.value;
23583
+ var numValue = Number(value);
23584
+ var currentYear = new Date().getFullYear();
23585
+ var isLastPeriod = index === periods.length - 1;
23586
+ // se valida que el último período no supere el año actual
23587
+ if (isLastPeriod && value && numValue > currentYear) {
23588
+ return; // no actualizar si supera el año actual
23589
+ }
23590
+ updatePeriod(index, 'hasta', value);
23591
+ }, className: "w-full px-3 py-2 pr-10 border rounded-lg focus:outline-none focus:ring-2 focus:border-transparent transition-all duration-200 hover:border-gray-400 ".concat(period.desde && period.hasta && !isValidRange(period.desde, period.hasta, dateType)
23592
+ ? 'border-red-500 focus:ring-red-500'
23593
+ : 'border-gray-300 focus:ring-blue-500') }), periods.length > 1 && (jsx("button", { type: "button", onClick: function () { return removePeriod(index); }, className: "absolute right-2 top-1/2 transform -translate-y-1/2 text-red-500 hover:text-red-700 transition-colors", title: "Eliminar per\u00EDodo", children: jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) }))] }) })] }), index > 0 && ((_a = periods[index - 1]) === null || _a === void 0 ? void 0 : _a.hasta) && period.desde && !isValidRange(periods[index - 1].hasta, period.desde, dateType) && (jsx("p", { className: "text-xs text-red-600", children: "El inicio debe ser posterior o igual al final del rango anterior" })), period.desde && period.hasta && !isValidRange(period.desde, period.hasta, dateType) && (jsx("p", { className: "text-xs text-red-600", children: "El a\u00F1o final debe ser posterior o igual al inicial" }))] }, index));
23594
+ }), jsx("div", { className: "w-full", children: jsx("button", { type: "button", onClick: addPeriod, className: "w-full px-3 py-2 text-sm bg-gray-100 text-gray-700 border border-gray-300 rounded-md hover:bg-gray-200 transition-colors", children: "+ Agregar rango" }) })] }))] }));
23595
+ };
23596
+ // se calcula la cantidad total de meses de los períodos seleccionados (para tags P)
23597
+ function calcularMesesDePeriodos(valor) {
23598
+ console.log('@@@calcularMesesDePeriodos valor:', valor);
23599
+ if (!valor)
23600
+ return 0;
23601
+ var dayPattern = /^\d{2}\/\d{2}\/\d{4}$/;
23602
+ var monthPattern = /^\d{2}\/\d{4}$/;
23603
+ var yearPattern = /^\d{4}$/;
23604
+ var parseDay = function (s) {
23605
+ var _a = s.split('/').map(function (x) { return Number(x); }), dd = _a[0], mm = _a[1], yyyy = _a[2];
23606
+ return { y: yyyy, m: mm, d: dd };
23607
+ };
23608
+ var monthsDiffInclusive = function (y1, m1, y2, m2) { return (y2 - y1) * 12 + (m2 - m1) + 1; };
23609
+ var parts = valor.split('|').map(function (p) { return p.trim(); }).filter(Boolean);
23610
+ var total = 0;
23611
+ for (var _i = 0, parts_1 = parts; _i < parts_1.length; _i++) {
23612
+ var p = parts_1[_i];
23613
+ var _a = p.split(' - ').map(function (x) { return (x || '').trim(); }), desde = _a[0], hasta = _a[1];
23614
+ if (!desde || !hasta)
23615
+ continue;
23616
+ if (dayPattern.test(desde) && dayPattern.test(hasta)) {
23617
+ var a = parseDay(desde);
23618
+ var b = parseDay(hasta);
23619
+ total += monthsDiffInclusive(a.y, a.m, b.y, b.m);
23620
+ }
23621
+ else if (monthPattern.test(desde) && monthPattern.test(hasta)) {
23622
+ var _b = desde.split('/').map(Number), m1 = _b[0], y1 = _b[1];
23623
+ var _c = hasta.split('/').map(Number), m2 = _c[0], y2 = _c[1];
23624
+ total += monthsDiffInclusive(y1, m1, y2, m2);
23625
+ }
23626
+ else if (yearPattern.test(desde) && yearPattern.test(hasta)) {
23627
+ var y1 = Number(desde);
23628
+ var y2 = Number(hasta);
23629
+ total += (y2 - y1 + 1) * 12;
23630
+ }
23631
+ }
23632
+ console.log('@@@calcularMesesDePeriodos meses:', total);
23633
+ return total;
23634
+ }
23635
+ // se verifica si un período está completo (tiene ambas fechas)
23636
+ function isPeriodComplete(valor) {
23637
+ if (!valor)
23638
+ return false;
23639
+ // patrones válidos: día (dd/mm/yyyy), mes (mm/yyyy), año (yyyy)
23640
+ var dayPattern = /^\d{2}\/\d{2}\/\d{4}$/;
23641
+ var monthPattern = /^\d{2}\/\d{4}$/;
23642
+ var yearPattern = /^\d{4}$/;
23643
+ // si es un valor único (no contiene ' - ' ni '|'), está completo si coincide con alguno de los formatos
23644
+ if (!valor.includes(' - ') && !valor.includes('|')) {
23645
+ var v = valor.trim();
23646
+ return dayPattern.test(v) || monthPattern.test(v) || yearPattern.test(v);
23647
+ }
23648
+ // si contiene períodos, se verifica que cada uno tenga ambas fechas
23649
+ var periods = valor.split('|');
23650
+ return periods.every(function (period) {
23651
+ var trimmedPeriod = period.trim();
23652
+ if (!trimmedPeriod.includes(' - '))
23653
+ return false;
23654
+ var _a = trimmedPeriod.split(' - '), desde = _a[0], hasta = _a[1];
23655
+ var d = (desde || '').trim();
23656
+ var h = (hasta || '').trim();
23657
+ var isValidSide = function (s) { return dayPattern.test(s) || monthPattern.test(s) || yearPattern.test(s); };
23658
+ return !!d && !!h && isValidSide(d) && isValidSide(h);
23659
+ });
23660
+ }
23661
+
23662
+ // se normaliza el input a números y una sola coma
23663
+ var normalizeAmount = function (text) {
23664
+ // permite dígitos y comas
23665
+ var onlyNumbersAndComma = text.replace(/[^0-9,]/g, '');
23666
+ // deja solo la primera coma si hubiera más de una
23667
+ var seenComma = false;
23668
+ var result = '';
23669
+ for (var _i = 0, onlyNumbersAndComma_1 = onlyNumbersAndComma; _i < onlyNumbersAndComma_1.length; _i++) {
23670
+ var ch = onlyNumbersAndComma_1[_i];
23671
+ if (ch === ',') {
23672
+ if (!seenComma) {
23673
+ result += ch;
23674
+ seenComma = true;
23675
+ }
23676
+ }
23677
+ else {
23678
+ result += ch;
23679
+ }
23680
+ }
23681
+ return result;
23682
+ };
23683
+ var AmountComponent = function (_a) {
23684
+ var label = _a.label, value = _a.value, onChange = _a.onChange, placeholder = _a.placeholder;
23685
+ var handleChange = useCallback(function (e) {
23686
+ var normalized = normalizeAmount(e.target.value);
23687
+ onChange(normalized);
23688
+ }, [onChange]);
23689
+ return (jsxs("div", { className: "space-y-4", children: [jsx("label", { className: "inline-block px-2 py-1 text-sm font-medium rounded ".concat(value ? 'text-green-800 bg-green-100' : 'text-orange-800'), style: value ? {} : { backgroundColor: 'rgb(254, 238, 221)' }, children: label }), jsx("input", { type: "text", inputMode: "decimal", value: value, onChange: handleChange, placeholder: placeholder, className: "w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200 hover:border-gray-400" })] }));
23690
+ };
23691
+
23692
+ // se convierte YYYY-MM-DD -> dd/mm/yyyy
23693
+ var toDDMMYYYY = function (yyyyMMdd) {
23694
+ if (!yyyyMMdd)
23695
+ return '';
23696
+ var _a = yyyyMMdd.split('-'), yyyy = _a[0], mm = _a[1], dd = _a[2];
23697
+ if (!yyyy || !mm || !dd)
23698
+ return yyyyMMdd;
23699
+ return "".concat(dd.padStart(2, '0'), "/").concat(mm.padStart(2, '0'), "/").concat(yyyy);
23700
+ };
23701
+ // se convierte dd/mm/yyyy -> YYYY-MM-DD
23702
+ var toYYYYMMDD = function (ddMMyyyy) {
23703
+ if (!ddMMyyyy)
23704
+ return '';
23705
+ var _a = ddMMyyyy.split('/'), dd = _a[0], mm = _a[1], yyyy = _a[2];
23706
+ if (!dd || !mm || !yyyy)
23707
+ return ddMMyyyy;
23708
+ return "".concat(yyyy, "-").concat(mm.padStart(2, '0'), "-").concat(dd.padStart(2, '0'));
23709
+ };
23710
+ var DateComponent = function (_a) {
23711
+ var label = _a.label, value = _a.value, onChange = _a.onChange;
23712
+ var inputValue = value ? toYYYYMMDD(value) : '';
23713
+ var handleChange = function (e) {
23714
+ var v = e.target.value; // YYYY-MM-DD
23715
+ onChange(toDDMMYYYY(v)); // guarda dd/mm/yyyy
23716
+ };
23717
+ return (jsxs("div", { className: "space-y-4", children: [jsx("label", { className: "inline-block px-2 py-1 text-sm font-medium rounded ".concat(value ? 'text-green-800 bg-green-100' : 'text-orange-800'), style: value ? {} : { backgroundColor: 'rgb(254, 238, 221)' }, children: label }), jsx("input", { type: "date", value: inputValue, onChange: handleChange, className: "w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200 hover:border-gray-400" })] }));
23718
+ };
23719
+
23720
+ // se normaliza a entero positivo (> 0)
23721
+ var normalizePositiveInt = function (text) {
23722
+ var digits = text.replace(/[^0-9]/g, '');
23723
+ if (!digits)
23724
+ return '';
23725
+ // elimina ceros a la izquierda
23726
+ var normalized = String(parseInt(digits, 10));
23727
+ // si parseInt da NaN o 0, devolver vacío (no válido)
23728
+ if (!normalized || normalized === '0' || normalized === 'NaN')
23729
+ return '';
23730
+ return normalized;
23731
+ };
23732
+ var NumberComponent = function (_a) {
23733
+ var label = _a.label, value = _a.value, onChange = _a.onChange, placeholder = _a.placeholder;
23734
+ var handleChange = useCallback(function (e) {
23735
+ var normalized = normalizePositiveInt(e.target.value);
23736
+ onChange(normalized);
23737
+ }, [onChange]);
23738
+ return (jsxs("div", { className: "space-y-4", children: [jsx("label", { className: "inline-block px-2 py-1 text-sm font-medium rounded ".concat(value ? 'text-green-800 bg-green-100' : 'text-orange-800'), style: value ? {} : { backgroundColor: 'rgb(254, 238, 221)' }, children: label }), jsx("input", { type: "number", min: 1, step: 1, inputMode: "numeric", value: value, onChange: handleChange, placeholder: placeholder, className: "w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200 hover:border-gray-400" })] }));
23739
+ };
23740
+
23741
+ var ConstruirHechoInfraccionalModal = function (_a) {
23742
+ var isOpen = _a.isOpen, onClose = _a.onClose, onSave = _a.onSave, nombreTrabajador = _a.nombreTrabajador, hechoInfraccionalDataProp = _a.hechoInfraccionalData, loading = _a.loading, hechoInfraccionalDataSaved = _a.hechoInfraccionalDataSaved, _b = _a.numeroTrabajadoresConstatados, numeroTrabajadoresConstatados = _b === void 0 ? 0 : _b;
23743
+ console.log('hechoInfraccionalDataProp:', hechoInfraccionalDataProp);
23744
+ // se manejan los estados internos para la carga de datos
23745
+ var _c = useState(null), hechoInfraccionalData = _c[0], setHechoInfraccionalData = _c[1];
23746
+ var _d = useState(false), isSaving = _d[0], setIsSaving = _d[1];
23747
+ var _e = useState({
23748
+ previsualizacion: '',
23749
+ elementos: {},
23750
+ }), formData = _e[0], setFormData = _e[1];
23751
+ var _f = useState(''), textoOriginal = _f[0], setTextoOriginal = _f[1];
23752
+ // se guarda un mapeo de código en mayúscula -> case original del texto_base
23753
+ var _g = useState({}), tagCaseMap = _g[0], setTagCaseMap = _g[1];
23754
+ var ensureObservationTag = function (data) {
23755
+ var _a, _b;
23756
+ if (!(data === null || data === void 0 ? void 0 : data.data))
23757
+ return data;
23758
+ var clonedData = data;
23759
+ var currentText = clonedData.data.texto_base || '';
23760
+ var hasObservationInText = /\(O\)/.test(currentText);
23761
+ if (!hasObservationInText) {
23762
+ var needsSpace = currentText && !currentText.endsWith(' ');
23763
+ clonedData.data.texto_base = "".concat(currentText).concat(needsSpace ? ' ' : '', "(O)");
23764
+ }
23765
+ if (!Array.isArray(clonedData.data.elementos)) {
23766
+ clonedData.data.elementos = [];
23767
+ }
23768
+ var hasObservationElement = clonedData.data.elementos.some(function (elemento) { return elemento.codigo === 'O'; });
23769
+ if (!hasObservationElement) {
23770
+ var lastElement = clonedData.data.elementos[clonedData.data.elementos.length - 1];
23771
+ var newId = lastElement ? lastElement.id + 1 : 1;
23772
+ var newHechoId = lastElement ? lastElement.hecho_id : ((_b = (_a = clonedData.data) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : null);
23773
+ clonedData.data.elementos.push({
23774
+ id: newId,
23775
+ hecho_id: newHechoId,
23776
+ codigo: 'O',
23777
+ texto_placeholder: 'Ingrese observaciones generales... ',
23778
+ tipo_dato: 'texto',
23779
+ es_multiple: false,
23780
+ es_obligatorio: false,
23781
+ opciones: [],
23782
+ });
23783
+ }
23784
+ return clonedData;
23785
+ };
23786
+ // se sincroniza el dato entregado por el padre
23787
+ useEffect(function () {
23788
+ if (isOpen) {
23789
+ var dataClone = hechoInfraccionalDataProp
23790
+ ? JSON.parse(JSON.stringify(hechoInfraccionalDataProp))
23791
+ : null;
23792
+ var enhancedData = dataClone ? ensureObservationTag(dataClone) : null;
23793
+ setHechoInfraccionalData(enhancedData);
23794
+ }
23795
+ }, [isOpen, hechoInfraccionalDataProp]);
23796
+ // se limpian los datos cuando el modal se cierra
23797
+ useEffect(function () {
23798
+ if (!isOpen) {
23799
+ setHechoInfraccionalData(null);
23800
+ setFormData({
23801
+ previsualizacion: '',
23802
+ elementos: {},
23803
+ });
23804
+ setTextoOriginal('');
23805
+ setTagCaseMap({});
23806
+ setIsSaving(false);
23807
+ }
23808
+ }, [isOpen]);
23809
+ // se extraen los tags del texto base preservando mayúsculas/minúsculas
23810
+ var extractTagsFromText = function (text) {
23811
+ // se usa un regex más específico que NO detecta (a) cuando está dentro de una palabra
23812
+ // busca patrones como (H1), (P), (T1) pero NO (a) dentro de "trabajador(a)"
23813
+ var tagRegex = /(?<!\w)\(([A-Za-z]\d*)\)(?!\w)/g;
23814
+ var matches = [];
23815
+ var match;
23816
+ while ((match = tagRegex.exec(text)) !== null) {
23817
+ matches.push(match[1]); // se preserva el case original
23818
+ }
23819
+ return matches;
23820
+ };
23821
+ // se extraen todos los tags del estado actual (incluyendo opciones seleccionadas)
23822
+ var extractAllTagsFromCurrentState = function () {
23823
+ var allTags = new Set();
23824
+ // se agregan los tags del texto base
23825
+ var baseTags = extractTagsFromText(textoOriginal);
23826
+ baseTags.forEach(function (tag) { return allTags.add(tag); });
23827
+ // se agregan los tags de las opciones seleccionadas
23828
+ Object.values(formData.elementos).forEach(function (valor) {
23829
+ if (valor) {
23830
+ var tagsInValue = extractTagsFromText(valor);
23831
+ tagsInValue.forEach(function (tag) { return allTags.add(tag); });
23832
+ }
23833
+ });
23834
+ return Array.from(allTags);
23835
+ };
23836
+ // se resetea cuando se abre el modal
23837
+ useEffect(function () {
23838
+ if (isOpen) {
23839
+ // se resetea inmediatamente cuando se abre el modal
23840
+ setFormData({
23841
+ previsualizacion: '',
23842
+ elementos: {},
23843
+ });
23844
+ setTextoOriginal('');
23845
+ }
23846
+ }, [isOpen]);
23847
+ // se cargan los datos cuando se abre el modal
23848
+ useEffect(function () {
23849
+ if (hechoInfraccionalData === null || hechoInfraccionalData === void 0 ? void 0 : hechoInfraccionalData.data) {
23850
+ var elementosIniciales_1 = {};
23851
+ var textoBase = hechoInfraccionalData.data.texto_base || '';
23852
+ var caseMap_1 = {};
23853
+ // se extrae el mapeo de case del texto_base
23854
+ var tagsInText = extractTagsFromText(textoBase);
23855
+ tagsInText.forEach(function (tag) {
23856
+ var upperTag = tag.toUpperCase();
23857
+ // se guarda el case original del texto_base usando la clave en mayúscula
23858
+ caseMap_1[upperTag] = tag;
23859
+ });
23860
+ // se inicializan todos los elementos disponibles (se muestran dinámicamente según necesidad)
23861
+ if (hechoInfraccionalData.data.elementos) {
23862
+ hechoInfraccionalData.data.elementos.forEach(function (elemento) {
23863
+ // la API devuelve el código en mayúscula, se usa como clave
23864
+ elementosIniciales_1[elemento.codigo.toUpperCase()] = '';
23865
+ // se reemplaza [TRABAJADOR] y [FECHA] en las opciones del elemento
23866
+ if (elemento.opciones) {
23867
+ elemento.opciones.forEach(function (opcion) {
23868
+ opcion.texto_visible = replaceTrabajadorTag(opcion.texto_visible);
23869
+ opcion.texto_visible = replaceFechaTag(opcion.texto_visible);
23870
+ opcion.texto_visible = replaceNumeroTrabajadoresConstatadosTag(opcion.texto_visible);
23871
+ // Tags como (T1)(T2) solo en opciones: inicializar claves y case como en front002
23872
+ extractTagsFromText(opcion.texto_visible).forEach(function (tag) {
23873
+ var upperTag = tag.toUpperCase();
23874
+ if (!elementosIniciales_1[upperTag]) {
23875
+ elementosIniciales_1[upperTag] = '';
23876
+ }
23877
+ if (!caseMap_1[upperTag]) {
23878
+ caseMap_1[upperTag] = tag;
23879
+ }
23880
+ });
23881
+ });
23882
+ }
23883
+ });
23884
+ }
23885
+ // se agregan elementos especiales (como P, M, F y N) que no están en la API
23886
+ tagsInText.forEach(function (tag) {
23887
+ var upperTag = tag.toUpperCase();
23888
+ var treatAsDate = isDateOverrideForPeriodTag(tag);
23889
+ var isSpecial = treatAsDate ||
23890
+ isPeriodTag(tag) ||
23891
+ isAmountTag(tag) ||
23892
+ isDateTag(tag) ||
23893
+ /^N\d*$/i.test(tag);
23894
+ if (isSpecial && !elementosIniciales_1[upperTag]) {
23895
+ elementosIniciales_1[upperTag] = '';
23896
+ }
23897
+ });
23898
+ // si hay data previamente guardada, sobreescribir valores
23899
+ console.log('hechoInfraccionalDataSaved:', { hechoInfraccionalDataSaved: hechoInfraccionalDataSaved });
23900
+ var elementosFinales = __assign({}, elementosIniciales_1);
23901
+ if (hechoInfraccionalDataSaved === null || hechoInfraccionalDataSaved === void 0 ? void 0 : hechoInfraccionalDataSaved.elementos) {
23902
+ elementosFinales = __assign(__assign({}, elementosIniciales_1), Object.fromEntries(Object.entries(hechoInfraccionalDataSaved.elementos).map(function (_a) {
23903
+ var k = _a[0], v = _a[1];
23904
+ return [
23905
+ k.toUpperCase(),
23906
+ String(v),
23907
+ ];
23908
+ })));
23909
+ }
23910
+ // reconstruir previsualización desde el texto base y elementos finales
23911
+ var previsualizacionInicial = rebuildTextFromOriginal(textoBase, elementosFinales);
23912
+ // se mantiene el texto base con los tags especiales para el coloreado
23913
+ setFormData({
23914
+ previsualizacion: previsualizacionInicial,
23915
+ elementos: elementosFinales,
23916
+ });
23917
+ setTextoOriginal(textoBase);
23918
+ setTagCaseMap(caseMap_1);
23919
+ }
23920
+ else {
23921
+ // se resetea cuando no hay datos
23922
+ setFormData({
23923
+ previsualizacion: '',
23924
+ elementos: {},
23925
+ });
23926
+ setTextoOriginal('');
23927
+ setTagCaseMap({});
23928
+ }
23929
+ }, [hechoInfraccionalData, hechoInfraccionalDataSaved]);
23930
+ // se detecta si un tag es de período
23931
+ var isPeriodTag = function (tag) {
23932
+ return /^P\d*$/i.test(tag);
23933
+ };
23934
+ // se detecta si un tag es de monto
23935
+ var isAmountTag = function (tag) {
23936
+ return /^M\d*$/i.test(tag);
23937
+ };
23938
+ // se detecta si un tag es de fecha específica (F)
23939
+ var isDateTag = function (tag) {
23940
+ return /^F\d*$/i.test(tag);
23941
+ };
23942
+ // si aparece "fecha(tag)" o "día(tag)" y el tag es de período (P), se interpreta como fecha (F)
23943
+ var isDateOverrideForPeriodTag = function (tag) {
23944
+ if (!isPeriodTag(tag))
23945
+ return false;
23946
+ var baseTag = tag.replace(/\d+$/, ''); // P2, P3 -> P
23947
+ var pattern = new RegExp("(?:fecha|(?:el\\s+)?d[i\u00ED]a)\\s*\\(\\s*".concat(baseTag, "\\s*\\)"), 'i');
23948
+ // buscar en el texto base
23949
+ if (pattern.test(textoOriginal)) {
23950
+ return true;
23951
+ }
23952
+ // buscar en los valores seleccionados (por ejemplo dentro de H2)
23953
+ for (var _i = 0, _a = Object.values(formData.elementos); _i < _a.length; _i++) {
23954
+ var valor = _a[_i];
23955
+ if (typeof valor === 'string' && pattern.test(valor)) {
23956
+ return true;
23957
+ }
23958
+ }
23959
+ return false;
23960
+ };
23961
+ // si aparece "año(tag)" y el tag es de período (P), se interpreta como número (año)
23962
+ var isYearOverrideForPeriodTag = function (tag) {
23963
+ if (!isPeriodTag(tag))
23964
+ return false;
23965
+ var baseTag = tag.replace(/\d+$/, ''); // P2, P3 -> P
23966
+ var pattern = new RegExp("a(?:\u00F1|n)os*(s*".concat(baseTag, "s*)"), 'i');
23967
+ // prueba directa con acento y sin acento
23968
+ if (pattern.test(textoOriginal))
23969
+ return true;
23970
+ var normalize = function (s) { return s.normalize('NFD').replace(/[\u0300-\u036f]/g, ''); };
23971
+ var textoSinAcentos = normalize(textoOriginal);
23972
+ var patternNoAccent = new RegExp("anos*(s*".concat(baseTag, "s*)"), 'i');
23973
+ if (patternNoAccent.test(textoSinAcentos))
23974
+ return true;
23975
+ // fallback por inclusión simple
23976
+ var low = textoOriginal.toLowerCase();
23977
+ if (low.includes("a\u00F1o (".concat(baseTag.toLowerCase(), ")")) ||
23978
+ low.includes("a\u00F1o(".concat(baseTag.toLowerCase(), ")")))
23979
+ return true;
23980
+ var lowNoAccent = textoSinAcentos.toLowerCase();
23981
+ if (lowNoAccent.includes("ano (".concat(baseTag.toLowerCase(), ")")) ||
23982
+ lowNoAccent.includes("ano(".concat(baseTag.toLowerCase(), ")")))
23983
+ return true;
23984
+ for (var _i = 0, _a = Object.values(formData.elementos); _i < _a.length; _i++) {
23985
+ var valor = _a[_i];
23986
+ if (typeof valor === 'string') {
23987
+ if (pattern.test(valor))
23988
+ return true;
23989
+ var valorSinAcentos = normalize(valor);
23990
+ if (patternNoAccent.test(valorSinAcentos))
23991
+ return true;
23992
+ var vlow = valor.toLowerCase();
23993
+ if (vlow.includes("a\u00F1o (".concat(baseTag.toLowerCase(), ")")) ||
23994
+ vlow.includes("a\u00F1o(".concat(baseTag.toLowerCase(), ")")))
23995
+ return true;
23996
+ var vlowNoAccent = valorSinAcentos.toLowerCase();
23997
+ if (vlowNoAccent.includes("ano (".concat(baseTag.toLowerCase(), ")")) ||
23998
+ vlowNoAccent.includes("ano(".concat(baseTag.toLowerCase(), ")")))
23999
+ return true;
24000
+ }
24001
+ }
24002
+ return false;
24003
+ };
24004
+ // se detecta si un tag es numérico (N)
24005
+ var isNumberTag = function (tag) {
24006
+ return /^N\d*$/i.test(tag);
24007
+ };
24008
+ // se reemplaza el tag [TRABAJADOR] con el nombre del trabajador
24009
+ var replaceTrabajadorTag = function (text) {
24010
+ return text.replace(/\[TRABAJADOR\]/g, nombreTrabajador);
24011
+ };
24012
+ var replaceNumeroTrabajadoresConstatadosTag = function (text) {
24013
+ return text.replace(/\[NUMEROTRABAJADORESCONSTATADOS\]/g, String(numeroTrabajadoresConstatados));
24014
+ };
24015
+ // se obtiene la fecha actual en formato dd/mm/yyyy
24016
+ var getFechaActual = function () {
24017
+ var hoy = new Date();
24018
+ var dia = hoy.getDate().toString().padStart(2, '0');
24019
+ var mes = (hoy.getMonth() + 1).toString().padStart(2, '0');
24020
+ var año = hoy.getFullYear();
24021
+ return "".concat(dia, "/").concat(mes, "/").concat(año);
24022
+ };
24023
+ function formatearMilesSinDecimales(valor) {
24024
+ var numero = Number(String(valor)
24025
+ .replace(/\./g, '') // quita puntos
24026
+ .replace(',', ''));
24027
+ return numero.toLocaleString('es-CL', {
24028
+ minimumFractionDigits: 0,
24029
+ maximumFractionDigits: 0,
24030
+ });
24031
+ }
24032
+ // se calcula la suma de meses considerando todos los tags P del formulario (excluye overrides a fecha o año)
24033
+ var calcularMesesTotales = function () {
24034
+ var tags = extractAllTagsFromCurrentState().filter(function (t) { return isPeriodTag(t) && !isDateOverrideForPeriodTag(t) && !isYearOverrideForPeriodTag(t); });
24035
+ var total = 0;
24036
+ tags.forEach(function (t) {
24037
+ var v = formData.elementos[t.toUpperCase()];
24038
+ if (v)
24039
+ total += calcularMesesDePeriodos(v);
24040
+ });
24041
+ return total;
24042
+ };
24043
+ // se reemplaza el tag [FECHA] con la fecha actual
24044
+ var replaceFechaTag = function (text) {
24045
+ return text.replace(/\[FECHA\]/g, getFechaActual());
24046
+ };
24047
+ // se manejan los cambios en elementos
24048
+ var handleElementoChange = function (codigo, valor) {
24049
+ setFormData(function (prev) {
24050
+ var nuevosElementos = __assign({}, prev.elementos);
24051
+ // se preserva el valor tal cual, sin normalizar a mayúsculas
24052
+ // solo se normalizan tags internos que NO son 'h' o 'H' solos
24053
+ var valorProcesado = valor;
24054
+ if (!isPeriodTag(codigo)) {
24055
+ // se convierten tags a mayúsculas excepto (h) que debe preservarse
24056
+ valorProcesado = valor.replace(/\(([a-z]\d*)\)/g, function (match, tag) {
24057
+ if (tag === 'h')
24058
+ return match; // se preserva (h) minúscula
24059
+ return "(".concat(tag.toUpperCase(), ")");
24060
+ });
24061
+ }
24062
+ if (isAmountTag(codigo)) {
24063
+ valorProcesado = '$' + formatearMilesSinDecimales(valor);
24064
+ }
24065
+ // se actualiza el elemento seleccionado
24066
+ var codigoUpper = codigo.toUpperCase();
24067
+ nuevosElementos[codigoUpper] = valorProcesado;
24068
+ // si se cambió un elemento padre, se resetean todos los elementos hijos
24069
+ // que ya no están presentes en el nuevo valor seleccionado
24070
+ if (valorProcesado) {
24071
+ var tagsEnNuevoValor_1 = extractTagsFromText(valorProcesado);
24072
+ var tagsEnValorAnterior = extractTagsFromText(prev.elementos[codigoUpper] || '');
24073
+ // se encuentran los tags que estaban en el valor anterior pero no en el nuevo
24074
+ var tagsAResetear = tagsEnValorAnterior.filter(function (tag) { return !tagsEnNuevoValor_1.includes(tag); });
24075
+ // se resetean los elementos que ya no son válidos
24076
+ tagsAResetear.forEach(function (tag) {
24077
+ nuevosElementos[tag.toUpperCase()] = '';
24078
+ });
24079
+ }
24080
+ else {
24081
+ // si se limpió el valor, se resetean todos los elementos hijos
24082
+ var tagsEnValorAnterior = extractTagsFromText(prev.elementos[codigoUpper] || '');
24083
+ tagsEnValorAnterior.forEach(function (tag) {
24084
+ nuevosElementos[tag.toUpperCase()] = '';
24085
+ });
24086
+ }
24087
+ // se reconstruye la previsualización desde el texto original
24088
+ var newPrevisualizacion = rebuildTextFromOriginal(textoOriginal, nuevosElementos);
24089
+ return __assign(__assign({}, prev), { elementos: nuevosElementos, previsualizacion: newPrevisualizacion });
24090
+ });
24091
+ };
24092
+ // se procesan los tags anidados en un valor
24093
+ var processNestedTags = function (text, elementos) {
24094
+ var result = text;
24095
+ var hasChanges = true;
24096
+ var iterations = 0;
24097
+ var maxIterations = 5; // se previenen bucles infinitos
24098
+ while (hasChanges && iterations < maxIterations) {
24099
+ hasChanges = false;
24100
+ iterations++;
24101
+ var tagRegex = /\(([A-Za-z]\d*)\)/g;
24102
+ var match = void 0;
24103
+ while ((match = tagRegex.exec(result)) !== null) {
24104
+ var fullMatch = match[0], codigo = match[1];
24105
+ // se busca el valor usando mayúscula (como vienen de la API)
24106
+ var codigoUpper = codigo.toUpperCase();
24107
+ var valor = elementos[codigoUpper];
24108
+ if (valor) {
24109
+ var valorFormateado = valor;
24110
+ if (isPeriodTag(codigo)) {
24111
+ valorFormateado = formatPeriodsForReplacement(valor);
24112
+ }
24113
+ else if (isAmountTag(codigo)) {
24114
+ valorFormateado = valor;
24115
+ }
24116
+ else {
24117
+ // se preserva el case, solo se normalizan tags internos excepto (h)
24118
+ valorFormateado = valor.replace(/\(([a-z]\d*)\)/g, function (match, tag) {
24119
+ if (tag === 'h')
24120
+ return match;
24121
+ return "(".concat(tag.toUpperCase(), ")");
24122
+ });
24123
+ }
24124
+ // se escapan caracteres especiales del regex
24125
+ var escapedTag = fullMatch.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
24126
+ var beforeReplace = result;
24127
+ console.log('processNestedTags', { fullMatch: fullMatch, codigo: codigo, valor: valor, valorFormateado: valorFormateado });
24128
+ result = result.replace(new RegExp(escapedTag, 'g'), valorFormateado);
24129
+ if (beforeReplace !== result) {
24130
+ hasChanges = true;
24131
+ }
24132
+ }
24133
+ }
24134
+ }
24135
+ return result;
24136
+ };
24137
+ // se reconstruye el texto desde el original con reemplazos anidados
24138
+ var rebuildTextFromOriginal = function (originalText, elementos) {
24139
+ var result = originalText;
24140
+ var hasChanges = true;
24141
+ var iterations = 0;
24142
+ var maxIterations = 10; // se previenen bucles infinitos
24143
+ // se itera hasta que no haya más reemplazos que hacer
24144
+ while (hasChanges && iterations < maxIterations) {
24145
+ hasChanges = false;
24146
+ iterations++;
24147
+ // Regex corregido: ahora incluye [NUMEROTRABAJADORESCONSTATADOS]
24148
+ var tagRegex = /((?<!\w)\(([A-Za-z]\d*)\)(?!\w)|\[TRABAJADOR\]|\[FECHA\]|\[NUMEROTRABAJADORESCONSTATADOS\])/g;
24149
+ var match = void 0;
24150
+ var replacements = [];
24151
+ // se busca el tag (O) y se elimina en caso de no tener valor
24152
+ var OBSERVATION_TAG = 'O';
24153
+ if (!elementos[OBSERVATION_TAG]) {
24154
+ result = result.replace(/\(O\)/g, '');
24155
+ }
24156
+ while ((match = tagRegex.exec(result)) !== null) {
24157
+ var fullMatch = match[0];
24158
+ // Tags especiales
24159
+ if (fullMatch === '[TRABAJADOR]' ||
24160
+ fullMatch === '[FECHA]' ||
24161
+ fullMatch === '[NUMEROTRABAJADORESCONSTATADOS]') {
24162
+ var replacement = fullMatch === '[TRABAJADOR]'
24163
+ ? nombreTrabajador
24164
+ : fullMatch === '[FECHA]'
24165
+ ? getFechaActual()
24166
+ : String(numeroTrabajadoresConstatados);
24167
+ replacements.push({ tag: fullMatch, replacement: replacement });
24168
+ }
24169
+ else {
24170
+ // Tag normal (H1), (T1), etc.
24171
+ var codigoSinParentesis = fullMatch.slice(1, -1); // (H1) -> H1
24172
+ var codigoUpper = codigoSinParentesis.toUpperCase();
24173
+ var valor = elementos[codigoUpper];
24174
+ if (valor) {
24175
+ var valorFormateado = valor;
24176
+ if (isPeriodTag(codigoSinParentesis)) {
24177
+ valorFormateado = formatPeriodsForReplacement(valor);
24178
+ }
24179
+ else if (isAmountTag(codigoSinParentesis)) {
24180
+ valorFormateado = valor;
24181
+ }
24182
+ else {
24183
+ // se preservan tags internos
24184
+ valorFormateado = valor.replace(/\(([a-z]\d*)\)/g, function (match, tag) {
24185
+ if (tag === 'h')
24186
+ return match;
24187
+ return "(".concat(tag.toUpperCase(), ")");
24188
+ });
24189
+ }
24190
+ // no se procesa recursivamente aquí, se hará en la siguiente iteración
24191
+ replacements.push({ tag: fullMatch, replacement: valorFormateado });
24192
+ }
24193
+ }
24194
+ }
24195
+ // se aplican los reemplazos
24196
+ replacements.forEach(function (_a) {
24197
+ var tag = _a.tag, replacement = _a.replacement;
24198
+ if (result.includes(tag)) {
24199
+ var escapedTag = tag.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
24200
+ var beforeReplace = result;
24201
+ result = result.replace(new RegExp(escapedTag, 'g'), replacement);
24202
+ if (beforeReplace !== result) {
24203
+ hasChanges = true;
24204
+ }
24205
+ }
24206
+ });
24207
+ }
24208
+ return result;
24209
+ };
24210
+ // se renderiza el texto con colores
24211
+ var renderTextWithColors = function (text) {
24212
+ if (!text)
24213
+ return null;
24214
+ var processNestedReplacements = function (inputText) {
24215
+ var parts = [];
24216
+ var lastIndex = 0;
24217
+ // se buscan los tags en el texto (incluyendo [TRABAJADOR] y [FECHA])
24218
+ // se usa el mismo regex mejorado que NO detecta (a) dentro de palabras
24219
+ var tagRegex = /((?<!\w)\([A-Za-z]\d*\)(?!\w)|\[TRABAJADOR\]|\[FECHA\]|\[NUMEROTRABAJADORESCONSTATADOS\])/g;
24220
+ var match;
24221
+ while ((match = tagRegex.exec(inputText)) !== null) {
24222
+ var fullMatch = match[0];
24223
+ var startIndex = match.index;
24224
+ // se agrega el texto antes del tag
24225
+ if (startIndex > lastIndex) {
24226
+ parts.push(inputText.slice(lastIndex, startIndex));
24227
+ }
24228
+ // se determina si es un tag especial [TRABAJADOR] o [FECHA]
24229
+ if (fullMatch === '[TRABAJADOR]' ||
24230
+ fullMatch === '[FECHA]' ||
24231
+ fullMatch === '[NUMEROTRABAJADORESCONSTATADOS]') {
24232
+ // tags especiales reemplazados - color verde
24233
+ var replacement = fullMatch === '[TRABAJADOR]'
24234
+ ? nombreTrabajador
24235
+ : fullMatch === '[FECHA]'
24236
+ ? getFechaActual()
24237
+ : String(numeroTrabajadoresConstatados);
24238
+ parts.push(jsx("span", { className: "rounded bg-green-100 px-1 text-green-800", children: replacement }, "".concat(fullMatch, "-").concat(startIndex)));
24239
+ }
24240
+ else {
24241
+ // se maneja como tag normal (H1), (T1), etc.
24242
+ var codigo = fullMatch.slice(1, -1); // remover paréntesis preservando case
24243
+ var codigoUpper = codigo.toUpperCase(); // se usa mayúscula para buscar en elementos
24244
+ // se busca el valor usando el código en mayúscula (como vienen de la API)
24245
+ var valor = formData.elementos[codigoUpper];
24246
+ if (valor) {
24247
+ var valorProcesado = void 0;
24248
+ if (isPeriodTag(codigoUpper)) {
24249
+ valorProcesado = formatPeriodsForReplacement(valor);
24250
+ }
24251
+ else if (isAmountTag(codigoUpper)) {
24252
+ valorProcesado = valor;
24253
+ }
24254
+ else {
24255
+ valorProcesado = processNestedTags(valor, formData.elementos);
24256
+ }
24257
+ // texto reemplazado - color verde
24258
+ parts.push(jsx("span", { className: "rounded bg-green-100 px-1 text-green-800", children: valorProcesado }, "".concat(codigo, "-").concat(startIndex)));
24259
+ }
24260
+ else {
24261
+ // tag sin reemplazar - color naranja (muestra el case original del texto_base)
24262
+ parts.push(jsx("span", { className: "rounded bg-orange-100 px-1 text-orange-800", children: fullMatch }, "".concat(codigo, "-").concat(startIndex)));
24263
+ }
24264
+ }
24265
+ lastIndex = startIndex + fullMatch.length;
24266
+ }
24267
+ // se agrega el texto restante
24268
+ if (lastIndex < inputText.length) {
24269
+ parts.push(inputText.slice(lastIndex));
24270
+ }
24271
+ return parts.length > 0 ? parts : inputText;
24272
+ };
24273
+ return processNestedReplacements(text);
24274
+ };
24275
+ // se renderiza el elemento según su tipo
24276
+ var renderElemento = function (elemento) {
24277
+ var tag = elemento.codigo;
24278
+ var valor = formData.elementos[tag.toUpperCase()] || '';
24279
+ var isDateOv = isDateOverrideForPeriodTag(tag);
24280
+ var isYearOv = isYearOverrideForPeriodTag(tag);
24281
+ // prioridad: fecha (override), año (override), luego período
24282
+ if (isDateTag(tag) || (isPeriodTag(tag) && isDateOv)) {
24283
+ return (jsx(DateComponent, { label: "(".concat(tag, ")"), value: valor, onChange: function (value) { return handleElementoChange(tag, value); } }, tag));
24284
+ }
24285
+ if (isPeriodTag(tag) && isYearOv) {
24286
+ return (jsx(NumberComponent, { label: "(".concat(tag, ")"), value: valor, onChange: function (value) { return handleElementoChange(tag, value); }, placeholder: 'Ingrese año (4 dígitos)' }, tag));
24287
+ }
24288
+ if (isPeriodTag(tag) && !isDateOv && !isYearOv) {
24289
+ return (jsx(PeriodComponent, { label: tag, value: valor, onChange: function (value) { return handleElementoChange(tag, value); } }, tag));
24290
+ }
24291
+ if (isAmountTag(tag)) {
24292
+ return (jsx(AmountComponent, { label: "(".concat(tag, ")"), value: valor, onChange: function (value) { return handleElementoChange(tag, value); }, placeholder: elemento.texto_placeholder || 'Ingrese el monto' }, tag));
24293
+ }
24294
+ if (/^N\d*$/i.test(tag)) {
24295
+ return (jsx(NumberComponent, { label: "(".concat(tag, ")"), value: valor, onChange: function (value) { return handleElementoChange(tag, value); }, placeholder: elemento.texto_placeholder || 'Ingrese un número mayor a 0' }, tag));
24296
+ }
24297
+ if (elemento.tipo_dato === 'seleccion') {
24298
+ // se obtiene el case original del texto_base para este tag
24299
+ // el tag ya viene en mayúscula de la API, se busca en el mapa (clave siempre en mayúscula)
24300
+ var originalCase = tagCaseMap[tag.toUpperCase()] || tag;
24301
+ // se detecta si es selección múltiple (H mayúscula) o simple (h minúscula) según el case original
24302
+ var isMultiple = originalCase === 'H' ||
24303
+ (originalCase.length > 1 && originalCase[0] === 'H' && /^\d+$/.test(originalCase.slice(1)));
24304
+ return (jsxs("div", { className: "space-y-4", children: [jsxs("label", { className: "inline-block rounded px-2 py-1 text-sm font-medium ".concat(valor ? 'bg-green-100 text-green-800' : 'text-orange-800'), style: valor ? {} : { backgroundColor: 'rgb(254, 238, 221)' }, children: ["(", originalCase, ")", isMultiple && jsx("span", { className: "ml-1 text-xs", children: "(m\u00FAltiple)" })] }), isMultiple ? (jsx(MultiSelectorComponent, { value: valor, onChange: function (value) { return handleElementoChange(tag, value); }, options: elemento.opciones, placeholder: "Seleccionar ".concat(originalCase, "...") })) : (jsx(SelectorComponent, { value: valor, onChange: function (value) { return handleElementoChange(tag, value); }, options: elemento.opciones, placeholder: "Seleccionar ".concat(originalCase, "...") }))] }, tag));
24305
+ }
24306
+ // por defecto, se renderiza como texto
24307
+ return (jsx(TextComponent, { label: tag !== 'O' ? "(".concat(tag, ")") : '(Observaciones)', value: valor, onChange: function (value) { return handleElementoChange(tag, value); }, placeholder: elemento.texto_placeholder || "Ingrese ".concat(tag, "..."), rows: 3 }, tag));
24308
+ };
24309
+ // se verifica si todos los tags están completos
24310
+ var areAllTagsComplete = function () {
24311
+ // se obtienen todos los tags del estado actual (incluidos anidados y renombrados como P2, P3, ...)
24312
+ var allTags = extractAllTagsFromCurrentState();
24313
+ var indexOfObservations = allTags.indexOf('O');
24314
+ if (indexOfObservations !== -1) {
24315
+ allTags.splice(indexOfObservations, 1);
24316
+ }
24317
+ // se verifica que todos los tags tengan valores
24318
+ return allTags.every(function (tag) {
24319
+ // se normaliza el tag a mayúscula para buscar en elementos (como vienen de la API)
24320
+ var tagUpper = tag.toUpperCase();
24321
+ if (isPeriodTag(tag) && !isDateOverrideForPeriodTag(tag)) {
24322
+ // para períodos, se verifica que tengan valor y estén completos
24323
+ var valor = formData.elementos[tagUpper];
24324
+ if (!valor || valor.trim() === '')
24325
+ return false;
24326
+ // se verifica que los períodos estén completos (tengan ambas fechas)
24327
+ return isPeriodComplete(valor);
24328
+ }
24329
+ else if (isPeriodTag(tag) && isDateOverrideForPeriodTag(tag)) {
24330
+ // si es override a fecha, requiere una fecha simple dd/mm/yyyy
24331
+ var valor = (formData.elementos[tagUpper] || '').trim();
24332
+ return /^\d{2}\/\d{2}\/\d{4}$/.test(valor);
24333
+ }
24334
+ else if (isNumberTag(tag)) {
24335
+ var valor = (formData.elementos[tagUpper] || '').trim();
24336
+ if (!valor)
24337
+ return false;
24338
+ // entero positivo > 0
24339
+ return /^[1-9]\d*$/.test(valor);
24340
+ }
24341
+ else if (isAmountTag(tag)) {
24342
+ var valor = (formData.elementos[tagUpper] || '').trim();
24343
+ if (valor == '$0')
24344
+ return false;
24345
+ return true;
24346
+ }
24347
+ else {
24348
+ // para otros elementos, se verifica que tengan valor
24349
+ return formData.elementos[tagUpper] && formData.elementos[tagUpper].trim() !== '';
24350
+ }
24351
+ });
24352
+ };
24353
+ // se verifica si un período está completo (tiene ambas fechas)
24354
+ // se maneja el guardado
24355
+ var handleSave = function () { return __awaiter$1(void 0, void 0, void 0, function () {
24356
+ var textoFinal, meses;
24357
+ return __generator(this, function (_a) {
24358
+ setIsSaving(true);
24359
+ try {
24360
+ console.log('formData to save:', formData);
24361
+ console.log('textoOriginal to save:', textoOriginal);
24362
+ textoFinal = rebuildTextFromOriginal(textoOriginal, formData.elementos);
24363
+ console.log('textoFinal to save:', textoFinal);
24364
+ meses = calcularMesesTotales();
24365
+ onSave({ texto: textoFinal, mesesPeriodos: meses, formData: formData });
24366
+ }
24367
+ finally {
24368
+ setIsSaving(false);
24369
+ }
24370
+ return [2 /*return*/];
24371
+ });
24372
+ }); };
24373
+ if (!isOpen)
24374
+ return null;
24375
+ return (jsx("div", { className: "fixed inset-0 z-50 flex items-end justify-end bg-black bg-opacity-50", children: jsxs("div", { className: "flex h-full w-1/2 flex-col bg-white", children: [jsx("div", { className: "border-b border-gray-200 bg-white px-6 py-12", children: jsx("h2", { className: "text-4xl font-bold text-blue", children: "Construir hecho infraccional" }) }), jsx("div", { className: "min-h-0 flex-1", children: jsx("form", { className: "flex h-full flex-col", children: jsx("div", { className: "min-h-0 flex-1", children: jsx("div", { className: "flex h-full flex-col", children: jsx("div", { className: "min-h-0 flex-1", children: jsxs("div", { className: "flex h-full flex-col", children: [jsx("div", { className: "flex-shrink-0 border-b border-gray-200 p-4", children: jsxs("div", { className: "mb-4", children: [jsx("h4", { className: "mb-2 text-sm font-bold text-gray-700", children: "Previsualizaci\u00F3n:" }), jsx("div", { className: "min-h-[60px] rounded-lg border border-gray-300 bg-white p-3 text-gray-800", children: renderTextWithColors(textoOriginal) })] }) }), jsx("div", { className: "min-h-0 flex-1 overflow-y-auto", style: { zIndex: 1 }, children: jsx("div", { className: "rounded-lg p-3", children: loading ? (jsx("div", { className: "flex items-center justify-center py-12", children: jsxs("div", { className: "flex flex-col items-center space-y-4", children: [jsx("div", { className: "border-blue-600 h-12 w-12 animate-spin rounded-full border-b-2" }), jsx("p", { className: "text-sm text-gray-600", children: "Cargando hecho infraccional..." })] }) })) : (jsx("div", { className: "space-y-4", children: (function () {
24376
+ var _a;
24377
+ // se extraen todos los tags (base + anidados)
24378
+ var allTags = extractAllTagsFromCurrentState();
24379
+ // se filtran los elementos que están en los tags detectados
24380
+ // se normaliza comparando en mayúscula porque la API devuelve códigos en mayúscula
24381
+ var allTagsUpper = allTags.map(function (t) { return t.toUpperCase(); });
24382
+ var elementosFromAPI = (((_a = hechoInfraccionalData === null || hechoInfraccionalData === void 0 ? void 0 : hechoInfraccionalData.data) === null || _a === void 0 ? void 0 : _a.elementos) || []).filter(function (elemento) {
24383
+ if (!allTagsUpper.includes(elemento.codigo.toUpperCase()))
24384
+ return false;
24385
+ // si algún tag P está overrideado en el texto base, también debemos excluirlo
24386
+ if (isPeriodTag(elemento.codigo) &&
24387
+ (isDateOverrideForPeriodTag(elemento.codigo) ||
24388
+ isYearOverrideForPeriodTag(elemento.codigo))) {
24389
+ return false; // evitar duplicar como periodo si será fecha o año
24390
+ }
24391
+ return true;
24392
+ });
24393
+ // se agregan elementos especiales que no están en la API (como P, M, F y N)
24394
+ var elementosEspeciales = allTags
24395
+ .filter(function (tag) {
24396
+ var _a, _b;
24397
+ return (isPeriodTag(tag) ||
24398
+ isAmountTag(tag) ||
24399
+ isDateTag(tag) ||
24400
+ isNumberTag(tag)) &&
24401
+ !((_b = (_a = hechoInfraccionalData === null || hechoInfraccionalData === void 0 ? void 0 : hechoInfraccionalData.data) === null || _a === void 0 ? void 0 : _a.elementos) === null || _b === void 0 ? void 0 : _b.some(function (e) {
24402
+ return e.codigo.toUpperCase() === tag.toUpperCase();
24403
+ }));
24404
+ })
24405
+ .map(function (tag) { return ({
24406
+ codigo: tag.toUpperCase(), // se normaliza a mayúscula como la API
24407
+ descripcion: "".concat(isPeriodTag(tag) ? 'Período' : isAmountTag(tag) ? 'Monto' : isDateTag(tag) ? 'Fecha' : 'Número', " ").concat(tag),
24408
+ tipo_dato: isPeriodTag(tag) &&
24409
+ !isDateOverrideForPeriodTag(tag) &&
24410
+ !isYearOverrideForPeriodTag(tag)
24411
+ ? 'periodo'
24412
+ : isAmountTag(tag)
24413
+ ? 'monto'
24414
+ : isDateTag(tag) ||
24415
+ (isPeriodTag(tag) && isDateOverrideForPeriodTag(tag))
24416
+ ? 'fecha'
24417
+ : 'numero',
24418
+ opciones: [],
24419
+ }); });
24420
+ var codigosYaRenderizados = new Set(__spreadArray(__spreadArray([], elementosFromAPI, true), elementosEspeciales, true).map(function (e) {
24421
+ return e.codigo.toUpperCase();
24422
+ }));
24423
+ // Tags visibles (p. ej. T1, T2) sin fila en API: campo texto como front002
24424
+ var elementosTextoImplicitos = allTags
24425
+ .map(function (t) { return t.toUpperCase(); })
24426
+ .filter(function (u, i, arr) { return arr.indexOf(u) === i; })
24427
+ .filter(function (u) { return u !== 'O' && !codigosYaRenderizados.has(u); })
24428
+ .map(function (u) { return ({
24429
+ id: 0,
24430
+ codigo: u,
24431
+ texto_placeholder: undefined,
24432
+ tipo_dato: 'texto',
24433
+ es_multiple: false,
24434
+ es_obligatorio: false,
24435
+ opciones: [],
24436
+ }); });
24437
+ var elementosToRender = __spreadArray(__spreadArray(__spreadArray([], elementosFromAPI, true), elementosEspeciales, true), elementosTextoImplicitos, true);
24438
+ var elementosObservacion = elementosToRender.filter(function (elemento) { var _a; return ((_a = elemento.codigo) === null || _a === void 0 ? void 0 : _a.toUpperCase()) === 'O'; });
24439
+ var elementosSinObservacion = elementosToRender.filter(function (elemento) { var _a; return ((_a = elemento.codigo) === null || _a === void 0 ? void 0 : _a.toUpperCase()) !== 'O'; });
24440
+ var elementosOrdenados = __spreadArray(__spreadArray([], elementosSinObservacion, true), elementosObservacion, true);
24441
+ return elementosOrdenados.map(function (elemento) {
24442
+ return renderElemento(elemento);
24443
+ });
24444
+ })() })) }) }), jsxs("div", { className: "mt-8 flex justify-between border-t border-gray-200 px-6 pb-6 pt-6", children: [jsx("button", { type: "button", className: "text-blue-600 hover:text-blue-800 border-blue-600 rounded-md border px-4 py-2 transition-colors", onClick: onClose, children: "Volver" }), jsx("button", { type: "button", disabled: loading || isSaving || !areAllTagsComplete(), className: "rounded-md px-4 py-2 transition-colors ".concat(loading || isSaving || !areAllTagsComplete()
24445
+ ? 'cursor-not-allowed bg-gray-400 text-gray-600'
24446
+ : 'hover:bg-blue-700 bg-blue text-white'), onClick: handleSave, children: isSaving ? 'Guardando...' : 'Guardar' })] })] }) }) }) }) }) })] }) }));
24447
+ };
24448
+
24449
+ export { AddressInput, Alert, CheckboxInput, Checklist, Common, ConstruirHechoInfraccionalModal, DatePicker, DynamicInput, GenericForm, GoogleMaps, InputWrapper, NavigationButton, RadioInput, RadioOption, RutInput, SelectInput, StatusScreen, SubtitleInput, SwornDeclaration, TextInput, TextInputField, TextareaInput, clean as cleanRut, commonValidations, createValidationSchema, formatRut, maskRut, useMiDt, validateOnlyNumbersAndLetters, validate as validateRut };