diff --git a/package-lock.json b/package-lock.json index 80007e7..a232baa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,8 @@ "@picocss/pico": "^1.5.13", "@splidejs/splide": "^4.1.4", "aos": "^3.0.0-beta.6", - "chart.js": "^4.4.2" + "chart.js": "^4.4.2", + "jquery": "^3.7.1" }, "devDependencies": { "@babel/core": "^7.24.5", @@ -3717,6 +3718,11 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/jquery": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", + "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==" + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", diff --git a/package.json b/package.json index 2fc7821..f1ffea8 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "@picocss/pico": "^1.5.13", "@splidejs/splide": "^4.1.4", "aos": "^3.0.0-beta.6", - "chart.js": "^4.4.2" + "chart.js": "^4.4.2", + "jquery": "^3.7.1" } } diff --git a/public/js_original/cart-view.js b/public/js_original/cart-view.js index 66ad5d7..bb0abf5 100644 --- a/public/js_original/cart-view.js +++ b/public/js_original/cart-view.js @@ -1,9 +1,14 @@ /** * This script is executed on /cart page. It allows users to modify their cart in real-time and view the updated totals. + * The order of operations is as follows: + * 1. Send cart data from local storage to server to request cart page. + * 2. Display a loading animation while cart page has not been received. + * 3. Receive actual cart page and render it. Event listeners are added as needed. */ import Cart from "./models/Cart"; import CartItem from "./models/CartItem"; +import $ from "jquery"; function updateCart(e) { const sectionNode = e.target.parentNode.parentNode; @@ -90,45 +95,45 @@ function preventKeyboardInput(event) { /** * This function must be called after DOM has loaded. + * It initializes event listeners on the true cart page received from server. */ function initCartPage() { - const quantityInputs = [ - ...document.querySelectorAll("section input[type='number']"), - ]; - + // if checkout button is present on page, add click event. (button is absent when cart is empty) const checkoutBtn = document.querySelector("#checkout-btn"); - - // if checkout button is present on page (button is absent when cart is empty) if (checkoutBtn !== null) { checkoutBtn.addEventListener("click", checkout); } + // add change listeners to inputs on page + const quantityInputs = [ + ...document.querySelectorAll("section input[type='number']"), + ]; quantityInputs.forEach((input) => { input.addEventListener("change", updateCart); input.addEventListener("keydown", preventKeyboardInput); }); - const itemCount = Cart().getCartSize(); - // update cart item count in header + const itemCount = Cart().getCartSize(); document.querySelector("#mini-cart-count").textContent = `(${itemCount})`; } -async function uploadCart() { - const items = Cart().getItems(); +function uploadCart() { + const items = Cart().getItems(); // items from local storage - const response = await fetch(window.location.href + "/upload", { + $.ajax({ + url: window.location.href + "/upload", method: "POST", - body: JSON.stringify(items), + data: JSON.stringify(items), + contentType: "application/json", + success: function (response) { + // add loading delay of 1s before displaying true cart page + setTimeout(function () { + $("body").html(response); + initCartPage(); + }, 1000); + }, }); - - // add loading delay of 1s - await new Promise((r) => setTimeout(r, 1000)); - - if (response.ok) { - document.body.innerHTML = await response.text(); - initCartPage(); - } } window.addEventListener("DOMContentLoaded", uploadCart); diff --git a/public/js_original/profile-view.js b/public/js_original/profile-view.js index 63ef734..eb333cc 100644 --- a/public/js_original/profile-view.js +++ b/public/js_original/profile-view.js @@ -1,30 +1,27 @@ -function openTab(evt, tabName) { - console.log("New tab = " + tabName); +/** + * This script is responsible for implementing the tab switching logic on the user profile page. + */ +import $ from "jquery"; +function openTab(tabLinkElement, tabName) { // hide all tab contents - const tabcontents = [...document.getElementsByClassName("tabcontent")]; - for (let i = 0; i < tabcontents.length; i++) { - tabcontents[i].style.display = "none"; - } - - // remove active class from the currently active tab link - const tablinks = document.getElementsByClassName("tablink"); - for (let i = 0; i < tablinks.length; i++) { - tablinks[i].className = tablinks[i].className.replace(" active", ""); - } + $(".tabcontent").hide(); // display content for clicked tab - document.getElementById(tabName).style.display = "block"; + $("#" + tabName).show(); + + // remove active class from the currently active tab link (same as removing active class from all tab links) + $(".tablink").removeClass("active"); // set active class only to the clicked tab link - evt.currentTarget.className += " active"; + $(tabLinkElement).addClass("active"); } -const tabs = ["Account", "Orders", "Settings"]; +$(document).ready(() => { + const tabIDs = ["Account", "Orders", "Settings"]; // IDs of container for tabs -window.addEventListener("DOMContentLoaded", () => { - [...document.getElementsByClassName("tablink")].forEach((tablink, i) => { - console.log(i, tablink); - tablink.addEventListener("click", (e) => openTab(e, tabs[i])); + // when user clicks on a tab, switch to respective tab + $(".tablink").each((i, tablink) => { + $(tablink).on("click", () => openTab(tablink, tabIDs[i])); }); -}); \ No newline at end of file +});