Created
November 9, 2022 14:16
-
-
Save bdelacretaz/08806f75113efee4f2e87f73057ecc82 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<!-- Also stored at https://codepen.io/bdelacretaz/pen/OJEWQLO --> | |
<head> | |
<title>AEM Headless Adventures</title> | |
<style type="text/css"> | |
body { | |
font-family: -apple-system, BlinkMacSystemFont, Helvetica, Arial, sans-serif; | |
} | |
#activities li { | |
display: inline; | |
background-color: blue; | |
opacity: 30%; | |
color: #ffffff; | |
cursor: pointer; | |
padding: 5px; | |
margin-right: 5px; | |
border-radius: 5px; | |
} | |
#activities .selected { | |
color: yellow; | |
background-color: blue; | |
opacity: 100%; | |
} | |
#results { | |
display: flex; | |
flex-wrap: wrap; | |
font-family: "Montserrat", Sans-serif; | |
} | |
.result-card { | |
width: 300px; | |
height: 300px; | |
background: #f8f8f8; | |
margin: 10px; | |
padding: 10px; | |
} | |
.photo-wrapper img { | |
object-fit: cover; | |
width: 100%; | |
height: 225px; | |
} | |
.result-card h3 { | |
display: flex; | |
list-style-type: none; | |
font-size: 12px; | |
font-weight: 400; | |
} | |
.result-card h2 { | |
margin-top: 10px; | |
font-size: 16px; | |
font-weight: 700; | |
} | |
</style> | |
</head> | |
<body> | |
<header> | |
<menu id="activities"> | |
<li>Activity types will be loaded from the AEM data</li> | |
</menu> | |
</header> | |
<main> | |
<h1 id="mainTitle">AEM Headless Adventures</h1> | |
<p>This is a "bare Web Platform" page, similar to the <a | |
href="https://experienceleague.adobe.com/landing/experience-manager/headless/developer/code.html">AEM Headless | |
Code Playground examples</a>, that doesn't use any framework.</p> | |
<div id="results" data-source="https://102588-505tanocelot-stage.adobeioruntime.net/api/v1/web/aem/persistedquery" | |
data-query="wknd-shared/adventures-all"><em>Loading data...</em></div> | |
</main> | |
<script type="module"> | |
import aemClient from "https://cdn.skypack.dev/@adobe/[email protected]"; | |
const dataSource = { | |
serviceUrl: document.getElementById("results").getAttribute("data-source"), | |
queryName: document.getElementById("results").getAttribute("data-query") | |
} | |
const aemService = new aemClient({ | |
serviceURL: dataSource.serviceUrl | |
}); | |
// Used to escape HTML which contains user data | |
import htm from "https://cdn.skypack.dev/[email protected]"; | |
import vhtml from "https://cdn.skypack.dev/[email protected]"; | |
const html = htm.bind(vhtml); | |
let currentActivity = null; | |
let currentData = {}; | |
const initialTitle = document.getElementById("mainTitle").textContent; | |
const renderCard = (card) => { | |
return html` | |
<div class="result-card"> | |
<div class="photo-wrapper"> | |
<img src="${card.primaryImage?._publishUrl}"></img> | |
</div> | |
<h2>${card.title}</h2> | |
<h3>${card.tripLength} / $${card.price}</h3> | |
</div> | |
`; | |
}; | |
const renderList = () => { | |
let cardsHtml = ""; | |
currentData?.adventureList?.items | |
.filter((card) => !currentActivity || card.activity == currentActivity) | |
.map((card) => (cardsHtml += renderCard(card))); | |
document.getElementById("results").innerHTML = cardsHtml; | |
const title = `${initialTitle} ${currentActivity ? ": " + currentActivity : "" | |
}`; | |
document.getElementById("mainTitle").innerHTML = title; | |
document.title = title; | |
}; | |
const activityClicked = (e) => { | |
const clicked = e.target?.textContent.trim(); | |
currentActivity = clicked == currentActivity ? null : clicked; | |
document.querySelectorAll("#activities li").forEach((activity) => { | |
activity.setAttribute( | |
"class", | |
activity.textContent.trim() == currentActivity ? "selected" : "" | |
); | |
}); | |
renderList(); | |
}; | |
const aemData = await aemService.runPersistedQuery( | |
dataSource.queryName | |
); | |
currentData = aemData.data; | |
// Setup the activities menu | |
let activitiesMenu = ""; | |
let activities = {}; | |
currentData?.adventureList?.items.map((card) => { | |
activities[card.activity] = true; | |
}); | |
Object.keys(activities) | |
.sort() | |
.map( | |
(a) => | |
(activitiesMenu += html` | |
<li>${a}</li> | |
`) | |
); | |
document.getElementById("activities").innerHTML = activitiesMenu; | |
document.querySelectorAll("#activities li").forEach((e) => { | |
e.addEventListener("click", activityClicked); | |
}); | |
renderList(); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment