diff --git a/README.md b/README.md index e2a913eb..e8a1c817 100644 --- a/README.md +++ b/README.md @@ -2,614 +2,138 @@ ## Índice -* [1. Preámbulo](#1-preámbulo) -* [2. Resumen del proyecto](#2-resumen-del-proyecto) -* [3. Objetivos de aprendizaje](#3-objetivos-de-aprendizaje) -* [4. Consideraciones generales](#4-consideraciones-generales) -* [5. Criterios de aceptación mínimos del proyecto](#5-criterios-de-aceptación-mínimos-del-proyecto) -* [6. Hacker edition](#6-hacker-edition) -* [7. Consideraciones técnicas](#7-consideraciones-técnicas) -* [8. Pistas, tips y lecturas complementarias](#8-pistas-tips-y-lecturas-complementarias) -* [9. Checklist](#9-checklist) +* [1. Descripción](#1-descripción) +* [2. Implementación del proyecto](#2-implementación-del-proyecto) +* [3. Encuestas](#3-encuestas) +* [4. Historias de usuario](#4-historias-de-usuario) +* [5. Prototipos de baja fidelidad](#5-prototipos-de-baja-fidelidad) +* [6. Prototipos de alta fidelidad](#6-prototipos-de-alta-fidelidad) +* [7. Test de usabilidad](#7-test-de-usabilidad) *** +## 1. Descripción -## 1. Preámbulo +Se trata de una interfaz que permite visualizar una lista de 251 pokémones de la región Kanto y Johto, filtrar por su tipo de poder y ordenar de menor a mayor probabilidad de captura (y viceversa), además incluye una imagen de cada pokémon y la altura y peso de cada uno. -Según [Forbes](https://www.forbes.com/sites/bernardmarr/2018/05/21/how-much-data-do-we-create-every-day-the-mind-blowing-stats-everyone-should-read), -el 90% de la data que existe hoy ha sido creada durante los últimos dos años. -Cada día generamos 2.5 millones de terabytes de datos, una cifra sin -precedentes. +El objetivo de la plataforma es ayudar tanto a los usuarios jugadores de Pokemon GO, como quienes quieren conocer un poco del mundo Pokémon a conocer la data más relevante que se necesita conocer sobre cada pokémon. -No obstante, los datos por sí mismos son de poca utilidad. Para que esas -grandes cantidades de datos se conviertan en **información** fácil de leer para -los usuarios, necesitamos entender y procesar estos datos. Una manera simple de -hacerlo es creando _interfaces_ y _visualizaciones_. +## 2. Implementación del proyecto -En la siguiente imagen, podrás ver cómo con la data que que se ve en la parte -izquierda se puede construir una interfaz amigable y entendible por las -usuarias, al lado derecho. +Este proyecto utiliza los métodos .filter para filtrar los pokémones y .sort para ordenarlos. -![pokemon-data-to-ui](https://user-images.githubusercontent.com/12631491/218505816-c6d11758-9de4-428f-affb-2a56ea4d68c4.png) +Inicialmente el usuario puede visualizar la lista de pokémones, luego tiene la posibilidad de seleccionar el botón para filtrar, desde el cual se despliega una lista con cada tipo de poder. El segundo botón permite ordenar, el usuario puede escoger entre dos opciones. -## 2. Resumen del proyecto +Se ha realizado una investigación de usuario a través de una encuesta para conocer sus preferencias y necesidades. A partir de allí se construyeron las historias de usuario. -En este proyecto **construirás una _página web_ para visualizar un -_conjunto (set) de datos_** que se adecúe a lo que descubras que tu usuario -necesita. +## 3. Encuestas -Como entregable final tendrás una página web que permita **visualizar la data, -filtrarla, ordenarla y hacer algún cálculo agregado**. Con cálculo agregado -nos referimos a distintos cálculos que puedes hacer con la data para mostrar -información aún más relevante para los usuarios (promedio, el valor máximo -o mínimo, etc). +Para el desarrollo del proyecto, creamos cuatro historias de usuario que implementamos teniendo en cuenta una encuesta que realizamos utilizando la herramienta de Google para crear formularios. -Esta vez te proponemos una serie de datos de diferentes _temáticas_ para que -explores y decidas con qué temática te interesa trabajar. Hemos elegido -específicamente estos sets de datos porque creemos que se adecúan bien a esta -etapa de tu aprendizaje. +Las preguntas que les hicimos a los usuarios fueron: +- ¿Qué tanto sabes sobre Pokémon? (Para conocer a los usuarios que iban a responder la encuesta) +- De estas opciones señala la que más te llame la atención. (Esto para saber cuál sería nuestro filtro) + - Region de cada pokémon, altura de cada pokémon, tipo de cada pokémon, etc. +- De estas opciones señala lo que más te gustaría conocer. (Esta pregunta nos guiaría para saber qué parámetros ordenaríamos) + - Pokémones de mayor a menor altura, pokémones de mayor a menor probabilidad de captura, etc. +- ¿Qué te gustaría conocer? (Esta pregunta para saber qué calculo podríamos hacer) + - El índice de masa corporal del pokémon, cuál es el promedio de estatura de los pokémones, etc. -Una vez que definas tu área de interés, buscar entender quién es tu usuario -y qué necesita saber o ver exactamente; luego podrás construir la interfaz que -le ayude a interactuar y entender mejor esos datos. +Aquí hay algunas capturas de pantalla de nuestra encuesta: -Estos son datos que te proponemos: +![image](https://github.com/carolinaposadl/DEV007-data-lovers/assets/129551206/d6ea48f0-b0c2-48b3-a64c-b0b36a8bfc19) +![image](https://github.com/carolinaposadl/DEV007-data-lovers/assets/129551206/e21336a9-6d90-4068-a096-ccb328b1ce95) +![image](https://github.com/carolinaposadl/DEV007-data-lovers/assets/129551206/c6c068bb-34f5-420c-a28d-76c6f6845527) +![image](https://github.com/carolinaposadl/DEV007-data-lovers/assets/129551206/6a91e7c4-e03e-4c09-a65e-7441bebeb9bd) -* [Pokémon](src/data/pokemon/pokemon.json): - En este set encontrarás una lista con los 251 Pokémon de la región de Kanto - y Johto, junto con sus respectivas estadísticas usadas en el juego - [Pokémon GO](http://pokemongolive.com). - - [Investigación con jugadores de Pokémon Go](src/data/pokemon/README.md) +## 4. Historias de usuario -* [League of Legends - Challenger leaderboard](src/data/lol/lol.json): - Este set de datos muestra la lista de campeones en una liga del - juego League of Legends (LoL). - - [Investigación con jugadores de LoL](src/data/lol/README.md) +Los resultados de la encuesta nos dieron como resultado estas cuatro historias de usuario: -* [Rick and Morty](src/data/rickandmorty/rickandmorty.json). - Este set nos proporciona la lista de los personajes de la serie Rick and - Morty. [API Rick and Morty](https://rickandmortyapi.com). - - [Investigación con seguidores de Rick and Morty](src/data/rickandmorty/README.md) +**Primera historia - Yo, como alguien que sabe un poco de la historia del mundo Pokemon, quiero poder ver una lista de los pokemon, para conocer algunos datos básicos.** -* [Juegos Olímpicos de Río de Janeiro](src/data/athletes/athletes.json). - Este set nos proporciona la lista de los atletas que ganaron medallas en las - olímpiadas de Río de Janeiro. - - [Investigación con interesados en juegos olímpicos de Río de Janeiro](src/data/athletes/README.md) +Criterios de aceptación +[ ] Quiero que la lista de pokemones se vea en la página principal en forma de ficha donde aparezca con su respectiva imagen, nombre, tipo de poder, probabilidad de captura y estatura (en inglés) +[ ] Quiero que sea responsive, para telefono y pc +[ ] Quiero que sea una interfaz sencilla de usar para el usuario +[ ] No hay ningún tipo de interacción -* [Studio Ghibli](src/data/ghibli/ghibli.json). - En este set encontrarás una lista de las animaciones y sus personajes del - [Studio Ghibli](https://ghiblicollection.com/). - - [Investigación con seguidores de las animaciones del Studio Ghibli](src/data/ghibli/README.md) +Definición de terminado -El objetivo principal de este proyecto es que aprendas a diseñar y construir una -interfaz web donde se pueda visualizar y manipular data, entendiendo lo que el -usuario necesita. +[ ] Todo el código está subido a la rama principal de repositorio. +[ ] Hemos hecho prueba de usabilidad con al menos 2 usuarios. +[ ] Hemos publicado la historia a una página de GitHub pages. -## 3. Objetivos de aprendizaje +**Segunda historia - Yo, como alguien que sabe un poco de la historia del mundo Pokemon, quiero poder ver una lista de los pokemon, para filtrarlos según su tipo de poder.** -Reflexiona y luego marca los objetivos que has llegado a entender y aplicar en tu proyecto. Piensa en eso al decidir tu estrategia de trabajo. +Criterios de aceptación -### HTML +[ ] Quiero que sea responsive, para telefono y pc +[ ] Quiero que sea una interfaz sencilla de usar para el usuario +[ ] Quiero filtrar los pokemones por tipos de poder (en inglés) -- [ ] **Uso de HTML semántico** +Definición de terminado -
Links

