diff --git a/README.md b/README.md index d7d6534a..78d291e8 100644 --- a/README.md +++ b/README.md @@ -123,4 +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 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()