Skip to content

Instantly share code, notes, and snippets.

@andreluiz1987
Last active March 17, 2025 21:33
Show Gist options
  • Save andreluiz1987/06d9ec1b381e942e9def0e969bd811a0 to your computer and use it in GitHub Desktop.
Save andreluiz1987/06d9ec1b381e942e9def0e969bd811a0 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Marketplace Facets</title>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
flex-direction: column;
margin: 20px;
}
.search-bar {
width: 100%;
display: flex;
justify-content: center;
margin-bottom: 20px;
}
.search-bar input {
width: 300px;
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 16px;
}
.container {
display: flex;
}
.sidebar {
width: 250px;
padding: 20px;
border-right: 1px solid #ddd;
}
.facets {
margin-bottom: 20px;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
background-color: #f9f9f9;
}
.facets h4 {
margin: 0 0 10px;
}
.facets label {
display: block;
margin-bottom: 5px;
}
.content {
flex-grow: 1;
padding: 20px;
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.card {
width: 250px;
height: 180px;
border: 1px solid #ddd;
border-radius: 5px;
padding: 15px;
text-align: center;
box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
justify-content: space-between;
}
.card img {
width: 100%;
border-radius: 5px;
height: 50px;
object-fit: contain;
}
.card h3 {
margin: 5px 0;
font-size: 14px;
}
.card p {
font-size: 12px;
margin: 5px 0;
}
</style>
</head>
<body>
<div class="search-bar">
<input type="text" id="searchInput" placeholder="Search products...">
</div>
<div class="container">
<aside class="sidebar">
<h3>Filter by</h3>
<div id="facets-container">Loading facets...</div>
</aside>
<!-- Product Cards -->
<section class="content" id="products-container">Loading products...</section>
</div>
<script>
// Simulate response from Elasticsearch
const apiResponse = {
"aggregations": {
"dynamic_facets": {
"doc_count": 6,
"facets": {
"buckets": [
{
"key": "Battery Life",
"facets": {
"buckets": [
{ "key": "4.5 hours", "doc_count": 1 },
{ "key": "9 hours", "doc_count": 1 }
]
}
},
{
"key": "Color Options",
"facets": {
"buckets": [
{ "key": "Unique Colors", "doc_count": 1 },
{ "key": "Vibrant Colors", "doc_count": 1 }
]
}
},
{
"key": "Gaming Compatibility",
"facets": {
"buckets": [
{ "key": "Handheld Mode", "doc_count": 1 }
]
}
},
{
"key": "Included Game",
"facets": {
"buckets": [
{ "key": "Super Mario Bros. Wonder", "doc_count": 1 }
]
}
},
{
"key": "Portability",
"facets": {
"buckets": [
{ "key": "Lightweight Design", "doc_count": 1 }
]
}
},
{
"key": "Screen Size",
"facets": {
"buckets": [
{ "key": "7-inch", "doc_count": 1 }
]
}
}
]
}
}
}
};
function renderFacets(response) {
const facetsContainer = document.getElementById("facets-container");
facetsContainer.innerHTML = "";
const facetsData = response.aggregations.dynamic_facets.facets.buckets;
facetsData.forEach(facet => {
const facetDiv = document.createElement("div");
facetDiv.classList.add("facets");
facetDiv.innerHTML = `<h4>${facet.key}</h4>`;
facet.facets.buckets.forEach(option => {
const label = document.createElement("label");
label.innerHTML = `<input type="checkbox"> ${option.key} (${option.doc_count})`;
facetDiv.appendChild(label);
});
facetsContainer.appendChild(facetDiv);
});
}
function renderProducts() {
const productsContainer = document.getElementById("products-container");
productsContainer.innerHTML = "";
const products = [
{
"name": "Nintendo Switch",
"image": "https://via.placeholder.com/100",
"description": "SHARPER, VIBRANT VISUALS. The new 7-inch screen on the Nintendo Switch OLED takes your gaming to...",
"price": "$299.99"
},
{
"name": "Nintendo Switch Lite",
"image": "https://via.placeholder.com/100",
"description": "MADE TO BE PORTABLE. Nintendo Switch Lite is designed specifically for portable gaming...",
"price": "$199.99"
}
];
products.forEach(product => {
const productCard = document.createElement("div");
productCard.classList.add("card");
productCard.innerHTML = `
<img src="${product.image}" alt="${product.name}">
<h3>${product.name}</h3>
<p>${product.description}</p>
<p><strong>${product.price}</strong></p>
`;
productsContainer.appendChild(productCard);
});
}
setTimeout(() => {
renderFacets(apiResponse);
renderProducts();
}, 500);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment