diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..8a6da6fc --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "chrome", + "request": "launch", + "name": "Launch Chrome against localhost", + "url": "http://localhost:5501", + "webRoot": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..6f3a2913 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "liveServer.settings.port": 5501 +} \ No newline at end of file diff --git a/README.md b/README.md index 04706ddd..413c908b 100644 --- a/README.md +++ b/README.md @@ -1,641 +1,106 @@ -# Data Lovers +# Cultura-travels ## Í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) +* [3. Historias de usuario](#3-Historias-de-usuario) +* [4. Prototipo de baja calidad](#4-Prototipo-de-baja-calidad) +* [5. Prototipo de Alta calidad](#5-Prototipo-de-Alta-calidad) +* [6. Prototipo de Final](#6-Prototipo-de-Final) *** ## 1. Preámbulo -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. +Cada vez viajar se hace más atractivo para las personas, nos damos cuenta que +en las últimas décadas las personas viajan a diferentes destinos sin tener +en cuenta el dinero e incluso si algunas personas los acompañan, es por esto +que se inicia con el proyecto Cultura-travels para dar facilidad a los +usuarios a encontrar o determinar con qué país están limitando, conocer +el idioma de un país y otros datos básicos. -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_. - -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. - -![pokemon-data-to-ui](https://user-images.githubusercontent.com/12631491/218505816-c6d11758-9de4-428f-affb-2a56ea4d68c4.png) ## 2. Resumen del proyecto -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. - -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 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. - -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 - [Studio Ghibli](https://ghiblicollection.com/). - - [Investigación con seguidores de las animaciones del Studio Ghibli](src/data/ghibli/README.md) - -* [Countries](src/data/countries/countries.json). - En este set encontrarás la informacion de varios paises - - [Investigación](src/data/countries/README.md) - -* [Tarot](src/data/tarot/tarot.json). - En este set encontrarás la informacion acerca de algunas cartas de tarot. - - [Investigación](src/data/tarot/README.md) - -* [Breaking Bad](src/data/breakingbad/breakingbad.json). - En este set encontrarás la informacion sobre los personajes de la serie breakingbad. - - [Investigación con los seguidores de la serie Breaking Bad](src/data/breakingbad/README.md) - -* [Juego de Tronos](src/data/got/got.json). - En este set encontrarás la informacion sobre algunos de los personajes de la serie GOT. - - [Investigación con los seguidores de la serie GOT](src/data/got/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. - -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 +Iniciamos con las historias de usuarios para luego seguir con el prototipo de +baja calidad, luego de eso continuamos con el prototipo de alta calidad aunque +al final le hicimos algunos cambios ya descritos al inicio, continuando con +la estructura HTML formando paso a paso lo que queríamos ver reflejado en +la página, seguimos con nuestro archivo CSS donde embellecemos nuestra +estructura con los diferentes estilos. En nuestro archivo MAIN.JS donde +invocamos al Dom. Nuestro archivo DATA.JS donde hicimos la funcionalidad +de nuestra página, finalmente el archivo DATA.SPEC.JS donde realizamos +los test de las funciones creadas finalizando este con gran éxito. -* 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: +En la siguiente imagen está descrita la información que sale al darle click a la bandera -### Definición del producto +Informacion banderA -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 +En esta imagen está básicamente descrita la funcionalidad de la página con los botones +funcionando al 100%. -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. +calcular area -Asegúrate de incluir la definición de terminado (_definition of done_) y los -Criterios de Aceptación para cada una. +limites -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). + Por último resaltar que el principal objetivo de la página es que el usuario pueda + usar esta herramienta para encontrar información sobre países de América del sur. -### Diseño de la Interfaz de Usuario +## 3. Historias de usuario + Se habló con 4 usuarios sobre la página y que le gustaría encontrar en ella, de esta + consulta se encontraron las siguientes: -#### Prototipo de baja fidelidad +Historia 1 -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`. +‘’ Yo como usuario quiero ver en la pantalla principal una lista de países con sus nombres +e imágenes que me llamen la atención. Para así mismo convencerme de ver la forma +detallada por país.” -#### Prototipo de alta fidelidad +Historia 2 -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. +“Como usuario quiero filtrar los países que limitan con Perú” Para así poder tener +más claridad sobre la ubicación del país.” -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](https://coda.io/d/Bootcamp-UX-Contenido_dqkqk2rV9Z2/Diseno-de-interfaces_suOT7#_luWsQ)_. +Historia 3 -#### Testeos de usabilidad + “Como usuario quiero poder ordenar los países en orden alfabético. Para que + de esta manera pueda ubicarlo más fácilmente” -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. +Historia 4 +“Yo Como usuario, Quiero conocer el total de metros cuadrados totales del Perú y Ecuador. +Para poder saber cuánto tiempo me demoro en conocer los dos países en carro” -### Implementación de la Interfaz de Usuario (HTML/CSS/JS) +## 4. Prototipo de baja calidad -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 +Baja fideliad -Como mínimo, tu implementación debe: +En este prototipo está descrito como se verá la página, es como un borrador que se +hizo de baja calidad, donde está descrito lo que contiene: inicialmente +-El título con su logotipo +-El área de los botones con su respectivo formulario y lista despegable +-También las banderas con su respectivo nombre +-Esta aunque no se ve reflejado la información que sale al darle click a las banderas, + se voltea y sale la información que se encuentra en historias de usuario. Y por último +-El pie de página donde sale el nombre de las desarrolladoras. -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_. +## 5. Prototipo de Alta calidad -### Pruebas unitarias +Como se puede observar en el prototipo de alta calidad hubo varios cambios, +ya que al principio lo habíamos realizado con la imagen de fondo diferente, +decidimos cambiarla para darle más contraste y resaltar las banderas, +también cambiamos el estilo de las banderas utilizando fication, +por recomendación del coach. Importante también resaltar que nos enfocamos +en los Paises de Sudamerica. -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. +Prototipo -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. Prototipo de Final -## 6. Hacker edition +Opciones -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 + + + + + + + +

