From 86372d15ed84bc69cbc9a7674b16520f1a71019a Mon Sep 17 00:00:00 2001 From: Rafael Livise Date: Tue, 14 Jun 2022 22:10:29 -0500 Subject: [PATCH 1/3] [FIX] Resolve all --- README.md | 133 +++---------------------------------- public/index.html | 35 +++++----- public/styles.css | 52 +++++++++++++++ src/index.js | 166 +++++++++++++++++++++++++++++++++++++++------- 4 files changed, 223 insertions(+), 163 deletions(-) diff --git a/README.md b/README.md index d7d6534a..84951262 100644 --- a/README.md +++ b/README.md @@ -1,126 +1,15 @@ -# PlatziStore +## DESCRIPTION -Somos comercio en línea con una gran cantidad de productos a comercializar. Estamos por lanzar nuestra implementación y necesitamos resolver los problemas que presenta nuestra aplicación. +Solución al reto: all (1 - 5) -PlatziStore tiene varios bugs, tareas sin completar y recursos a implementar para su lanzamiento oficial. +Nombre: Rafael Livise +Usuario Platzi: Rafaeru +Correo Electronico: r.livise@hotmail.com -### Instalación +## Reto: -``` -npm install -``` - -### Ejecución - -``` -npm run start -``` - -### Debug - -http://localhost:8080/public/ - -### Documentación - -- Variable llamada $app donde haremos render de nuestra app. -- Elemento del DOM que será Observado. -- Constante 'API': Utilizamos la FakeAPI de Platzi. - -```javascript -const $app = document.getElementById("app"); -const $observe = document.getElementById("observe"); -const API = "https://api.escuelajs.co/api/v1/products"; -``` - -Función llamada 'getData' que se encarga de hacer Fetch a una API y debe de construir un elemento nuevo en el DOM. - -```javascript -const getData = (api) => { - fetch(api) - .then((response) => response.json()) - .then((response) => { - const products = response; - }) - .catch((error) => console.log(error)); -}; -``` - -Función encargada de obtener de los Productos. - -```javascript -const loadData = () => { - getData(API); -}; -``` - -Intersection Observer - -```javascript -const intersectionObserver = new IntersectionObserver( - (entries) => { - // logic... - }, - { - rootMargin: "0px 0px 100% 0px", - } -); - -intersectionObserver.observe($observe); -``` - -## RETO - -### Primer problema - -1. Analiza la API: fakeapi.platzi.com -2. Implementa la API de productos iniciando en el producto 5 y obteniendo los siguientes 10 productos. -3. Guarda en localStorage la posición inicial ("pagination") y actualízala en cada petición nueva para traer los siguientes productos. -4. Crear la lógica para implementar un scroll infinito con Intersection Observer. - -### Segundo Problema - -1. Crear la estructura de HTML para mostrar cada producto dentro de Items -2. Crear un article con la clase "Card" para contener la imagen, título y precio de un producto: - -```html -
- -

- Producto - $ Precio -

