Final Individual Part

This supports a software dev. class for businesspeople that you can find here: https://www.alexandercowan.com/making-html-manageable And a case you can find here: https://www.alexandercowan.com/making-html-manageable

by Alex Cowan

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/3.6.0/jasmine.min.js"></script>
<!-- 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="//netdna.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<div class="top-bar">
  <ul class="nav-list">
    <li><a href="#">Home</a></li>
    <li><a href="#">Parts</a></li>
    <li><a href="#">Search</a></li>
    <li><a href="#">Help</a></li>
  </ul>
  <div id="search-box">
    <input type="text" name="parts-search" placeholder="Mfg., Model, or Part Number" size=30>
  </div>
</div>

<div id="part-info">
  <img id='part-img' alt="PCB board" style="width:300px;">
  <h2 id='part-title'></h2> <button type="button" id='order-btn'>Add to Cart</button><button type="button" id='checkout-btn'>Checkout</button>
  <h3 id='availability'>...

CSS

.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;
}

.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;
}

/* PH */
p {
  font-family: 'Lucida Sans Unicode', 'Lucida Grande', sans-serif;
  /* line-height: 1; */
  overflow: scroll;
}

#part-info {
  margin: 15px;
  padding: 0px 5px;
  width: 100%;
}

#part-info img {
  float: left;
  padding: 5px;
}

#part-info h2 {
  display: inline;
}

/* PH */
button {
  display: inline;
  font-size: 20px;
  margin: 0px 5px 5px 0px;
}

#part-info h3 {
  margin: 0px;
}

#review-form h3 {
  clear: both;
  margin: 20px 0px 5px 0px;
}

/* PH */
.stars {
 width: 70px;
}

input.star {
  display: none;
}

label.star {
  float: right;
  padding: 0px;
  font-size: 15px;
  color: #444;
}

input.star:checked~label.star:before {
  content: '\f005';
  color: #000;
  transition: all .25s;
}

label.star:before {
  content: '\f006';
  font-family: FontAwesome;
}

#review-text {
  clear: both;
  width: 100%;
}

/* PH 
#review-form {
  float: right;
  display: relative;
}

*/

/* PH
#part-reviews {
  float: left;
}
*/
.indReview {
  border-style: solid;
}

.fa-star {
  opacity: .5;
}

.checked {
  color: black;
  opacity: 1;
}

#review {
  display: none;
}

#add-review {
  display: none;
}

/* PH */
#user-reviews {
  clear: both;
  /*
  display: grid;
  float: left;
  */
}

/* PH */
#user-reviews h2 {
  margin: 5px 5px 5px 0px;
}

JavaScript

var db = firebase.firestore();

//get just the part number. Splits on '#' and takes second element of the array
//var partnum = localStorage.getItem('pn').split('#', 2)[1];

var partnum = "GR1688";
var partnum = "GR1688";

//Defint the file path for where the part data lives
part_file_path = '/parts/' + partnum

//Go get the part data
doc = db.doc(part_file_path).get().then((doc) => {
  //draw the part information on the page
  var part = doc.data()
  var id = doc.id
  $('#partnum').text('Part #: ' + id)
  $('#availability').text('Availability: ' + part.availability)
  $('#orders').text('Orders (90 day): ' + part.orders)
  //Make sure prices show two digits and have a dollar sign. We'll have to ensure that these are floats in the rules when new parts are added
  $('#price').text('Price: $' + part.Price.toFixed(2))
  $('#part-title').text(part.Manufacturer + ' ' + part.Model + ' ' + part.Type)
  $('#part-img').attr('src', 'https://' + part.imageURL)
  //add the stars
  var $starSpan
  //get average rating
  total_score = part.total_score;
  numRating = part.total_ratings;
  avgRating = Math.round(total_score / numRating)
  // add 5 stars and check them if they are <= average rating
  for (var i = 1; i <= 5; i++) {
    $starSpan = $('<span class="fa fa-star" />');
    if (i <= avgRating) {
      $starSpan.addClass('checked')
    }
    $('#part-info').append($starSpan);
  }
  $('#description').text(part.description)

  // Check if someone is logged in and show add-review button if they are if they have not submitted a review before
  if (firebase.auth().currentUser) {
    review_file_path = '/parts/' + partnum + '/reviews'
    //only show if the person hasn't written a review for this part yet
    db.collection(review_file_path).where('user', '==', firebase.auth().currentUser.uid).get().then((querySnapshot) => {
      // show the add review form if there are no reviews with their username so far.
      if (querySnapshot.empty) {
        $('#add-review').show()
     ...