diff --git a/intermedio/ejercicios/57-sensor-moto-dom/resoluciones/maria-montepeque/index.html b/intermedio/ejercicios/57-sensor-moto-dom/resoluciones/maria-montepeque/index.html new file mode 100644 index 0000000..9381338 --- /dev/null +++ b/intermedio/ejercicios/57-sensor-moto-dom/resoluciones/maria-montepeque/index.html @@ -0,0 +1,17 @@ + + + + + + Panel de sensores moto + + + +
+

Panel de sensores

+
+ +
+ + + diff --git a/intermedio/ejercicios/57-sensor-moto-dom/resoluciones/maria-montepeque/maria-montepeque.js b/intermedio/ejercicios/57-sensor-moto-dom/resoluciones/maria-montepeque/maria-montepeque.js new file mode 100644 index 0000000..b64cf0e --- /dev/null +++ b/intermedio/ejercicios/57-sensor-moto-dom/resoluciones/maria-montepeque/maria-montepeque.js @@ -0,0 +1,102 @@ +// 57. Panel DOM de sensores moto - Resolucion Maria Montepeque + +const sensores = [ + { nombre: 'Temperatura motor', valor: 92, unidad: 'C', umbralMin: 60, umbralMax: 105 }, + { nombre: 'Presion de aceite', valor: 35, unidad: 'psi', umbralMin: 25, umbralMax: 65 }, + { nombre: 'RPM', valor: 9200, unidad: 'rpm', umbralMin: 800, umbralMax: 9000 }, + { nombre: 'Voltaje bateria', valor: 12.6, unidad: 'V', umbralMin: 12, umbralMax: 14.5 } +]; + +function esSensorValido(sensor) { + return ( + sensor && + typeof sensor.nombre === 'string' && + sensor.nombre.trim() !== '' && + typeof sensor.valor === 'number' && + typeof sensor.unidad === 'string' && + sensor.unidad.trim() !== '' && + typeof sensor.umbralMin === 'number' && + typeof sensor.umbralMax === 'number' && + sensor.umbralMin < sensor.umbralMax + ); +} + +function estaEnAlerta(sensor) { + return sensor.valor < sensor.umbralMin || sensor.valor > sensor.umbralMax; +} + +function obtenerClaseEstado(sensor) { + return estaEnAlerta(sensor) ? 'alerta' : 'normal'; +} + +function resumirSensor(sensor) { + return { nombre: sensor.nombre, valor: sensor.valor, unidad: sensor.unidad, estado: obtenerClaseEstado(sensor) }; +} + +function renderizarSensoresEnDOM(sensoresValidos) { + if (typeof document === 'undefined') return; + const contenedor = document.querySelector('#panel-sensores'); + if (!contenedor) return; + + contenedor.innerHTML = ''; + sensoresValidos.forEach((sensor) => { + const tarjeta = document.createElement('div'); + tarjeta.className = `tarjeta-sensor ${obtenerClaseEstado(sensor)}`; + tarjeta.innerHTML = `

${sensor.nombre}

${sensor.valor} ${sensor.unidad}

`; + contenedor.appendChild(tarjeta); + }); +} + +function actualizarLectura(sensoresValidos, nombreSensor, nuevoValor) { + return sensoresValidos.map((sensor) => (sensor.nombre === nombreSensor ? { ...sensor, valor: nuevoValor } : sensor)); +} + +function inicializarPanel(sensoresIniciales) { + if (typeof document === 'undefined') return; + + let sensoresActuales = sensoresIniciales.filter(esSensorValido); + renderizarSensoresEnDOM(sensoresActuales); + + const boton = document.querySelector('#simular-lectura'); + if (!boton) return; + + boton.addEventListener('click', () => { + sensoresActuales = sensoresActuales.map((sensor) => ({ + ...sensor, + valor: Number((sensor.valor + (Math.random() * 10 - 5)).toFixed(1)) + })); + renderizarSensoresEnDOM(sensoresActuales); + }); +} + +function generarPanelSensores(sensoresBase, actualizacion) { + const sensoresValidos = sensoresBase.filter(esSensorValido); + const resumenInicial = sensoresValidos.map(resumirSensor); + + const sensoresActualizados = actualizacion + ? actualizarLectura(sensoresValidos, actualizacion.nombre, actualizacion.nuevoValor) + : sensoresValidos; + const resumenFinal = sensoresActualizados.map(resumirSensor); + + renderizarSensoresEnDOM(sensoresActualizados); + + return { + totalSensores: sensoresBase.length, + sensoresInvalidos: sensoresBase.length - sensoresValidos.length, + resumenInicial, + alertasIniciales: resumenInicial.filter((sensor) => sensor.estado === 'alerta').map((sensor) => sensor.nombre), + actualizacion, + resumenFinal, + alertasFinal: resumenFinal.filter((sensor) => sensor.estado === 'alerta').map((sensor) => sensor.nombre) + }; +} + +console.log('Caso 1: panel inicial (RPM ya en alerta) y se actualiza Temperatura motor a 110 (nueva alerta)'); +console.log(JSON.stringify(generarPanelSensores(sensores, { nombre: 'Temperatura motor', nuevoValor: 110 }), null, 2)); + +const sensoresConCasoLimite = [...sensores, { nombre: 'Sensor mal calibrado', valor: 50, unidad: 'x', umbralMin: 80, umbralMax: 20 }]; + +console.log('\nCaso 2: incluye sensor invalido (umbralMin mayor que umbralMax) y actualiza un sensor inexistente'); +console.log(JSON.stringify(generarPanelSensores(sensoresConCasoLimite, { nombre: 'Sensor Fantasma', nuevoValor: 999 }), null, 2)); + +inicializarPanel(sensores); diff --git a/intermedio/ejercicios/57-sensor-moto-dom/resoluciones/maria-montepeque/style.css b/intermedio/ejercicios/57-sensor-moto-dom/resoluciones/maria-montepeque/style.css new file mode 100644 index 0000000..3c5401b --- /dev/null +++ b/intermedio/ejercicios/57-sensor-moto-dom/resoluciones/maria-montepeque/style.css @@ -0,0 +1,55 @@ +body { + font-family: sans-serif; + background-color: #0f1115; + color: #eef1f7; + display: flex; + justify-content: center; + padding: 2rem; +} + +.panel-container { + width: min(500px, 100%); +} + +#panel-sensores { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 0.75rem; + margin: 1rem 0; +} + +.tarjeta-sensor { + padding: 0.75rem; + border-radius: 6px; + border: 1px solid #2f3648; +} + +.tarjeta-sensor.normal { + background-color: #16321f; + border-color: #2f8a4b; +} + +.tarjeta-sensor.alerta { + background-color: #3a1a1a; + border-color: #d9534f; +} + +.tarjeta-sensor h3 { + margin: 0 0 0.25rem; + font-size: 0.95rem; +} + +.tarjeta-sensor p { + margin: 0; + font-size: 1.1rem; + font-weight: bold; +} + +#simular-lectura { + padding: 0.6rem 1rem; + border-radius: 4px; + border: none; + background-color: #4c9aff; + color: #10131a; + cursor: pointer; +}