diff --git a/.gitignore b/.gitignore index 0783cf6a..4bc66b23 100644 --- a/.gitignore +++ b/.gitignore @@ -90,4 +90,5 @@ sw.* styles/utils.scss styles/_utils.css eyeliner.js +driver.js tailwind.config.cjs diff --git a/assets/add-to-cart.js b/assets/add-to-cart.js index 3327f5ca..5fbfb0e2 100644 --- a/assets/add-to-cart.js +++ b/assets/add-to-cart.js @@ -17,9 +17,10 @@ async function addToCart() { const cart = document.querySelector('#cart-items-badge'); if (cart) { - let cartBadgeBudge = Number(cart.innerHTML); + cart.innerHTML = response.items.length; - cart.innerHTML = ++cartBadgeBudge; + addCartItemToDrawerDOM(response.items); + openDrawer('.cart-drawer'); } stopLoad('#loading__checkout'); @@ -29,3 +30,57 @@ async function addToCart() { notify(err.message, 'error'); } } + +function addCartItemToDrawerDOM(cartItems) { + const cartItemsTable = document.querySelector('.cart-items-table'); + const cartItemsTableBody = cartItemsTable.querySelector('tbody'); + const cartItemTemplate = document.querySelector('.cart__item'); + const cartItemClone = cartItemTemplate.cloneNode(true); + + cartItemsTableBody.innerHTML = ''; + + cartItems.forEach((cartItem) => { + const cartItemName = cartItemClone.querySelector('.cart__item-name'); + const cartItemPrice = cartItemClone.querySelector('.cart__item-price'); + const quantityWrapper = cartItemClone.querySelector('.quantity-wrapper'); + const cartItemImage = cartItemClone.querySelector('img'); + + cartItemClone.id = cartItem.id; + cartItemImage.setAttribute( + 'src', + cartItem.productVariant.image.url || cartItem.productVariant.product.images[0].url, + ); + + cartItemName.innerText = cartItem.productVariant.product.name; + console.log(cartItem); + cartItemName.setAttribute('href', cartItem.url); + + cartItemPrice.innerText = cartItem.price; + + quantityWrapper.innerHTML = ` +
+ +
+ +
+ +
+ `; + + cartItemsTableBody.appendChild(cartItemClone); + }); +} diff --git a/assets/cart-drawer.css b/assets/cart-drawer.css new file mode 100644 index 00000000..ac01dc19 --- /dev/null +++ b/assets/cart-drawer.css @@ -0,0 +1,9 @@ +.cart-drawer { + width: 80vw !important; + max-width: 500px !important; + padding: 0 20px !important; +} +.cart-drawer, +.cart-drawer *:not(.yc-btn):not(ion-icon) { + color: var(--yc-primary-color) !important; +} diff --git a/assets/cart-table.css b/assets/cart-table.css new file mode 100644 index 00000000..8c83d845 --- /dev/null +++ b/assets/cart-table.css @@ -0,0 +1,87 @@ +.cart-items-table { + margin-top: 17px; +} +.cart-items-table th { + text-align: start; +} +.cart-items-table thead { + border-bottom: 1px solid #eaeaea; +} +.cart-items-table thead th { + padding: 1rem 0; + font-size: 0.9rem; + font-weight: 400 !important; +} +.cart-items-table tbody td { + vertical-align: top; + padding-top: 1.5rem; +} +.cart-items-table tbody .cart-item-loader-spinner { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(255, 255, 255, 0.8); + display: flex; + justify-content: center; + align-items: center; + z-index: 8; +} +.cart-items-table tbody .cart-item-loader-spinner.hidden { + display: none !important; +} +.cart-items-table .quantity-head, +.cart-items-table .quantity-on-desktop { + display: none; +} +.cart-items-table .quantity-on-mobile { + display: table-cell; +} +@media (min-width: 768px) { + .cart-items-table .quantity-on-desktop { + display: table-cell; + } + .cart-items-table .quantity-head { + display: block; + } +} +.cart-items-table.mobile .quantity-head { + display: none; +} +.cart-items-table.desktop .quantity-head { + display: block; +} +.cart-items-table .quantity-wrapper { + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.11); + width: fit-content; + border: 1px solid var(--yc-primary-color); + display: flex; + align-items: center; +} +.cart-items-table .quantity-wrapper button { + width: 37px !important; + min-width: 37px !important; + max-width: 37px !important; + height: 37px !important; + min-height: 37px !important; + max-height: 37px !important; +} +.cart-items-table .quantity-wrapper input { + width: 37px !important; + min-width: 37px !important; + max-width: 37px !important; + height: 37px !important; + min-height: 37px !important; + max-height: 37px !important; + box-shadow: none !important; + border: 1px solid var(--yc-primary-color) !important; + border-top: none !important; + border-bottom: none !important; + margin: 0 !important; + padding: 0 !important; + display: flex; + align-items: center; + justify-content: center; + text-align: center; +} diff --git a/assets/cart-table.js b/assets/cart-table.js new file mode 100644 index 00000000..81cb0c6e --- /dev/null +++ b/assets/cart-table.js @@ -0,0 +1,120 @@ +function updateDOM(cartItemId, productVariantId, quantity) { + const inputHolder = document.getElementById(cartItemId); + const input = inputHolder.querySelector(`input[id="${productVariantId}"]`); + console.log(input, productVariantId); + input.value = quantity; + const decrease = input.previousElementSibling; + const increase = input.nextElementSibling; + + decrease + .querySelector('button') + .setAttribute('onclick', `decreaseQuantity('${cartItemId}', '${productVariantId}', '${Number(quantity) - 1}')`); + increase + .querySelector('button') + .setAttribute('onclick', `increaseQuantity('${cartItemId}', '${productVariantId}', '${Number(quantity) + 1}')`); +} + +async function updateQuantity(cartItemId, productVariantId, quantity) { + load(`#loading__${cartItemId}`); + try { + await youcanjs.cart.updateItem({ cartItemId, productVariantId, quantity }); + } catch (e) { + notify(e.message, 'error'); + } finally { + stopLoad(`#loading__${cartItemId}`); + } + updateDOM(cartItemId, productVariantId, quantity); +} + +async function updateOnchange(cartItemId, productVariantId) { + const inputHolder = document.getElementById(cartItemId); + const input = inputHolder.querySelector(`input[id="${productVariantId}"]`); + const quantity = input.value; + + await updateQuantity(cartItemId, productVariantId, quantity); + updateDOM(cartItemId, productVariantId, quantity); +} + +async function decreaseQuantity(cartItemId, productVariantId, quantity) { + if (quantity < 1) { + return; + } + await updateQuantity(cartItemId, productVariantId, quantity); +} + +async function increaseQuantity(cartItemId, productVariantId, quantity) { + await updateQuantity(cartItemId, productVariantId, quantity); +} + +async function removeItem(cartItemId, productVariantId) { + load(`#loading__${cartItemId}`); + try { + await youcanjs.cart.removeItem({ cartItemId, productVariantId }); + document.getElementById(cartItemId).remove(); + + const cartItemsBadge = document.getElementById('cart-items-badge'); + + const cartItems = document.querySelectorAll('.cart__item'); + + if (cartItemsBadge) { + cartItemsBadge.innerText = parseInt(cartItemsBadge.innerText) + 1; + } + + if (cartItems.length === 0) { + if (cartItemsBadge) { + cartItemsBadge.innerText = 0; + } + document.querySelector('.cart-table').remove(); + document.querySelector('.empty-cart').classList.remove('hidden'); + } + } catch (e) { + notify(e.message, 'error'); + } finally { + stopLoad(`#loading__${cartItemId}`); + } +} + +function moveQuantityWrapper() { + const cartItemsTable = document.querySelector('.cart-items-table'); + const cartItemsTableWidth = cartItemsTable ? cartItemsTable.offsetWidth : 0; + + const mobileBreakpoint = 768; + + const quantityWrapper = document.querySelector('.quantity-wrapper'); + const quantityOnDesktop = document.querySelector('.quantity-on-desktop'); + const quantityOnMobile = document.querySelector('.quantity-on-mobile'); + + if (window.innerWidth > mobileBreakpoint || cartItemsTableWidth > 500) { + quantityOnDesktop.appendChild(quantityWrapper); + + if (quantityOnMobile.contains(quantityWrapper)) { + quantityOnMobile.removeChild(quantityWrapper); + } + + if (cartItemsTable.classList.contains('mobile')) { + cartItemsTable.classList.remove('mobile'); + } + + if (!cartItemsTable.classList.contains('desktop')) { + cartItemsTable.classList.add('desktop'); + } + } + if (window.innerWidth < mobileBreakpoint || cartItemsTableWidth < 500) { + quantityOnMobile.appendChild(quantityWrapper); + + if (quantityOnDesktop.contains(quantityWrapper)) { + quantityOnDesktop.removeChild(quantityWrapper); + } + + if (!cartItemsTable.classList.contains('mobile')) { + cartItemsTable.classList.add('mobile'); + } + + if (cartItemsTable.classList.contains('desktop')) { + cartItemsTable.classList.remove('desktop'); + } + } +} + +moveQuantityWrapper(); +window.addEventListener('resize', moveQuantityWrapper); diff --git a/assets/cart.css b/assets/cart.css index 3a68dbbf..78dddbc9 100644 --- a/assets/cart.css +++ b/assets/cart.css @@ -9,69 +9,3 @@ max-width: 100%; min-width: 22rem; } -.yc-cart .cart-table th { - text-align: start; -} -.yc-cart .cart-table thead { - border-bottom: 1px solid #eaeaea; -} -.yc-cart .cart-table thead th { - padding: 1rem 0; - font-size: 0.9rem; - font-weight: 400 !important; -} -.yc-cart .cart-table tbody td { - vertical-align: top; - padding-top: 1.5rem; -} -.yc-cart .cart-table tbody .cart-item-loader-spinner { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgba(255, 255, 255, 0.8); - display: flex; - justify-content: center; - align-items: center; - z-index: 8; -} -.yc-cart .cart-table tbody .cart-item-loader-spinner.hidden { - display: none !important; -} -.yc-cart table { - margin-top: 17px; -} -.yc-cart .quantity-wrapper { - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.11); - width: fit-content; - border: 1px solid var(--yc-primary-color); - display: flex; - align-items: center; -} -.yc-cart .quantity-wrapper button { - width: 37px !important; - min-width: 37px !important; - max-width: 37px !important; - height: 37px !important; - min-height: 37px !important; - max-height: 37px !important; -} -.yc-cart .quantity-wrapper input { - width: 37px !important; - min-width: 37px !important; - max-width: 37px !important; - height: 37px !important; - min-height: 37px !important; - max-height: 37px !important; - box-shadow: none !important; - border: 1px solid var(--yc-primary-color) !important; - border-top: none !important; - border-bottom: none !important; - margin: 0 !important; - padding: 0 !important; - display: flex; - align-items: center; - justify-content: center; - text-align: center; -} diff --git a/assets/cart.js b/assets/cart.js index 4b0ed5ad..77bcc0ae 100644 --- a/assets/cart.js +++ b/assets/cart.js @@ -15,102 +15,3 @@ async function addPromo(e) { stopLoad('#loading__coupon'); } } - -function updateDOM(cartItemId, productVariantId, quantity) { - const inputHolder = document.getElementById(cartItemId); - const input = inputHolder.querySelector(`input[id="${productVariantId}"]`); - input.value = quantity; - const decrease = input.previousElementSibling; - const increase = input.nextElementSibling; - - decrease - .querySelector('button') - .setAttribute('onclick', `decreaseQuantity('${cartItemId}', '${productVariantId}', '${Number(quantity) - 1}')`); - increase - .querySelector('button') - .setAttribute('onclick', `increaseQuantity('${cartItemId}', '${productVariantId}', '${Number(quantity) + 1}')`); -} - -async function updateQuantity(cartItemId, productVariantId, quantity) { - load(`#loading__${cartItemId}`); - try { - await youcanjs.cart.updateItem({ cartItemId, productVariantId, quantity }); - } catch (e) { - notify(e.message, 'error'); - } finally { - stopLoad(`#loading__${cartItemId}`); - } - updateDOM(cartItemId, productVariantId, quantity); -} - -async function updateOnchange(cartItemId, productVariantId) { - const inputHolder = document.getElementById(cartItemId); - const input = inputHolder.querySelector(`input[id="${productVariantId}"]`); - const quantity = input.value; - - await updateQuantity(cartItemId, productVariantId, quantity); - updateDOM(cartItemId, productVariantId, quantity); -} - -async function decreaseQuantity(cartItemId, productVariantId, quantity) { - if (quantity < 1) { - return; - } - await updateQuantity(cartItemId, productVariantId, quantity); -} - -async function increaseQuantity(cartItemId, productVariantId, quantity) { - await updateQuantity(cartItemId, productVariantId, quantity); -} - -async function removeItem(cartItemId, productVariantId) { - load(`#loading__${cartItemId}`); - try { - await youcanjs.cart.removeItem({ cartItemId, productVariantId }); - document.getElementById(cartItemId).remove(); - - const cartItemsBadge = document.getElementById('cart-items-badge'); - - const cartItems = document.querySelectorAll('.cart__item'); - - if (cartItemsBadge) { - cartItemsBadge.innerText = parseInt(cartItemsBadge.innerText) + 1; - } - - if (cartItems.length === 0) { - if (cartItemsBadge) { - cartItemsBadge.innerText = 0; - } - document.querySelector('.cart-table').remove(); - document.querySelector('.empty-cart').classList.remove('hidden'); - } - } catch (e) { - notify(e.message, 'error'); - } finally { - stopLoad(`#loading__${cartItemId}`); - } -} - -function moveQuantityWrapper() { - const quantityWrapper = document.querySelector('.quantity-wrapper'); - const quantityOnDesktop = document.querySelector('.quantity-on-desktop'); - const quantityOnMobile = document.querySelector('.quantity-on-mobile'); - - if (window.innerWidth > 768) { - quantityOnDesktop.appendChild(quantityWrapper); - - if (quantityOnMobile.contains(quantityWrapper)) { - quantityOnMobile.removeChild(quantityWrapper); - } - } - if (window.innerWidth < 768) { - quantityOnMobile.appendChild(quantityWrapper); - - if (quantityOnDesktop.contains(quantityWrapper)) { - quantityOnDesktop.removeChild(quantityWrapper); - } - } -} - -moveQuantityWrapper(); -window.addEventListener('resize', moveQuantityWrapper); diff --git a/assets/main.js b/assets/main.js index 54d4a47c..15b32454 100644 --- a/assets/main.js +++ b/assets/main.js @@ -78,25 +78,36 @@ function notify(msg, type = 'success', timeout = 3000) { /* ----- navigation-drawer ----- */ /* ----------------------------- */ const overlay = document.querySelector('.global-overlay'); -const drawer = document.querySelector('.navigation-drawer'); +const drawers = document.querySelectorAll('.navigation-drawer'); if (overlay) { overlay.addEventListener('click', function (e) { if (e.target === overlay) { overlay.style.visibility = 'hidden'; overlay.style.opacity = '0'; - drawer.style.transform = 'translateX(-150vw)'; + + drawers.forEach((drawer) => { + drawer.classList.contains('right') + ? (drawer.style.transform = 'translateX(150vw)') + : (drawer.style.transform = 'translateX(-150vw)'); + + drawer.style.opacity = '0'; + drawer.style.visibility = 'hidden'; + }); } }); } function openDrawer(el) { const targetedDrawer = document.querySelector(`.navigation-drawer${el}`); + if (targetedDrawer) { overlay.style.visibility = 'visible'; overlay.style.opacity = '1'; + targetedDrawer.style.transform = 'none'; targetedDrawer.style.opacity = '1'; + targetedDrawer.style.visibility = 'visible'; } } diff --git a/assets/navbar.css b/assets/navbar.css index fc0e9182..2b9ee892 100644 --- a/assets/navbar.css +++ b/assets/navbar.css @@ -178,7 +178,6 @@ .navigation-drawer { background-color: var(--yc-drawer-background); transition-duration: 0.2s; - transition-property: opacity, transform; transform: translateX(-150vw); position: fixed; left: 0; @@ -188,6 +187,11 @@ opacity: 0; z-index: 99; } +.navigation-drawer.right { + left: auto; + right: 0; + transform: translateX(150vw); +} .navigation-drawer .logo { padding: 3rem 1rem; } diff --git a/assets/utils.css b/assets/utils.css index 0825d165..39dd3889 100644 --- a/assets/utils.css +++ b/assets/utils.css @@ -264,10 +264,6 @@ video { margin-top: 0.25rem; } -.mt-7 { - margin-top: 1.75rem; -} - .mt-5 { margin-top: 1.25rem; } @@ -284,6 +280,10 @@ video { margin-top: -0.25rem; } +.mt-7 { + margin-top: 1.75rem; +} + .mt-8 { margin-top: 2rem; } @@ -312,19 +312,24 @@ video { height: 100%; } -.h-9 { - height: 2.25rem; -} - .h-fit { height: -moz-fit-content; height: fit-content; } +.h-9 { + height: 2.25rem; +} + .w-full { width: 100%; } +.w-fit { + width: -moz-fit-content; + width: fit-content; +} + .w-9 { width: 2.25rem; } @@ -333,11 +338,6 @@ video { width: 6rem; } -.w-fit { - width: -moz-fit-content; - width: fit-content; -} - .table-auto { table-layout: auto; } @@ -370,26 +370,26 @@ video { gap: 3.5rem; } -.gap-6 { - gap: 1.5rem; -} - -.gap-3 { - gap: 0.75rem; +.gap-2 { + gap: 0.5rem; } .gap-1 { gap: 0.25rem; } -.gap-2 { - gap: 0.5rem; +.gap-3 { + gap: 0.75rem; } .gap-10 { gap: 2.5rem; } +.gap-6 { + gap: 1.5rem; +} + .self-baseline { align-self: baseline; } @@ -450,11 +450,6 @@ video { line-height: 2.5rem; } -.text-base { - font-size: 1rem; - line-height: 1.5rem; -} - .text-2xl { font-size: 1.5rem; line-height: 2rem; @@ -480,6 +475,11 @@ video { line-height: 1.75rem; } +.text-base { + font-size: 1rem; + line-height: 1.5rem; +} + .capitalize { text-transform: capitalize; } @@ -493,12 +493,6 @@ video { } @media (min-width: 768px) { - .md\:block { - display: block; - } - .md\:table-cell { - display: table-cell; - } .md\:hidden { display: none; } diff --git a/config/settings_data.json b/config/settings_data.json index cc934403..d2e98d83 100644 --- a/config/settings_data.json +++ b/config/settings_data.json @@ -1,14 +1,10 @@ { "current": { - "font_family": "Cairo", - "theme_direction": "ltr", - "primary_color": "#030303FF", - "navbar_logo": "xkQ9K8c7A4PKLqgcZlsMC5zcCwMxDl4B46DJhudA-2IqyMhNuxyIpY6fTgnIwkOhpR7T.png", - "navbar_background_color": "#000000FF", - "navbar_links_color": "#FFFFFFFF", - "navbar_height": 85 + "font_family": "Cairo" }, "presets": { - "Default": {} + "Default": { + "font_family": "Cairo" + } } } diff --git a/config/settings_schema.json b/config/settings_schema.json index 973f68e7..dd4a0f33 100644 --- a/config/settings_schema.json +++ b/config/settings_schema.json @@ -731,7 +731,7 @@ "label": "Bottom left" } ], - "default": "top-right" + "default": "bottom-left" }, { "type": "range", diff --git a/layouts/theme.liquid b/layouts/theme.liquid index c393f963..7cf6bca2 100644 --- a/layouts/theme.liquid +++ b/layouts/theme.liquid @@ -13,6 +13,7 @@ {%- render 'overlay' -%} {%- render 'alert' -%} + {%- render 'cart-drawer' -%} {{ content_for_layout }} diff --git a/sections/main-cart.liquid b/sections/main-cart.liquid index 17d85172..ed31445e 100644 --- a/sections/main-cart.liquid +++ b/sections/main-cart.liquid @@ -1,4 +1,5 @@ {{ 'cart.css' | asset_url | stylesheet_tag }} +{{ 'cart-table.css' | asset_url | stylesheet_tag }}
{%- if cart and cart.items %} @@ -10,62 +11,7 @@

- - - - - - - - - - {%- for item in cart.items %} - - - - - - {%- endfor %} - -
{{ 'cart.items.total' | t }}
- -
- product-name -
-
- {{ item.name }} -
-
{{ item.price | money }}
-
- -
-
{{ item.price | times: item.quantity | money }}
+ {%- render 'cart-table', cart: cart -%} {{ 'cart.js' | asset_url | script_tag_deferred }} +{{ 'cart-table.js' | asset_url | script_tag_deferred }} {% schema %} { diff --git a/sections/main-navbar.liquid b/sections/main-navbar.liquid index 60f5e3db..fa2d5264 100644 --- a/sections/main-navbar.liquid +++ b/sections/main-navbar.liquid @@ -56,15 +56,16 @@
- {{- cart.items | size -}} - +
diff --git a/snippets/cart-table.liquid b/snippets/cart-table.liquid new file mode 100644 index 00000000..2b686ab4 --- /dev/null +++ b/snippets/cart-table.liquid @@ -0,0 +1,60 @@ +{{ 'cart-table.css' | asset_url | stylesheet_tag }} + + + + + + + + + + + {%- for item in cart.items %} + + + + + + {%- endfor %} + +
+ {{ 'cart.items.quantity' | t }} + {{ 'cart.items.total' | t }}
+ +
+ product-name +
+
+ {{ item.name }} +
+
{{ item.price | money }}
+
+ +
+
+ {%- render 'quantity-input', item: item -%} + {{ item.price | times: item.quantity }}
+ +{{ 'cart-table.js' | asset_url | script_tag_deferred }} diff --git a/snippets/head-config.liquid b/snippets/head-config.liquid index ed13152a..ede19b6f 100644 --- a/snippets/head-config.liquid +++ b/snippets/head-config.liquid @@ -138,6 +138,11 @@ {%- endif -%} } {%- endstyle -%} + {%- if settings.favicon %}