-
-``` - -3. Index.html debe de cumplir con los elementos mínimos de SEO (title = "PlatziStore", descripcion = "...") - -### Tercer Problema - -Cuando cerramos la pestaña o recargamos la pagina se debe de volver a mostrar los primeros 10 Productos. - -1. Mostrar los primeros 10 productos. -2. Eliminar el localStorage. -3. Actualiza la función loadData() a Async/Await. - -### Cuarto Problema - -La API utilizada "fakeAPI" retorna 200 productos, utilizaremos la paginación propuesta en su documentación para obtener los productos en bloques de 10, cuando la última petición sea ejecutada debes de mostrar un mensaje "Todos los productos Obtenidos", a su vez debes de destruir el intersection observer. - -1. Implementar mensaje: "Todos los productos Obtenidos". -2. Deja de observar el elemento "observe". - -### Quinto Problema (Bonus) - -Desplegar la aplicación en alguno de los siguientes servicios: GitHub Pages, Netlify, Vercel. - -### Enviar solución de reto - -Debes de hacer un "Fork" de este proyecto, revolver los problemas y crear un Pull Request hacia este repositorio. - -### Contribuir - -Si alguien quiere agregar o mejorar algo, lo invito a colaborar directamente en este repositorio: [js-challenge](https://github.com/platzi/js-challenge/) - -### Licencia - -js-challenge se lanza bajo la licencia [MIT](https://opensource.org/licenses/MIT). +- [✔️] Primer problema +- [✔️] Segundo problema +- [✔️] Tercer problema +- [✔️] Cuarto Problema +- [✔️] Quinto Problema diff --git a/public/index.html b/public/index.html index 5f8fbe0d..f60211f1 100755 --- a/public/index.html +++ b/public/index.html @@ -1,22 +1,21 @@ + + + + + PlatziStore + + - - - - - - - + +
+

PlatziStore

+
+
+
+
+ - -
-

PlatziStore

-
-
-
- - - - - \ No newline at end of file + + diff --git a/public/styles.css b/public/styles.css index ada53a1a..c0a1215e 100755 --- a/public/styles.css +++ b/public/styles.css @@ -7,6 +7,10 @@ body { font-family: "Open Sans", sans-serif; } +#app{ + min-height: 100vh; +} + .Main { padding: 10px; grid-template-columns: minmax(auto, 768px); @@ -54,3 +58,51 @@ body { opacity: 1; } } + +.footer { + display: flex; + align-items: center; + justify-content: center; + animation: footer-animation 1s linear infinite alternate; +} + + +@keyframes footer-animation { + 0% { + background-color: hsl(200, 20%, 80%); + } + 100% { + background-color: hsl(200, 20%, 95%); + } +} + +.footer-text { + width: 100%; + height: 2.7rem; + text-align: center; + margin-bottom: 0.5rem; + border-radius: 0.25rem; +} + +#error{ + position: fixed; + top: 10px; + right: 10px; +} + +#error section{ + padding: 0.7em; + background-color: red; + color: white; + border-radius: 6px; + animation: error 1s; +} + +@keyframes error { + 0% { + width: 0; + } + 100% { + width: 100%; + } +} \ No newline at end of file diff --git a/src/index.js b/src/index.js index eb2631c2..49960460 100755 --- a/src/index.js +++ b/src/index.js @@ -1,31 +1,151 @@ const $app = document.getElementById('app'); const $observe = document.getElementById('observe'); +const $error = document.getElementById('error'); const API = 'https://api.escuelajs.co/api/v1/products'; +const PAGINATION_NAME = "pagination" +const FIRST_PAGINATION = 5 +const LAST_PAGINATION = 189 +const PAGINATION_LIMIT = 10 + + const getData = api => { - fetch(api) - .then(response => response.json()) - .then(response => { - let products = response; - let output = products.map(product => { - // template - }); - let newItem = document.createElement('section'); - newItem.classList.add('Item'); - newItem.innerHTML = output; - $app.appendChild(newItem); - }) - .catch(error => console.log(error)); -} - -const loadData = () => { - getData(API); -} - -const intersectionObserver = new IntersectionObserver(entries => { - // logic... + return new Promise((resolve, reject) => { + fetch(api) + .then(response => response.json()) + .then(response => { + let products = response; + let output = products.map(product => { + return (` +
+ ${product.title} +

+ ${product.id}-${product.title} + $ ${product.price} +

+
`) + }); + let newItem = document.createElement('section'); + newItem.classList.add('Items'); + newItem.innerHTML = output.join(""); + $app.appendChild(newItem); + resolve() + }) + .catch(error => reject(error)) + }) +} +/** + * Load data in DOM by pagination + * @param {Number} pagination fisrt item of the block + * @returns Print in DOM + */ +const loadData = async (pagination) => { + const offset = pagination + const limit = PAGINATION_LIMIT + return await getData(`${API}?offset=${offset}&limit=${limit}`); +} + +const intersectionObserver = new IntersectionObserver(async (entries) => { + + try { + const pagination = GET_NEW_PAGINATION() + await loadData(pagination) + if (GET_PAGINATION() >= LAST_PAGINATION) { + intersectionObserver.unobserve($observe); + loadFotter() + } + } catch (err) { + console.error(err) + loadError("Error.") + } + + }, { - rootMargin: '0px 0px 100% 0px', + rootMargin: '0px 0px 0px 0px', }); -intersectionObserver.observe($observe); +/** + * Load footer message in DOM + */ +const loadFotter = () => { + const output = ` + + ` + let newItem = document.createElement('section'); + newItem.innerHTML = `${output} `; + $observe.appendChild(newItem); + +} + +/** + * Load error message for 4s in DOM + * @param {String} error Error message + */ +const loadError = (error) => { + const output = ` +
+

${error}

