Created
July 20, 2025 14:22
-
-
Save thinkphp/2c1b71aec92f1804d4e5ac1e652370dc to your computer and use it in GitHub Desktop.
coffee-shop.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
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Coffee Shop Cart</title> | |
<style> | |
body { | |
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
line-height: 1.6; | |
color: #333; | |
background-color: #f5f5f5; | |
margin: 0; | |
padding: 20px; | |
} | |
.container { | |
max-width: 1200px; | |
margin: 0 auto; | |
display: grid; | |
grid-template-columns: 2fr 1fr; | |
gap: 30px; | |
} | |
.header { | |
grid-column: 1 / -1; | |
text-align: center; | |
margin-bottom: 20px; | |
} | |
h1, h2, h3 { | |
color: #5d4037; | |
} | |
.products { | |
display: grid; | |
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); | |
gap: 20px; | |
} | |
.product-card { | |
background-color: white; | |
border-radius: 8px; | |
overflow: hidden; | |
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); | |
transition: transform 0.3s ease; | |
} | |
.product-card:hover { | |
transform: translateY(-5px); | |
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); | |
} | |
.product-image { | |
height: 180px; | |
background-color: #d7ccc8; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
color: #5d4037; | |
font-weight: bold; | |
} | |
.product-info { | |
padding: 15px; | |
} | |
.product-title { | |
margin: 0 0 10px 0; | |
font-size: 18px; | |
} | |
.product-price { | |
font-weight: bold; | |
margin-bottom: 10px; | |
color: #5d4037; | |
} | |
.product-description { | |
font-size: 14px; | |
color: #666; | |
margin-bottom: 15px; | |
} | |
button { | |
background-color: #795548; | |
color: white; | |
border: none; | |
padding: 8px 15px; | |
border-radius: 4px; | |
cursor: pointer; | |
font-size: 14px; | |
transition: background-color 0.3s ease; | |
} | |
button:hover { | |
background-color: #5d4037; | |
} | |
button:disabled { | |
background-color: #ccc; | |
cursor: not-allowed; | |
} | |
.cart { | |
background-color: white; | |
border-radius: 8px; | |
padding: 20px; | |
position: sticky; | |
top: 20px; | |
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); | |
} | |
.cart-item { | |
display: flex; | |
justify-content: space-between; | |
margin-bottom: 15px; | |
padding-bottom: 15px; | |
border-bottom: 1px solid #eee; | |
} | |
.item-info { | |
flex-grow: 1; | |
} | |
.item-title { | |
margin: 0 0 5px 0; | |
font-size: 16px; | |
} | |
.item-price { | |
font-size: 14px; | |
color: #666; | |
} | |
.item-controls { | |
display: flex; | |
align-items: center; | |
} | |
.item-quantity { | |
margin: 0 10px; | |
width: 30px; | |
text-align: center; | |
} | |
.cart-total { | |
margin-top: 20px; | |
font-weight: bold; | |
font-size: 18px; | |
text-align: right; | |
} | |
.checkout-button { | |
width: 100%; | |
padding: 12px; | |
font-size: 16px; | |
background-color: #4caf50; | |
margin-top: 20px; | |
} | |
.checkout-button:hover { | |
background-color: #388e3c; | |
} | |
.emptycart-button { | |
width: 100%; | |
padding: 8px; | |
font-size: 14px; | |
background-color: #f44336; | |
margin-top: 10px; | |
} | |
.emptycart-button:hover { | |
background-color: #d32f2f; | |
} | |
.notification { | |
position: fixed; | |
top: 20px; | |
right: 20px; | |
background-color: #4caf50; | |
color: white; | |
padding: 15px 25px; | |
border-radius: 4px; | |
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); | |
transform: translateX(200%); | |
transition: transform 0.3s ease; | |
} | |
.notification.show { | |
transform: translateX(0); | |
} | |
.empty-cart-message { | |
text-align: center; | |
color: #666; | |
margin: 30px 0; | |
} | |
@media (max-width: 768px) { | |
.container { | |
grid-template-columns: 1fr; | |
} | |
.cart { | |
position: static; | |
margin-top: 30px; | |
} | |
} | |
</style> | |
</head> | |
<body> | |
<div class="container"> | |
<header class="header"> | |
<h1>Coffee Shop</h1> | |
<p>Select your favorite coffee and add it to cart</p> | |
</header> | |
<main class="products" id="products-container"> | |
<!-- Products will be added here by JavaScript --> | |
</main> | |
<aside class="cart" id="cart-container"> | |
<h2>Your Cart</h2> | |
<div id="cart-items"> | |
<!-- Cart items will be added here by JavaScript --> | |
<p class="empty-cart-message">Your cart is empty</p> | |
</div> | |
<div class="cart-total" id="cart-total">Total: $0.00</div> | |
<button class="checkout-button" id="checkout-button" disabled>Proceed to Checkout</button> | |
<button class="emptycart-button" id="emptycart-button" disabled>Empty Cart</button> | |
</aside> | |
</div> | |
<div class="notification" id="notification">Item added to cart!</div> | |
<script> | |
// Coffee products data | |
const coffeeProducts = [ | |
{ | |
id: 1, | |
name: "Espresso", | |
price: 2.99, | |
description: "Strong and concentrated coffee shot" | |
}, | |
{ | |
id: 2, | |
name: "Cappuccino", | |
price: 4.50, | |
description: "Espresso with steamed milk and foam" | |
}, | |
{ | |
id: 3, | |
name: "Latte", | |
price: 4.99, | |
description: "Espresso with a lot of steamed milk" | |
}, | |
{ | |
id: 4, | |
name: "Americano", | |
price: 3.50, | |
description: "Espresso diluted with hot water" | |
}, | |
{ | |
id: 5, | |
name: "Mocha", | |
price: 5.50, | |
description: "Espresso with chocolate and steamed milk" | |
}, | |
{ | |
id: 6, | |
name: "Macchiato", | |
price: 3.99, | |
description: "Espresso with a dollop of milk foam" | |
} | |
]; | |
// Shopping cart array | |
let cart = []; | |
// DOM elements | |
const productsContainer = document.getElementById('products-container'); | |
const cartItemsContainer = document.getElementById('cart-items'); | |
const cartTotalElement = document.getElementById('cart-total'); | |
const checkoutButton = document.getElementById('checkout-button'); | |
const emptyCartButton = document.getElementById('emptycart-button'); | |
const notification = document.getElementById('notification'); | |
// Display products | |
function displayProducts() { | |
productsContainer.innerHTML = ''; | |
coffeeProducts.forEach(product => { | |
const productCard = document.createElement('div'); | |
productCard.className = 'product-card'; | |
productCard.innerHTML = ` | |
<div class="product-image">Coffee Image: ${product.name}</div> | |
<div class="product-info"> | |
<h3 class="product-title">${product.name}</h3> | |
<div class="product-price">$${product.price.toFixed(2)}</div> | |
<div class="product-description">${product.description}</div> | |
<button class="add-to-cart-button" data-id="${product.id}">Add to Cart</button> | |
</div> | |
`; | |
productsContainer.appendChild(productCard); | |
}); | |
// Add event listeners to all "Add to Cart" buttons | |
document.querySelectorAll('.add-to-cart-button').forEach(button => { | |
button.addEventListener('click', addToCart); | |
}); | |
} | |
// Add to cart function | |
function addToCart(event) { | |
const productId = parseInt(event.target.getAttribute('data-id')); | |
const product = coffeeProducts.find(p => p.id === productId); | |
// Check if the product already exists in the cart | |
const existingItem = cart.find(item => item.id === productId); | |
if (existingItem) { | |
existingItem.quantity += 1; | |
} else { | |
cart.push({ | |
id: product.id, | |
name: product.name, | |
price: product.price, | |
quantity: 1 | |
}); | |
} | |
// Show notification | |
showNotification(`Added ${product.name} to cart!`); | |
// Update cart display | |
updateCart(); | |
} | |
// Update cart display | |
function updateCart() { | |
if (cart.length === 0) { | |
cartItemsContainer.innerHTML = '<p class="empty-cart-message">Your cart is empty</p>'; | |
checkoutButton.disabled = true; | |
emptyCartButton.disabled = true; | |
} else { | |
cartItemsContainer.innerHTML = ''; | |
cart.forEach(item => { | |
const cartItem = document.createElement('div'); | |
cartItem.className = 'cart-item'; | |
cartItem.innerHTML = ` | |
<div class="item-info"> | |
<h3 class="item-title">${item.name}</h3> | |
<div class="item-price">$${item.price.toFixed(2)} each</div> | |
</div> | |
<div class="item-controls"> | |
<button class="decrease-quantity" data-id="${item.id}">-</button> | |
<span class="item-quantity">${item.quantity}</span> | |
<button class="increase-quantity" data-id="${item.id}">+</button> | |
<button class="remove-item" data-id="${item.id}" style="margin-left: 10px; background-color: #f44336;">×</button> | |
</div> | |
`; | |
cartItemsContainer.appendChild(cartItem); | |
}); | |
checkoutButton.disabled = false; | |
emptyCartButton.disabled = false; | |
} | |
// Calculate and update the cart total | |
updateCartTotal(); | |
// Add event listeners to quantity buttons | |
document.querySelectorAll('.decrease-quantity').forEach(button => { | |
button.addEventListener('click', decreaseQuantity); | |
}); | |
document.querySelectorAll('.increase-quantity').forEach(button => { | |
button.addEventListener('click', increaseQuantity); | |
}); | |
document.querySelectorAll('.remove-item').forEach(button => { | |
button.addEventListener('click', removeItem); | |
}); | |
} | |
// Update cart total | |
function updateCartTotal() { | |
const total = cart.reduce((sum, item) => sum + (item.price * item.quantity), 0); | |
cartTotalElement.textContent = `Total: $${total.toFixed(2)}`; | |
} | |
// Increase item quantity | |
function increaseQuantity(event) { | |
const productId = parseInt(event.target.getAttribute('data-id')); | |
const item = cart.find(item => item.id === productId); | |
if (item) { | |
item.quantity += 1; | |
updateCart(); | |
} | |
} | |
// Decrease item quantity | |
function decreaseQuantity(event) { | |
const productId = parseInt(event.target.getAttribute('data-id')); | |
const item = cart.find(item => item.id === productId); | |
if (item) { | |
item.quantity -= 1; | |
if (item.quantity <= 0) { | |
removeItem(event); | |
} else { | |
updateCart(); | |
} | |
} | |
} | |
// Remove item from cart | |
function removeItem(event) { | |
const productId = parseInt(event.target.getAttribute('data-id')); | |
cart = cart.filter(item => item.id !== productId); | |
updateCart(); | |
} | |
// Empty the cart | |
function emptyCart() { | |
cart = []; | |
updateCart(); | |
showNotification('Cart has been emptied'); | |
} | |
// Show notification | |
function showNotification(message) { | |
notification.textContent = message; | |
notification.classList.add('show'); | |
setTimeout(() => { | |
notification.classList.remove('show'); | |
}, 3000); | |
} | |
// Checkout function | |
function checkout() { | |
// In a real application, this would connect to a payment processor | |
alert(`Proceeding to checkout with ${cart.length} items. Total: $${calculateTotal().toFixed(2)}`); | |
cart = []; | |
updateCart(); | |
showNotification('Thank you for your order!'); | |
} | |
// Calculate total function (for checkout) | |
function calculateTotal() { | |
return cart.reduce((sum, item) => sum + (item.price * item.quantity), 0); | |
} | |
// Initialize the application | |
function init() { | |
// Display products | |
displayProducts(); | |
// Initial cart update | |
updateCart(); | |
// Add event listeners for checkout and empty cart buttons | |
checkoutButton.addEventListener('click', checkout); | |
emptyCartButton.addEventListener('click', emptyCart); | |
} | |
// Start the application when DOM is fully loaded | |
document.addEventListener('DOMContentLoaded', init); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment