Skip to content

Plazi Blockchain challenge by Carlos J. Ramirez #158

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,7 @@ typings/

# next.js build output
.next

# cypress test run files
cypress/screenshots/*
cypress/videos/*
6 changes: 3 additions & 3 deletions PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

Solución al reto:

Nombre:
Usuario Platzi:
Correo Electronico:
Nombre: Carlos J. Ramirez
Usuario Platzi: carlosrd@gmail.com
Correo Electronico: carlosrd@gmail.com

## Reto:

Expand Down
26 changes: 26 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<meta name="description" content="PlatziStore for JS-Challenge, by Carlos J. Ramirez | http://carlosjramirez.com/ " />
<title>PlatziStore</title>
<link type="text/css" href="public/styles.css" rel="stylesheet">
</head>

<body>
<div class="Main">
<h1>PlatziStore</h1>
<div id="eofAlert" class="alert">
<script type="text/javascript">document.getElementById('eofAlert').style.display='none';</script>
<span class="closebtn" onclick="this.parentElement.style.display='none';">&times;</span>
<div id="eofAlertMessage" class="alertMessage"></div>
</div>
<div id="app"></div>
<div id="observe"></div>
</div>
</body>

<script type="text/javascript" src="/src/index.js"></script>
</html>
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added public/favicon.ico
Binary file not shown.
8 changes: 7 additions & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,19 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
<title>PlatziStore</title>
<meta name="description" content="Tienda en línea de muebles, accesorios, ropa, zapatos, comida, autos. Entregas en toda Colombia.">
<link type="text/css" href="styles.css" rel="stylesheet">
</head>

<body>
<div class="Main">
<h1>PlatziStore</h1>
<div id="eofAlert" class="alert">
<script type="text/javascript">document.getElementById('eofAlert').style.display='none';</script>
<span class="closebtn" onclick="this.parentElement.style.display='none';">&times;</span>
<div id="eofAlertMessage" class="alertMessage"></div>
</div>
<div id="app"></div>
<div id="observe"></div>
</div>
Expand Down
37 changes: 37 additions & 0 deletions public/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,40 @@ body {
opacity: 1;
}
}

.alert {
/* padding: 20px; */

position: fixed;
bottom: 35px;
right: 20px;
margin-left: 20px;

background-color: #36a5f4;
color: white;
}

.alertMessage {
margin-left: 10px;
margin-top: 10px;
margin-bottom: 10px;
float: left;
}

.closebtn {
margin-left: 15px;
margin-right: 10px;
margin-top: 10px;
margin-bottom: 10px;
color: white;
font-weight: bold;
float: right;
font-size: 22px;
line-height: 20px;
cursor: pointer;
transition: 0.3s;
}

.closebtn:hover {
color: black;
}
109 changes: 102 additions & 7 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,126 @@
const $app = document.getElementById('app');
const $observe = document.getElementById('observe');
const API = 'https://api.escuelajs.co/api/v1/products';
const itemsPerPage = 10;
const initialItem = 5;
const debug = true;
const productTemplateType='0'; // '0' = prod, '1' = test/debug

const getData = api => {
// Carga los datos de la API para la pagina corriente
const getData = (api, initialId, resolve) => {
fetch(api)
.then(response => response.json())
.then(response => {
let products = response;
let output = products.map(product => {
// template
if(debug) console.log('getData initialId = ' + initialId);
let endingId = null;
let itemsCounterForFilter = 0;
let itemsInPage = 0;
let output = products
.filter(product => (product.id >= initialId && product.id != null && ++itemsCounterForFilter <= itemsPerPage))
.map(function (product) {
itemsInPage++;
endingId = product.id;
// Returns the product in a template
return productCardTemplate(productTemplateType, product);
});
localStorage.setItem('itemsInPage', itemsInPage);
localStorage.setItem('nextPagination', endingId + 1);
if(debug) console.log('getData itemsCounterForFilter = ' + itemsCounterForFilter + ', itemsInPage = ' + itemsInPage + ', endingId = ' + endingId + ', pagination = ' + localStorage.getItem('pagination'));
let newItem = document.createElement('section');
newItem.classList.add('Item');
newItem.innerHTML = output;
newItem.classList.add('Items');
newItem.innerHTML = output.join('');
$app.appendChild(newItem);
resolve("All Set");
})
.catch(error => console.log(error));
}

const loadData = () => {
getData(API);
// Carga los datos para la pagina corriente
async function loadData(currentPagination) {
let promise = new Promise((resolve, reject) => {
getData(API, currentPagination, resolve);
});
let result = await promise; // wait until the promise resolves (*)
}

// Hace aparecer el mensaje con un boton para cerrarlo
const showMessage = (msg) => {
document.getElementById('eofAlert').style.display='block'
document.getElementById('eofAlertMessage').innerHTML=msg;
}

// Card template
const productCardTemplate = (templateType, product) => {
switch(templateType) {
case '1':
return '' +
'<article class="Card">' +
'<h2>' +
product.id +
' | ' +
product.title +
'<small>Precio: $' + product.price + '</small>' +
'</h2>' +
'<img src="' + product.images[0] +'"></img>' +
'<h2>' + product.description + '</h2>' +
'</article>';
case '0':
default:
return '' +
'<article class="Card">' +
'<img src="' + product.images[0] +'"></img>' +
'<h2>' +
product.title +
'<small>Precio: $' + product.price + '</small>' +
'</h2>' +
'</article>';
}
}

// Reinicia el localstorage cuando se hace refresh
window.onbeforeunload = function() {
localStorage.removeItem('pagination');
localStorage.removeItem('itemsInPage');
}

// Maneja el EOF (fin de archivo) de la API
const eofHandler = function() {
if(debug) console.log('Todos los productos Obtenidos');
showMessage('Todos los productos Obtenidos');
intersectionObserver.unobserve($observe);
}

const paginationHandler = function() {
if(localStorage.getItem('pagination') == null) {
// Primera vez
localStorage.setItem('pagination', initialItem);
if(debug) console.log('paginationHandler - initial pagination = ' + localStorage.getItem('pagination'));
} else {
if(debug) console.log('paginationHandler - pagination = ' + localStorage.getItem('pagination'));
if(debug) console.log('paginationHandler - nextPagination = ' + localStorage.getItem('nextPagination'));
localStorage.setItem('pagination', localStorage.getItem('nextPagination'));
}
}

// Implementa el Intersection Observer
const intersectionObserver = new IntersectionObserver(entries => {
// logic...
if (entries[0].intersectionRatio <= 0) return;
if(debug) console.log('..........');
// Maneja la paginacion
paginationHandler();
// Hace la llamada a loadData de manera asincrona
loadData(parseInt(localStorage.getItem('pagination'))).then(function() {
// Verifica el EOF
if(parseInt(localStorage.getItem('itemsInPage')) < itemsPerPage) {
// Maneja el EOF
eofHandler();
}
});
}, {
rootMargin: '0px 0px 100% 0px',
});

// Ejecuta el Intersection Observer
intersectionObserver.observe($observe);