diff --git a/README.md b/README.md index 0e78340d..7224f9aa 100644 --- a/README.md +++ b/README.md @@ -2,624 +2,116 @@ ## Í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 para solicitar PF](#9-checklist-para-solicitar-pf) +* [1. ¿Qué haré?](#1-preámbulo) +* [2. ¿Qué entregaré?](#2-resumen-del-proyecto) +* [3. Selección de tema e historias:](#3-objetivos-de-aprendizaje) +* [4. Mis objetivos de aprendizaje](#4-consideraciones-generales) *** -## 1. Preámbulo +## 1. ¿Qué haré? -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. +Página web para visualizar un conjunto (set) de datos: +- Visualizar la data +- Filtrar la data +- Ordenar la data +- Hacer algún cálculo agregado -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_. +La página web se desarrollará teniendo en cuenta la información que se descubra acerca de las preferencias y requerimientos del usuario, de modo que la visualización de los datos se adapte a sus necesidades específicas. -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. +¿Por qué lo haré? +El objetivo principal de este proyecto es aprender a diseñar y construir una interfaz web donde se pueda visualizar y manipular data, entendiendo lo que el usuario necesita. -![pokemon-data-to-ui](https://user-images.githubusercontent.com/12631491/218505816-c6d11758-9de4-428f-affb-2a56ea4d68c4.png) -## 2. Resumen del proyecto +## 2. ¿Qué entregaré? -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. +El proyecto será entregado subiendo el código a GitHub (commit/push) y la interfaz será desplegada usando GitHub Pages. -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). +Esta es mi interpretación de los criterios mínimos de aceptación: -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. +Definición del producto (1era etapa) +- Documenta: README.md: proceso de diseño y cómo el producto resuelve el problema (o problemas) que tiene tu usuario. +- Historias de usuario: incluir la definición de terminado (definition of done) y los criterios de aceptación para cada una. +- Termina una historia de usuario antes de pasar a la siguiente. +- Diseño de la interfaz de usuario: prototipo de baja fidelidad (papel +fotos), alta fidelidad (ideal), testeos de usabilidad (para iterar, con problemas de usabilidad y sus soluciones - no son lo mismo que las pruebas unitarias). +Implementación (2da etapa) +- Implementación de la Interfaz de Usuario (HTML/CSS/JS): +- Muestra +- Interactúa +- Responsive (se adapta a los tamaños de pantalla) +- Visual design +Pruebas (3ra etapa) +- Pruebas unitarias que no son lo mismo que los test de usabilidad en prototipos: para las funciones encargadas de procesar, filtrar y ordenar la data, así como calcular estadísticas (cubrir al menos el 70%). -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. - -Estos son datos que te proponemos: - -* [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) - -* [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) - -* [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) - -* [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) * [Studio Ghibli](src/data/ghibli/ghibli.json). - En este set encontrarás una lista de las animaciones y sus personajes del + Este set es el que será mi data. [Studio Ghibli](https://ghiblicollection.com/). - [Investigación con seguidores de las animaciones del Studio Ghibli](src/data/ghibli/README.md) -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. - -## 3. Objetivos de aprendizaje - -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. - -### HTML - -- [ ] **Uso de HTML semántico** - -
Links

- - * [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) -

- -### CSS - -- [ ] **Uso de selectores de CSS** - -
Links

- - * [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) -

- -- [ ] **Modelo de caja (box model): borde, margen, padding** - -
Links

- - * [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/) -

- -- [ ] **Uso de flexbox en CSS** - -
Links

- - * [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) -

- -### Web APIs - -- [ ] **Uso de selectores del DOM** - -
Links

- - * [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) -

- -- [ ] **Manejo de eventos del DOM (listeners, propagación, delegación)** - -
Links

