Files
2026-08-04 19:45:50 -03:00

256 lines
7.8 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
document.addEventListener("DOMContentLoaded", () => {
if (serverErrors.length > 0) mostrarErrores(serverErrors);
if (serverSuccess.length > 0) mostrarSuccess(serverSuccess);
const form = document.getElementById("form-crear-usuario") || document.getElementById("form-editar-usuario");
if (!form) return;
// Si no hay submit (operador), no validar
if (!form.querySelector("button[type='submit']")) return;
// Funciones utilitarias
function isEmpty(value) {
return !value || value.trim() === '';
}
function hasNoSpaces(value) {
return !value.includes(' ');
}
function isValidEmail(email) {
return /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(email);
}
function isValidName(value) {
return /^[A-ZÁÉÍÓÚÑ][a-záéíóúñ]+(?: [A-ZÁÉÍÓÚÑ][a-záéíóúñ]+)*$/.test(value);
}
function isValidUsername(value) {
return /^(?=.*[a-zA-Z])(?!.*[._]{2})[a-zA-Z0-9._]{5,30}$/.test(value);
}
function isValidPassword(value) {
return /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{6,}$/.test(value);
}
// Submit
form.addEventListener("submit", (e) => {
let errores = [];
const nombre = form.querySelector("input[name='nombre']");
const apellido = form.querySelector("input[name='apellido']");
const usuario = form.querySelector("input[name='usuario']");
const telefono = form.querySelector("input[name='telefono']");
const email = form.querySelector("input[name='email']");
const password = form.querySelector("input[name='password']");
// Limpiar estados previos
form.querySelectorAll(".is-invalid").forEach(el =>
el.classList.remove("is-invalid")
);
// NOMBRE
if (nombre) {
if (isEmpty(nombre.value)) {
errores.push("El nombre es obligatorio.");
nombre.classList.add("is-invalid");
} else if (!isValidName(nombre.value)) {
errores.push("El nombre debe comenzar con mayúscula y solo contener letras.");
nombre.classList.add("is-invalid");
} else if (nombre.value.length < 2) {
errores.push("El nombre debe tener al menos 2 caracteres.");
nombre.classList.add("is-invalid");
} else if (nombre.value.length > 50) {
errores.push("El nombre no puede superar los 50 caracteres.");
nombre.classList.add("is-invalid");
}
}
// APELLIDO
if (apellido) {
if (isEmpty(apellido.value)) {
errores.push("El apellido es obligatorio.");
apellido.classList.add("is-invalid");
} else if (!isValidName(apellido.value)) {
errores.push("El apellido debe comenzar con mayúscula y solo contener letras.");
apellido.classList.add("is-invalid");
} else if (apellido.value.length < 2) {
errores.push("El apellido debe tener al menos 2 caracteres.");
apellido.classList.add("is-invalid");
} else if (apellido.value.length > 50) {
errores.push("El apellido no puede superar los 50 caracteres.");
apellido.classList.add("is-invalid");
}
}
// USUARIO
if (isEmpty(usuario)) {
errores.push("El usuario es obligatorio.");
usuarioInput.classList.add("is-invalid");
} else if (!isValidUsername(usuario)) {
errores.push("El usuario debe tener 530 caracteres, incluir al menos una letra y solo usar letras, números, puntos o guiónes bajos no consecutivos.");
usuarioInput.classList.add("is-invalid");
}
// TELÉFONO
if (telefono) {
if (isEmpty(telefono.value)) {
errores.push("El teléfono es obligatorio.");
telefono.classList.add("is-invalid");
} else if (telefono.value.length != 10) {
errores.push("El teléfono debe poseer 10 dígitos.");
telefono.classList.add("is-invalid");
}
}
// EMAIL
if (email) {
if (isEmpty(email.value)) {
errores.push("El email es obligatorio.");
email.classList.add("is-invalid");
} else if (!isValidEmail(email.value)) {
errores.push("El email no tiene un formato válido.");
email.classList.add("is-invalid");
} else if (email.value.length > 100) {
errores.push("El email no puede superar los 100 caracteres.");
email.classList.add("is-invalid");
}
}
// PASSWORD
if (isEmpty(password)) {
errores.push("La contraseña es obligatoria.");
passInput.classList.add("is-invalid");
} else if (!hasNoSpaces(password)) {
errores.push("La contraseña no puede contener espacios.");
passInput.classList.add("is-invalid");
} else if (!isValidPassword(password)) {
errores.push("La contraseña debe tener al menos una mayúscula, una minúscula y un número, y mínimo 6 caracteres.");
passInput.classList.add("is-invalid");
}
// Resultado
if (errores.length > 0) {
e.preventDefault();
mostrarErrores(errores);
}
});
// FUNCIÓN PARA MOSTRAR ERRORES
function mostrarErrores(errores) {
// Buscar si hay un toast previo
const viejo = document.getElementById("toastErrores");
// Si existe, se elimina (evita duplicados)
if (viejo) viejo.remove();
// Crea el contenedor del toast
const toast = document.createElement("div");
// Se le asigna ID para identificarlo
toast.id = "toastErrores";
// Clases de estilo (Bootstrap + CSS)
toast.className = "toast-flotante alert alert-danger";
// Inserta el contenido dinámico (lista de errores)
toast.innerHTML = `
<strong>Se encontraron errores:</strong>
<ul class="mb-0 mt-2">
${errores.map(e => `<li>${e}</li>`).join("")} <!-- convierte array a <li> -->
</ul>
`;
// Agrega el toast al body (lo hace visible)
document.body.appendChild(toast);
// Auto-cierre
setTimeout(() => {
// Agrega clase para animación de salida (CSS)
toast.classList.add("toast-out");
// Elimina el elemento después de la animación
setTimeout(() => {
toast.remove(); // Elimina el DOM
}, 350);
}, 5000); // Visible durante 5 segundos
}
});
// FUNCIÓN PARA MOSTRAR SUCCESS
function mostrarSuccess(mensajes) {
// Elimina toast previo de éxito si existe
const viejo = document.getElementById("toastSuccess");
if (viejo) viejo.remove();
// Crea el contenedor del toast
const toast = document.createElement("div");
// Se le asigna ID único
toast.id = "toastSuccess";
// Estilo
toast.className = "toast-flotante alert alert-success";
// Inserta mensajes dinámicos
toast.innerHTML = `
<strong>Mensajes de éxito:</strong>
<ul class="mb-0 mt-2">
${mensajes.map(m => `<li>${m}</li>`).join("")}
</ul>
`;
// Agrega al DOM
document.body.appendChild(toast);
// Auto-cierre a los 5 segundos
setTimeout(() => {
// Animación de salida
toast.classList.add("toast-out");
// Eliminación final
setTimeout(() => {
toast.remove();
}, 350);
}, 5000);
}