Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature/134-cart-layout Cart layout #134 #270

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from
Open
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
118 changes: 115 additions & 3 deletions src/components/cart/cart.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { roundNumber } from '../../js/utils';
import cartItemsTemplate from '../../pages/cart/cart-items.hbs';
import cartMoneyBoxTemplate from '../../pages/cart/cart-moneybox.hbs';
import cartQuanitySummaryTemplate from '../../pages/cart/cart-quantity-summary.hbs';
import * as Modal from '../../components/modal/modal';

function pushCartUpdatedEvent(detail){
const event = new CustomEvent('update:cart', { detail });
Expand Down Expand Up @@ -30,7 +34,6 @@ function getCartSubtotal(cartItems){
return accumulator + Number(cartItem.total_price);
}, 0);
}

function addToCart(newCartItem){
let cart = getCartFromStorage();
cart.cartIndex++;
Expand All @@ -39,7 +42,6 @@ function addToCart(newCartItem){
cart.cartItems.push(newCartItem);
updateCart(cart);
}

function removeFromCart(itemId) {
let cart = getCartFromStorage();
const updatedCartItems = cart.cartItems.filter(function(cartItem){
Expand All @@ -48,13 +50,123 @@ function removeFromCart(itemId) {
cart.cartItems = updatedCartItems;
updateCart(cart);
}
function removeItemFromCart(cartItemsEl) {
const removeItems = cartItemsEl.querySelectorAll('[data-remove]');
if (removeItems) {
removeItems.forEach(el => {
el.addEventListener('click', (event) => {
removeFromCart(event.target.dataset.remove);
event.stopPropagation();
});
});
}
}
/*
* function will be called on increase and decrease click event and on quantity input change event
*
* @function changeItemQuantity
* @param event
* @param {element} - cartIemsEL - will contain [data-template="cart-items"] element
* @param {String} - eventType - to indentify the event type
*
*/
function changeItemQuantity(event, cartItemsEl, eventType) {
let cart = getCartFromStorage();
let cartItems = cart.cartItems;
cartItems.forEach(cartItem => {
if (cartItem.cart_id == event.target.dataset.eventCartId) {
let itemEl = cartItemsEl.querySelector('li[data-cart-id="' + cartItem.cart_id + '"')
let quantityInput = itemEl.querySelector('[data-js="quantity"]');

if (eventType != 'onChange') {
if (eventType === "increment") {
quantityInput.value++;
} else {
quantityInput.value--;
}
}
// set quantity value to 1 if quantity is negative value
cartItem.quantity = quantityInput.value < 0 ? 1 : quantityInput.value;
cartItem.total_price = roundNumber(parseInt(cartItem.quantity ) * Number(cartItem.price_sale)).toFixed(2);
itemEl.querySelector(".cart-items__column .detail__price").innerHTML = `$${cartItem.total_price}`;
// remove item if quantity is 0
if (cartItem.quantity == 0) {
setTimeout(function(){
removeFromCart(cartItem.cart_id);
}, 300);
return;
}
updateCart(cart);
}
});
}
/*
* function will load/refresh the cart page on page load and change event
*
* @function loadCard
* @param {Object} - cart // will contain card data
*
*/
function loadCart(cart) {
const cartItemsEl = document.querySelector('[data-template="cart-items"]');
const cartMoneyBoxEl = document.querySelector('[data-template="cart-moneybox"]');
const cartQuantitySummaryEl = document.querySelector('[data-template="cart-quantity-summary"]');

if (cartItemsEl && cartMoneyBoxEl) {
cartItemsEl.outerHTML = cartItemsTemplate(cart);
cartMoneyBoxEl.outerHTML = cartMoneyBoxTemplate(cart);
cartQuantitySummaryEl.innerHTML = cartQuanitySummaryTemplate(cart);
init();
}
}
function updateCart(cart) {
cart.cartItemCount = getCartItemCount(cart.cartItems);
cart.cartSubtotal = getCartSubtotal(cart.cartItems).toFixed(2);
cart.cartItemsLabel = (cart.cartItemCount === 1) ? 'item' : 'items';
putCartInStorage(cart);
pushCartUpdatedEvent(cart);
loadCart(cart);
}
/*
* function will be called on page load and change event
*
* @function init
*
*/
function init(){
Modal.init('construction-modal');
const cartItemsEl = document.querySelector('[data-template="cart-items"]');

if (cartItemsEl) {
const increment = cartItemsEl.querySelectorAll('.quantity-comp__increase');
const decrement = cartItemsEl.querySelectorAll('.quantity-comp__decrease');
const quantityInput = document.querySelectorAll('[data-js="quantity"]');

increment.forEach(el => {
el.addEventListener('click', function (event) {
event.preventDefault();
changeItemQuantity(event, cartItemsEl, "increment");
});
});

decrement.forEach(el => {
el.addEventListener('click', function (event) {
event.preventDefault();
changeItemQuantity(event, cartItemsEl, "decrement");
});
});

quantityInput.forEach(el => {
el.addEventListener('click', function (event) {
event.preventDefault();
})
el.addEventListener('change', function (event) {
changeItemQuantity(event, cartItemsEl, "onChange");
});
});

removeItemFromCart(cartItemsEl);
}
}

export { addToCart, getCartFromStorage, removeFromCart, getCartSubtotal };
export { init, addToCart, getCartFromStorage, removeFromCart, getCartSubtotal, loadCart };
2 changes: 1 addition & 1 deletion src/components/mini-cart/mini-cart.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

<div data-template="mini-cart-items" class="mini-cart__items"></div>
<div class="mini-cart__summary-controls">
<a href="{{rootPath}}/cart/index.html" class="mini-cart__cta-btn btn btn--outline-black" data-modal-show="construction-modal">View Cart</a>
<a href="{{rootPath}}/cart/index.html" class="mini-cart__cta-btn btn btn--outline-black">View Cart</a>
<a href="{{rootPath}}/checkout/index.html" class="mini-cart__cta-btn mini-cart__checkout btn btn--primary">Checkout</a>
</div>
</div>
Binary file added src/images/easy-return-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/truck-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
88 changes: 83 additions & 5 deletions src/pages/cart/cart-items.hbs
Original file line number Diff line number Diff line change
@@ -1,5 +1,83 @@
<ul>
{{#each cartItems}}
<li>{{product_name}}</li>
{{/each}}
</ul>
<div class="cart-items" data-template="cart-items">
<h2 class="heading heading--section">Items in Cart</h2>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per BEM, should this be .cart-items__heading?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are other places it was used like this so I just copied and pasted
like in
cart-moneyBox.hbs
product-sort.hbs
product-filter.hbs

Do you still want me to changes?
if yes
is this ok?

<h2 class="cart-items__heading heading--section">Items in Cart</h2>

<ul class="cart-items__item-list">
{{#each cartItems}}
<li class="cart-items__item" data-cart-id="{{cart_id}}">
<a class="cart-items__item-link" href="../pdp/index.html?product_id={{product_id}}" aria-label="Shirt Malo.
Size: Medium, Color: blue, quantity: {{quantity}}, Item unit price: ${{price_sale}}, Item total price: ${{total_price}}">
<img class="cart-items__image" alt="" src="{{../rootPath}}/{{thumbnail_url}}">
<div class="cart-items__description">
<p class="cart-items__item-title">{{product_name}}</p>
<dl class="cart-items__details">
<div class="cart-items__detail">
<dt>Price</dt>
<dd class="detail__price">${{price_sale}}</dd>
</div>
<div class="cart-items__detail">
<dt>Color</dt>
<dd>{{color}}</dd>
</div>
<div class="cart-items__detail">
<dt>Size</dt>
<dd>{{size}}</dd>
</div>
</dl>
<dl class="cart-items__details">
<div class="cart-items__detail cart-items__column">
<dt>Quantity</dt>
<dd>
<span class="quantity-comp">
<button class="quantity-comp__decrease btn btn--black-inverted btn--icon" type="button" data-event-cart-id="{{cart_id}}">
<span class="sr-only">Decrease quantity</span>
<svg class="icon icon--ruler">
<use xlink:href="../sprite.svg#remove"></use>
</svg>
</button>
<!-- <label for="quantity">Qty:</label> -->
<input type="test" aria-label="quantity" value="{{quantity}}" class="quantity-comp__text" name="quantity"
id="quantity" data-js="quantity" data-event-cart-id="{{cart_id}}">
<span aria-live="assertive" aria-atomic="true" class="element-invisible quantity-comp__aria">Quantity is
now
<span> {{quantity}} </span></span>
<button class="quantity-comp__increase btn btn--black-inverted btn--icon" type="button" data-event-cart-id="{{cart_id}}">
<span class="sr-only">Increase quantity</span>
<svg class="icon icon--ruler">
<use xlink:href="../sprite.svg#add"></use>
</svg>
</button>
</span>
</dd>
</div>
</dl>
<dl class="cart-items__details">
<div class="cart-items__detail cart-items__column">
<dt>Item Total</dt>
<dd class="detail__price">${{total_price}}</dd>
</div>
</dl>
</div>
</a>
<div class="cart-items__controls">
<button class="cart-items__control btn--link" data-remove="{{cart_id}}">
<svg class="icon mini-cart__control-icon">
<use xlink:href="{{../rootPath}}/sprite.svg#trash"></use>
</svg>
Remove <span class="sr-only">item</span>
</button>
<a class="cart-items__control btn--link" href="../pdp/index.html?product_id={{product_id}}">
<svg class="icon mini-cart__control-icon">
<use xlink:href="{{../rootPath}}/sprite.svg#edit"></use>
</svg>
Edit <span class="sr-only">item</span>
</a>
<button class="cart-items__control btn--link" data-modal-show="construction-modal">
<svg class="icon mini-cart__control-icon icon--heart-outline">
<use xlink:href="{{../rootPath}}/sprite.svg#heart"></use>
</svg>
Save <span class="sr-only">to wish list</span>
</button>
</div>
</li>
{{/each}}
</ul>
</div>
24 changes: 24 additions & 0 deletions src/pages/cart/cart-moneybox.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<div class="cart-moneybox" data-template="cart-moneybox">
<h2 class="heading heading--section">Cost of Cart</h2>
<div class="cart-moneybox__summary-subtotal--header">
<p class="cart-moneybox__subtotal-title">Subtotal</p>
<p class="cart-moneybox__subtotal">${{cartSubtotal}}</p>
</div>
<div class="cart-moneybox__summary-subtotal">
<p class="cart-moneybox__subtotal-title">Shipping estimate</p>
<p class="cart-moneybox__subtotal">Free</p>
</div>
<div class="cart-moneybox__summary-subtotal">
<p class="cart-moneybox__subtotal-title">Taxes estimate</p>
<p class="cart-moneybox__subtotal">$0.00</p>
</div>
<hr class="divider">
<div class="cart-moneybox__summary-subtotal">
<p class="cart-moneybox__subtotal-title">Estimated Total</p>
<p class="cart-moneybox__subtotal">${{cartSubtotal}}</p>
</div>
<div class="cart-moneybox__summary-controls">
<a href="../plp/index.html" class="cart-moneybox__cta-btn btn btn--outline-black">Continue Shopping</a>
<a href="../checkout/index.html" class="cart-moneybox__cta-btn cart-moneybox__checkout btn btn--primary">Pay Securely Now</a>
</div>
</div>
9 changes: 4 additions & 5 deletions src/pages/cart/cart-page.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { getCartFromStorage } from '../../components/cart/cart';
import cartItemsTemplate from './cart-items.hbs';
import { getCartFromStorage, loadCart} from '../../components/cart/cart';

(function cartPage() {
const cartData = getCartFromStorage();
const cartItemsEl = document.querySelector('[data-template="cart-items"]');
cartItemsEl.outerHTML = cartItemsTemplate(cartData);
})();
// load card data on page load
loadCart(cartData);
})();
2 changes: 2 additions & 0 deletions src/pages/cart/cart-quantity-summary.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<h1 class="template-heading">Your Cart</h1>
<p class="cart__total-quantity">You have {{cartItemCount}} {{cartItemsLabel}} in your cart. Estimated total is ${{cartSubtotal}}.</p>
Loading