- - * [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** - -
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). +El corazón de este proyecto es la manipulación de datos a través de arreglos y objetos. -### Diseño de la Interfaz de Usuario -#### Prototipo de baja fidelidad +## 3. Selección de tema: -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`. +Una vez definida el área de interés, buscar entender quién es el usuario y qué necesita saber o ver exactamente -#### Prototipo de alta fidelidad +### Seleccioné: +Studio Ghibli -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. +Lo que necesitan usuarias de Ghibli: +Hay un grupo que desea poder interactuar y ver la información de las animaciones y sus personajes. Lo que necesitan las usuarias se reflejan en las historias: -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_. +### Historias: -#### Testeos de usabilidad +#### Historia 1: +Yo, como fanático de Ghibli quiero visualizar la lista de personajes por película. Para analizar los personajes por su película y recordar los que ya he visto pero he olvidado. -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. +##### Criterios de aceptación: +Tiene botón para filtrar personajes por películas. +Se aplica correctamente los filtros de orden por película. +Se realiza un cálculo agregado sobre: +Cada personaje con ficha que contenga: nombre, edad, género y especie. -### Implementación de la Interfaz de Usuario (HTML/CSS/JS) +##### Definición de terminado (se relaciona con la calidad, aplica para el resto de historias de usuarios): +- El usuario entra cómodamente a la página y se desplaza de manera intuitiva +- El usuario reconoce que la página se trata del Studio Ghibli +- Responsive +- Estilos CSS +- Código en el repositorio +- Código pasa los test +- Historia testeada por 2 usuarios que notaron las mejoras después del testeo de usabilidad. -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 +#### Historia 2: +Yo, como fanático del cine quiero conocer la lista de películas en Ghibli organizadas según sus directores. Con ficha que contenga el poster de la película y breve descripción. Para saber qué directores han repetido producciones con el Studio Ghibli. -Como mínimo, tu implementación debe: +#### Historia 3: +Yo, como fanático automotriz, quisiera conocer los vehículos raros en las películas Ghibli, ordenados según su clase. Y en su ficha algún tipo de descripción. Para conocer nuevos vehículos. -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_. +#### Historia 4: +Yo, como ilustrador, quisiera conocer las especies raras en las películas Ghibli, ordenadas según su clase. Y en su ficha algún tipo de descripción. Para analizar cuántas especies hay en las películas del Studio Ghibli. -### 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. +## Más información: +Más información sobre las historias y sus actividades específicas se encuentran en el siguiente tablero de figma, incluidas las gráficas de los prototipos de alta y baja fidelidad: https://www.figma.com/file/K6QRYN1ZpzO5Uv6NsJXqI6/SCRUM-DATA-LOVERS?type=design&node-id=0-1&mode=design&t=ei5RKGyngPX5lXQY-0 -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). +Prototpo de alta fidelidad: https://www.figma.com/file/tgFvxhKu3sby3yYR1nkIAw/Prototipo-de-alta-fidelidad?type=design&node-id=0-1&mode=design&t=L96q8hfp9Rbfaz0D-0 -## 6. Hacker edition +## Mis objetivos de aprendizaje: +- [] Usa VanillaJS +- [] Pasa linter (npm run pretest) +- [] Pasa tests (npm test): al final del proyecto los test se convirtieron en mi bloqueo mayor. +- [] Las pruebas unitarias cubren un mínimo del 70% de statements, functions y lines y branches. +- [] Incluye Definición del producto clara e informativa en README.md. +- [] Incluye historias de usuario en README.md. +- [] Incluye sketch de la solución (prototipo de baja fidelidad) en README.md. +- [] Incluye Diseño de la Interfaz de Usuario (prototipo de alta fidelidad) en README.md. +- [] Incluye link a Figma Dinámico para el test de usabilidad en README.md. +- [] Incluye el listado de problemas que detectaste a través de tests de usabilidad en el README.md. +- [] UI: Muestra lista y/o tabla con datos y/o indicadores. +- [] UI: Permite ordenar data por uno o más campos (asc y desc). +- [] UI: Permite filtrar data en base a una condición. +- [] UI: Es responsive. -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 ` - - + + + + + + Data Lovers + + + + + +
+ + + +
+ + + + +
+ +
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/src/main.js b/src/main.js index 71c59f2d..59f4f079 100644 --- a/src/main.js +++ b/src/main.js @@ -1,6 +1,459 @@ -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'; +//en este archivo se importar data y funciones desde diferentes archivos. También se hacen impresiones en la cónsola +//se importa un objeto que llamaremos data desde el archivo './data/ghibli/ghibli.js' - el objeto tiene una exportación default +import data from './data/ghibli/ghibli.js'; -console.log(example, data); +import { prom, alphabeticalOrderPeople, alphabeticalOrderFilms, yearOrderMovies, directorOrderMovies, countSpecies, countVehicles, moviesOrderPeople } from './data.js'; + +//______PERSONAJES ORDENADOS ALFABÉTICAMENTE + +const people = alphabeticalOrderPeople(data.films); + +//console.log("estoy ordenando personas",people); +//console.log("estoy mostrando la data", data); + +//HTML de la lista de personas +const peopleList = document.getElementById('people-list'); + +//Recorrer el arreglo ordenado y crear elementos HTML para cada persona +people.forEach(people => { + const peopleItem = document.createElement('div'); + const peopleImage = document.createElement('img'); + const peopleName = document.createElement('p'); + + peopleImage.src = people.img; + peopleName.textContent = people.name; + + peopleItem.appendChild(peopleImage); + peopleItem.appendChild(peopleName); + peopleList.appendChild(peopleItem); +}); + +//______CLICK PERSONAJES ORDENADOS ALFABÉTICAMENTE +const ordenAlfabeticoPeopleLink = document.getElementById('orden-alfabetico-people'); + +ordenAlfabeticoPeopleLink.addEventListener('click', function(event) { + event.preventDefault(); // Evita que el enlace realice la acción predeterminada + + // if para el caso de que no se haya interactuado aún en la página y para el caso en el que haya interactuado érp peoplelist display=none + if (peopleList.style.display === '' || peopleList.style.display === 'none') { + peopleList.style.display = 'grid'; // Muestra peopleList + filmsDateList.style.display = 'none'; // Oculta filmsDateList + filmsList.style.display = 'none'; // Oculta filmsList + peopleFilmList.style.display = 'none'; + filmsListDirector.style.display = 'none'; + peopleListAge.style.display = 'none'; + filmsListSpecie.style.display = 'none'; + homeContent.style.display = 'none'; + vehiclesElement.style.display = 'none'; + promElement.style.display = 'none'; + + + } +}); + +//______PELÍCULAS ORDENADAS ALFABÉTICAMENTE +const films = data.films; +alphabeticalOrderFilms(films); +//console.log("estoy ordenando películas", films); + +const filmsList = document.getElementById('films-list'); +//filmsList.innerHTML = ''; + +films.forEach(film => { + const titleItem = document.createElement('div'); + const titleImage = document.createElement('img'); + const titleName = document.createElement('p'); + + titleImage.src = film.poster; + titleName.textContent = film.title; + + titleItem.appendChild(titleImage); + titleItem.appendChild(titleName); + filmsList.appendChild(titleItem); +}); + +//______CLICK PELÍCULAS ORDENADAS ALFABÉTICAMENTE +const ordenAlfabeticoFilmsLink = document.getElementById('orden-alfabetico-films'); + +ordenAlfabeticoFilmsLink.addEventListener('click', function(event) { + event.preventDefault(); // Evita que el enlace realice la acción predeterminada + + if (filmsList.style.display === '' || filmsList.style.display === 'none') { + filmsList.style.display = 'grid'; + filmsDateList.style.display = 'none'; // Oculta filmsDateList + peopleList.style.display = 'none'; // Oculta peopleList + peopleFilmList.style.display = 'none'; + filmsListDirector.style.display = 'none'; + peopleListAge.style.display = 'none'; + filmsListSpecie.style.display = 'none'; + homeContent.style.display = 'none'; + vehiclesElement.style.display = 'none'; + promElement.style.display = 'none'; + } +}); + + +//______PELÍCULAS ORDENADAS POR AÑO ('release_date') +const filmsDate = data.films; +yearOrderMovies(filmsDate); +//console.log("estoy ordenando películas por año", filmsDate); + +const filmsDateList = document.getElementById('films-list-year'); +//filmsList.innerHTML = ''; + +filmsDate.forEach(film => { + const dateItem = document.createElement('div'); + const dateImage = document.createElement('img'); + const dateName = document.createElement('p'); + const dateYear = document.createElement('p'); + + dateImage.src = film.poster; + dateName.textContent = film.title; + dateYear.textContent = film.release_date; + + dateItem.appendChild(dateImage); + dateItem.appendChild(dateName); + dateItem.appendChild(dateYear); + filmsDateList.appendChild(dateItem); +}); + +//______CLICK PELÍCULAS ORDENADAS POR AÑO ('release_date') + +const ordenDateFilmsLink = document.getElementById('orden-date-films'); + +ordenDateFilmsLink.addEventListener('click', function(event) { + event.preventDefault(); // Evita que el enlace realice la acción predeterminada + + if (filmsDateList.style.display === '' || filmsDateList.style.display === 'none') { + filmsDateList.style.display = 'grid'; + filmsList.style.display = 'none'; // Oculta filmsList + peopleList.style.display = 'none'; // Oculta peopleList + peopleFilmList.style.display = 'none'; + filmsListDirector.style.display = 'none'; + peopleListAge.style.display = 'none'; + filmsListSpecie.style.display = 'none'; + homeContent.style.display = 'none'; + vehiclesElement.style.display = 'none'; + promElement.style.display = 'none'; + } +}); + +//______PERSONAJES ORDENADOS POR PELÍCULA ('people' y 'film') +const peopleFilm = data.films; +const peopleFilmOrdered = moviesOrderPeople(peopleFilm); // Almacena el resultado ordenado en una nueva variable + +const peopleFilmList = document.getElementById('people-list-film'); + +// Recorrer el arreglo ordenado y crear elementos HTML para cada personaje +peopleFilmOrdered.forEach(({ name, film, img }) => { + const peopleItem = document.createElement('div'); + const peopleImage = document.createElement('img'); + const peopleName = document.createElement('p'); + const peopleFilmElement = document.createElement('p'); // Cambiar el nombre para evitar conflicto de nombres + + peopleImage.src = img; + peopleName.textContent = name; + peopleFilmElement.textContent = film; // Cambiar el nombre para evitar conflicto de nombres + + peopleItem.appendChild(peopleImage); + peopleItem.appendChild(peopleName); + peopleItem.appendChild(peopleFilmElement); // Cambiar el nombre para evitar conflicto de nombres + peopleFilmList.appendChild(peopleItem); +}); + +//______CLICK PERSONAJES ORDENADOS POR PELÍCULA ('people' y 'film') + +const ordenPeopleFilmsLink = document.getElementById('orden-people-films'); + +ordenPeopleFilmsLink.addEventListener('click', function(event) { + event.preventDefault(); // Evita que el enlace realice la acción predeterminada + + if (peopleFilmList.style.display === '' || peopleFilmList.style.display === 'none') { + peopleFilmList.style.display = 'grid'; + filmsDateList.style.display = 'none'; + filmsList.style.display = 'none'; // Oculta filmsList + peopleList.style.display = 'none'; // Oculta peopleList + filmsListDirector.style.display = 'none'; + peopleListAge.style.display = 'none'; + filmsListSpecie.style.display = 'none'; + homeContent.style.display = 'none'; + vehiclesElement.style.display = 'none'; + promElement.style.display = 'none'; + + } +}); + +//______PELÍCULAS ORDENADAS POR DIRECTOR ('director') +const filmsDirector = data.films; +directorOrderMovies(filmsDirector); +//console.log("estoy ordenando películas por director", filmsDirector); + +const filmsListDirector = document.getElementById('films-list-director') + +filmsDirector.forEach(film => { + const directorItem = document.createElement('div'); + const directorImage = document.createElement('img'); + const directorName = document.createElement('p'); + const directorDirector = document.createElement('p'); + + directorImage.src = film.poster; + directorName.textContent = film.title; + directorDirector.textContent = film.director; + + directorItem.appendChild(directorImage); + directorItem.appendChild(directorName); + directorItem.appendChild(directorDirector); + filmsListDirector.appendChild(directorItem); + +}); + +//______CLICK PELÍCULAS ORDENADAS POR DIRECTOR ('director') + +const ordenDirectorFilmsLink = document.getElementById('orden-director-films'); + +ordenDirectorFilmsLink.addEventListener('click', function(event) { + event.preventDefault(); // Evita que el enlace realice la acción predeterminada + + if (filmsListDirector.style.display === '' || filmsListDirector.style.display === 'none') { + filmsListDirector.style.display = 'grid'; + filmsDateList.style.display = 'none'; + filmsList.style.display = 'none'; // Oculta filmsList + peopleList.style.display = 'none'; // Oculta peopleList + peopleFilmList.style.display = 'none'; + peopleListAge.style.display = 'none'; + filmsListSpecie.style.display = 'none'; + homeContent.style.display = 'none'; + vehiclesElement.style.display = 'none'; + promElement.style.display = 'none'; + + } +}); + +//______PERSONAJES ORDENADOS POR GRUPO ETARIO ('age') +const agePeople = []; +data.films.forEach(film => { + film.people.filter(people => Number(people.age)).forEach(people => agePeople.push(people)); +}); + +const peopleListAge = document.getElementById('people-list-age') + +agePeople.sort((a, b) => { + if (a.age && b.age) { + const ageA = parseInt(a.age); + const ageB = parseInt(b.age); + + return ageA - ageB; + } + return 0; +}); + +//console.log("estoy ordenando personajes por edad", agePeople); + +agePeople.forEach(people => { + const peopleItem = document.createElement('div'); + const peopleImage = document.createElement('img'); + const peopleName = document.createElement('p'); + const peopleAge = document.createElement('p'); + + peopleImage.src = people.img; + peopleName.textContent = people.name; + peopleAge.textContent = people.age; + + peopleItem.appendChild(peopleImage); + peopleItem.appendChild(peopleName); + peopleItem.appendChild(peopleAge); + peopleListAge.appendChild(peopleItem); +}); + +//______CLICK PERSONAJES ORDENADOS POR GRUPO ETARIO ('age') + +const ordenPeopleAgeLink = document.getElementById('orden-people-age'); + +ordenPeopleAgeLink.addEventListener('click', function(event) { + event.preventDefault(); // Evita que el enlace realice la acción predeterminada + + if (peopleListAge.style.display === '' || peopleListAge.style.display === 'none') { + peopleListAge.style.display = 'grid'; + filmsDateList.style.display = 'none'; + filmsList.style.display = 'none'; // Oculta filmsList + peopleList.style.display = 'none'; // Oculta peopleList + filmsListDirector.style.display = 'none'; + peopleFilmList.style.display = 'none'; + filmsListSpecie.style.display = 'none'; + homeContent.style.display = 'none'; + vehiclesElement.style.display = 'none'; + promElement.style.display = 'none'; + + } +}); + +//______PERSONAJES POR ESPECIE + +const peopleSpecie = []; +data.films.forEach(film => { + film.people.filter(people => people.name).forEach(({ name, img, specie }) => peopleSpecie.push({ name, specie, img })); +}); + +const filmsListSpecie = document.getElementById("people-specie") + +peopleSpecie.sort((a, b) => a.specie.localeCompare(b.specie)); +//console.log("Estoy ordenando por especie", peopleSpecie); + +peopleSpecie.forEach(specie => { + const specieItem = document.createElement('div'); + const specieImage = document.createElement('img'); + const specieName = document.createElement('p'); + const specieSpecie = document.createElement('p'); + + specieImage.src = specie.img; + specieName.textContent = specie.name; + specieSpecie.textContent = specie.specie; + + specieItem.appendChild(specieImage); + specieItem.appendChild(specieName); + specieItem.appendChild(specieSpecie); + filmsListSpecie.appendChild(specieItem); +}); + +//______CLICK PERSONAJES POR ESPECIE ('specie') + +const ordenSpecieFilmsLink = document.getElementById('people-specie-prom'); + +ordenSpecieFilmsLink.addEventListener('click', function(event) { + event.preventDefault(); // Evita que el enlace realice la acción predeterminada + + if (filmsListSpecie.style.display === '' || filmsListSpecie.style.display === 'none') { + filmsListSpecie.style.display = 'grid'; + filmsDateList.style.display = 'none'; + filmsList.style.display = 'none'; // Oculta filmsList + peopleList.style.display = 'none'; // Oculta peopleList + filmsListDirector.style.display = 'none'; // Oculta peliculas por director + peopleListAge.style.display = 'none'; + peopleFilmList.style.display = 'none'; + homeContent.style.display = 'none'; + promElement.style.display = 'none'; + vehiclesElement.style.display = 'none'; + + } +}); + +//______________TOTAL DE ESPECIES + +const totalSpeciesCount = data.films; +const mostrarTotalSpecies = countSpecies(totalSpeciesCount); +console.log("Estoy mostrando el total de especies", countSpecies(data.films)); + +const resulTotalSpecies = document.querySelector('.total-species'); +resulTotalSpecies.textContent = `Total de Especies en Ghibli: ${mostrarTotalSpecies}`; + +const speciesTotalLink = document.getElementById('people-specie-prom'); + +speciesTotalLink.addEventListener('click', function(event) { + event.preventDefault(); + + if (resulTotalSpecies.style.display === '' || resulTotalSpecies.style.display === 'none') { + resulTotalSpecies.style.display = 'grid'; + filmsDateList.style.display = 'none'; // Oculta filmsDateList + filmsList.style.display = 'none'; // Oculta filmsList + peopleFilmList.style.display = 'none'; + filmsListDirector.style.display = 'none'; + peopleListAge.style.display = 'none'; + filmsListSpecie.style.display = 'none'; + homeContent.style.display = 'none'; + peopleList.style.display = 'none'; + promElement.style.display = 'none'; + vehiclesElement.style.display = 'none'; + } + +}); + + +//______________TOTAL DE VEHÍCULOS + +const totalVehiclesCount = data.films; +const mostrarTotalVehiculos = countVehicles(totalVehiclesCount); +console.log("Estoy mostrando el total de vehículos", countVehicles(data.films)); + +const vehiclesElement = document.getElementById('vehicles'); +vehiclesElement.textContent = `Total de Vehículos: ${mostrarTotalVehiculos}`; + +const vehiclesLink = document.getElementById('vehicles-prom'); + +vehiclesLink.addEventListener('click', function(event) { + event.preventDefault(); + + if (vehiclesElement.style.display === '' || vehiclesElement.style.display === 'none') { + vehiclesElement.style.display = 'grid'; + filmsDateList.style.display = 'none'; // Oculta filmsDateList + filmsList.style.display = 'none'; // Oculta filmsList + peopleFilmList.style.display = 'none'; + filmsListDirector.style.display = 'none'; + peopleListAge.style.display = 'none'; + filmsListSpecie.style.display = 'none'; + homeContent.style.display = 'none'; + peopleList.style.display = 'none'; + promElement.style.display = 'none'; + } + +}); + + + + +//______________SCORE PROMEDIO EN ROTTEN TOMATOES ('rt_score') + +const score = data.films; +const mostrarScore = prom(score); +//console.log("Estoy mostrando el promedio en rotten tomatoes", prom(data.films)); + +const promElement = document.getElementById('prom'); +promElement.textContent = `Promedio Rotten Tomatoes: ${mostrarScore}`; + +const promPromLink = document.getElementById('prom-prom'); + +promPromLink.addEventListener('click', function(event) { + event.preventDefault(); + + if (promElement.style.display === '' || promElement.style.display === 'none') { + promElement.style.display = 'grid'; + filmsDateList.style.display = 'none'; // Oculta filmsDateList + filmsList.style.display = 'none'; // Oculta filmsList + peopleFilmList.style.display = 'none'; + filmsListDirector.style.display = 'none'; + peopleListAge.style.display = 'none'; + filmsListSpecie.style.display = 'none'; + homeContent.style.display = 'none'; + peopleList.style.display = 'none'; + vehiclesElement.style.display = 'none'; + } + +}); + +//______CLICK home +const homeContent = document.getElementById('home-content') +const homeLink = document.getElementById('home-link'); + +function showHomeContent() { + homeContent.style.display = 'grid'; // Muestra homeContent + // Oculta otros elementos si es necesario +} + +// Mostrar homeContent al iniciar la página +showHomeContent(); + +homeLink.addEventListener('click', function(event) { + event.preventDefault(); // Evita que el enlace realice la acción predeterminada + + if (homeContent.style.display === '' || homeContent.style.display === 'none') { + homeContent.style.display = 'grid'; // Muestra peopleList + peopleList.style.display = 'none'; + filmsDateList.style.display = 'none'; // Oculta filmsDateList + filmsList.style.display = 'none'; // Oculta filmsList + peopleFilmList.style.display = 'none'; + filmsListDirector.style.display = 'none'; + peopleListAge.style.display = 'none'; + filmsListSpecie.style.display = 'none'; + vehiclesElement.style.display = 'none'; + promElement.style.display = 'none'; + } +}); \ No newline at end of file diff --git a/src/style.css b/src/style.css index e69de29b..d9a98cf4 100644 --- a/src/style.css +++ b/src/style.css @@ -0,0 +1,205 @@ +/* Estilos iniciales para que no tome los que tiene el navegador por defecto */ +/* "*" es un selector universal*/ +* { + margin: 0; + padding: 0; /* relleno */ + box-sizing: border-box; + font-family: 'Calibri', 'Trebuchet MS', sans-serif; +} + +#logo{ + width: 400px; + height: auto; + margin: 0 auto; + display: block; +} + +nav{ + max-width: 900px; + background-color: #333; + font-size: 20px; + margin-top: 50px; + border-radius: 20px; + padding: 5px 0; + margin-left: auto; + margin-right: auto; +} + +body{ + background-color: #44A6A6; /* no repeat */ + background-size: cover; /* La imagen de fondo se ajusta para cubrir todo el elemento */ +} + +/* Selecciona los elementos con la clase "menu-horizontal" */ +.menu-horizontal{ + list-style: none; /* Elimina estilos de lista predeterminados */ + display: flex; /* Los elementos de la lista se muestran en línea uno al lado del otro */ + justify-content: space-around; /* Los elementos se distribuyen equitativamente*/ +} + +/* Selecciona los elementos de ancla dentro de los elementos
  • que son hijos directos de elementos con la clase "menu-horizontal" */ +.menu-horizontal > li > a{ + display: block; + padding: 15px 20px; + color: white; + text-decoration: none; +} + +/* Selecciona los elementos
  • cuando se pasa el cursor por encima de ellos, dentro de elementos con la clase "menu-horizontal" */ +.menu-horizontal > li:hover{ + background-color: #44A6A6; /* Color de fondo cuando se pasa el cursor por encima*/ +} + +/* Selecciona los elementos con la clase "menu-vertical" */ +.menu-vertical{ + position: absolute; + display: none; /* El menú vertical está oculto por defecto */ + list-style: none; + width: 200px; + background-color: #44A6A6; +} + +/* Selecciona los elementos con la clase "menu-vertical" cuando se pasa el cursor por encima de los elementos
  • dentro de elementos con la clase "menu-horizontal" */ +/* hover: pasar el cursor por encima. en CSS se utilizan las pseudoclases :hover */ +.menu-horizontal li:hover .menu-vertical{ + display: block; /* Muestra el menú vertical cuando se pasa el cursor por encima de los elementos de la lista horizontal */ +} + +/* Selecciona los elementos
  • cuando se pasa el cursor por encima de ellos, dentro de elementos con la clase "menu-vertical" */ +.menu-vertical li:hover{ + background-color:rgb(255, 255, 255); /* Color de fondo cuando se pasa el cursor por encima de los elementos del menú vertical */ + cursor: pointer; /*Para que el cursor muestre la mano de selección no solo en el elemento