Skip to content

Commit

Permalink
Adds building a shopping cart
Browse files Browse the repository at this point in the history
  • Loading branch information
fullStackRacc committed Mar 25, 2024
1 parent e60785b commit ed250a9
Show file tree
Hide file tree
Showing 3 changed files with 341 additions and 0 deletions.
30 changes: 30 additions & 0 deletions building-a-shopping-cart/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>freeCodeCamp Shopping Cart</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<header>
<h1 class="title">Desserts Page</h1>
</header>
<main>
<button id="cart-btn" type="button" class="btn">
<span id="show-hide-cart">Show</span> Cart
</button>
<div id="cart-container">
<button class="btn" id="clear-cart-btn">Clear Cart</button>
<div id="products-container"></div>
<p>Total number of items: <span id="total-items">0</span></p>
<p>Subtotal: <span id="subtotal">$0</span></p>
<p>Taxes: <span id="taxes">$0</span></p>
<p>Total: <span id="total">$0</span></p>
</div>
<div id="dessert-card-container"></div>
</main>
<script src="./script.js"></script>
</body>
</html>
195 changes: 195 additions & 0 deletions building-a-shopping-cart/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
const cartContainer = document.getElementById("cart-container");
const productsContainer = document.getElementById("products-container");
const dessertCards = document.getElementById("dessert-card-container");
const cartBtn = document.getElementById("cart-btn");
const clearCartBtn = document.getElementById("clear-cart-btn");
const totalNumberOfItems = document.getElementById("total-items");
const cartSubTotal = document.getElementById("subtotal");
const cartTaxes = document.getElementById("taxes");
const cartTotal = document.getElementById("total");
const showHideCartSpan = document.getElementById("show-hide-cart");
let isCartShowing = false;

const products = [
{
id: 1,
name: "Vanilla Cupcakes (6 Pack)",
price: 12.99,
category: "Cupcake",
},
{
id: 2,
name: "French Macaron",
price: 3.99,
category: "Macaron",
},
{
id: 3,
name: "Pumpkin Cupcake",
price: 3.99,
category: "Cupcake",
},
{
id: 4,
name: "Chocolate Cupcake",
price: 5.99,
category: "Cupcake",
},
{
id: 5,
name: "Chocolate Pretzels (4 Pack)",
price: 10.99,
category: "Pretzel",
},
{
id: 6,
name: "Strawberry Ice Cream",
price: 2.99,
category: "Ice Cream",
},
{
id: 7,
name: "Chocolate Macarons (4 Pack)",
price: 9.99,
category: "Macaron",
},
{
id: 8,
name: "Strawberry Pretzel",
price: 4.99,
category: "Pretzel",
},
{
id: 9,
name: "Butter Pecan Ice Cream",
price: 2.99,
category: "Ice Cream",
},
{
id: 10,
name: "Rocky Road Ice Cream",
price: 2.99,
category: "Ice Cream",
},
{
id: 11,
name: "Vanilla Macarons (5 Pack)",
price: 11.99,
category: "Macaron",
},
{
id: 12,
name: "Lemon Cupcakes (4 Pack)",
price: 12.99,
category: "Cupcake",
},
];

products.forEach(
({ name, id, price, category }) => {
dessertCards.innerHTML += `
<div class="dessert-card">
<h2>${name}</h2>
<p class="dessert-price">$${price}</p>
<p class="product-category">Category: ${category}</p>
<button
id="${id}"
class="btn add-to-cart-btn">Add to cart
</button>
</div>
`;
}
);

