Skip to content
This repository has been archived by the owner on Jul 18, 2024. It is now read-only.

Snippets > cart drawer #120

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,5 @@ sw.*
styles/utils.scss
styles/_utils.css
eyeliner.js
driver.js
tailwind.config.cjs
59 changes: 57 additions & 2 deletions assets/add-to-cart.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand All @@ -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 = `
<div class='decrease'>
<button onclick="decreaseQuantity('${cartItem.id}',
'${cartItem.productVariant.id}',
'${(cartItem.quantity <= 0 ? 1 : cartItem.quantity) - 1}')"
>
-
</button>
</div>
<input
onchange="updateOnchange('${cartItem.id}', '${cartItem.productVariant.id}')"
type='text'
value='${cartItem.quantity}'
id='6baf66d1-b440-41b8-97b4-56daaaf96e94'>
<div class='increase'>
<button onclick="increaseQuantity('${cartItem.id}',
'${cartItem.productVariant.id}',
'${cartItem.quantity + 1}')"
>
+
</button>
</div>
`;

cartItemsTableBody.appendChild(cartItemClone);
});
}
9 changes: 9 additions & 0 deletions assets/cart-drawer.css
Original file line number Diff line number Diff line change
@@ -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;
}
87 changes: 87 additions & 0 deletions assets/cart-table.css
Original file line number Diff line number Diff line change
@@ -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;
}
120 changes: 120 additions & 0 deletions assets/cart-table.js
Original file line number Diff line number Diff line change
@@ -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);
66 changes: 0 additions & 66 deletions assets/cart.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Loading