+[ ] Todo el código está subido a la rama principal de repositorio. +[ ] Hemos hecho prueba de usabilidad con al menos 2 usuarios. +[ ] Hemos publicado la historia a una página de GitHub pages. - * [HTML semántico](https://curriculum.laboratoria.la/es/topics/html/02-html5/02-semantic-html) - * [Semantics - MDN Web Docs Glossary](https://developer.mozilla.org/en-US/docs/Glossary/Semantics#Semantics_in_HTML) -

+**Tercera historia - Yo, como alguien que sabe un poco de la historia del mundo Pokemon, quiero poder ver una lista de los pokemon, para ordenar los pokemones de mayor a menor probabilidad de captura.** -### CSS +Criterios de aceptación -- [ ] **Uso de selectores de CSS** +[ ] Quiero que sea responsive, para telefono y pc +[ ] Quiero que sea una interfaz sencilla de usar para el usuario +[ ] Quiero ordenar la lista de pokemones de mayor a menor probabilidad de captura (en inglés) -
Links

+Definición de terminado - * [Intro a CSS](https://curriculum.laboratoria.la/es/topics/css/01-css/01-intro-css) - * [CSS Selectors - MDN](https://developer.mozilla.org/es/docs/Web/CSS/CSS_Selectors) -

+[ ] Hemos hecho prueba de usabilidad con al menos 2 usuarios. +[ ] Todo el código está subido a la rama principal de repositorio. +[ ] Hemos publicado la historia a una página de GitHub pages. -- [ ] **Modelo de caja (box model): borde, margen, padding** +**Cuarta historia - Yo, como alguien que sabe un poco de la historia del mundo Pokemon, quiero poder ver una lista de los pokemon, para calcular el promedio de estatura de los pokemones.** -
Links

+Criterios de aceptación - * [Box Model & Display](https://curriculum.laboratoria.la/es/topics/css/01-css/02-boxmodel-and-display) - * [The box model - MDN](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/The_box_model) - * [Introduction to the CSS box model - MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model) - * [CSS display - MDN](https://developer.mozilla.org/pt-BR/docs/Web/CSS/display) - * [display - CSS Tricks](https://css-tricks.com/almanac/properties/d/display/) -

+[ ] Quiero que sea responsive, para telefono y pc +[ ] Quiero que sea una interfaz sencilla de usar para el usuario +[ ] Quiero calcular el promedio de estatura de los pokemones. -- [ ] **Uso de flexbox en CSS** +Definición de terminado -
Links

+[ ] Hemos hecho prueba de usabilidad con al menos 2 usuarios. +[ ] Todo el código está subido a la rama principal de repositorio. +[ ] Hemos publicado la historia a una página de GitHub pages. - * [A Complete Guide to Flexbox - CSS Tricks](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) - * [Flexbox Froggy](https://flexboxfroggy.com/#es) - * [Flexbox - MDN](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) -

+## 5. Prototipos de baja fidelidad -### Web APIs +Creamos los prototipos de baja fidelidad usando lápiz y papel. Aquí están las fotos: -- [ ] **Uso de selectores del DOM** +![image](https://github.com/carolinaposadl/DEV007-data-lovers/assets/129551206/6524de7d-7e2a-4c57-aa30-2a3270921ab4) +![image](https://github.com/carolinaposadl/DEV007-data-lovers/assets/129551206/ce9cc10d-c111-41e7-ba05-c0fb19b39541) +![image](https://github.com/carolinaposadl/DEV007-data-lovers/assets/129551206/3db45489-7d8a-4b7e-9e04-45fa04c17d63) +![image](https://github.com/carolinaposadl/DEV007-data-lovers/assets/129551206/fc0a1345-0ee0-44e9-918b-1b547aa1f0fe) +![image](https://github.com/carolinaposadl/DEV007-data-lovers/assets/129551206/f7854474-7de6-4180-97fd-c2282704270c) +![image](https://github.com/carolinaposadl/DEV007-data-lovers/assets/129551206/be4febfb-2f1b-42b9-838a-5f6cd452514c) +![image](https://github.com/carolinaposadl/DEV007-data-lovers/assets/129551206/6a9d7135-0cf2-423e-8ead-20d788e852fc) -
Links

+## 6. Prototipos de alta fidelidad +Creamos los prototipos de alta fidelidad usando Figma. - * [Manipulación del DOM](https://curriculum.laboratoria.la/es/topics/browser/02-dom/03-1-dom-methods-selection) - * [Introducción al DOM - MDN](https://developer.mozilla.org/es/docs/Web/API/Document_Object_Model/Introduction) - * [Localizando elementos DOM usando selectores - MDN](https://developer.mozilla.org/es/docs/Web/API/Document_object_model/Locating_DOM_elements_using_selectors) -

+Aquí está el link para acceder a la vista del prototipo en Figma: +https://www.figma.com/file/U0KPK97klYB7pwpgWTGtoS/Prototipo-data-lovers?type=design&node-id=0%3A1&t=iIlefLPmZNn4a50R-1 -- [ ] **Manejo de eventos del DOM (listeners, propagación, delegación)** +Aquí están algunas capturas de pantalla: -
Links

+![image](https://github.com/carolinaposadl/DEV007-data-lovers/assets/129551206/a273937c-bdd5-451a-9ac6-1a12304d2b15) +![image](https://github.com/carolinaposadl/DEV007-data-lovers/assets/129551206/b92d8b1e-c144-4f48-93cf-a21e294211b6) +![image](https://github.com/carolinaposadl/DEV007-data-lovers/assets/129551206/17368b69-2574-4a3d-b864-a62d200eb1af) +![image](https://github.com/carolinaposadl/DEV007-data-lovers/assets/129551206/0237ba45-06e9-4d08-8a4a-9a7ef1fb72de) +![image](https://github.com/carolinaposadl/DEV007-data-lovers/assets/129551206/21f21ce6-43ea-4b79-9289-94ea1b88b795) +![image](https://github.com/carolinaposadl/DEV007-data-lovers/assets/129551206/79a204be-8350-4216-a573-bdac3fad8d09) +![image](https://github.com/carolinaposadl/DEV007-data-lovers/assets/129551206/899de3b4-b718-46fd-9bce-4f0eb7ae3d51) - * [Introducción a eventos - MDN](https://developer.mozilla.org/es/docs/Learn/JavaScript/Building_blocks/Events) - * [EventTarget.addEventListener() - MDN](https://developer.mozilla.org/es/docs/Web/API/EventTarget/addEventListener) - * [EventTarget.removeEventListener() - MDN](https://developer.mozilla.org/es/docs/Web/API/EventTarget/removeEventListener) - * [El objeto Event](https://developer.mozilla.org/es/docs/Web/API/Event) -

-- [ ] **Manipulación dinámica del DOM** +## 7. Test de usabilidad -
Links

- - * [Introducción al DOM](https://developer.mozilla.org/es/docs/Web/API/Document_Object_Model/Introduction) - * [Node.appendChild() - MDN](https://developer.mozilla.org/es/docs/Web/API/Node/appendChild) - * [Document.createElement() - MDN](https://developer.mozilla.org/es/docs/Web/API/Document/createElement) - * [Document.createTextNode()](https://developer.mozilla.org/es/docs/Web/API/Document/createTextNode) - * [Element.innerHTML - MDN](https://developer.mozilla.org/es/docs/Web/API/Element/innerHTML) - * [Node.textContent - MDN](https://developer.mozilla.org/es/docs/Web/API/Node/textContent) -

- -### JavaScript - -- [ ] **Diferenciar entre tipos de datos primitivos y no primitivos** - -- [ ] **Arrays (arreglos)** - -
Links

- - * [Arreglos](https://curriculum.laboratoria.la/es/topics/javascript/04-arrays) - * [Array - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/) - * [Array.prototype.sort() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) - * [Array.prototype.forEach() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) - * [Array.prototype.map() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/map) - * [Array.prototype.filter() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) - * [Array.prototype.reduce() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce) -

- -- [ ] **Objetos (key, value)** - -
Links

- - * [Objetos en JavaScript](https://curriculum.laboratoria.la/es/topics/javascript/05-objects/01-objects) -

- -- [ ] **Variables (declaración, asignación, ámbito)** - -
Links

- - * [Valores, tipos de datos y operadores](https://curriculum.laboratoria.la/es/topics/javascript/01-basics/01-values-variables-and-types) - * [Variables](https://curriculum.laboratoria.la/es/topics/javascript/01-basics/02-variables) -

- -- [ ] **Uso de condicionales (if-else, switch, operador ternario, lógica booleana)** - -
Links

- - * [Estructuras condicionales y repetitivas](https://curriculum.laboratoria.la/es/topics/javascript/02-flow-control/01-conditionals-and-loops) - * [Tomando decisiones en tu código — condicionales - MDN](https://developer.mozilla.org/es/docs/Learn/JavaScript/Building_blocks/conditionals) -

- -- [ ] **Uso de bucles/ciclos (while, for, for..of)** - -
Links

- - * [Bucles (Loops)](https://curriculum.laboratoria.la/es/topics/javascript/02-flow-control/02-loops) - * [Bucles e iteración - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Loops_and_iteration) -

- -- [ ] **Funciones (params, args, return)** - -
Links

- - * [Funciones (control de flujo)](https://curriculum.laboratoria.la/es/topics/javascript/02-flow-control/03-functions) - * [Funciones clásicas](https://curriculum.laboratoria.la/es/topics/javascript/03-functions/01-classic) - * [Arrow Functions](https://curriculum.laboratoria.la/es/topics/javascript/03-functions/02-arrow) - * [Funciones — bloques de código reutilizables - MDN](https://developer.mozilla.org/es/docs/Learn/JavaScript/Building_blocks/Functions) -

- -- [ ] **Pruebas unitarias (unit tests)** - -
Links

- - * [Empezando con Jest - Documentación oficial](https://jestjs.io/docs/es-ES/getting-started) -

- -- [ ] **Módulos de ECMAScript (ES Modules)** - -
Links

- - * [import - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/import) - * [export - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/export) -

- -- [ ] **Uso de linter (ESLINT)** - -- [ ] **Uso de identificadores descriptivos (Nomenclatura y Semántica)** - -- [ ] **Diferenciar entre expresiones (expressions) y sentencias (statements)** - -### Control de Versiones (Git y GitHub) - -- [ ] **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** - -
Links

- - * [Sitio oficial de GitHub Pages](https://pages.github.com/) -

- -- [ ] **GitHub: Colaboración en Github (branches | forks | pull requests | code review | tags)** - -### Centrado en el usuario - -- [ ] **Diseñar y desarrollar un producto o servicio poniendo a las usuarias en el centro** - -### Diseño de producto - -- [ ] **Crear prototipos de alta fidelidad que incluyan interacciones** - -- [ ] **Seguir los principios básicos de diseño visual** - -### Investigación - -- [ ] **Planear y ejecutar testeos de usabilidad de prototipos en distintos niveles de fidelidad** - -
Links

- - * [Intro a testeos usabilidad](https://coda.io/@bootcamp-laboratoria/contenido-ux/test-de-usabilidad-15) - * [Pruebas con Usuarios 1 — ¿Qué, cuándo y para qué testeamos?](https://eugeniacasabona.medium.com/pruebas-con-usuarios-1-qu%C3%A9-cu%C3%A1ndo-y-para-qu%C3%A9-testeamos-7c3a89b4b5e7) -

- -## 4. Consideraciones generales - -* Este proyecto se debe resolver en duplas. -* El rango de tiempo estimado para completar el proyecto es de 3 a 4 Sprints. -* El proyecto será entregado subiendo tu código a GitHub (commit/push) y la - interfaz será desplegada usando [GitHub Pages](https://pages.github.com/). - -## 5. Criterios de aceptación mínimos del proyecto - -Los criterios para considerar que has completado este proyecto son: - -### Definición del producto - -Documenta brevemente tu trabajo en el archivo `README.md` de tu repositorio, -contándonos cómo fue tu proceso de diseño y cómo crees que el producto resuelve -el problema (o problemas) que tiene tu usuario. - -### Historias de usuario - -Una vez que entiendas las necesidades de tus usuarios, escribe las [Historias -de Usuario](https://es.wikipedia.org/wiki/Historias_de_usuario) que representen -todo lo que el usuario necesita hacer/ver. Las **Historias de Usuario** deben -ser el resultado de tu proceso de investigación o _research_ de tus usuarios. - -Asegúrate de incluir la definición de terminado (_definition of done_) y los -Criterios de Aceptación para cada una. - -En la medida de lo posible, termina una historia de usuario antes de pasar -a la siguiente (Cumple con Definición de Terminado + Criterios de Aceptación). - -### Diseño de la Interfaz de Usuario - -#### Prototipo de baja fidelidad - -Durante tu trabajo deberás haber hecho e iterado bocetos (_sketches_) de tu -solución usando papel y lápiz. Te recomendamos tomar fotos de todas las -iteraciones que hagas, que las subas a tu repositorio y las menciones en tu -`README.md`. - -#### Prototipo de alta fidelidad - -Lo siguiente es diseñar tu Interfaz de Usuario (UI por sus siglas en inglés - -_User Interface_). Para eso debes aprender a utilizar alguna herramienta de -diseño visual. Nosotros te recomendamos [Figma](https://www.figma.com/) que es -una herramienta que funciona en el navegador y, además, puedes crear una cuenta -gratis. Sin embargo, eres libre de utilizar otros editores gráficos como -Illustrator, Photoshop, PowerPoint, Keynote, etc. - -El diseño debe representar el _ideal_ de tu solución. Digamos que es lo que -desearías implementar si tuvieras tiempo ilimitado para trabajar. Además, tu -diseño debe seguir los fundamentos de _visual design_. - -#### Testeos de usabilidad - -Durante el reto deberás hacer _tests_ de usabilidad con distintos usuarios, y -en base a los resultados, deberás iterar tus diseños. Cuéntanos -qué problemas de usabilidad detectaste a través de los _tests_ y cómo los -mejoraste en tu propuesta final. - -### Implementación de la Interfaz de Usuario (HTML/CSS/JS) - -Luego de diseñar tu interfaz de usuario deberás trabajar en su implementación. -**No** es necesario que construyas la interfaz exactamente como la diseñaste. -Tu tiempo de hacking es escaso, así que deberás priorizar - -Como mínimo, tu implementación debe: - -1. Mostrar la data en una interfaz: puede ser un card, una tabla, una lista, - etc. -2. Permitir al usuario interactuar para obtener la infomación que necesita. -3. Ser _responsive_, es decir, debe visualizarse sin problemas desde distintos - tamaños de pantallas: móviles, tablets y desktops. -4. Que la interfaz siga los fundamentos de _visual design_. - -### Pruebas unitarias - -El _boilerplate_ de este proyecto no incluye Pruebas Unitarias (_tests_), así es -que tendrás que escribirlas tú para las funciones encargadas de _procesar_, -_filtrar_ y _ordenar_ la data, así como _calcular_ estadísticas. - -Tus _pruebas unitarias_ deben dar una cobertura del 70% de _statements_ -(_sentencias_), _functions_ (_funciones_), _lines_ (_líneas_), y _branches_ -(_ramas_) del archivo `src/data.js` que contenga tus funciones y está detallado -en la sección de [Consideraciones técnicas](#srcdatajs). - -## 6. Hacker edition - -Las secciones llamadas _Hacker Edition_ son **opcionales**. Si **terminaste** -con todo lo anterior y te queda tiempo, intenta completarlas. Así podrás -profundizar y/o ejercitar más sobre los objetivos de aprendizaje del proyecto. - -Features/características extra sugeridas: - -* En lugar de consumir la data estática brindada en este repositorio, puedes - consumir la data de forma dinámica, cargando un archivo JSON por medio de - `fetch`. La carpeta `src/data` contiene una versión `.js` y una `.json` de - de cada set datos. -* Agregarle a tu interfaz de usuario implementada visualizaciones gráficas. Para - ello te recomendamos explorar librerías de gráficas como - [Chart.js](https://www.chartjs.org/) - o [Google Charts](https://developers.google.com/chart/). -* 100% Coverage - -## 7. Consideraciones técnicas - -La lógica del proyecto debe estar implementada completamente en JavaScript -(ES6), HTML y CSS. En este proyecto NO está permitido usar librerías o -frameworks, solo [vanilla JavaScript](https://medium.com/laboratoria-how-to/vanillajs-vs-jquery-31e623bbd46e), -con la excepción de librerías para hacer gráficas (charts); ver -[_Parte opcional_](#6-hacker-edition) más arriba. - -El _boilerplate_ contiene una estructura de archivos como punto de partida así -como toda la configuración de dependencias: - -```text -. -├── EXTRA.md -├── README.md -├── package.json -├── src -| ├── data (según con qué data trabajes) -| | ├── lol -| | | ├── lol.js -| | | ├── lol.json -| | | └── README.md -| | ├── pokemon -| | | ├── pokemon.js -| | | ├── pokemon.json -| | | └── README.md -| | └── rickandmorty -| | | ├── rickandmorty.js -| | | ├── rickandmorty.json -| | | └── README.md -| | └── athletes -| | | ├── athletes.js -| | | ├── athletes.json -| | | └── README.md -| | └── ghibli -| | | ├── ghibli.js -| | | ├── ghibli.json -| | | └── README.md -| ├── data.js -| ├── index.html -| ├── main.js -| └── style.css -└── test - └── data.spec.js - -directory: 7 file: 20 -``` - -### `src/index.html` - -Como en el proyecto anterior, existe un archivo `index.html`. Como ya sabes, -acá va la página que se mostrará al usuario. También nos sirve para indicar -qué scripts se usarán y unir todo lo que hemos hecho. - -### `src/main.js` - -Recomendamos usar `src/main.js` para todo tu código que tenga que ver con -mostrar los datos en la pantalla. Con esto nos referimos básicamente a la -interacción con el DOM. Operaciones como creación de nodos, registro de -manejadores de eventos (_event listeners_ o _event handlers_), .... - -Esta no es la única forma de dividir tu código, puedes usar más archivos y -carpetas, siempre y cuando la estructura sea clara para tus compañeras. - -En este archivo encontrarás una serie de _imports_ _comentados_. Para _cargar_ -las diferentes fuentes de datos tendrás que _descomentar_ la línea -correspondiente. - -Por ejemplo, si "descomentamos" la siguiente línea: - -```js -// import data from './data/lol/lol.js'; -``` - -La línea quedaría así: - -```js -import data from './data/lol/lol.js'; -``` - -Y ahora tendríamos la variable `data` disponible en el script `src/main.js`. - -### `src/data.js` - -El corazón de este proyecto es la manipulación de datos a través de arreglos -y objetos. - -Te recomendamos que este archivo contenga toda la funcionalidad que corresponda -a obtener, procesar y manipular datos (tus funciones). Por ejemplo: - -* `filterData(data, condition)`: esta función `filter` o filtrar recibiría la - data, y nos retornaría aquellos datos que sí cumplan con la condición. - -* `sortData(data, sortBy, sortOrder)`: esta función `sort` u ordenar - recibe tres parámetros. - El primer parámetro, `data`, nos entrega los datos. - El segundo parámetro, `sortBy`, nos dice con respecto a cuál de los campos de - la data se quiere ordenar. - El tercer parámetro, `sortOrder`, indica si se quiere ordenar de manera - ascendente o descendente. - -* `computeStats(data)`: la función `compute` o calcular, nos permitirá hacer - cálculos estadísticos básicos para ser mostrados de acuerdo a la data - proporcionada. - -Estos nombres de funciones y de parámetros son solamente referenciales, lo que -decidas depende de tu propia implementación. - -Estas funciones deben ser [_puras_](https://medium.com/laboratoria-developers/introducci%C3%B3n-a-la-programaci%C3%B3n-funcional-en-javascript-parte-2-funciones-puras-b99e08c2895d) -e independientes del DOM. Estas funciones serán después usadas desde el archivo -`src/main.js`, al cargar la página, y cada vez que el usuario interactúe (click, -filtrado, ordenado, ...). - -### `src/data` - -En esta carpeta están los datos de las diferentes fuentes. Encontrarás una -carpeta por cada fuente, y dentro de cada carpeta dos archivos: uno con la -extensión `.js` y otro `.json`. Ambos archivos contienen la misma data; la -diferencia es que el `.js` lo usaremos a través de una etiqueta ` diff --git a/src/main.js b/src/main.js index 71c59f2d..af74fb41 100644 --- a/src/main.js +++ b/src/main.js @@ -1,6 +1,98 @@ -import { example } from './data.js'; -// import data from './data/lol/lol.js'; -import data from './data/pokemon/pokemon.js'; -// import data from './data/rickandmorty/rickandmorty.js'; +import { filtroPokemones, ordenarPokemones } from "./data.js"; +import data from "./data/pokemon/pokemon.js"; + +//Declaramos variables que vamos a usar +const pokemones = data.pokemon; +const contenedorPokemones = document.getElementById("contenedor_pokemones"); +const logoPokemon = document.getElementById("imagenLogoPokemon"); + +// Refrescar la página al hacer clic en la imagen del logo +logoPokemon.addEventListener("click", () => { + //al hacer click en el logo que trajimos arriba con la id se recarga la página + location.reload(); //-reload se usa para recargar la página +}); + +// --------------------------- HISTORIA DE USUARIO 1 : Creación de la función de la tarjeta de pokemones para reusarla después +const tarjetaPokemon = (pokemon) => { + //se extraen las propiedades del objeto pokemon con la función flecha + const img = pokemon.img; + const name = pokemon.name; + const height = pokemon.size.height; + const weight = pokemon.size.weight; + const type = pokemon.type.join(", "); // .join sirve para poner elementos entre los elementos del array + const baseCaptureRate = pokemon.encounter["base-capture-rate"]; // también se puede acceder a una propiedad específica dentro del objeto mediante los []. La notación de corchetes es útil cuando el nombre de la propiedad es dinámico o cuando contiene caracteres especiales, como espacios o guiones. + + const card = document.createElement("div"); //.createElement sirve para crear un div que contiene la tarjeta del pokémon. + card.className = "pokemon-card"; //Se asigna la clase "pokemon-card" al elemento de la tarjeta para modificar en CSS + card.innerHTML = ` + ${name} +

${name}

+
+

Height: ${height}

+

Weight: ${weight}

+

Base Capture Rate: ${baseCaptureRate}

+

Type: ${type}

+
+ `; + //Establecemos el contenido de la tarjeta con .innerHTML + //los ${template string} permiten que se inserte el valor original dela propiedad + return card; //Aquí retornamos el elemento de la tarjeta creado +}; + +// Visualización de los pokemones con el método .forEach +pokemones.forEach((pokemon) => { + //se usa el metodo forEach para ir por cada pokemon y ejecutar la función que los muestra + const card = tarjetaPokemon(pokemon); + contenedorPokemones.appendChild(card); + //appendChild se usa para mostrar la tarjeta en el html (contenedor_pokemones) + //el forEach hace que el proceso de crear una tarjeta se repita con cada pokemon + //la tarjeta creada la traemos de data.js +}); + +// --------------------------- HISTORIA DE USUARIO 2: Filtro de pokemones +/*const pokemonesGrass = filtroPokemones(data, "grass"); console.log(pokemonesGrass); esto nos sirve para comprobar que funciona el filtro*/ + +const valoresLista = document.getElementById("lista-desplegable-filtrar"); +//los valores son los tipos de pokemon y se toman de la lista desplegable de html + +valoresLista.addEventListener("change", () => { + //cuando se hace un cambio en la lista-desplegable-filtrar se ejecuta la función flecha + const valorSeleccionado = valoresLista.value; // se obtiene el valor seleccionado .value + + if (valorSeleccionado === "show-all") { + // si se selecciona el valor de show-all se ejecuta el metodo de forEach para mostrar todas las tarjetas con todos los pokemones + contenedorPokemones.innerHTML = ""; + pokemones.forEach((pokemon) => { + const card = tarjetaPokemon(pokemon); + contenedorPokemones.appendChild(card); + }); + } else { + // Si no se selecciona el valor de show-all, entonces se filtran los pokemones por el valor seleccionado + const pokemonesFiltrados = filtroPokemones(data, valorSeleccionado); + contenedorPokemones.innerHTML = ""; //se debe dejar el contenedor vacio siempre para que no se sobre escriban los datos de las nuevas funciones + pokemonesFiltrados.forEach((pokemon) => { + //la función forEach se ejecuta para mostrar las tarjetas + const card = tarjetaPokemon(pokemon); + contenedorPokemones.appendChild(card); + }); + } +}); + +//----------------------------------- HISTORIA DE USUARIO 3: Filtro de ordenamiento + +const ordenarValores = document.getElementById("lista-desplegable-ordenar"); +ordenarValores.addEventListener("change", () => { + const valoresOrdenados = ordenarValores.value; //obteniendo el valor seleccionado .value + ordenarPokemones(pokemones, valoresOrdenados); //llamando la función ordenarPokemones, pasando como argumento pokemones (donde está la data) y donde se guardó el valor seleccionado + + if (valoresOrdenados === "from-lower-to-higher" || valoresOrdenados === "from-higher-to-lower") { + contenedorPokemones.innerHTML = ""; + data.pokemon.forEach((pokemon) => { //recorriendo el arreglo original data.pokemon + const card = tarjetaPokemon(pokemon); + contenedorPokemones.appendChild(card); + }); + } +}); + + -console.log(example, data); diff --git a/src/style.css b/src/style.css index e69de29b..8042ef29 100644 --- a/src/style.css +++ b/src/style.css @@ -0,0 +1,145 @@ +body { + background-color: #1a2234; + font-family: sans-serif; +} + +.container_titulo { + text-align: center; + padding: 20px; +} + +.logoPokemon { + width: 266px; + height: 93px; + text-align: center; + cursor: pointer; +} + +.principal_parrafo { + padding: 20px; + padding-left: 50px; + padding-right: 50px; + color: white; + line-height: 1.5; + font-size: 16px; +} + +.container_botones_principal { + justify-content: center; + text-align: center; + display: flex; + gap: 30px; + padding: 20px; +} + +button { + background-color: #fffc0f; + color: #1a2234; + border: hidden; + border-radius: 10px; + padding: 5px 30px; + font-weight: bold; + height: 32px; + width: 170px; + font-size: 16px; + box-shadow: 0px 0px 10px #0d0e0e; + cursor: pointer; +} + +button:hover { + background-color: #4776fa; +} + +select { + /*lista desplegable*/ + background-color: #fffc0f; + text-align: center; + color: #1a2234; + border: hidden; + border-radius: 10px; + font-weight: bold; + height: 32px; + width: 260px; + font-size: 16px; + box-shadow: 0px 0px 10px #0d0e0e; + cursor: pointer; + + /* Para quitar la flecha de la lista*/ + -moz-appearance: none; + -webkit-appearance: none; + display: none; +} + +/* Para quitar la primera opción de la lista desplegable (select)*/ +select option:first-child { + display: none; +} + +select option { + /* Para cambiar el color de la lista desplegable*/ + background-color: #f0ee8b; + box-shadow: 0px 0px 10px #0d0e0e; +} + +/*--------------------------- HISTORIA DE USUARIO 1 (visualización)---------------------------*/ +/* Tarjeta de cada Pokemon*/ +.pokemon-card { + width: 252px; + height: 250px; + background-color: #354058; + border-radius: 10px; + padding-bottom: 5px; + padding-top: 40px; + margin-bottom: 40px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + text-align: left; + padding-bottom: 50px; + box-shadow: 0px 0px 10px #0d0e0e; +} + +.pokemon-card:hover { + box-shadow: 0 4rem 4rem rgba(0.5, 0.5, 0.5, 0.5); +} + +.pokemon-card img { + width: 150px; + height: 150px; + padding-top: 40px; +} + +.pokemon-card h3 { + margin-top: 10px; + font-size: 18px; + text-align: center; + font-weight: bold; +} + +.pokemon-card p { + margin: 5px 0; + font-size: 14px; + width: 100%; +} + +.cardp { + background-color: #283248; + padding: 25px; + padding-right: 100px; + border-radius: 10px; +} + +/*Contenedor de pokemones*/ +.contenedor_pokemones { + display: flex; + flex-wrap: wrap; + justify-content: space-evenly; + color: white; + padding: 30px; +} + +/*--------------------------- HISTORIA DE USUARIO 2 (filtro)---------------------------*/ +.boton:hover { + background-color: #4776fa; +} diff --git a/test/data.spec.js b/test/data.spec.js index 09b1f23f..a73afb15 100644 --- a/test/data.spec.js +++ b/test/data.spec.js @@ -1,23 +1,122 @@ -import { example, anotherExample } from '../src/data.js'; +import { filtroPokemones, ordenarPokemones } from "../src/data.js"; +//-----------------------------------Test del filtro de pokemones +//Data ficticia simulando la data real +const data = { + pokemon: [ + { name: "bulbasaur", type: ["grass"] }, + { name: "squirtle", type: ["water"] }, + { name: "charmander", type: ["fire"] }, + { name: "pikachu", type: ["electric"] }, + ], +}; -describe('example', () => { - it('is a function', () => { - expect(typeof example).toBe('function'); +//Resultados esperados +const pokemonGrass = [{ name: "bulbasaur", type: ["grass"] }]; +const pokemonWater = [{ name: "squirtle", type: ["water"] }]; +const pokemonFire = [{ name: "charmander", type: ["fire"] }]; +const pokemonElectric = [{ name: "pikachu", type: ["electric"] }]; + +// Pruebas del filtro por tipo de pokemon + +describe("filtroPokemones", () => { + it("Debería retornar el tipo grass", () => { + expect(filtroPokemones(data, "grass")).toEqual(pokemonGrass); }); - it('returns `example`', () => { - expect(example()).toBe('example'); + it("Debería retornar el tipo water", () => { + expect(filtroPokemones(data, "water")).toEqual(pokemonWater); }); -}); + it("Debería retornar el tipo fire", () => { + expect(filtroPokemones(data, "fire")).toEqual(pokemonFire); + }); + + it("Debería retornar los pokémones del tipo electric", () => { + expect(filtroPokemones(data, "electric")).toEqual(pokemonElectric); + }); -describe('anotherExample', () => { - it('is a function', () => { - expect(typeof anotherExample).toBe('function'); + // Test de la función + it("Debería ser una función", () => { + expect(typeof filtroPokemones).toBe("function"); }); - it('returns `anotherExample`', () => { - expect(anotherExample()).toBe('OMG'); + // Test de que es un array + it("Debería retornar un array de pokémones", () => { + const result = filtroPokemones(data, "grass"); + expect(Array.isArray(result)).toBe(true); + }); + + // Test para ver si contiene el pokemon que se selecciona + it("Debería incluir a Pikachu en el resultado al filtrar por tipo electric", () => { + const resultado = filtroPokemones(data, "electric"); + expect(resultado).toContainEqual({ name: "pikachu", type: ["electric"] }); + }); + + it("Debería incluir a Squirtle en el resultado al filtrar por tipo agua", () => { + const resultado = filtroPokemones(data, "water"); + expect(resultado).toContainEqual({ name: "squirtle", type: ["water"] }); + }); + + it("Debería incluir a Bulbasaur en el resultado al filtrar por tipo grass", () => { + const resultado = filtroPokemones(data, "grass"); + expect(resultado).toContainEqual({ name: "bulbasaur", type: ["grass"] }); }); }); + +//-----------------------------------Test función ordenar +//Data ficticia simulando la data real +const dataPokemon = [ + { + "name": "bulbasaur", + "encounter": { + "base-capture-rate": "0.2" + } + }, + { + "name": "charmeleon", + "encounter": { + "base-capture-rate": "0.1" + } + }, + { + "name": "blastoise", + "encounter": { + "base-capture-rate": "0.05" + } + }, + { + "name": "pichu", + "encounter": { + "base-capture-rate": "not in capture" + } + }, +] + +const asc = [ + { "name": "pichu", "encounter": { "base-capture-rate": "not in capture" } }, + { "name": "bulbasaur", "encounter": { "base-capture-rate": "0.2" } }, + { "name": "charmeleon", "encounter": { "base-capture-rate": "0.1" } }, + { "name": "blastoise", "encounter": { "base-capture-rate": "0.05" } }, +] + +const desc = [ + { "name": "blastoise", "encounter": { "base-capture-rate": "0.05" } }, + { "name": "charmeleon", "encounter": { "base-capture-rate": "0.1" } }, + { "name": "bulbasaur", "encounter": { "base-capture-rate": "0.2" } }, + { "name": "pichu", "encounter": { "base-capture-rate": "not in capture" } }, +] + +describe("ordenarPokemones", () => { //nombre de la función + it("debería ser una función", () => { //descripción de la función + expect(typeof ordenarPokemones).toBe("function"); + }); + + it("debería devolver los pokemones ordenados ascendentemente", () => { + expect(ordenarPokemones(dataPokemon, "from-lower-to-higher")).toEqual(asc); + }); + + it("debería devolver los pokemones ordenados descendentemente", () => { + expect(ordenarPokemones(dataPokemon, "from-higher-to-lower")).toEqual(desc); + }); +}); \ No newline at end of file