JSFiddle - React, Tailwind, and code Playground
HTML
<!-- Loader -->
<div class="loader hidden">
<img src="rocket.svg" alt="Rocket Icon" />
</div>
<!-- Container -->
<div class="container">
<div class="header">
<div class="navigation-container">
<span class="background"></span>
<!-- Results Nav -->
<span class="navigation-items" id="resultsNav">
<h3 class="clickable" onclick="updateDOM('favorites')">Favorites</h3>
<h3> • </h3>
<h3 class="clickable" onclick="getNasaPictures()">Load More</h3>
</span>
<!-- Favorites Nav -->
<span class="navigation-items hidden" id="favoritesNav">
<h3 class="clickable" onclick="getNasaPictures()">
Load More NASA Images
</h3>
</span>
</div>
</div>
<div class="banner"></div>
<div class="hero">hero</div>
<div class="content">
<div class="container-fluid">
<div class="row">
<div class="column">
<div id="myImg" class="images-container"></div>
</div>
</div>
</div>
</div>
<!-- The Modal -->
<div id="myModal" class="modal">
<span class="close">×</span>
<img class="modal-content" id="img01">
<span><button>Add To Favourites</button></span>
<div id="caption"></div>
</div>
<div class="footer">
footer
</div>
</div>
<div class="save-confirmed" hidden>
<h1>ADDED!</h1>
</div>
CSS
.container {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 3% 5% 5% 1fr 0.1fr;
gap: 0px 0px;
grid-auto-flow: row;
grid-template-areas:
"header"
"banner"
"hero"
"content"
"footer";
}
.header {
grid-area: header;
background-color: red;
}
.banner {
grid-area: banner;
background-color: yellow;
}
.hero {
grid-area: hero;
background-color: blue;
}
.content {
grid-area: content;
background-color: orange;
align-self: center;
justify-self: center;
}
.footer {
grid-area: footer;
background-color: green;
}
html {
box-sizing: border-box;
}
body {
margin: 0;
background: whitesmoke;
overflow-x: hidden;
font-family: Verdana, sans-serif;
font-size: 1rem;
line-height: 1.8rem;
}
.loader {
position: fixed;
z-index: 40;
background: whitesmoke;
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
}
/* Navigation */
.navigation-container {
position: fixed;
top: 0;
}
.navigation-items {
display: flex;
justify-content: center;
}
.background {
background: whitesmoke;
position: fixed;
right: 0;
width: 100%;
height: 60px;
z-index: -1;
}
.clickable {
color: #0b3d91;
cursor: pointer;
user-select: none;
}
.clickable:hover {
color: #fc3d21;
}
/* Images Container */
.images-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
/* padding-top: 100px; */
}
.card {
margin: 10px 10px 10px;
width: 300px;
height: 300px;
}
.card-img-top {
width: 300px;
height: 300px;
}
.card-body {
padding: 20px;
}
.card-title {
margin: 10px auto;
font-size: 24px;
}
/* Save Confirmation */
.save-confirmed {
background: white;
padding: 8px 16px;
border-radius: 5px;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
transition: 0.3s;
position: fixed;
bottom: 25px;
right: 50px;
z-index: 500;
}
/* Hidden */
.hidden {
display: none;
}
.brand {
float: right;
}
.fave {
margin-right:...
JavaScript
const resultsNav = document.getElementById("resultsNav");
const favoritesNav = document.getElementById("favoritesNav");
const imagesContainer = document.querySelector(".images-container");
const saveConfirmed = document.querySelector(".save-confirmed");
const loader = document.querySelector(".loader");
// NASA API
const count = 3;
const apiKey = 'DEMO_KEY';
const apiUrl = `https://api.nasa.gov/planetary/apod?api_key=${apiKey}&count=${count}`;
let resultsArray = [];
let favorites = {};
// Show Content
function showContent(page) {
window.scrollTo({
top: 0,
behavior: "instant"
});
if (page === "results") {
resultsNav.classList.remove("hidden");
favoritesNav.classList.add("hidden");
} else {
resultsNav.classList.add("hidden");
favoritesNav.classList.remove("hidden");
}
loader.classList.add("hidden");
}
// Create DOM Nodes
function createDOMNodes(page) {
const currentArray =
page === "results" ? resultsArray : Object.values(favorites);
currentArray.forEach((result) => {
// Card Container
const card = document.createElement("div");
card.classList.add("card");
// Link that wraps the image
const link = document.createElement("a");
// Get the modal
var modal = document.getElementById("myModal");
// Get the image and insert it inside the modal - use its "alt" text as a caption
var img = document.getElementById("myImg");
var modalImg = document.getElementById("img01");
var captionText = document.getElementById("caption");
img.onclick = function() {
modal.style.display = "block";
modalImg.src = event.target.src;
captionText.innerHTML = event.target.alt;
}
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
// When the user clicks on <span> (x), close the modal
span.onclick = function() {
modal.style.display = "none";
}
// Image
const image =...