$.ajaxSetup({
headers: {
'Authorization': 'Bearer ',
'X-User-Token': 'es',
}
});
if(axios) {
axios.defaults.headers.common['X-User-Lang'] = 'es';
axios.defaults.headers.common['Authorization'] = 'Bearer ';
}
const AppInstance = function() {
this.auth = {
signIn: false,
user: {"cl_pueblo": ""} }
this.authToken = '';
this.baseUrl = 'https://tulicenciapr.com/';
this.baseApiUrl = 'https://api.tulicenciapr.com:2053/api';
}
AppInstance.prototype = {
route: function(uri, params = {}) {
return route(uri, params);
},
apiUrl: function(uri) {
return `${this.baseApiUrl}${uri}`
},
getStepItem: function (name, def = null, formIndex = 0) {
var nameKey = `stepForm-${formIndex}-${name}`
return localStorage.getItem(nameKey) ? localStorage.getItem(nameKey) : def;
},
setStepItem: function (name, value = '', formIndex = 0) {
var nameKey = `stepForm-${formIndex}-${name}`
localStorage.setItem(nameKey, _.toString(value));
}
}
window['App'] = new AppInstance();
const TranslatorInstance = function() {
this.lang = 'es';
this.translations = [];
this.load();
}
TranslatorInstance.prototype = {
load: function () {
var self = this;
axios.get(`https://api.tulicenciapr.com:2053/api/Translation/Json/es?`)
.then(function(response) {
self.translations = response.data;
})
},
replaceArgs: function(template, args) {
return template.replace(/\{(\d+)\}/g, function(match, index) {
return args[index] !== undefined ? args[index] : match;
})
},
translate: function(name, trans = '', args = []) {
if (Array.isArray(trans)) {
args = trans;
trans = undefined;
}
const value = this.translations[name.toLowerCase()] ?? trans ?? name;
var text = typeof value === "string" && value.includes("::") ? value.split("::")[1] : value;
return this.replaceArgs(text, args);
},
t: function(name, trans = '', args = []) {
return this.translate(name, trans, args);
}
}
window['Translator'] = new TranslatorInstance();
/**
* Validaciones
*/
$.validator.methods.email = function (value, element) {
return this.optional(element) || /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/.test(value);
};
$.validator.addMethod("license-number", function (value, element) {
return this.optional(element) || /^[A-Za-z0-9]+$/.test(value);
}, 'La licencia solo puede contener letras y números, sin espacios ni símbolos.');
$.extend($.validator.messages, {
required: 'Este campo es requerido',
email: 'Ingrese un correo electrónico válido',
numbers: 'Solo se permiten números',
minlength: $.validator.format('El campo no puede tener menos de {0} caracteres'),
maxlength: $.validator.format('El campo no puede tener más de {0} caracteres'),
equalTo: 'Ingrese el mismo valor de nuevo',
digits: 'Solo se permiten dígitos',
letters: 'Solo se permiten letras',
range: $.validator.format('El valor debe estar entre {0} y {1}'),
max: $.validator.format('El valor máximo del campo es {0}'),
min: $.validator.format('El valor mínimo del campo es {0}'),
phone: 'Formato de teléfono inválido. Ej: (999) 999-9994',
username: 'Solo se permiten letras, números y guiones bajos',
password: 'La contraseña debe contener al menos 8 caracteres, una letra mayúscula, un número y un carácter especial.',
card: 'Ingrese un número de tarjeta válido (Visa, MasterCard, Amex, etc.).',
'email-exists': 'Este correo ingresado ya se encuentrado registrado.',
'username-exists': 'El usuario ingresado ya existe en nuestros registros.',
'min-age': 'No cumples con la edad mínima requerida.',
});
const phoneFormat = function(value) {
if (!value) return value;
const phoneNumber = value.replace(/[^\d]/g, "");
const phoneNumberLength = phoneNumber.length;
if (phoneNumberLength < 4) {
return phoneNumber
}
if (phoneNumberLength < 7) {
return `(${phoneNumber.slice(0, 3)}) ${phoneNumber.slice(3)}`;
}
return `(${phoneNumber.slice(0, 3)}) ${phoneNumber.slice(3, 6)}-${phoneNumber.slice(6, 10)}`;
}
const detectCardType = function (numero) {
const value = numero.replace(/\D/g, ''); // eliminar espacios o guiones
const cardPatterns = {
visa: /^4\d{0,15}$/,
mastercard: /^(5[1-5]|2[2-7])\d{0,14}$/,
amex: /^3[47]\d{0,13}$/,
discover: /^6(?:011|5)/,
diners: /^3(?:0[0-5]|[68])/,
jcb: /^(?:2131|1800|35)/
};
for (let tipo in cardPatterns) {
if (cardPatterns[tipo].test(value)) {
return tipo;
}
}
return null;
}
$('input[data-rule-phone="true"]').on('input', function(e) {
$(this).val(phoneFormat(e.currentTarget.value));
});
$('input[data-rule-card="true"]').on('input', function(e) {
const numberCard = $(this).val();
const typeCard = detectCardType(numberCard);
const $output = $(this).closest('.input-group').find('.input-icon');
if (typeCard) {
$output.html(`
`);
} else {
$output.html(`
`);
}
});
$.validator.addMethod("numbers", function(value, element) {
return this.optional(element) || /^[0-9]+$/.test(value);
});
$.validator.addMethod("letters", function(value, element) {
return this.optional(element) || /^[a-zA-ZáéíóúÁÉÍÓÚñÑ\s]+$/.test(value);
});
$.validator.addMethod("phone", function(value, element) {
return this.optional(element) || /^\(\d{3}\)\s\d{3}-\d{4}$/.test(value);
});
$.validator.addMethod("username", function (value, element) {
return this.optional(element) || /^[A-Za-z0-9_]+$/.test(value);
});
$.validator.addMethod("password", function (value, element) {
return this.optional(element) || /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{8,}$/.test(value);
});
$.validator.addMethod("card", function (value, element) {
if (this.optional(element)) return true;
// Eliminar espacios y guiones
value = value.replace(/[\s-]/g, '');
// Validar solo números
if (!/^\d+$/.test(value)) return false;
// Tipos de tarjeta comunes (regex)
const cardPatterns = {
visa: /^4\d{12}(?:\d{3})?$/, // 13 o 16 dígitos
mastercard: /^5[1-5]\d{14}|^2[2-7]\d{14}$/, // MasterCard 51–55 o 2221–2720
amex: /^3[47]\d{13}$/, // American Express
discover: /^6(?:011|5\d{2})\d{12}$/, // Discover
diners: /^3(?:0[0-5]|[68]\d)\d{11}$/, // Diners Club
jcb: /^(?:2131|1800|35\d{3})\d{11}$/ // JCB
};
// Comprobar coincidencia con algún tipo
let isValidType = false;
for (let key in cardPatterns) {
if (cardPatterns[key].test(value)) {
isValidType = true;
break;
}
}
if (!isValidType) return false;
// Validar con algoritmo Luhn
let sum = 0;
let shouldDouble = false;
for (let i = value.length - 1; i >= 0; i--) {
let digit = parseInt(value.charAt(i), 10);
if (shouldDouble) {
digit *= 2;
if (digit > 9) digit -= 9;
}
sum += digit;
shouldDouble = !shouldDouble;
}
return (sum % 10) === 0;
});
$.validator.addMethod("email-exists", function(value, element, param) {
let isValid = false;
$.ajax({
url: `https://api.tulicenciapr.com:2053/api/Usuario/ListarCorreos?query=${value}`,
type: "GET",
dataType: "json",
async: false,
success: function(response) {
isValid = response.length === 0;
},
error: function() {
isValid = false;
}
});
return isValid;
});
$.validator.addMethod("username-exists", function(value, element, param) {
let isValid = false;
$.ajax({
url: `https://api.tulicenciapr.com:2053/api/Usuario/ListarUsuarios?query=${value}`,
type: "GET",
dataType: "json",
async: false,
success: function(response) {
isValid = response.length === 0;
},
error: function() {
isValid = false;
}
});
return isValid;
});
$.validator.addMethod("min-age", function (value, element, param) {
if (!value) return false;
const inputDate = new Date(value);
const today = new Date();
let age = today.getFullYear() - inputDate.getFullYear();
const monthDiff = today.getMonth() - inputDate.getMonth();
const dayDiff = today.getDate() - inputDate.getDate();
if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
age--;
}
return age >= parseInt(param);
});
/**
**
* */
$('[name="licenseCategory"]').on('change', function(e) {
var licenseCategory = $(this).val();
var $vehicleType = $('[name="vehicleType"]');
$vehicleType.closest('.field').toggleClass('!hidden', licenseCategory !== 'Chofer');
if(licenseCategory !== 'Chofer') {
$vehicleType.val('');
}
});
$('[name="identificationType"]').on('change', function() {
var identificationType = $(this).val();
if(identificationType === 'Seguro Social') {
$('[name="identificationNumber"]').attr('maxlength', 4);
$('[name="identificationNumber"]').attr('readonly', 'true');
$('[name="identificationNumber"]').val(App.auth.user.cl_numeroSeguro);
$('[name="identificationNumber"]').val(App.auth.user.cl_numeroSeguro);
App.setStepItem('identificationNumber', App.auth.user.cl_numeroSeguro)
} else {
$('[name="identificationNumber"]').attr('maxlength', 9);
$('[name="identificationNumber"]').removeAttr('readonly');
$('[name="identificationNumber"]').val('');
App.setStepItem('identificationNumber')
}
});
$('[name="addressResidential"]').on('change', function() {
$('#addressResidentialContainer').toggleClass('hidden', $(this).val() === 'Sí');
});
$(document).ready(function() {
$(`[name="licenseCategory"]`).val(App.getStepItem('licenseCategory', 'Conductor')).trigger('change');
$(`[name="identificationType"][value="${App.getStepItem('identificationType', 'Seguro Social')}"]`).prop('checked', true).trigger('change');
$(`[name="identificationNumber"]`).val(App.getStepItem('identificationNumber'));
$('[name="licenseNumber"]').val(App.auth.user.cl_numeroLicencia);
$('[name="town"]').val(App.auth.user.cl_pueblo.pl_id).trigger('change');
$('[name="zip"]').val(App.auth.user.cl_zip).trigger('change');
$('#addressResidentialContainer').toggleClass('hidden', $('[name="addressResidential"]').val() === 'No');
});