+
+ ` + let newItem = document.createElement('section'); + newItem.innerHTML = `${output} `; + $error.appendChild(newItem); + setTimeout(() => { + if ($error.firstChild()) { + $error.removeChild($error.firstChild) + } + }, 4000) + +} + + +// Local Storage + +/** + * Get next pagination if it don't have use FIRST_PAGINATION + * @returns newPagination + */ +const GET_NEW_PAGINATION = () => { + let fooPagination; + if (!GET_PAGINATION()) { + fooPagination = FIRST_PAGINATION + } else { + fooPagination = GET_PAGINATION() + PAGINATION_LIMIT + } + SET_PAGINATION(fooPagination) + return fooPagination +} +/** + * Get pagination from local storage + * @returns Actual pagination + */ +const GET_PAGINATION = () => { + return parseInt(window.localStorage.getItem(PAGINATION_NAME)) +} + +/** + * Save pagination in local storage + * @param {Number,String} numberPag newPagination + */ +const SET_PAGINATION = (numberPag) => { + window.localStorage.setItem(PAGINATION_NAME, numberPag) +} + +/** + * Purge the pagination from local storage + */ +const PURGE_PAGINATION = () => [ + window.localStorage.removeItem(PAGINATION_NAME) +] + + +const main = () => { + PURGE_PAGINATION() + intersectionObserver.observe($observe); + +} + +main() From 531e4928267e67eb42f1a6c9904e35c5fcbcaed8 Mon Sep 17 00:00:00 2001 From: Rafael Livise Date: Tue, 14 Jun 2022 22:18:24 -0500 Subject: [PATCH 2/3] [UPDATE] Return README --- README.md | 134 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 123 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 84951262..afc4c72c 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,127 @@ -## DESCRIPTION +# PlatziStore -Solución al reto: all (1 - 5) +Somos comercio en línea con una gran cantidad de productos a comercializar. Estamos por lanzar nuestra implementación y necesitamos resolver los problemas que presenta nuestra aplicación. -Nombre: Rafael Livise -Usuario Platzi: Rafaeru -Correo Electronico: r.livise@hotmail.com +PlatziStore tiene varios bugs, tareas sin completar y recursos a implementar para su lanzamiento oficial. -## Reto: +### Instalación + +``` +npm install +``` + +### Ejecución + +``` +npm run start +``` + +### Debug + +http://localhost:8080/public/ + +### Documentación + +- Variable llamada $app donde haremos render de nuestra app. +- Elemento del DOM que será Observado. +- Constante 'API': Utilizamos la FakeAPI de Platzi. + +```javascript +const $app = document.getElementById("app"); +const $observe = document.getElementById("observe"); +const API = "https://api.escuelajs.co/api/v1/products"; +``` + +Función llamada 'getData' que se encarga de hacer Fetch a una API y debe de construir un elemento nuevo en el DOM. + +```javascript +const getData = (api) => { + fetch(api) + .then((response) => response.json()) + .then((response) => { + const products = response; + }) + .catch((error) => console.log(error)); +}; +``` + +Función encargada de obtener de los Productos. + +```javascript +const loadData = () => { + getData(API); +}; +``` + +Intersection Observer + +```javascript +const intersectionObserver = new IntersectionObserver( + (entries) => { + // logic... + }, + { + rootMargin: "0px 0px 100% 0px", + } +); + +intersectionObserver.observe($observe); +``` + +## RETO + +### Primer problema + +1. Analiza la API: fakeapi.platzi.com +2. Implementa la API de productos iniciando en el producto 5 y obteniendo los siguientes 10 productos. +3. Guarda en localStorage la posición inicial ("pagination") y actualízala en cada petición nueva para traer los siguientes productos. +4. Crear la lógica para implementar un scroll infinito con Intersection Observer. + +### Segundo Problema + +1. Crear la estructura de HTML para mostrar cada producto dentro de Items +2. Crear un article con la clase "Card" para contener la imagen, título y precio de un producto: + +```html +
+ +

+ Producto + $ Precio +

+
+``` + +3. Index.html debe de cumplir con los elementos mínimos de SEO (title = "PlatziStore", descripcion = "...") + +### Tercer Problema + +Cuando cerramos la pestaña o recargamos la pagina se debe de volver a mostrar los primeros 10 Productos. + +1. Mostrar los primeros 10 productos. +2. Eliminar el localStorage. +3. Actualiza la función loadData() a Async/Await. + +### Cuarto Problema + +La API utilizada "fakeAPI" retorna 200 productos, utilizaremos la paginación propuesta en su documentación para obtener los productos en bloques de 10, cuando la última petición sea ejecutada debes de mostrar un mensaje "Todos los productos Obtenidos", a su vez debes de destruir el intersection observer. + +1. Implementar mensaje: "Todos los productos Obtenidos". +2. Deja de observar el elemento "observe". + +### Quinto Problema (Bonus) + +Desplegar la aplicación en alguno de los siguientes servicios: GitHub Pages, Netlify, Vercel. + +### Enviar solución de reto + +Debes de hacer un "Fork" de este proyecto, revolver los problemas y crear un Pull Request hacia este repositorio. + +### Contribuir + +Si alguien quiere agregar o mejorar algo, lo invito a colaborar directamente en este repositorio: [js-challenge](https://github.com/platzi/js-challenge/) + +### Licencia + +js-challenge se lanza bajo la licencia [MIT](https://opensource.org/licenses/MIT). -- [✔️] Primer problema -- [✔️] Segundo problema -- [✔️] Tercer problema -- [✔️] Cuarto Problema -- [✔️] Quinto Problema From 119eaee6347a678a5a4110a43c8c405c2506cb8e Mon Sep 17 00:00:00 2001 From: Rafael Livise Date: Tue, 14 Jun 2022 22:20:28 -0500 Subject: [PATCH 3/3] [UPDATE] Return README space --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index afc4c72c..78d291e8 100644 --- a/README.md +++ b/README.md @@ -123,5 +123,4 @@ Si alguien quiere agregar o mejorar algo, lo invito a colaborar directamente en ### Licencia -js-challenge se lanza bajo la licencia [MIT](https://opensource.org/licenses/MIT). - +js-challenge se lanza bajo la licencia [MIT](https://opensource.org/licenses/MIT). \ No newline at end of file