- 1. Resumen del proyecto
- 2. Funcionalidades destacadas
- 3. Consideraciones técnicas
- 4. Criterios de aceptación mínimos del proyecto
- 5. Objetivos de aprendizaje
- 6. Algunos conceptos aplicados
En este proyecto, hemos creado la plataforma web MovieDev, la cual funciona como una colección de tarjetas que abarcan 24 películas de los géneros: documental, thriller, ciencia ficción, drama y animación. Todos las películas vinculadas al fascinante mundo de la tecnología, pensando en nuestras usuarias ideales: "Desarrolladoras Web". La información recopilada se basa en un conjunto de datos generados con la colaboración de ChatGPT.
--
--
La página web MovieDev se centra en ofrecer tres funciones clave:
- Ordenamiento: las películas pueden ser ordenadas de manera intuitiva.
- Filtrado: la capacidad de filtrar la información.
- Estadísticas: se realizan distintos cálculos con los datos de las 24 películas
-
Ordenamiento por año: los usuarios pueden organizar la lista de películas según el año de lanzamiento, facilitando la exploración cronológica y permitiendo sumergirse en la evolución de las representaciones tecnológicas en el cine.
-
Ordenamiento por nombre: la opción de ordenar alfabéticamente facilita la búsqueda de películas específicas por título, proporcionando una ruta rápida y eficiente a la información deseada.
- La capacidad de filtrar las películas según su género: documental, thriller, ciencia ficción, drama y animación, permite a los usuarios obtener resultados específicos al explorar el contenido.
-
Estadísticas por puntaje: selecciona y muestra en pantalla la data que cumple estrictamente con alguno de estos tres requisitos del puntaje en porcentaje, entre el 50% y 70%, 70% y 90%, y sobre el 90% de aceptación.
-
Estadísticas por país: calcula la frecuencia de películas existentes por país, proporcionando una visión estadística de la distribución geográfica de las películas en el conjunto de datos de MovieDev.
-
Diseño adaptativo: la página web ha sido diseñada pensando en la accesibilidad, siendo completamente responsive para adaptarse a dispositivos de diferentes tamaños, desde computadoras de escritorio hasta teléfonos móviles.
-
Estilo atractivo: la interfaz se beneficia de un diseño estéticamente agradable, con colores y elementos visuales que mejoran la experiencia de navegación y destacan la temática tecnológica.
MovieDev fue desarrollada en conjunto con un exhaustivo conjunto de pruebas unitarias en formato Jest, una herramienta ampliamente reconocida para la realización de pruebas en proyectos JavaScript.
La ventaja clave de emplear pruebas unitarias radica en su capacidad para verificar la funcionalidad correcta de las diversas funciones y la eficaz modularización del código.
Durante el proceso de prueba, nos enfocamos en cada función individual, asegurándonos de que cumpliera con su propósito específico. Estas pruebas no solo ayudaron a identificar y corregir posibles errores, sino que también garantizaron la estabilidad y fiabilidad de la aplicación.
La aplicación fue realizada en el marco del bootcamp para Desarrolladoras Web de Laboratoria, en el que a su vez se nos solicitaron las siguientes consideraciones técnicas:
-
Las funcionalidades de ordenar deben operar sobre la data filtrada. Por ejemplo, si filtro las películas de comedia y luego las ordeno por nombre ascendentemente, la aplicación deberá mantener el filtro aplicado y ordenar las películas de comedia.
-
La aplicación permite a la usuaria reiniciar la aplicación, limpiando filtros y ordenamiento, con un
<button>con un atributo de datosdata-testid="button-clear". -
Las operaciones de filtrar, ordenar, limpiar, etc. no deben recargar la página, si no que deben agregar el contenido en una manera dinámica via javascript.
-
La aplicación es responsive, es decir, debe visualizarse sin problemas desde distintos tamaños de pantallas: móviles, tablets y desktops.
Diseño Mobile:
Tomamos en cuenta las propuestas de Laboratoria para nuestro diseño:
-
Wireframe mobile 1 (sugerencia de Laboratoria).
-
Resultado (pantalla responsive):
--
Diseño Desktop:
-
Wireframe desktop 1 (sugerencia de Laboratoria).
-
Resultado:
--
El boilerplate contiene una estructura de archivos como punto de partida así como toda la configuración de dependencias:
.
├── README.md
├── package.json
├── src
| ├── data
| | └── dataset.js (La que hayas generado con la IA)
| ├── dataFunctions.js
| ├── view.js
| ├── index.html
| ├── main.js
| └── style.css
└── test
└── data.js
└── dataFunctions.spec.js
└── tests-read-only
Al ser parte del programa de bootcamper Laboratoria para Desarrolladoras Web, el proyecto presenta criterios mínimos de aceptación para considerarse entregable, a continuación se describen:
Conjunto de pruebas que se superen exitosamente:
npm run test:oas-html
npm run test:oas-css
npm run test:oas-web-api
npm run test:oas-js
npm run test:oas-prompting
npm run test:oas // Esto es para correr todos los tests de OAs-
Uso de HTML semántico
- Tiene un
<header>con<h1> - Tiene un
<footer> - Tiene un
<main>con<h2> - Todas las etiquetas de controles (inputs, selects, radio, etc) tienen
<label> -
<ul>esta usado para dibujar la data - Los hijos de
<li>usan attributos de microdataitemscopeeitemprop
- Tiene un
-
Uso de selectores de CSS
- Uso de selector class para los items
- Uso de flexbox en sentido
rowycolumn - Uso de flexbox para el elemento que contiene los items
- Uso de flexbox para el elemento que contiene los UI inputs
-
Uso de selectores del DOM
- La aplicación usa
querySelectorpara buscar los elementos del DOM
- La aplicación usa
-
Manejo de eventos del DOM (listeners, propagación, delegación)
-
addEventListenercon callback que tiene parámetro deevent, lo que permite el uso del objetoeventconevent.targetoevent.currentTarget - La aplicación registra Event Listeners
para escuchar
click,change,keyupdependiendo del evento que se quiere escuchar
-
-
Manipulación dinámica del DOM
- La aplicación actualiza el atributo
innerHTML. - La aplicación usa
createElementyappendChild, o template strings para crear elementos
- La aplicación actualiza el atributo
-
Variables (declaración, asignación, ámbito)
-
Uso de condicionales (if-else, switch, operador ternario, lógica booleana)
- La aplicación usa el statement
if..elsepara evaluar condiciones
- La aplicación usa el statement
-
Uso de bucles/ciclos (while, for, for..of)
-
Funciones (params, args, return)
En el archivo
dataFunctions.jsdefine las siguientes funciones:- una función
sortByque tiene 3 parámetros (data,sortBy,sortOrder) y devuelve el arreglo ordenado - una función
filterByque tiene 3 parámetros (data,filterBy,value) y devuelve el arreglo filtrado - una función
computeStatsque tiene al menos un parámetro (data) y devuelve un valor computado
Más sobre estos puntos en la sección dataFunctions.js
- una función
-
Arrays (arreglos)
- Uso de Arreglos
- Uso de Array.prototype.sort() - MDN o Array.prototype.toSorted - MDN
- Uso de Array.prototype.forEach() - MDN
- Uso de Array.prototype.map() - MDN
- Uso de Array.prototype.filter() - MDN
- Uso de Array.prototype.reduce() - MDN
-
Objetos
- Uso de notación de punto para acceder propiedades
- Uso de notación de brackets para acceder propiedades
-
Módulos de ECMAScript (ES Modules)
Esta data tiene una estructura archivo javascript. Este archivo, exporta un arreglo con 24 objetos y la estructura de cada objeto es la siguiente:
id: identificador único (no pueden haber dos elementos con el mismoid). Debe ser un string de no más de 32 characteres, en minúscula, compuesto solo por letras, números, underscore (_) o guión (-). Por ejemplo:"ada-lovelace".name: el nombre del personaje, país, película, etc.shortDescription: descripción corta del elemento. Esta descripción deberá tener como máximo 20 palabras.description: descripción extendida del elemento. Esta descripción deberá tener entre 80 y 100 palabras. Al momento de mostrar este dato en pantalla puedes truncarlo para que no ocupe tanto espacio.imageUrl: URL de la imagen. Esta imagen será generada a través de alguna herramienta basada en inteligencia artifical. Una vez generada la imagen, y guardada en tu repo, deberás agregar la URL en este campo.facts: un objeto con al menos 3 "hechos" o "info" sobre este elemento.
Un ejemplo de data de MovieDev:
export default [
{
"id": "hackers",
"name": "Hackers",
"shortDescription": "Jóvenes hackers y aventureros luchan contra la injusticia.",
"description": "Ambientada en el mundo del ciberespacio.....",
"imageUrl": "https://raw.githubusercontent.com/MilenaPacheco/DEV013-dataverse/main/src/img/Hackers.png",
"facts": {
"yearMovie": 1995,
"directorMovie": "Iain Softley",
"productionCompany": "MGM",
"genreMovie": "Thriller",
"genreValue": "thriller"
},
"extraInfo": {
"rottenTomatoesScore": "32%",
"countryMovie": "Estados Unidos",
"durationMovie": "107 minutos"
}
},
},
//... 23 objetos más
]- Capturas del prompting:
La data utilizada en MovieDev se generó con ayuda de inteligencia artificial como se presenta a continuación:
--
--
Además, usamos imágenes generadas a través de inteligencia artificial. Ejemplo de promp y resultado:
--
Después de seleccionar la temática que queríamos trabajar: página web sobre películas de tecnología y desarrollo web, decidimos definir a nuestra usuaria ideal respondiendo las siguientes preguntas:
- ¿Quiénes son las principales usuarias del producto?
Mujeres, futuras programadoras Web. Con interés en inmersión en el mundo del desarrollo Web.
- ¿Cuáles son los objetivos de estas usuarias en relación con el producto?
Saber más sobre tecnología, sus usos, alcances, historia, utopías y distopías. Contextualizarse más. Información para conversaciones interesantes con personas del rubro.
- ¿Cuáles son los datos más relevantes que quieren ver en la interfaz y por qué?
Datos básicos y estadísticos interesantes. Resúmenes, imágenes asociadas a los films.
- ¿Cuándo utilizan o utilizarían el producto
En tiempo de ocio.
Nuestra investigación derivó en todas las HISTORIAS DE USUARIA de nuestro proyecto, que se muestran a continuación:
--
A continuación se muestran capturas de nuestros prototipos de baja, mediana y alta fidelidad. Para los cuales pedimos feedback a nuestras compañeras y coaches.
__
Arrojaron lo siguiente:
- Problemas de usabilidad en la posición del menú de filtrado, ordenado y botones asociados, así como en la adecuación de sus tamaños. Este desafío surgió debido a que la disposición y el tamaño de estos son factores cruciales para garantizar una experiencia de usuario intuitiva y eficiente. Enfrentamos este desafío con un enfoque cuidadoso en el diseño de la interfaz.
- Teníamos muchos colores en el diseño de la interfaz. También resultaban muy brillantes.
- No funcionaba en cualquier tamaño de dispositivo.
- Se cargaban las tarjetas sin las imágenes.
- Fuentes muy grandes o ilegibles por falta de correcto contraste.
- Toda la página no tenía el mismo nivel de diseño, habían partes más crudas que otras.
Todos estos temas fueron considerados y abordados en nuestro entregable.
Como equipo reflexionamos y marcamos los objetivos que hemos llegado a entender y aplicar en el proyecto. Estos objetivos fueron determinantes en nuestra estrategia de trabajo.
-
Uso de HTML semántico
-
Uso de selectores de CSS
-
Modelo de caja (box model): borde, margen, padding
-
Uso de flexbox en CSS
-
Uso de selectores del DOM
-
Manejo de eventos del DOM (listeners, propagación, delegación)
-
Manipulación dinámica del DOM
-
Diferenciar entre tipos de datos primitivos y no primitivos
-
Arrays (arreglos)
-
Objetos (key, value)
-
Variables (declaración, asignación, ámbito)
-
Uso de condicionales (if-else, switch, operador ternario, lógica booleana)
-
Uso de bucles/ciclos (while, for, for..of)
-
Funciones (params, args, return)
-
Pruebas unitarias (unit tests)
-
Módulos de ECMAScript (ES Modules)
-
Uso de linter (ESLINT)
-
Uso de identificadores descriptivos (Nomenclatura y Semántica)
-
Diferenciar entre expresiones (expressions) y sentencias (statements)
-
Git: Instalación y configuración
-
Git: Control de versiones con git (init, clone, add, commit, status, push, pull, remote)
-
Git: Integración de cambios entre ramas (branch, checkout, fetch, merge, reset, rebase, tag)
-
GitHub: Creación de cuenta y repos, configuración de llaves SSH
-
GitHub: Despliegue con GitHub Pages
- GitHub: Colaboración en Github (branches | forks | pull requests | code review | tags)
- Diseñar y desarrollar un producto o servicio poniendo a las usuarias en el centro
-
Crear prototipos de alta fidelidad que incluyan interacciones
-
Seguir los principios básicos de diseño visual
-
Planear y ejecutar testeos de usabilidad de prototipos en distintos niveles de fidelidad
-
Dando Instrucciones
-
Few shot prompting
Filtra elementos de un array basándose en una condición especificada. Sintaxis:
const newArray = array.filter(callback(element[, index[, array]])[, thisArg]);Ordena los elementos de un array de acuerdo con la función de comparación proporcionada. Sintaxis:
array.sort([compareFunction]);Crea un nuevo array con los resultados de llamar a una función proporcionada para cada elemento del array. Sintaxis:
const newArray = array.map(callback(currentValue[, index[, array]])[, thisArg]);Aplica una función acumulativa a los elementos de un array para reducirlos a un solo valor. Sintaxis:
array.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue]);Convierte una cadena en un número de punto flotante. Sintaxis:
const number = parseFloat(string);Compara dos cadenas de texto y devuelve un valor que indica si una es menor, igual o mayor que la otra. Sintaxis:
const comparison = string1.localeCompare(string2);Agrega uno o más elementos al final de un array. Sintaxis:
array.push(element1[, element2[, ...[, elementN]]]);Devuelve la cantidad de elementos en un array. Sintaxis:
const arrayLength = array.length;Se utiliza para acceder a propiedades de un objeto. Sintaxis:
const person = {
name: 'John',
age: 30,
job: 'Developer'
};
console.log(person.name); // Resultado: 'John'Se utiliza para acceder a elementos de un array o propiedades de un objeto cuando el nombre de la propiedad es dinámico o contiene caracteres especiales. Sintaxis:
const fruits = ['apple', 'banana', 'orange'];
console.log(fruits[1]); // Resultado: 'banana'
const propertyName = 'age';
const person = {
name: 'Alice',
age: 25
};
console.log(person[propertyName]); // Resultado: 25Selecciona el primer elemento del DOM que coincida con el selector especificado. Arroja un elemento del DOM o null si no se encuentra ninguna coincidencia.
const element = document.querySelector(selector);Alterna entre añadir y eliminar una clase en un elemento del DOM.
element.classList.toggle(className);Agrega un evento a un elemento del DOM para que escuche eventos específicos y ejecute una función cuando se produce el evento.
element.addEventListener(eventType, callback);Crea un nuevo elemento del DOM con el nombre de la etiqueta especificada.
const newElement = document.createElement(tagName);Añade un nodo al final de la lista de hijos de un nodo padre.
parentNode.appendChild(childNode);Elimina un nodo hijo de un nodo padre.
parentNode.removeChild(childNode);Obtiene o establece el contenido HTML de un elemento del DOM.
const content = element.innerHTML;
element.innerHTML = newContent;Obtiene o establece el contenido de texto de un elemento del DOM.
const textContent = element.textContent;
element.textContent = newTextContent;Ejecuta una función a intervalos regulares especificados en milisegundos.
const intervalId = setInterval(callback, interval);Obtiene o establece la clase de un elemento del DOM.
const classes = element.className;
element.className = newClasses;Obtiene una lista de las clases de un elemento del DOM
const classes = element.classList;Obtiene o establece el estilo de un elemento del DOM.
const elementStyle = element.style;Obtiene o establece el índice seleccionado en un elemento "select" del DOM.
const index = selectElement.selectedIndex;
selectElement.selectedIndex = newIndex;Obtiene el nodo padre de un elemento del DOM.
const parent = element.parentNode;Obtiene o establece el valor de un elemento del DOM, como en los elementos de entrada.
const elementValue = element.value;
element.value = newValue;En un evento, e.target se refiere al elemento que desencadenó el evento, y .value extrae el valor actual de ese elemento. Se utiliza para obtener el valor de un elemento en el que se ha desencadenado un evento, comúnmente usado en eventos de cambio (change) en elementos de formulario.
const handleChange = (e) => {
const value = e.target.value;
// Resto del código...
};
// Agregando el event listener para el evento de cambio
elemento.addEventListener('change', handleChange);Se utiliza para obtener un array que contiene las claves del objeto proporcionado, permitiendo el acceso a las propiedades del objeto de manera iterable.
const obj = { a: 1, b: 2, c: 3 };
const keysArray = Object.keys(obj);
console.log(keysArray); // Resultado: ['a', 'b', 'c']Eventos:
Se activa cuando el valor de un elemento cambia (por ejemplo, en un elemento de formulario).
element.addEventListener('change', callback);Se activa cuando se hace clic en un elemento.
element.addEventListener('click', callback);Elementos del DOM:
La interfaz Document representa cualquier página web cargada en el navegador y sirve como punto de entrada al contenido de la página web, que es el árbol DOM.
Representa la ventana del navegador y proporciona métodos y propiedades .
-
Expresión: una expresión es cualquier fragmento de código que produce un valor. Ejemplo: 2 + 3 es una expresión que evalúa a 5.
-
Sentencia: una sentencia es una unidad completa de código que realiza una acción. Ejemplo: if (x > 0) { console.log("Positivo"); } es una sentencia que ejecuta un bloque de código si la condición es verdadera.
La distinción clave radica en que una expresión produce un valor, mientras que una sentencia realiza una acción o controla el flujo del programa.





