Begin Store Front project using web components
This commit is contained in:
parent
4e61a13d5e
commit
1aeaed646e
6 changed files with 184 additions and 0 deletions
20
web-apps/main.go
Normal file
20
web-apps/main.go
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
|
||||||
|
mux.Handle("GET /store-front/", http.StripPrefix("/store-front", http.FileServer(http.Dir("store-front"))))
|
||||||
|
|
||||||
|
log.Println("Start the web server...")
|
||||||
|
err := http.ListenAndServe(":8080", mux)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
24
web-apps/store-front/css/grid.css
Normal file
24
web-apps/store-front/css/grid.css
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/**
|
||||||
|
* Grid Layout
|
||||||
|
*/
|
||||||
|
|
||||||
|
@media (min-width: 20em) {
|
||||||
|
grid-of-photos div {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 50% 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 32em) {
|
||||||
|
grid-of-photos div {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 33% 33% 33%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 42em) {
|
||||||
|
grid-of-photos div {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 20% 20% 20% 20% 20%;
|
||||||
|
}
|
||||||
|
}
|
4
web-apps/store-front/css/pico.min.css
vendored
Normal file
4
web-apps/store-front/css/pico.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
34
web-apps/store-front/index.html
Normal file
34
web-apps/store-front/index.html
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="color-scheme" content="light dark">
|
||||||
|
<link rel="stylesheet" href="css/pico.min.css">
|
||||||
|
<link rel="stylesheet" href="css/grid.css">
|
||||||
|
<title>Project - Store Front</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<nav>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Sparrow Photography</strong></li>
|
||||||
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<li><a href="#">About</a></li>
|
||||||
|
<li><a href="#">Services</a></li>
|
||||||
|
<li><a href="#">Products</a></li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<grid-of-photos>
|
||||||
|
<p aria-busy="true">Loading...</p>
|
||||||
|
</grid-of-photos>
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<p><em>Photos by Jack Sparrow. All rights reserved.</em></p>
|
||||||
|
</div>
|
||||||
|
<script src="js/grid-of-photos.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
1
web-apps/store-front/js/.#grid-of-photos.js
Symbolic link
1
web-apps/store-front/js/.#grid-of-photos.js
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
andrea@lv5.321700:1727085997
|
101
web-apps/store-front/js/grid-of-photos.js
Normal file
101
web-apps/store-front/js/grid-of-photos.js
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
const endpoint = 'https://leanwebclub.com/course-apis/photos.json';
|
||||||
|
|
||||||
|
class GridOfPhotos extends HTMLElement {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate the component
|
||||||
|
*/
|
||||||
|
constructor () {
|
||||||
|
// Inherit parent class properties
|
||||||
|
super();
|
||||||
|
|
||||||
|
// LIsten for events
|
||||||
|
this.addEventListener('click', this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs each time the element is appended to or moved in the DOM
|
||||||
|
*/
|
||||||
|
async connectedCallback () {
|
||||||
|
|
||||||
|
// Fetch the photos from the API
|
||||||
|
this.photos = await this.fetchPhotos();
|
||||||
|
|
||||||
|
// If there are no photos
|
||||||
|
if (!this.photos || !this.photos.length) {
|
||||||
|
this.innerHTML = '<p>There are no available photos at this time. Please try again later. Sorry!</p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render the element
|
||||||
|
this.innerHTML = `
|
||||||
|
<div>
|
||||||
|
${this.photos.map( (image) => { return `<img src="${image.url}" alt="${image.description}"></img>` } ).join('')}
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch photos from the API
|
||||||
|
* @return {Promise} response - The response from the API
|
||||||
|
*/
|
||||||
|
async fetchPhotos () {
|
||||||
|
try {
|
||||||
|
let response = await fetch(endpoint);
|
||||||
|
if (!response.ok) throw response.status;
|
||||||
|
|
||||||
|
let data = await response.json();
|
||||||
|
if (!data) throw 'No data!';
|
||||||
|
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
console.warn("ERR:", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle events
|
||||||
|
* @param {Event} event - The event object
|
||||||
|
*/
|
||||||
|
handleEvent (event) {
|
||||||
|
this[`on${event.type}`](event);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the click event
|
||||||
|
* @param {Event} event - The event object
|
||||||
|
*/
|
||||||
|
onclick (event) {
|
||||||
|
if (!event.target.closest('img')) return;
|
||||||
|
|
||||||
|
let dialog = document.createElement('dialog');
|
||||||
|
dialog.setAttribute('open', '');
|
||||||
|
|
||||||
|
dialog.innerHTML = `
|
||||||
|
<article>
|
||||||
|
<h2>Confirm Your Membership</h2>
|
||||||
|
<p>
|
||||||
|
Thank you for signing up for a membership!
|
||||||
|
Please review the membership details below:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>Membership: Individual</li>
|
||||||
|
<li>Price: $10</li>
|
||||||
|
</ul>
|
||||||
|
<footer>
|
||||||
|
<button class="secondary">
|
||||||
|
Close
|
||||||
|
</button>
|
||||||
|
</footer>
|
||||||
|
</article>
|
||||||
|
`
|
||||||
|
this.append(dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define the new web component
|
||||||
|
if ('customElements' in window) {
|
||||||
|
customElements.define('grid-of-photos', GridOfPhotos);
|
||||||
|
}
|
Loading…
Reference in a new issue