+ Cultura-travels +

+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+ +
+ + + + + + + + \ No newline at end of file diff --git a/src/main.js b/src/main.js index 71c59f2d..1b3c6b31 100644 --- a/src/main.js +++ b/src/main.js @@ -1,6 +1,165 @@ -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 { filtrarIdioma, ordenar, filtrarPaisesLimitantes, calcularArea } from './data.js'; //aqui se agrego ordenar de AZ para darle funcionalidad al boton desde data.js +//import { example, filtrarDataLimites} from './data.js'; -console.log(example, data); +import data from './data/countries/countries.js'; + + +// Boton de volver +const opcionSeleccionada = document.getElementById("opciones"); +const botonInicio = document.getElementById("volver"); +botonInicio.addEventListener("click", volverInicio); +function volverInicio() { + ocultarContenidos(); +} +function ocultarContenidos() { + document.getElementById("idioma").style.display = "none"; + document.getElementById("limites").style.display = "none"; + document.getElementById("areaForm").style.display = "none"; + document.getElementById("opciones").style.display = "block"; + document.getElementById("ordenar").style.display = "block"; + pintarData(data.countries) +} + +opcionSeleccionada.addEventListener("change", function () { + + const valorSeleccionado = opcionSeleccionada.value; + if (valorSeleccionado === "limitantes") { + document.getElementById("limites").style.display = "block"; + document.getElementById("areaForm").style.display = "none"; + document.getElementById("idioma").style.display = "none"; + + + } + else if (valorSeleccionado === "idioma") { + document.getElementById("idioma").style.display = "block"; + document.getElementById("areaForm").style.display = "none"; + document.getElementById("limites").style.display = "none"; + + } + + else if (valorSeleccionado === "calculo") { + document.getElementById("areaForm").style.display = "block"; + document.getElementById("idioma").style.display = "none"; + document.getElementById("limites").style.display = "none"; + + + } + +}) + + +// me trae de la data nombre y banderas +const root = document.getElementById('root'); + +//movimiento de las banderas y informacion trasera de las bandera + +function pintarData(data) { + let contentRootInfo = ''; + for (let i = 0; i < data.length; i++) { + if (data[i].subregion === 'South America') { + + const country = data[i]; + const languages = Object.values(country.languages).join(', '); // object.value convierte los valores de un objeto en un array, join une los elementos de un array + + contentRootInfo += `
+ +
+
+ + +
${country.name.common}
+
+
+
+

