JavaScript – Proyecto – Cotizador con prototypes

//Constructores
function Seguro(datoMarca, datoYear, datoTipo) { //Objeto constructor con el que se va a crear el objeto con los datos del formulario
    this.marca = datoMarca;
    this.year = datoYear;
    this.tipo= datoTipo;    
}

//Prototypes del constructor Seguro
//Una vez que se asegura que los datos del formulario están completos entonces sacamos la cuenta de la cantidad a pagar
//Creando un prototipe para ese objeto con esos datos 
Seguro.prototype.cotizarSeguro = function () {

    //aquí va el algoritmo que lo hace
    let cantidad; //Creamos la variable donde mostraremos ese dato
    const base = 2000; //Creamos un precio base que variará dependiendo de la marca, año y tipo de seguro seleccionado

    switch(this.marca) { //Aumentamos la basse dependiendo de la marca seleccionada
        case '1':
            cantidad = base * 1.15;
            break;
        case '2':
            cantidad = base * 1.05;
            break;
        case '3':
            cantidad = base * 1.35;
            break;
        default:
            break;
    }
    
    //Evaluar el año
    
    //Me queda la duda de por qué no se pasa primero a un valor tipo número y aún así funciona
    const diferencia = new Date().getFullYear() - this.year;
    
    // disminuímos la cantidad en un factor de 3 por ciento por cada año de antigúedad
    cantidad -= diferencia * 0.03 * cantidad; 

    if(this.tipo === 'basico') {
        cantidad *= 1.30; //Si es tipo básico se sube un 30% la cantidad
    } else {
        cantidad *= 1.50; //Sí es tipo completo se sube un 50% la cantidad
    }

    return cantidad; //El prototype retorna el dato cantidad con el valor final a mostrar

}

function UI() {}

//Construir la lista de opciones de años
//Para ello creamos una función pero como esto es una clase de prototipos entonces la hacemos de esa manera
//Anteriormente hemos creado el constructor UI pero sin nada, sin argumentos ni código
//Pero lo vamos a usar para crear este primer prototype

UI.prototype.listaAnos = () => {  //Aquí lo único que estamos haciendo es crear una función que vamos a usar a modo de método,
    const max = new Date().getFullYear(); //es decir, sintaxis de punto
    const min = max - 20;

    const selectYear = document.querySelector('#year'); //Seleccionamos el <select> donde van a ir los <option> para los años

    for(let i = max; i>min; i--) { //Por cada año,
        let option = document.createElement('option'); //creamos una etiqueta option,
        option.value = i; //con value igual al año con el que se está trabajado
        option.textContent = i; //e igualmente su conenido va a ser ese año en texto y
        selectYear.appendChild(option); //finalmente se mete en el select respectivo
    }  //ya tenemos el prototipe para crear los años listados
}

//Mostrar las alertas en pantalla
//Solo para mostrar entre dos posibles mensajes, formulario incompleto o procesando info
UI.prototype.mostrarMensaje = (mensaje, tipo) => {
    const div = document.createElement('div');

    if(tipo === 'error') {
        div.classList.add('error');
    } else {
        // div.classList.remove('error');
        div.classList.add('correcto');
    }

    div.classList.add('mensaje', 'mt-10');
    div.textContent = mensaje;

    //el mismo que se usa más abajo solo que le dio flojera hacerlo una variable global
    const formulario = document.querySelector('#cotizar-seguro');
    formulario.insertBefore(div, document.querySelector('#resultado'));

    setTimeout( () => {div.remove()}, 1000); //Transcurrido ese tiempo quito el mensaje
}

//Cuando ya se tiene el valor de cantidad procedemos a crear el prototipe que va a mostrar eso
UI.prototype.mostrarResultado = (total, seguro) => {

    const { marca, year, tipo } = seguro;

    let textoMarca;

    switch(marca) {
        case "1": textoMarca = 'Americano';
            break;
        case "2": textoMarca = 'Asiático';
            break;
        case "3": textoMarca = 'Europeo';
            break;
        default:
            break;
    }

    //Esto lo hice yo para que apareciera la palabra Básico con el acento
    let ifBasico = 'Completo';

    if(tipo === 'basico') {
        ifBasico = 'Básico';
    }

    const div = document.createElement('div');
    div.classList.add('mt-10');

    div.innerHTML = `
        <p class = "header">Tu Resumen</p>
        <p class = "font-bold">Marca: <span class="font-normal"> ${textoMarca}</span></p>
        <p class = "font-bold">Año: <span class="font-normal"> ${year}</span></p>
        <p class = "font-bold">Tipo: <span class="font-normal"> ${ifBasico}</span></p>
        <p class = "font-bold">Total: <span class="font-normal"> $${total}</span></p>
    
    `;
    const resultadoDiv = document.querySelector('#resultado');

    //El spinner
    const spinner = document.querySelector('#cargando');
    spinner.style.display = 'block'; //Muestro el spinner

    //Pasado un segundo quito el spinner y muestro el resultado
    setTimeout( () => { 
        spinner.style.display = 'none';
        resultadoDiv.appendChild(div);
    }, 1000 );
}

//Instanciar UI
const ui = new UI(); //Ahora creamos una instancia del constructor UI.

document.addEventListener('DOMContentLoaded', () => { //Ejecutamos la creación de la lista de años por medio del prototipe específico para instancias 
    ui.listaAnos(); //del constructor UI pero automáticamente una vez que se cargue la página.
});

// eventListeners();
// function eventListeners() {
    // const formulario = document.querySelector('#cotizar-seguro'); //El código selecciona el formulario y se queda a espera del evento
    //Cuando ocurra este evento se ejecuta esta función para chequear que se tengas todos los datos
    // formulario.addEventListener('submit', evaluarDatos); 
    document.querySelector('#cotizar-seguro').addEventListener('submit', evaluarDatos); //Creo que está mejor así
// }

function evaluarDatos(e) {
    e.preventDefault(); 

    //Leer la marca
    //Pido el valor del select, el select va a tener el valor de uno de los options, ese dato para a ser parte de la etiquete <select>
    const marca = document.querySelector('#marca').value;
    
    //Leer en año
    const year = document.querySelector('#year').value;

    //Leer el tipo de cobertura
    //La forma habitual de copiar el value de un botón radio (radio button) que esté marcado, eso es CSS avanzado, ya vea ud
    const tipo = document.querySelector('input[name="tipo"]:checked').value;

    if(marca === '' || year === '' || tipo === '') { //Validando que todos los campos tengan contenido
        ui.mostrarMensaje('Todos los campos son obligatorios', 'error');
        return;
    }
    ui.mostrarMensaje('Cotizando...', 'exito');

    //Ocultar cotizaciones previas
    const resultados = document.querySelector('#resultado div');
    if(resultados != null) {
        resultados.remove();
    }

    //De estar todo bien resta crear una instancia de Seguro con los datos del formulario que es lo que se necesita para
    //crear esa instancia, marca, año y tipo
    const seguro = new Seguro(marca, year, tipo); 
    //Aquí es donde le le aplicamos a ese objeto el método creado con prototype para determinar una cantidad a cobrar y se la estamos asignando
    //a una variable llamada total
    const total = seguro.cotizarSeguro();
    ui.mostrarResultado(total, seguro);
    
}

Leave a Comment