diff --git a/public/js_original/cart-view.js b/public/js_original/cart-view.js index dc5cca23..1b1eb18f 100644 --- a/public/js_original/cart-view.js +++ b/public/js_original/cart-view.js @@ -4,7 +4,6 @@ import Cart from "./models/Cart"; import CartItem from "./models/CartItem"; -import ModalManager from "./modal"; function updateCart(e) { const sectionNode = e.target.parentNode.parentNode; @@ -50,6 +49,9 @@ function updateCart(e) { } async function checkout() { + // set loading animation on checkout button to prevent multiple form submissions + document.querySelector("#checkout-btn").setAttribute("aria-busy", "true"); + const myCart = Cart(); const items = myCart.getItems(); @@ -63,10 +65,14 @@ async function checkout() { body: JSON.stringify(data), }); + // stop loading animation + document.querySelector("#checkout-btn").removeAttribute("aria-busy"); + if (response.ok) { // Clear cart items from localStorage if checkout is successful myCart.clear(); - ModalManager("my-modal").openModal(); + + document.querySelector("#my-modal").setAttribute("open", ""); return; } const x = await response.json(); @@ -85,9 +91,12 @@ function initCartPage() { ...document.querySelectorAll("section input[type='number']"), ]; - ModalManager("my-modal").init(); + const checkoutBtn = document.querySelector("#checkout-btn"); - document.querySelector("#checkout-btn").addEventListener("click", checkout); + // if checkout button is present on page (button is absent when cart is empty) + if (checkoutBtn !== null) { + checkoutBtn.addEventListener("click", checkout); + } quantityInputs.forEach((input) => { input.addEventListener("change", updateCart); diff --git a/public/js_original/profile-view.js b/public/js_original/profile-view.js new file mode 100644 index 00000000..63ef7341 --- /dev/null +++ b/public/js_original/profile-view.js @@ -0,0 +1,30 @@ +function openTab(evt, tabName) { + console.log("New tab = " + 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", ""); + } + + // display content for clicked tab + document.getElementById(tabName).style.display = "block"; + + // set active class only to the clicked tab link + evt.currentTarget.className += " active"; +} + +const tabs = ["Account", "Orders", "Settings"]; + +window.addEventListener("DOMContentLoaded", () => { + [...document.getElementsByClassName("tablink")].forEach((tablink, i) => { + console.log(i, tablink); + tablink.addEventListener("click", (e) => openTab(e, tabs[i])); + }); +}); \ No newline at end of file diff --git a/public/styles/views/Profile.css b/public/styles/views/Profile.css index dd8bc4cb..f89067b5 100644 --- a/public/styles/views/Profile.css +++ b/public/styles/views/Profile.css @@ -18,11 +18,32 @@ button[name="account_delete_submit"] { background-color: red; } -table button{ - padding:5px; +table button { + padding: 5px; } -table tr button:first-of-type{ +table tr button:first-of-type { border: 0; background-color: red; +} + +/* Style tab links */ +.tablink { + float: left; + border: none; + outline: none; + cursor: pointer; + font-size: 17px; + background-color: var(--secondary); +} + +.active { + background-color: var(--contrast); + color: var(--contrast-inverse); +} + +/* Style the tab content (and add height:100% for full page content) */ +.tabcontent { + display: none; + padding: 20px 0; } \ No newline at end of file diff --git a/src/controllers/Cart.php b/src/controllers/Cart.php index aec8d85c..58588ad4 100644 --- a/src/controllers/Cart.php +++ b/src/controllers/Cart.php @@ -5,6 +5,7 @@ namespace Steamy\Controller; use Exception; +use PDOException; use Steamy\Core\Controller; use Steamy\Core\Utility; use Steamy\Model\Order; @@ -110,13 +111,17 @@ private function handleCheckout(): void // attempt to save order. An exception will be generated in case of any errors. try { $success_order = $new_order->save(); + } catch (PDOException $e) { + error_log($e->getMessage()); + http_response_code(503); + echo json_encode(['error' => 'Database error: ' . $e->getMessage()]); + return; } catch (Exception $e) { error_log($e->getMessage()); - http_response_code(500); + http_response_code(400); echo json_encode(['error' => $e->getMessage()]); return; } - // if order was unsuccessfully saved without any exceptions generated if (!$success_order) { http_response_code(500); @@ -137,6 +142,9 @@ private function handleCheckout(): void http_response_code(503); echo json_encode(['error' => "Order was saved but email could not be sent for an unknown reason."]); } + + // if everything is good, tell client to reset the document view + http_response_code(205); } public function index(): void diff --git a/src/views/Cart.php b/src/views/Cart.php index e29a73dc..4948ddd6 100644 --- a/src/views/Cart.php +++ b/src/views/Cart.php @@ -16,24 +16,11 @@ ?>
- -

Checkout successful! ✨

+

Your order has been successfully placed and an email has been sent to you.