${country.name.common}

+

Población: ${country.population}

+

Área: ${country.area}

+

Países Frontera: ${country.borders}

+

Idiomas: ${languages}

+
+
`; + } + } + root.innerHTML = contentRootInfo; // lo traigo desde html y digo que es igual a variable contentRootInfo + + // selecciona cada badera y luego itera sobre cada una de ellas + const banderaImages = document.querySelectorAll('.Bandera'); + + banderaImages.forEach(image => { + const container = image.closest('.bandera-container'); // closest encuentra el mas cercano e igual con un selector especifico + const infoBack = container.querySelector('.info-back'); // si se encuentra una concidencia se almacena en container + + + image.addEventListener('click', function () { + container.classList.toggle('show-info'); // toggle agrega o quita (en este caso esta tratando de alternas la clase .show-info) + + image.classList.toggle('rotate'); + }); + + infoBack.addEventListener('click', function () { + container.classList.remove('show-info'); //remove elimina un elemento en este caso esta eliminando show-info + image.classList.remove('rotate'); + + }); + }); + +} +pintarData(data.countries) + +// Organizar + +const selectOrden = document.getElementById('ordenar'); // Obtén una referencia al botón de ordenar +selectOrden.addEventListener('change', function () { // Agrega un evento de clic al botón + const ordenElegido = selectOrden.value; + const bandOrdenadas = ordenar(data.countries, ordenElegido) + + pintarData(bandOrdenadas); +}); + + +//Boton de filtros paises limitantes. + +const selectPais = document.getElementById('limites'); +selectPais.addEventListener("change", function () { + const paisElegido = selectPais.value; + + const paisesLimitantes = filtrarPaisesLimitantes(data, paisElegido); + pintarData(paisesLimitantes); + +}); + + +// Boton de filtro Idioma + +const selectIdioma = document.getElementById('idioma'); + +selectIdioma.addEventListener("change", function () { + const idiomaElegido = selectIdioma.value; + const dataFiltradaPorIdioma = filtrarIdioma(data.countries, idiomaElegido); + + pintarData(dataFiltradaPorIdioma); +}) + +//calcular área entre dos paises +const btnCalcular = document.getElementById('calcular'); +const resultadoCalcular = document.getElementById('resultadoCalcular'); +const closeModalButton = document.getElementById('closeModalButton'); + +btnCalcular.addEventListener('click', function () { + const inpuCalcular1 = document.getElementById('area1').value; + const inpuCalcular2 = document.getElementById('area2').value; + const sumaArea = calcularArea(data, inpuCalcular1, inpuCalcular2); + + resultadoCalcular.innerHTML = `

Área Total

El área total calculada es: ${sumaArea}

`; + resultadoCalcular.style.display = 'block'; + +}); +closeModalButton.addEventListener('click', function () { + const inputCalcular1 = document.getElementById('area1'); + const inputCalcular2 = document.getElementById('area2'); + + inputCalcular1.value = ''; + inputCalcular2.value = ''; + resultadoCalcular.style.display = 'none'; + +}); diff --git a/src/opciones .png b/src/opciones .png new file mode 100644 index 00000000..b990a845 Binary files /dev/null and b/src/opciones .png differ diff --git a/src/style.css b/src/style.css index e69de29b..77b21c32 100644 --- a/src/style.css +++ b/src/style.css @@ -0,0 +1,567 @@ +body { + background-image: url('https://media.admagazine.com/photos/618a6b8e3174d0288cf2d478/master/w_1600%2Cc_limit/33730.jpg'); + margin: 0; + background-repeat: no-repeat; + /* Evita que la imagen de fondo se repita */ + background-size: cover; + /* Ajusta la imagen de fondo para cubrir todo el cuerpo */ + background-position: center center; + /* Centra la imagen de fondo en el cuerpo */ + +} + +h1 { + display: flex; + /* visualizar contenido */ + justify-content: center; + padding: 10px; + background-color: #ffffff; + color: #250ac2; + /*Color de letra*/ + margin: 40px; + border-radius: 15px; +} + +#sudamerica { + /* imagen que esta en el titulo*/ + width: 60px; +} + +#root { + /* todo lo del estilo cajon de banderas*/ + display: grid; + /*Contenedor de cuadricula */ + grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); + /*Distribuir las columnas segun ancho de pagina */ + gap: 40px; + /*establece espacio entre imagenes */ + padding: 10px; + margin: 40px; + justify-items: center; + align-items: center; +} + + +footer { + text-align: center; + /* Centra el contenido del pie de página */ + background-color: #ffffff; + /* Color de fondo del pie de página */ + padding: 5px; + /* Espaciado interno para el recuadro */ + font-family: "arial", "helvetica", sans-serif; + /* tipo de letra del pie de pagina */ + color: #250ac2; + margin: 40px; + font-size: 15px; + /* cambia tamaño del letra de pagina */ + + +} + +.Bandera { + /*estilo de banderas */ + width: 100%; + height: 100%; + /* Ajusta el ancho de las banderas (25% para cuatro en una fila) */ + margin: 15px; + /* Espacio entre las banderas */ + +} + + +h4 { + color: #3409cf; + font-size: 20px; + margin: 0px; +} + + +.Bandera.rotate { + transform: rotateY(180deg); + /* Gira la imagen en el eje Y, creando un efecto de volteo */ + overflow: hidden; + /* Oculta el contenido que se desborda del contenedor */ + z-index: 1; + /* Establece el índice z para controlar la superposición de elementos */ + +} + + + +@media (max-width: 768px) { + + /* Estilos específicos para dispositivos móviles */ + + h1 { + font-size: 20px; + justify-content: space-around; + align-items: center; + + } + + header { + padding: 15px; + justify-content: space-around; + align-items: center; + + + } + + #botones { + flex-direction: column; + align-items: flex-start; + padding: 0; + justify-content: space-around; + align-items: center; + margin: 0; + width:100%; + + } + + #root { + flex-direction: column; + align-items: flex-start; + + + } + + .Bandera.rotate { + flex-direction: column; + align-items: flex-start; + } + + .BanderaContenedor { + flex-direction: column; + align-items: flex-start; + display: flex; + } + + .bandera-wrapper { + flex-direction: column; + align-items: flex-start; + + } + + .info-back { + + box-sizing: content-box; + + } + + .info-back h4 { + font-size: 10px; + justify-content: space-around; + align-items: center; + + + } + + .info-back p { + font-size: 5px; + justify-content: space-around; + align-items: center; + padding:valor; + box-sizing: border-box; + } + label { + flex-direction: column; + align-items: flex-start; + + } + + input { + flex-direction: column; + align-items: flex-start; + + } + + #limites { + flex-direction: column; + align-items: flex-start; + + } + + #ordenar { + flex-direction: column; + align-items: flex-start; + + } + + #botones { + flex-direction: column; + align-items: flex-start; + } + + .button { + flex-direction: column; + align-items: flex-start; + + } + + #areaForm { + flex-direction: start; + align-items: start; + + } + + #idioma { + padding: 1px; + flex-direction: column; + align-items: flex-start; + + } + + + #resultadoCalcular { + display: flex; + justify-content: start; + + } + + + .opciones{ + margin: 20px; + flex-direction: column; + align-items: flex-start; + + } + + +} +.BanderaContenedor { + display: flex; + flex-direction: column; + align-items: center; + display: flex; + +} + + + +/* Estilos para el contenedor envolvente de la bandera */ +.bandera-wrapper { + display: flex; + flex-direction: column; + align-items: center; +} + + +.bandera-container.show-info { + display: flex; + flex-direction: column; + align-items: center; + position: fixed; + /* Posición fija en la ventana del navegador */ + top: 0; + /* Ubicación en la parte superior de la ventana */ + left: 0; + /* Ubicación en el extremo izquierdo de la ventana */ + width: 100%; + /* Ancho ocupa toda la ventana */ + height: 100%; + /* Alto ocupa toda la ventana */ + display: center; + /* Utiliza el modelo de caja flexible */ + justify-content: center; + /* Centra elementos horizontalmente */ + align-items: center; + /* Centra elementos verticalmente */ + background-color: rgba(47, 42, 42, 0.8); + /* Fondo semitransparente para el efecto de superposición */ + z-index: 9999; + /* Capa de apilamiento alta para mostrar encima de otros elementos */ +} + +.info-back { + height: 15%; + /*Alto de la tarjeta trasera en relación al contenedor envolvente */ + width: 15%; + /* Ancho de la tarjeta trasera en relación al contenedor envolvente */ + background-color: rgb(138, 177, 216); + /* Color de fondo de la tarjeta trasera */ + border-radius: 5px; + /* Borde redondeado para la tarjeta trasera */ + display: none; + /* Oculta la tarjeta trasera por defecto */ + opacity: 0; + /* Opacidad inicial de la tarjeta trasera (transparente) */ + transform: rotateY(180deg) scale(0); + /* Volteo y escala para animación de entrada */ + transition: opacity 1s ease-in-out, transform 1s ease-in-out, width 0.5s ease-in-out, height 0.5s ease-in-out; + /* Transiciones suaves para animaciones */ + display: flex; + /* Utiliza el modelo de caja flexible para contenido interno */ + flex-direction: column; + /* Alinea elementos verticalmente en una columna */ + justify-content: 100%; + /* Ajusta el ancho del texto al 100% del contenedor */ + position: absolute; + /* Posiciona el elemento de forma absoluta en relación a su contenedor padre */ + z-index: 2; + /* Establece un índice z mayor para el cuadro de texto */ + padding: 3px; + /* Agrega un margen alrededor del contenido del cuadro */ + box-sizing: 100%; + /* Incluye el padding en el ancho y alto total del elemento */ + white-space: nowrap; + /* Evita que el texto se divida en varias líneas */ + overflow: visible; + /* Oculta el texto que desborda el contenedor */ + text-overflow: ellipsis; + /* Muestra "..." al final del texto que desborda */ + white-space: normal; + /* Controla cómo se manejan los espacios en blanco y saltos de línea */ + word-break: break-all; + /* Controla cómo se rompen las palabras en caso de que excedan el ancho */ +} + +/* Estilos para mostrar la información ampliada en la bandera (parte trasera) */ +.bandera-container.show-info .info-back { + display: center; + /* Muestra el contenido de la parte trasera */ + opacity: 1; + /* Opacidad completa para hacer visible el contenido */ + transform: rotateY(0deg) scale(2); + /* Vuelve a la posición normal y escala la tarjeta */ +} + +/* Estilos para el título en la parte trasera de la bandera */ +.info-back h4 { + display: flex; + /* Utiliza el modelo de caja flexible */ + justify-content: center; + /* Centra el contenido horizontalmente */ +} + +.info-back p { + font-size: 40%; + line-height: 0.2; +} + +label { + font-weight: bold; + color: #f0edf7; + font-size: 20px; + margin: 5px; + display: start; + /* visualizar contenido */ + justify-content: center; + /*border: 1px solid #ccc;*/ + + +} + +input { + color: #03000a; + padding: 1px; + width: 120px; + /* Ancho personalizado */ + height: 1px; + /* Altura personalizada */ + padding: 10px; + /* Espacio interno */ + font-size: 15px; + /* Tamaño de fuente */ + border: 1px solid #ccc; + /* Borde */ + border-radius: 5px; + /* Borde redondeado */ + + +} + +#limites { + border: 1px solid #ccc; + padding: 10px; + display: flex; + /* visualizar contenido */ + justify-content: center; + width: 150px; + margin-left: 20px; + border-radius: 10px; + cursor: pointer; + +} + +#ordenar { + display: flex; + /* visualizar contenido */ + justify-content: start; + /* se aplica a display: center para que el texto quede centrado*/ + padding: 5px; + color: #250ac2; + /*Color de letra*/ + margin-left: 50px; + border-radius: 15px; + cursor: pointer; + font-weight: bold; + +} + +#botones { + display: flex; + /* visualizar contenido */ + justify-content: start; + /* se aplica a display: center para que el texto quede centrado*/ + padding: 5px; + color: #250ac2; + /*Color de letra*/ + margin-left: 50px; + border-radius: 15px; + cursor: pointer; + font-weight: bold; +} + +.button { + display: flex; + /* visualizar contenido */ + justify-content: start; + /* se aplica a display: center para que el texto quede centrado*/ + padding: 5px; + color: #250ac2; + /*Color de letra*/ + border-radius: 15px; + cursor: pointer; + font-weight: bold; + +} + + + + +#areaForm { + display: flex; + /* visualizar contenido */ + justify-content: flex-end; + /* se aplica a display: center para que el texto quede centrado*/ + padding: 10px; + /*background-color: #f7faf6; */ + color: #250ac2; + /*Color de letra*/ + margin-left: 300px; + margin-right: 300px; + margin-top: 50px; + order: 1px solid #ccc; + height: 200px; + background-color: #4c95c5; +} + + +#opciones { + display: flex; + /* visualizar contenido */ + justify-content: start; + /* se aplica a display: center para que el texto quede centrado*/ + padding: 5px; + color: #250ac2; + /*Color de letra*/ + margin-left: 50px; + border-radius: 15px; + cursor: pointer; + font-weight: bold; +} + +#ordenar { + display: flex; + /* visualizar contenido */ + justify-content: start; + /* se aplica a display: center para que el texto quede centrado*/ + padding: 5px; + color: #250ac2; + /*Color de letra*/ + margin-left: 50px; + border-radius: 15px; + cursor: pointer; + font-weight: bold; +} + + +#idioma { + border: 1px solid #ccc; + padding: 10px; + display: flex; + /* visualizar contenido */ + justify-content: center; + width: 150px; + margin-left: 20px; + border-radius: 10px; + cursor: pointer; + +} + + +#resultadoCalcular { + border: 10px solid #4c95c5; + background-color: #ebe8f1; + position: fixed; + border-radius: 10px; + padding: 20px; + top: 305px; + left: 500px; + display: none; + justify-content: center; + align-items: center; +} + + + +#calcular2 { + + color: #0038f0; + margin: 30px; + justify-content: center; + background-color: white; + padding: 20px; + border-radius: 5px; + display: none; +} + +img { + max-width: 150px; + max-height: 150px; +} + +figcaption { + + color: #1c10c2; + font: italic smaller sans-serif; + padding: 1px; + text-align: center; + border-radius: 15px; + font-weight: bold; + +} + + + +figure { + border: thin #c0c0c0 solid; + display: flex; + flex-flow: column; + padding: 5px; + max-width: 220px; + margin: auto; + background-color: #f0f1f3; + margin: 1px; + border-radius: 15px +} + +.ordenar1{ + margin-left: 70px; + +} + +#area { + margin:20px; + margin-right: 5px; + + + + +} + +.buttonCalcular{ + background-color: #67749e; + +} \ No newline at end of file diff --git a/test/data.spec.js b/test/data.spec.js index 09b1f23f..842e3ed8 100644 --- a/test/data.spec.js +++ b/test/data.spec.js @@ -1,8 +1,13 @@ -import { example, anotherExample } from '../src/data.js'; - +import { example, filtrarIdioma, ordenar, filtrarPaisesLimitantes, calcularArea } from '../src/data.js'; +import data from '../src/data/countries/countries.js'; +//describe, descripcion de un conjunto de test describe('example', () => { + // it, planteamos cada test + // descripcion del test it('is a function', () => { + // expect - la prueba + //matcher - toBe, toEqual expect(typeof example).toBe('function'); }); @@ -12,12 +17,89 @@ describe('example', () => { }); -describe('anotherExample', () => { - it('is a function', () => { - expect(typeof anotherExample).toBe('function'); +//Test Calcular Area + +describe('calcularArea', () => { + it('returns `calcularArea`', () => { + const nombrePais = "Colombia"; + const nombrePais2 = "Peru"; + expect(calcularArea(data, nombrePais, nombrePais2)).toBe(2426964); + }); + + + it('returns `calcularArea`', () => { + const nombrePais = "Peru"; + const nombrePais2 = "Peru"; + expect(calcularArea(data, nombrePais, nombrePais2)).toBe(2570432); + + }); + + it('returns `calcularArea`', () => { + const nombrePais = "Brazil"; + const nombrePais2 = "Pais diferente"; + expect(calcularArea(data, nombrePais, nombrePais2)).toEqual('No existe alguno de los paises intente de nuevo'); + }); + + +}); + +// test Idioma +describe('filtrarIdioma', () => { + it('returns `filtrarIdioma`', () => { + const idiomaFiltrado = "Dutch"; + + expect(filtrarIdioma(data, idiomaFiltrado)).toBe['Suriname']; + }); + + it('returns `lenguajes`', () => { + const data = [{ "languages": {"nld": " Dutch"}}, { "languages": {"spa": "Spanish" }}]; + const idiomaFiltrado = "Dutch"; + + expect(filtrarIdioma(data, idiomaFiltrado)).toBe['Suriname']; }); - it('returns `anotherExample`', () => { - expect(anotherExample()).toBe('OMG'); + it('returns `lenguajes`', () => { + const data = [{ "languages": {"nld": " Dutch"}}, { "languages": {"spa": "Spanish" }}]; + const idiomaFiltrado = "Spanish"; + + expect(filtrarIdioma(data, idiomaFiltrado)).toBe['Spanish']; + }); + + +}); + + +//test ordenar + +describe('ordenar', () => { + it('returns `ordenar`', () => { + const listaPaises = [{ 'name': { 'common': 'Argentina' } }, { 'name': { 'common': 'Brazil' } }, { 'name': { 'common': 'Bolivia' } }]; + const resultadoEsperado = listaPaises.sort((a, b) => a.name.common.localeCompare(b.name.common)) + + const resultadoObtenido = ordenar(listaPaises, 'asc') + + expect(resultadoObtenido).toEqual(resultadoEsperado); + }); + + it('returns `ordenar`', () => { + const listaPaises = [{ 'name': { 'common': 'Argentina' } }, { 'name': { 'common': 'Brazil' } }, { 'name': { 'common': 'Bolivia' } }]; + const resultadoEsperado = listaPaises.sort((a, b) => a.name.common.localeCompare(b.name.common)) + + const resultadoObtenido = ordenar(listaPaises, 'dsc') + + expect(resultadoObtenido).toEqual(resultadoEsperado); + }); + }); + + +// test Limites + +describe('filtrarPaisesLimitantes', () => { + it('devuelve una lista de países limitantes válida', () => { + + const paisElegido = 'Colombia'; + + const paisesLimitantes = filtrarPaisesLimitantes(data, paisElegido); + expect(Array.isArray(paisesLimitantes)).toBe(true); }); });