Created
February 13, 2023 00:49
-
-
Save angusgrant/478892f2ca9a72e7b3e041e4d70e13e3 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> | |
<head> | |
<meta charset="utf-8"> | |
<title>Sparrow Photography</title> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<link rel="stylesheet" type="text/css" href="styles.css"> | |
</head> | |
<body> | |
<nav class="nav"> | |
<a class="logo" href="index.html"><strong>Sparrow Photography</strong></a> | |
</nav> | |
<h1>Sparrow Photography</h1> | |
<div id="app">Loading...</div> | |
<footer> | |
<p><em>Photos by Jack Sparrow. All rights reserved.</em></p> | |
</footer> | |
<script type="module"> | |
import {render} from 'https://cdn.jsdelivr.net/npm/reefjs@12/dist/reef.es.min.js'; | |
import {getPhotos} from './components/api.js'; | |
// Get the #app element | |
let app = document.querySelector('#app'); | |
/** | |
* Generate an HTML of available photos | |
* @param {Object} photos The photo data | |
* @return {String} A list of available photos | |
*/ | |
function photoHTML (photos) { | |
// If there are no photos | |
if (!photos.length) { | |
return '<p>There are no available photos at this time. Please try again later. Sorry!</p>'; | |
} | |
// Otherwise, show photos | |
return ` | |
<p>High-end photography from the Seven Seas, brought to you by world-famous photographer Captain Jack Sparrow.</p> | |
<div id="photos"> | |
${photos.map(function (photo) { | |
return ` | |
<div class="photo"> | |
<a href="/photo.html?id=${encodeURIComponent(photo.id)}"> | |
<img alt="${photo.description}" src="${photo.url}"> | |
<div>${photo.name}</div> | |
</a> | |
</div>`; | |
}).join('')} | |
</div>`; | |
} | |
// Initialize | |
getPhotos().then(function (photos) { | |
render(app, photoHTML(photos)); | |
}); | |
</script> | |
</body> | |
</html> |
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> | |
<head> | |
<meta charset="utf-8"> | |
<title>Sparrow Photography</title> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<link rel="stylesheet" type="text/css" href="styles.css"> | |
</head> | |
<body> | |
<nav class="nav"> | |
<a class="logo" href="index.html"><strong>Sparrow Photography</strong></a> | |
</nav> | |
<div id="app">Loading...</div> | |
<footer> | |
<p><em>Photos by Jack Sparrow. All rights reserved.</em></p> | |
</footer> | |
<script type="module"> | |
import {render} from 'https://cdn.jsdelivr.net/npm/reefjs@12/dist/reef.es.min.js'; | |
import {getPhotos} from './components/api.js'; | |
import {storeCart, retrieveCart} from './components/cart.js'; | |
// Get the #app element | |
let app = document.querySelector('#app'); | |
let photos = []; | |
/** | |
* Get the photo ID from the URL | |
* @return {String} The photo ID | |
*/ | |
function getPhotoID () { | |
return new URL(window.location.href).searchParams.get('id'); | |
} | |
/** | |
* Get a photo by its ID | |
* @param {Array} photos All photos | |
* @param {String} id The ID of the photo to get | |
* @return {Object} The photo data | |
*/ | |
function getPhotoByID (photos, id) { | |
return photos.find(function (photo) { | |
return photo.id === id; | |
}); | |
} | |
/** | |
* The HTML string for when no photo is found | |
* @return {String} The HTML string | |
*/ | |
function noPhotoHTML () { | |
return ` | |
<h1>Uh oh!</h1> | |
<p>This photo is missing. Sorry!</p>`; | |
} | |
/** | |
* Generate an HTML of available photos | |
* @param {Object} photos The photo data | |
* @return {String} The photo HTML string | |
*/ | |
function photoHTML () { | |
// Get the photo ID | |
let id = getPhotoID(); | |
if (!id) return noPhotoHTML(); | |
// Get the photo data | |
let photo = getPhotoByID(photos, id); | |
if (!photo) return noPhotoHTML(); | |
//check item is stored in cart | |
let itemInCartBool = retrieveCart(id) == 'true' ? true : false; | |
// Update the document.title | |
document.title = `${photo.name} | ${document.title}`; | |
// Show the photo | |
return ` | |
<h1>${photo.name}</h1> | |
<p><img alt="" src="${photo.url}"></p> | |
<p aria-live="polite">${photo.description}</p> | |
${itemInCartBool ? `<p><b>Your Item is already in your cart</b></p>` : | |
`<button data-add-to-cart-id="${photo.id}">Add to cart - $${photo.price}</button>`} | |
` | |
; | |
} | |
/** | |
* Handle Click events | |
* @param {Event} event the event object | |
*/ | |
function clickHandler (event) { | |
//Only run for [data-add-to-cart-id] | |
const id = event.target.dataset.addToCartId; | |
if (!id) return; | |
//store to cart | |
storeCart(id); | |
render(app, photoHTML(photos)); | |
} | |
// Initialize | |
getPhotos().then(function (data) { | |
photos = data; | |
render(app, photoHTML(photos)); | |
document.addEventListener('click', clickHandler); | |
}); | |
</script> | |
</body> | |
</html> |
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
body { | |
margin: 0 auto; | |
max-width: 50em; | |
width: 88%; | |
} | |
/** | |
* Grid Layout | |
*/ | |
@media (min-width: 20em) { | |
#photos { | |
display: grid; | |
grid-template-columns: repeat(2, 1fr); | |
grid-template-rows: 1fr; | |
grid-column-gap: 2em; | |
grid-row-gap: 2em; | |
} | |
} | |
@media (min-width: 32em) { | |
#photos { | |
grid-template-columns: repeat(3, 1fr); | |
} | |
} | |
@media (min-width: 42em) { | |
#photos { | |
grid-template-columns: repeat(4, 1fr); | |
} | |
} | |
/** | |
* Nav Menu | |
*/ | |
.nav { | |
padding: 1em 0; | |
} | |
.nav a { | |
text-decoration: none; | |
} | |
.nav a:focus, | |
.nav a:hover { | |
text-decoration: underline; | |
} | |
/** | |
* Footer | |
*/ | |
footer { | |
border-top: 1px solid #e5e5e5; | |
margin-top: 5em; | |
} | |
/** | |
* Responsive images | |
*/ | |
img { | |
height: auto; | |
max-width: 100%; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment