/*** @description external api provied demo data for testing or populating the UI* @name client* @global* @constant***/const client = contentful.createClient({space: "tzsry6lrietp",accessToken:"45db9d587d237f603aa7bfddb35918bb377e6505f129200c9c1e07968be1c628",host: "512063bb41145bfc98748478968f3fae74b98d9fa305d00c3920a669599985e0"});// console.log(client);// variables/*** @description assigning div.cart-btn DOM to cartBtn object* @name cartBtn* @constant* @global* @type {Object}*/const cartBtn = document.querySelector(".cart-btn");/*** @description assigning div.close-cart DOM to closeCartBtn object* @name closeCartBtn* @constant* @global* @type {Object}*/const closeCartBtn = document.querySelector(".close-cart");/*** @description assigning button.clear-cart DOM to clearBtn object* @name clearBtn* @constant* @global* @type {Object}*/const clearBtn = document.querySelector(".clear-cart");/*** @description assigning div.cart DOM to cartDOM object* @name cartDOM* @constant* @global* @type {Object}*/const cartDOM = document.querySelector(".cart");/*** @description assigning div.overlay DOM to cartOverlay object* @name cartOverlay* @constant* @global* @type {Object}*/const cartOverlay = document.querySelector(".cart-overlay");/*** @description assigning div.cart-items html DOM element to cartItems object* @name cartItems* @constant* @global* @type {Object[]}*/const cartItems = document.querySelector(".cart-items");/*** @description assigning span.cart-total html DOM element to cartTotal object* @name cartTotal* @constant* @global* @type {Object}*/const cartTotal = document.querySelector(".cart-total");/*** @description assigning div.cart-content html DOM element to cartContent object* @name cartContent* @constant* @global* @type {Object}*/const cartContent = document.querySelector(".cart-content");/*** @description assigning div.products-center html DOM element to productsDOM object* @name productsDOM* @constant* @global* @type {Object}*/const productsDOM = document.querySelector(".products-center");/*** @description array of {@link cartItem} objects represents products was added to cart* @name cart* @type {Array.<cartItem>}**/let cart = [];/*** @description array of {@link buttons} objects represents buttons.btn-bag* - note "those buttons created and populated into DOM using javascript"* @name buttonsDOM* @type {Array.<Object>} DOM element "document.querySelectorAll(".bag-btn")"**/let buttonsDOM = [];// getting the products/*** @description class responsible about fetching and destructuring items(products)* then assigning them to an array of product object* @class* @name Products* @example const products = new Products();*/class Products {/*** @description fetching and destructuring items(products)* then assigning them to an array of product object* @name getProducts* @async* @inner* @public* @function* @this Products* @returns [{Array.<Object>}] [array of product object]* @example products.getProducts();**/async getProducts() {/*** @description surrounding the functinality of the function in try-catch block**/try {/*** @await* @description asigning items to contentful object* @name contentful*/let contentful = await client.getEntries({content_type: "comfyHouseFurrniture"});/*** @description testing function*/console.log(contentful);let result = await fetch("../../products.json");let data = await result.json();/*** @description assigning to an array* @name products* @type {Array}*/let products = contentful.items;// console.log(contentful);/*** @description destructuring items from the array then reassign as* @function* @name map array higher order function* @param function* @returns {Array.<Object>}*/products = products.map(item => {const { title, price } = item.fields;const { id } = item.sys;const image = item.fields.image.fields.file.url;return { title, price, id, image };});return products;} catch (error) {console.log(error);}}}/*** @description this class wraps the function that responsible for displaying {@link products} item and adding their functionality* @summary DISPLAYING PRODUCTS* @name UI* @example const ui =new UI();* @class**/class UI {/*** @description takes an array of {@link products} and populate the DOM* @see {@link https://www.w3schools.com/js/js_htmldom.asp}* @this UI* @name displayProducts* @function* @param {Array.<Objects>} products to be displayed*/displayProducts(products) {let result = "";products.forEach(product => {result += `<!-- single product --><article class="product"><div class="img-container"><imgsrc=${product.image}class="product-img"alt="img product"/><button class="bag-btn" data-id=${product.id}><i class="fas fa-shopping-cart"></i>Add to bag</button></div><h3>${product.title}</h3><h4>$${product.price} </h4></article><!-- end of single product -->`;});productsDOM.innerHTML = result;}getBagButtons() {const buttons = [...document.querySelectorAll(".bag-btn")];// buttonsDOM = buttons;buttonsDOM = buttons;buttons.forEach(button => {let id = button.dataset.id;let inCart = cart.find(item => item.id === id);if (inCart) {button.textContent = "In Cart";button.disabled = true;}button.addEventListener("click", event => {event.target.textContent = "In Cart";event.target.disabled = true;// get product from productslet cartItem = { ...Storage.getProducts(id), amount: 1 };console.log(cartItem);// add product from to the cartcart = [...cart, cartItem];// console.log(cart);// save product in the local storageStorage.saveCart(cart);// set cart valuesthis.setCartValues(cart);// display cart itemsthis.addCartItem(cartItem);// show the cartthis.showCart();});});}setCartValues(cart) {let tempTotal = 0;let itemsTotal = 0;cart.map(item => {tempTotal += item.price * item.amount;itemsTotal += item.amount;});cartTotal.textContent = parseFloat(tempTotal.toFixed(2));cartItems.textContent = itemsTotal;}addCartItem(item) {const div = document.createElement("div");div.classList.add("cart-item");div.innerHTML = `<img src=${item.image} alt="" /><div><h4> ${item.title} </h4><h5>$${item.price}</h5><span class="remove-item" data-id=${item.id}>remove</span></div><div><i class="fas fa-chevron-up" data-id=${item.id}></i><p class="item-amount">${item.amount}</p><i class="fas fa-chevron-down" data-id=${item.id}></i></div>`;cartContent.appendChild(div);// console.log(cart);// console.log(cartContent);}showCart() {cartOverlay.classList.add("transparentBcg");cartDOM.classList.add("showCart");}// setup AppsetupApp() {cart = Storage.getCart();this.setCartValues(cart);this.populateCart(cart);cartBtn.addEventListener("click", this.showCart);closeCartBtn.addEventListener("click", this.hideCart);}populateCart(cart) {cart.forEach(item => this.addCartItem(item));}hideCart() {cartOverlay.classList.remove("transparentBcg");cartDOM.classList.remove("showCart");}cartLogic() {// clear cart buttonclearBtn.addEventListener("click", () => {this.clearCart();});// cart functionalitycartContent.addEventListener("click", () => {if (event.target.classList.contains("remove-item")) {let removeItem = event.target;let id = removeItem.dataset.id;cartContent.removeChild(removeItem.parentElement.parentElement);this.removeItem(id);} else if (event.target.classList.contains("fa-chevron-up")) {let addAmount = event.target;let id = addAmount.dataset.id;// console.log(cart);let tempItem = cart.find(item => item.id === id);tempItem.amount = tempItem.amount + 1;Storage.saveCart(cart);this.setCartValues(cart);addAmount.nextElementSibling.innerText = tempItem.amount;} else if (event.target.classList.contains("fa-chevron-down")) {let lowerAmount = event.target;let id = lowerAmount.dataset.id;// console.log(cart);let tempItem = cart.find(item => item.id === id);tempItem.amount = tempItem.amount - 1;if (tempItem.amount > 0) {Storage.saveCart(cart);this.setCartValues(cart);lowerAmount.previousElementSibling.innerText = tempItem.amount;} else {cartContent.removeChild(lowerAmount.parentElement.parentElement);this.removeItem(id);}}});}clearCart() {let cartItems = cart.map(item => item.id);cartItems.forEach(id => this.removeItem(id));while (cartContent.children.length > 0) {cartContent.removeChild(cartContent.children[0]);}}removeItem(id) {cart = cart.filter(item => item.id !== id);this.setCartValues(cart);Storage.saveCart(cart);let button = this.getSingleButton(id);button.disabled = false;button.innerHTML = "<i class='fas fa-shopping-cart'></i> Add to cart";}getSingleButton(id) {return buttonsDOM.find(button => button.dataset.id === id);}}/*** @description class cares about adding and removing product in and from the browser local storage* contains main four functions* 1- function {@link saveProducts} saves {@link products} into the browser local storage* 2- function {@link getProducts} reads {@link products} from the browser local storage* 3- function {@link saveCart} saves {@link cart} item into the browser local storage* 4- function {@link getCart} reads products from the browser local storage* @name Storage* @class* @example const strage = new Storage();* @summary BROWSER LOCAL STORAGE CREATING/READING OPERATIONS*/class Storage {/*** @description saving products in the browser localt storage takes products array as a parameter* {@link products}* @method* @static* @inner* @name saveProducts* @this Storage* @param {Array.<Object>} pruducts to be saved* @example Storage.saveProducts(products);*/static saveProducts(products) {localStorage.setItem("products", JSON.stringify(products));}/*** @description reading products from the browser localt storage takes the id of product as a parameter* and returns product matches that array* @method* @static* @inner* @this Storage* @name getProducts* @param {number} id of item to be fetched* @example Storage.getProducts(1);* @returns {Object}*/static getProducts(id) {let products = JSON.parse(localStorage.getItem("products"));return products.find(product => product.id === id);}/*** @description saving cartItems array in the browser local storage takes the {@link cart} items array as a parameter* @method* @static* @inner* @this Storage* @name saveCart* @param {Array<Object>} cart items {@link cartItems} to be saved* @example Storage.saveCart(cart)*/static saveCart(cart) {localStorage.setItem("cart", JSON.stringify(cart));}/*** @description reading (fetching) cartItems array {@link cart} from the browser local storage* @method* @static* @inner* @name getCart* @this Storage* @param {Array<Object>}* @returns {Array.<Object>} cart* @example Storage.getCart()*/static getCart() {return localStorage.getItem("cart")? JSON.parse(localStorage.getItem("cart")): [];}}document.addEventListener("DOMContentLoaded", () => {const ui = new UI();const products = new Products();// set up methodsui.setupApp();// get all prooductsproducts.getProducts().then(products => {ui.displayProducts(products);Storage.saveProducts(products);}).then(() => {ui.getBagButtons();ui.cartLogic();});});
Source