A Pen by Elliott Benson on CodePen.
Created
April 3, 2024 15:45
-
-
Save egga22/8a561bb075da944760237d00d44ad34e to your computer and use it in GitHub Desktop.
oNOeMjg
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Simple Shopping Site</title> | |
<link rel="stylesheet" href="style.css"> | |
</head> | |
<body> | |
<!-- Top Left Corner --> | |
<div id="top-left-corner"> | |
<div id="register"> | |
<h3>Register</h3> | |
<input type="text" id="register-username" placeholder="Username"> | |
<input type="password" id="register-password" placeholder="Password"> | |
<button onclick="register()">Register</button> | |
</div> | |
<!-- User Login --> | |
<div id="login"> | |
<h3>Login</h3> | |
<input type="text" id="login-username" placeholder="Username"> | |
<input type="password" id="login-password" placeholder="Password"> | |
<button onclick="login()">Login</button> | |
</div> | |
<div id="redeem-gift-card"> | |
<input type="text" id="gift-card-code" placeholder="Gift Card Code"> | |
<button onclick="redeemGiftCard()">Redeem</button> | |
</div> | |
<!-- Logout Button --> | |
<div id="logout-section" style="display:none;"> | |
<button onclick="logout()">Logout</button> | |
</div> | |
</div> | |
<div id="cart-container"> | |
<div id="cart"> | |
<h2>Cart</h2> | |
<div id="cart-items"></div> | |
<button onclick="checkout()">Checkout</button> | |
<div> | |
<input type="text" id="discount-code" placeholder="Discount Code"> | |
<button onclick="applyDiscount()">Apply Discount</button> | |
</div> | |
</div> | |
</div> | |
<!-- Top Right Corner --> | |
<div id="top-right-corner"> | |
<div id="search-box"> | |
<input type="text" id="search-input" placeholder="Search products..." oninput="searchProducts()"> | |
</div> | |
<div id="sort-options"> | |
<select id="sortSelect" onchange="sortProducts(this.value)"> | |
<option value="priceLowToHigh">Price: Low to High</option> | |
<option value="priceHighToLow">Price: High to Low</option> | |
<option value="alphabeticalAZ">Alphabetical: A-Z</option> | |
<option value="alphabeticalZA">Alphabetical: Z-A</option> | |
</select> | |
</div> | |
</div> | |
<!-- Main Content Area --> | |
<div class="main-content"> | |
<div id="product-list"> | |
<!-- Products will be rendered here by JavaScript --> | |
</div> | |
<div id="wishlist"> | |
<h3>Your Wishlist</h3> | |
<div id="wishlist-items"></div> | |
</div> | |
</div> | |
<!-- Bottom Right Corner --> | |
<div id="bottom-right-corner"> | |
<div id="balance"> | |
<h2>Balance: $<span id="balance-amount">0</span></h2> | |
<button onclick="addBalance()">Add to Balance</button> | |
<div id="balance-presets"> | |
<button onclick="updateBalance(5)">Add $5</button> | |
<button onclick="updateBalance(10)">Add $10</button> | |
<button onclick="updateBalance(20)">Add $20</button> | |
<button onclick="updateBalance(70)">Add $70</button> | |
<button onclick="updateBalance(100)">Add $100</button> | |
</div> | |
</div> | |
<div id="purchase-history"> | |
<h2>Purchase History</h2> | |
<div id="history-items"></div> | |
<button onclick="clearHistory()" class="clear-button">Clear History</button> | |
</div> | |
</div> | |
<!-- Bottom Right Corner (if the cart is to be placed at the bottom, otherwise move this inside top-right-corner) --> | |
<script src="//code.tidio.co/5z0n53bzc7ghm2lkd7pefyfwuprka1bt.js" async></script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let balance = 0; | |
let cart = []; | |
let purchaseHistory = []; | |
let discountApplied = false; | |
let appliedDiscountPercentage = 0; | |
const discountCodes = { | |
'melikemoney': 20, // This means a 20% discount | |
'mereallylikemoney': 40, | |
'mehopeyougobankrupt': 60, | |
'melikefreestuff': 100, | |
}; | |
let giftCardCodes = {}; // Stores codes and their values | |
function generateGiftCardCode(value) { | |
const code = 'GC' + Math.random().toString(36).substr(2, 9).toUpperCase(); | |
giftCardCodes[code] = value; | |
return code; // Return the code for use in the checkout function | |
} | |
function addToCart(productName, price, isGiftCard = false) { | |
cart.push({productName, price, isGiftCard}); | |
renderCartItems(); | |
} | |
const products = [ | |
//products | |
{ name: 'Video Game', price: 60 }, | |
{ name: 'Gaming Console', price: 500 }, | |
{ name: 'Ice Cream', price: 12 }, | |
{ name: 'Movie Ticket', price: 14 }, | |
{ name: 'Pair of Pants', price: 40 }, | |
{ name: 'Nerf Gun', price: 25 }, | |
{ name: 'Pokemon Card Pack', price: 15 }, | |
{ name: 'Anime Convention Ticket', price: 150 }, | |
{ name: 'Fancy Pencil Set', price: 25 }, | |
{ name: 'Movie Ticket 3 Pack', price: 40 }, | |
{ name: 'High End Skateboard', price: 100 }, | |
{ name: '$5 Roblox Gift Card', price: 5 }, | |
{ name: '$10 Roblox Gift Card', price: 10 }, | |
{ name: '$20 Roblox Gift Card', price: 20 }, | |
{ name: 'Nike Shoes', price: 120 }, | |
{ name: 'Lego Set', price: 80 }, | |
{ name: 'Poster', price: 20 }, | |
{ name: 'Music Album', price: 10 }, | |
{ name: '3 Pizzas', price: 40 }, | |
{ name: 'Anime Tee Shirt', price: 70 }, | |
{ name: '$10 Arcade credits', price: 10 }, | |
{ name: '$20 Arcade credits', price: 20 }, | |
{ name: '$40 Arcade credits', price: 40 }, | |
{ name: '$100 Arcade credits', price: 100 }, | |
{ name: '$5 Gift Card', price: 5, isGiftCard: true }, | |
{ name: '$10 Gift Card', price: 10, isGiftCard: true }, | |
{ name: '$20 Gift Card', price: 20, isGiftCard: true } | |
]; | |
let currentDisplayedProducts = products; // This will always hold the currently displayed products | |
function renderCartItems() { | |
const cartItemsEl = document.getElementById('cart-items'); | |
cartItemsEl.innerHTML = ''; | |
cart.forEach((item, index) => { | |
const itemEl = document.createElement('div'); | |
itemEl.textContent = `${item.productName} - $${item.price}`; | |
const removeBtn = document.createElement('button'); | |
removeBtn.textContent = 'Remove'; | |
removeBtn.onclick = () => removeFromCart(index); | |
itemEl.appendChild(removeBtn); | |
cartItemsEl.appendChild(itemEl); | |
}); | |
} | |
function applyDiscount() { | |
const discountCode = document.getElementById('discount-code').value; | |
if (discountCodes[discountCode] && !discountApplied) { | |
appliedDiscountPercentage = discountCodes[discountCode]; | |
alert(`Discount applied: ${appliedDiscountPercentage}%`); | |
discountApplied = true; | |
} else if (discountApplied) { | |
alert('Discount already applied.'); | |
} else { | |
alert('Invalid discount code.'); | |
} | |
} | |
function checkout() { | |
const total = cart.reduce((acc, item) => acc + item.price, 0); | |
let discountAmount = total * (appliedDiscountPercentage / 100); | |
let finalTotal = total - discountAmount; | |
if (finalTotal > balance) { | |
alert(`Insufficient balance. You need $${finalTotal - balance} more.`); | |
return; | |
} | |
// Process gift cards in the cart | |
cart.forEach(item => { | |
if (item.isGiftCard) { | |
const code = generateGiftCardCode(item.price); // Adjust generateGiftCardCode to return the code | |
alert(`Your gift card code: ${code}\nValue: $${item.price}`); | |
} | |
}); | |
// Complete the checkout process | |
balance -= finalTotal; | |
purchaseHistory.push(...cart.filter(item => !item.isGiftCard)); // Exclude gift cards from purchase history | |
cart = []; // Clear the cart | |
alert('Purchase successful!'); | |
updateBalanceDisplay(); | |
renderCartItems(); | |
renderPurchaseHistory(); | |
discountApplied = false; | |
appliedDiscountPercentage = 0; | |
document.getElementById('discount-code').value = ''; // Clear the discount code field | |
} | |
function addBalance() { | |
const amount = prompt('How much would you like to add?'); | |
if (amount) { | |
balance += parseInt(amount, 10); | |
updateBalanceDisplay(); | |
} | |
} | |
function updateBalanceDisplay() { | |
document.getElementById('balance-amount').textContent = balance; | |
} | |
function renderPurchaseHistory() { | |
const historyItemsEl = document.getElementById('history-items'); | |
historyItemsEl.innerHTML = ''; // Clear current items | |
purchaseHistory.forEach(item => { | |
const itemEl = document.createElement('div'); | |
itemEl.textContent = `${item.productName} - $${item.price}`; | |
historyItemsEl.appendChild(itemEl); | |
}); | |
} | |
function clearHistory() { | |
purchaseHistory = []; | |
renderPurchaseHistory(); | |
} | |
function sortProducts(sortMethod) { | |
let sortedProducts = [...currentDisplayedProducts]; // Create a copy to sort | |
switch (sortMethod) { | |
case 'priceLowToHigh': | |
sortedProducts.sort((a, b) => a.price - b.price); | |
break; | |
case 'priceHighToLow': | |
sortedProducts.sort((a, b) => b.price - a.price); | |
break; | |
case 'alphabeticalAZ': | |
sortedProducts.sort((a, b) => a.name.localeCompare(b.name)); | |
break; | |
case 'alphabeticalZA': | |
sortedProducts.sort((a, b) => b.name.localeCompare(a.name)); | |
break; | |
case 'default': | |
// If you want "default" to return to the original list order, | |
// you'll need to maintain an original, unsorted copy of products | |
// or reload it if it's dynamically fetched. | |
break; | |
} | |
renderProducts(sortedProducts); // Render the sorted list | |
} | |
function renderProducts(productArray) { | |
const productListEl = document.getElementById('product-list'); | |
productListEl.innerHTML = ''; // Clear existing items | |
productArray.forEach(product => { | |
const productEl = document.createElement('div'); | |
productEl.className = 'product'; | |
productEl.innerHTML = ` | |
<span class="name">${product.name}</span> | |
<span class="price">$${product.price}</span> | |
<button onclick="addToCart('${product.name.replace("'", "\\'")}', ${product.price}${product.isGiftCard ? ', true' : ''})">Add to Cart</button> | |
<button onclick="addToWishlist('${product.name.replace("'", "\\'")}')" class="wishlist-btn">Add to Wishlist</button> | |
`; | |
productListEl.appendChild(productEl); | |
}); | |
} | |
// Existing JavaScript code | |
function updateBalance(amount) { | |
balance += amount; | |
updateBalanceDisplay(); | |
} | |
function searchProducts() { | |
const searchValue = document.getElementById('search-input').value.toLowerCase(); | |
const filteredProducts = products.filter(product => | |
product.name.toLowerCase().includes(searchValue) | |
); | |
renderProducts(filteredProducts); // Ensure this calls the correctly defined renderProducts function | |
} | |
function register() { | |
const username = document.getElementById('register-username').value; | |
const password = document.getElementById('register-password').value; | |
localStorage.setItem('user', JSON.stringify({ username, password })); | |
alert('Registration successful'); | |
} | |
function login() { | |
const storedUser = JSON.parse(localStorage.getItem('user')); | |
const username = document.getElementById('login-username').value; | |
const password = document.getElementById('login-password').value; | |
if (storedUser && storedUser.username === username && storedUser.password === password) { | |
alert('Login successful'); | |
localStorage.setItem('isLoggedIn', 'true'); | |
updateLoginStatus(); | |
} else { | |
alert('Login failed'); | |
} | |
} | |
function logout() { | |
localStorage.removeItem('isLoggedIn'); | |
updateLoginStatus(); | |
} | |
function updateLoginStatus() { | |
const isLoggedIn = localStorage.getItem('isLoggedIn'); | |
if (isLoggedIn) { | |
document.getElementById('login').style.display = 'none'; | |
document.getElementById('register').style.display = 'none'; | |
document.getElementById('logout-section').style.display = 'block'; | |
} else { | |
document.getElementById('login').style.display = 'block'; | |
document.getElementById('register').style.display = 'block'; | |
document.getElementById('logout-section').style.display = 'none'; | |
} | |
} | |
function redeemGiftCard() { | |
const code = document.getElementById('gift-card-code').value; | |
if (giftCardCodes[code]) { | |
balance += giftCardCodes[code]; | |
alert(`$${giftCardCodes[code]} added to your balance.`); | |
delete giftCardCodes[code]; // Ensure the code can't be used again | |
updateBalanceDisplay(); | |
document.getElementById('gift-card-code').value = ''; // Clear input | |
} else { | |
alert('Invalid or already used gift card code.'); | |
} | |
} | |
function renderWishlist() { | |
const wishlistItemsEl = document.getElementById('wishlist-items'); | |
let wishlist = JSON.parse(localStorage.getItem('wishlist')) || []; | |
wishlistItemsEl.innerHTML = ''; | |
wishlist.forEach(productName => { | |
const itemEl = document.createElement('div'); | |
itemEl.textContent = productName; | |
const addToCartBtn = document.createElement('button'); | |
addToCartBtn.textContent = 'Add to Cart'; | |
addToCartBtn.onclick = () => addToCartFromWishlist(productName); | |
const removeBtn = document.createElement('button'); | |
removeBtn.textContent = 'Remove'; | |
removeBtn.onclick = () => removeFromWishlist(productName); | |
itemEl.appendChild(addToCartBtn); | |
itemEl.appendChild(removeBtn); | |
wishlistItemsEl.appendChild(itemEl); | |
}); | |
} | |
function addToWishlist(productName) { | |
console.log(`Adding ${productName} to wishlist`); // Debugging line | |
let wishlist = JSON.parse(localStorage.getItem('wishlist')) || []; | |
if (!wishlist.includes(productName)) { | |
wishlist.push(productName); | |
localStorage.setItem('wishlist', JSON.stringify(wishlist)); | |
alert(`${productName} added to wishlist!`); | |
} else { | |
alert(`${productName} is already in your wishlist.`); | |
} | |
renderWishlist(); // Make sure to call renderWishlist to update the wishlist display | |
} | |
function addToCartFromWishlist(productName) { | |
const product = products.find(p => p.name === productName); | |
if (product) { | |
addToCart(product.name, product.price, product.isGiftCard || false); | |
// Remove from wishlist | |
let wishlist = JSON.parse(localStorage.getItem('wishlist')) || []; | |
wishlist = wishlist.filter(name => name !== productName); | |
localStorage.setItem('wishlist', JSON.stringify(wishlist)); | |
renderWishlist(); // Refresh the wishlist display | |
alert(`${productName} added to cart and removed from wishlist!`); | |
} else { | |
alert('Product not found.'); | |
} | |
} | |
function removeFromWishlist(productName) { | |
let wishlist = JSON.parse(localStorage.getItem('wishlist')) || []; | |
wishlist = wishlist.filter(name => name !== productName); | |
localStorage.setItem('wishlist', JSON.stringify(wishlist)); | |
renderWishlist(); // Refresh the wishlist display | |
} | |
function removeFromCart(index) { | |
cart.splice(index, 1); // Remove item at index | |
renderCartItems(); // Refresh the cart display | |
} | |
// Call updateLoginStatus on page load to reflect the correct login state | |
window.onload = function() { | |
updateLoginStatus(); | |
}; | |
// Make sure to include this new function in your existing script. | |
renderProducts(products); | |
updateBalanceDisplay(); | |
renderWishlist(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Reset and base styles */ | |
* { | |
margin: 0; | |
padding: 0; | |
box-sizing: border-box; | |
} | |
body, html { | |
font-family: Arial, sans-serif; | |
width: 100%; | |
height: 100%; | |
background-color: #f9f9f9; /* Light grey background */ | |
} | |
/* Layout styles for corner boxes */ | |
#top-left-corner, #top-right-corner, #bottom-right-corner { | |
background-color: #fff; /* White background for boxes */ | |
padding: 20px; | |
border-radius: 10px; | |
box-shadow: 0 4px 8px rgba(0,0,0,0.1); /* Soft shadow for depth */ | |
position: fixed; /* Ensure position is fixed for corners */ | |
z-index: 10; /* Ensure these are above the main content */ | |
display: flex; | |
flex-direction: column; | |
} | |
#cart-container { | |
position: static; /* Allow it to follow the natural document flow under redeem section */ | |
margin: 20px auto; /* Center it and add some space above */ | |
} | |
/* Positioning for corner boxes */ | |
#top-left-corner { | |
top: 10px; | |
left: 10px; | |
} | |
#top-right-corner { | |
top: 10px; | |
right: 10px; | |
} | |
#bottom-right-corner { | |
bottom: 10px; | |
right: 10px; | |
} | |
/* Flexbox centering for the main content */ | |
.main-content { | |
margin: 150px 20% 100px; /* Increased margin for more space around corners */ | |
display: flex; | |
justify-content: center; | |
align-items: flex-start; | |
flex-wrap: wrap; | |
gap: 20px; | |
position: relative; /* Needed for z-index to work */ | |
z-index: 1; /* Below corner box interactive elements */ | |
} | |
/* Grid layout for products */ | |
#product-list { | |
display: grid; | |
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); /* Adjust grid size */ | |
gap: 20px; | |
width: auto; /* Allows grid to fit within adjusted margins */ | |
margin: 0 auto; /* Center grid in the available space */ | |
position: relative; /* Needed for z-index to work */ | |
z-index: 1; /* Ensures the product list is positioned correctly */ | |
} | |
/* Form styles for text input fields */ | |
input[type="text"], input[type="password"], input[type="search"] { | |
padding: 10px; | |
margin: 10px auto; /* Centered horizontally */ | |
border: 1px solid #ccc; | |
border-radius: 5px; | |
width: 100%; | |
max-width: 200px; /* Keep text boxes small */ | |
display: block; /* Ensure inputs are block level */ | |
} | |
/* Button styles */ | |
button { | |
padding: 10px; | |
margin: 10px auto; /* Center buttons */ | |
background-color: #007bff; | |
color: #fff; | |
border: none; | |
border-radius: 5px; | |
cursor: pointer; | |
transition: background-color 0.3s; | |
width: auto; /* Adjust width based on content */ | |
max-width: 200px; /* Max width for consistency */ | |
display: block; /* Ensure buttons are block level */ | |
} | |
button:hover { | |
background-color: #0056b3; | |
} | |
/* Styles for the balance presets grid */ | |
#balance-presets { | |
display: grid; | |
grid-template-columns: repeat(3, 1fr); /* Create a tighter grid */ | |
gap: 10px; /* Maintain gap for spacing */ | |
justify-content: center; /* Center grid items */ | |
margin-top: 10px; /* Space above the grid */ | |
} | |
/* Responsive adjustments */ | |
@media (max-width: 1024px) { | |
.main-content { | |
margin: 120px 18% 80px; /* Slightly smaller margins for tablet landscape */ | |
} | |
} | |
@media (max-width: 768px) { | |
.main-content { | |
margin: 100px 15% 60px; /* Reduced margins for tablet portrait */ | |
} | |
} | |
@media (max-width: 480px) { | |
.main-content { | |
margin: 80px 10% 40px; /* Reduced margins for mobile */ | |
} | |
} | |
#wishlist { | |
width: 100%; /* Ensures the wishlist takes the full width */ | |
margin-top: 20px; /* Adds space between the product list and wishlist */ | |
padding: 20px; /* Optional: Adds padding inside the wishlist container */ | |
background-color: #f0f0f0; /* Optional: Sets a different background color */ | |
border-radius: 8px; /* Optional: Rounds the corners of the wishlist container */ | |
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* Optional: Adds a subtle shadow */ | |
} | |
@media (max-width: 768px) { | |
#wishlist { | |
padding: 10px; | |
margin-top: 15px; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment