From Design to Database with Firestore

by Alex Cowan

HTML

<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/8.2.5/firebase-app.js"></script>

<!-- TODO: Add SDKs for Firebase products that you want to use
     https://firebase.google.com/docs/web/setup#available-libraries -->
<script src="https://www.gstatic.com/firebasejs/8.2.1/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.2.5/firebase-firestore.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.2.5/firebase-analytics.js"></script>

<script>
  // Your web app's Firebase configuration
  // For Firebase JS SDK v7.20.0 and later, measurementId is optional
  var firebaseConfig = {
    apiKey: "AIzaSyCOPgDQ4PAwNtOxZQtkkRpy0LV37VVEzJg",
    authDomain: "hinh-78995.firebaseapp.com",
    projectId: "hinh-78995",
    storageBucket: "hinh-78995.appspot.com",
    messagingSenderId: "389014950808",
    appId: "1:389014950808:web:5599635662f42697b091ed",
    measurementId: "G-XL6BSRZLQE",
  }
  // Initialize Firebase
  firebase.initializeApp(firebaseConfig)
  firebase.analytics()
</script>
<link
  rel="stylesheet"
  href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>

<!-- Top Bar: Navigation, Search Box, and Authentication Controls -->
<div class="top-bar">
  <ul class="nav-list">
    <li><a href="#">Home</a></li>
    <li><a href="#">Help</a></li>
  </ul>

  <div id="search-box">

  </div>

  <div id="auth-control">
    <img
      src="https://www.alexandercowan.com/wp-content/uploads/2018/04/login-icon.png"
      alt="auth"
      style="width: 30px; float: left"
    />
    <ul class="nav-list">
      <li id="login-trigger"><a href="#" id="auth-text">Log In</a></li>
    </ul>

    <div id="login-content">
      <!-- Login Form (CHANGED: Updated form ID to "loginForm") -->
      <form id="loginForm" onsubmit="return false">
        <input type="text" placeholder="Email" id="login_email" required />
        <input...

CSS

body {
    display: block;
    margin: 8px;
}

.top-bar, #search-box, .nav-list li, .nav-list a {
	background-color: #002D45;
	font-family: Proxima Nova,helvetica neue,helvetica,sans-serif;
	font-weight: bold;
	font-size: 110%;
	color: #ffffff;
}

.top-bar {
	color: #FFFFFF;
	height: 40px;
	margin: 0px;
	padding: 10px;
    display: flex;
    align-items: center;
}
#Header {
	font-family: Proxima Nova,helvetica neue,helvetica,sans-serif;
	font-weight: bold;
	font-size: 200%;
	color: rgb(0, 0, 0);
}

.nav-list {
    list-style-type: none;
    padding: 0;
		display: inline;

}

.nav-list li {
	    float: left;
}

.nav-list a {
    display: inline;
    padding: 8px;
		text-decoration: none;
}

#search-box {
	margin-left: auto;
	margin-right: 0;
	padding: 10px;
 }
 
 #login-content {
  display: none;
  position: absolute;
	margin-right: 10px;
  top: 60px;
  right: 0;
	left: 1000;
  z-index: 999;
  background: #ffffff;
  padding: 15px;
	border: 1px solid #CCC;
  width: 200px;
}

/* Keeps this in sync w/ the login-content div */
#login-form {
  display: none;
}

 #login-content input {
  margin-bottom: 3px;
  padding: 10px;
  width: 90%;
  border: 1px solid #CCC;
}

 #login-content label {
  cursor: pointer;
  font-family: Proxima Nova,helvetica neue,helvetica,sans-serif;
	color: #002D45;
}

 #login-content #register-form {
  display: none;
}

 #login-content #forgotten-form {
  display: none;
}

 #login-content, #after-reset, #if-error, #if-reg-error {
  display: none;
}

 #login-content .auth-link {
  cursor: pointer;
  font-family: Proxima Nova,helvetica neue,helvetica, sans-serif;
	color: #002D45;
}

#forgotten-link, #reset-response, #after-reset, #login-link-modal, #if-error, #if-reg-error {
  cursor: pointer;
  font-family: Proxima Nova,helvetica neue,helvetica,sans-serif;
	color: #002D45;
	font-size: 80%;
}

#login-link-modal {
	font-size: 120%;
}

#go-btn {
  margin: 5px;
 }


#search-controls {
	background-color: #ffffff;
	font-family: Proxima Nova,helvetica...

JavaScript

// -----------------------------
// CODE THAT LOADS THE HVAC PARTS (FROM FIRESTORE)
// -----------------------------

var db = firebase.firestore();

db.collection("parts")
	.limit(10)
	.get()
	.then((querySnapshot) => {
		querySnapshot.forEach((doc) => {
			const data = doc.data();
			const partArray = [
				doc.id,
				data.imageURL,
				data.Manufacturer,
				data.Model,
				data.Type,
				data.Price,
				data.Availability,
				data.Orders,
			];
			drawDiv(partArray);
		});
	});

function drawDiv(divData) {
	if (divData == null) return null;
	let partNum = divData[0].trim();
	let imgURL = divData[1].trim();
	let mfr = divData[2].trim();
	let model = divData[3].trim();
	let type = divData[4].trim();
	let price = "$" + Number(divData[5]).toFixed(2);
	let avail = divData[6].trim();
	let orders = String(divData[7]).trim();

	var newPartsDiv = document.createElement("div");
	newPartsDiv.className = "catalog-part";
	newPartsDiv.setAttribute("mfr", mfr);
	newPartsDiv.setAttribute("model", model);

	var partImg = document.createElement("img");
	partImg.setAttribute("src", "https://" + imgURL);
	newPartsDiv.appendChild(partImg);

	var newOverlayDiv = document.createElement("div");
	newOverlayDiv.className = "overlay";

	var link = document.createElement("a");
	link.className = "part-ref";
	link.setAttribute("href", "#");
	link.textContent = mfr + " #" + partNum;

	var newOverlayDivP = document.createElement("p");
	newOverlayDivP.appendChild(link);
	newOverlayDivP.appendChild(document.createElement("br"));
	newOverlayDivP.appendChild(document.createTextNode(orders + " Orders"));
	newOverlayDivP.appendChild(document.createElement("br"));
	newOverlayDivP.appendChild(document.createTextNode(price + " " + avail));

	var reviewContainer = document.createElement("span");
	reviewContainer.id = "review-" +...