class ShoppingCart {
constructor() {
this.items = [];
this.total = 0;
this.taxRate = 8.25;
}

addItem(id, products) {
const product = products.find((item) => item.id === id);
const { name, price } = product;
this.items.push(product);

const totalCountPerProduct = {};
this.items.forEach((dessert) => {
totalCountPerProduct[dessert.id] = (totalCountPerProduct[dessert.id] || 0) + 1;
})

const currentProductCount = totalCountPerProduct[product.id];
const currentProductCountSpan = document.getElementById(`product-count-for-id${id}`);

currentProductCount > 1
? currentProductCountSpan.textContent = `${currentProductCount}x`
: productsContainer.innerHTML += `
<div id=dessert${id} class="product">
<p>
<span class="product-count" id=product-count-for-id${id}></span>${name}
</p>
<p>${price}</p>
</div>
`;
}

getCounts() {
return this.items.length;
}

clearCart() {
if (!this.items.length) {
alert("Your shopping cart is already empty");
return;
}

const isCartCleared = confirm(
"Are you sure you want to clear all items from your shopping cart?"
);

if (isCartCleared) {
this.items = [];
this.total = 0;
productsContainer.innerHTML = "";
totalNumberOfItems.textContent = 0;
cartSubTotal.textContent = 0;
cartTaxes.textContent = 0;
cartTotal.textContent = 0;
}
}

calculateTaxes(amount) {
return parseFloat(((this.taxRate / 100) * amount).toFixed(2));
}

calculateTotal() {
const subTotal = this.items.reduce((total, item) => total + item.price, 0);
const tax = this.calculateTaxes(subTotal);
this.total = subTotal + tax;
cartSubTotal.textContent = `$${subTotal.toFixed(2)}`;
cartTaxes.textContent = `$${tax.toFixed(2)}`;
cartTotal.textContent = `$${this.total.toFixed(2)}`;
return this.total;
}
};

const cart = new ShoppingCart();
const addToCartBtns = document.getElementsByClassName("add-to-cart-btn");

[...addToCartBtns].forEach(
(btn) => {
btn.addEventListener("click", (event) => {
cart.addItem(Number(event.target.id), products);
totalNumberOfItems.textContent = cart.getCounts();
cart.calculateTotal();
})
}
);

cartBtn.addEventListener("click", () => {
isCartShowing = !isCartShowing;
showHideCartSpan.textContent = isCartShowing ? "Hide" : "Show";
cartContainer.style.display = isCartShowing ? "block" : "none";
});

clearCartBtn.addEventListener("click", cart.clearCart.bind(cart))
116 changes: 116 additions & 0 deletions building-a-shopping-cart/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}

:root {
--dark-grey: #1b1b32;
--light-grey: #f5f6f7;
--black: #000;
--white: #fff;
--grey: #3b3b4f;
--golden-yellow: #fecc4c;
--yellow: #ffcc4c;
--gold: #feac32;
--orange: #ffac33;
--dark-orange: #f89808;
}

body {
background-color: var(--dark-grey);
}

.title {
color: var(--light-grey);
text-align: center;
margin: 25px 0;
}

#dessert-card-container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: center;
}

.dessert-card {
background-color: var(--light-grey);
padding: 15px;
text-align: center;
border-radius: 15px;
margin: 20px 10px;
}

.dessert-price {
font-size: 1.2rem;
}

.btn {
display: block;
cursor: pointer;
width: 100px;
color: var(--dark-grey);
background-color: var(--gold);
background-image: linear-gradient(var(--golden-yellow), var(--orange));
border-color: var(--gold);
border-width: 3px;
}

.btn:hover {
background-image: linear-gradient(var(--yellow), var(--dark-orange));
}

#cart-btn {
position: absolute;
top: 0;
right: 0;
}

.add-to-cart-btn {
margin: 30px auto 10px;
}

#cart-container {
display: none;
position: absolute;
top: 60px;
right: 0;
background-color: var(--light-grey);
width: 200px;
height: 400px;
border: 8px double var(--black);
border-radius: 15px;
text-align: center;
font-size: 1.2rem;
overflow-y: scroll;
}

.product {
margin: 25px 0;
}

.product-count {
display: inline-block;
margin-right: 10px;
}

.product-category {
margin: 10px 0;
}

@media (min-width: 768px) {
#dessert-card-container {
flex-direction: row;
}

.dessert-card {
flex: 1 0 21%;
}

#cart-container {
width: 300px;
}
}

0 comments on commit ed250a9

Please sign in to comment.