| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>ShopEasy - One Page E-Commerce</title> |
| |
| <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet"> |
| |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"> |
| <style> |
| .section { |
| display: none; |
| animation: fadeIn 0.5s; |
| } |
| .active-section { |
| display: block; |
| } |
| .nav-item { |
| cursor: pointer; |
| } |
| .nav-link.active { |
| background-color: #0d6efd; |
| color: white !important; |
| } |
| .card { |
| transition: transform 0.3s; |
| height: 100%; |
| } |
| .card:hover { |
| transform: translateY(-5px); |
| box-shadow: 0 5px 15px rgba(0,0,0,0.1); |
| } |
| .cart-item { |
| border-bottom: 1px solid #eee; |
| padding: 10px 0; |
| } |
| .quantity-control { |
| display: flex; |
| align-items: center; |
| gap: 10px; |
| } |
| .product-img { |
| height: 200px; |
| object-fit: cover; |
| width: 100%; |
| } |
| .badge-notification { |
| position: absolute; |
| top: -5px; |
| right: -5px; |
| } |
| @keyframes fadeIn { |
| from { opacity: 0; } |
| to { opacity: 1; } |
| } |
| .checkout-step { |
| display: none; |
| } |
| .checkout-step.active { |
| display: block; |
| } |
| .order-summary { |
| background-color: #f8f9fa; |
| border-radius: 10px; |
| padding: 20px; |
| } |
| </style> |
| </head> |
| <body> |
| |
| <nav class="navbar navbar-expand-lg navbar-dark bg-primary sticky-top"> |
| <div class="container"> |
| <a class="navbar-brand" href="#" onclick="showSection('home')"> |
| <i class="fas fa-shopping-bag me-2"></i>ShopEasy |
| </a> |
| <div class="d-flex align-items-center"> |
| |
| <div class="position-relative me-3" onclick="showSection('cart')" style="cursor: pointer;"> |
| <i class="fas fa-shopping-cart fa-lg text-white"></i> |
| <span id="cartBadge" class="badge bg-danger badge-notification">0</span> |
| </div> |
| |
| <ul class="navbar-nav"> |
| <li class="nav-item"> |
| <a class="nav-link" onclick="showSection('home')">Home</a> |
| </li> |
| <li class="nav-item"> |
| <a class="nav-link" onclick="showSection('products')">Products</a> |
| </li> |
| <li class="nav-item"> |
| <a class="nav-link" onclick="showSection('cart')">Cart</a> |
| </li> |
| <li class="nav-item"> |
| <a class="nav-link" onclick="showSection('checkout')">Checkout</a> |
| </li> |
| </ul> |
| </div> |
| </div> |
| </nav> |
|
|
| |
| <div class="container mt-4"> |
| |
| |
| <div id="home" class="section active-section"> |
| <div class="jumbotron bg-light p-5 rounded"> |
| <h1 class="display-4">Welcome to ShopEasy!</h1> |
| <p class="lead">Your one-stop shop for all your needs. Browse our products, add them to cart, and checkout securely.</p> |
| <hr class="my-4"> |
| <p>We offer high-quality products with fast delivery and excellent customer service.</p> |
| <button class="btn btn-primary btn-lg" onclick="showSection('products')"> |
| Start Shopping <i class="fas fa-arrow-right ms-2"></i> |
| </button> |
| </div> |
| |
| <div class="row mt-5"> |
| <div class="col-md-4"> |
| <div class="card text-center"> |
| <div class="card-body"> |
| <i class="fas fa-shipping-fast fa-3x text-primary mb-3"></i> |
| <h5 class="card-title">Fast Delivery</h5> |
| <p class="card-text">Get your orders delivered within 2-3 business days.</p> |
| </div> |
| </div> |
| </div> |
| <div class="col-md-4"> |
| <div class="card text-center"> |
| <div class="card-body"> |
| <i class="fas fa-shield-alt fa-3x text-success mb-3"></i> |
| <h5 class="card-title">Secure Payment</h5> |
| <p class="card-text">100% secure payment processing with encryption.</p> |
| </div> |
| </div> |
| </div> |
| <div class="col-md-4"> |
| <div class="card text-center"> |
| <div class="card-body"> |
| <i class="fas fa-headset fa-3x text-warning mb-3"></i> |
| <h5 class="card-title">24/7 Support</h5> |
| <p class="card-text">Our support team is always ready to help you.</p> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div id="products" class="section"> |
| <h2 class="mb-4">Our Products</h2> |
| <div class="row" id="productsGrid"> |
| |
| </div> |
| </div> |
|
|
| |
| <div id="cart" class="section"> |
| <h2 class="mb-4">Your Shopping Cart</h2> |
| <div class="row"> |
| <div class="col-md-8"> |
| <div id="cartItems"> |
| |
| <p class="text-muted" id="emptyCartMessage">Your cart is empty. <a href="#" onclick="showSection('products')">Browse products</a></p> |
| </div> |
| </div> |
| <div class="col-md-4"> |
| <div class="order-summary"> |
| <h5>Order Summary</h5> |
| <table class="table"> |
| <tr> |
| <td>Subtotal:</td> |
| <td class="text-end">$<span id="subtotal">0.00</span></td> |
| </tr> |
| <tr> |
| <td>Shipping:</td> |
| <td class="text-end">$<span id="shipping">5.00</span></td> |
| </tr> |
| <tr> |
| <td>Tax:</td> |
| <td class="text-end">$<span id="tax">0.00</span></td> |
| </tr> |
| <tr class="table-active"> |
| <th>Total:</th> |
| <th class="text-end">$<span id="total">5.00</span></th> |
| </tr> |
| </table> |
| <button class="btn btn-primary w-100" onclick="showSection('checkout')" id="checkoutBtn" disabled> |
| Proceed to Checkout |
| </button> |
| <button class="btn btn-outline-secondary w-100 mt-2" onclick="clearCart()"> |
| Clear Cart |
| </button> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div id="checkout" class="section"> |
| <h2 class="mb-4">Checkout</h2> |
| <div class="row"> |
| <div class="col-md-8"> |
| <div id="checkoutSteps"> |
| |
| <div id="step1" class="checkout-step active"> |
| <h4>Shipping Information</h4> |
| <form id="shippingForm"> |
| <div class="row mb-3"> |
| <div class="col-md-6"> |
| <label class="form-label">First Name *</label> |
| <input type="text" class="form-control" required> |
| </div> |
| <div class="col-md-6"> |
| <label class="form-label">Last Name *</label> |
| <input type="text" class="form-control" required> |
| </div> |
| </div> |
| <div class="mb-3"> |
| <label class="form-label">Address *</label> |
| <input type="text" class="form-control" required> |
| </div> |
| <div class="row mb-3"> |
| <div class="col-md-6"> |
| <label class="form-label">City *</label> |
| <input type="text" class="form-control" required> |
| </div> |
| <div class="col-md-6"> |
| <label class="form-label">ZIP Code *</label> |
| <input type="text" class="form-control" required> |
| </div> |
| </div> |
| <div class="mb-3"> |
| <label class="form-label">Email *</label> |
| <input type="email" class="form-control" required> |
| </div> |
| <button type="button" class="btn btn-primary" onclick="nextStep(2)">Continue to Payment</button> |
| </form> |
| </div> |
|
|
| |
| <div id="step2" class="checkout-step"> |
| <h4>Payment Information</h4> |
| <form id="paymentForm"> |
| <div class="mb-3"> |
| <label class="form-label">Card Number *</label> |
| <input type="text" class="form-control" placeholder="1234 5678 9012 3456" required> |
| </div> |
| <div class="row mb-3"> |
| <div class="col-md-6"> |
| <label class="form-label">Expiry Date *</label> |
| <input type="text" class="form-control" placeholder="MM/YY" required> |
| </div> |
| <div class="col-md-6"> |
| <label class="form-label">CVV *</label> |
| <input type="text" class="form-control" required> |
| </div> |
| </div> |
| <div class="mb-3"> |
| <label class="form-label">Name on Card *</label> |
| <input type="text" class="form-control" required> |
| </div> |
| <button type="button" class="btn btn-secondary" onclick="prevStep(1)">Back</button> |
| <button type="button" class="btn btn-primary" onclick="nextStep(3)">Review Order</button> |
| </form> |
| </div> |
|
|
| |
| <div id="step3" class="checkout-step"> |
| <h4>Review Your Order</h4> |
| <div id="reviewOrderItems" class="mb-4"> |
| |
| </div> |
| <div class="order-summary mb-4"> |
| <h5>Order Total: $<span id="reviewTotal">0.00</span></h5> |
| </div> |
| <div class="mb-3"> |
| <h5>Shipping Address:</h5> |
| <p id="reviewAddress">Not provided yet</p> |
| </div> |
| <button type="button" class="btn btn-secondary" onclick="prevStep(2)">Back</button> |
| <button type="button" class="btn btn-success" onclick="placeOrder()"> |
| <i class="fas fa-lock me-2"></i>Place Order |
| </button> |
| </div> |
|
|
| |
| <div id="step4" class="checkout-step"> |
| <div class="text-center py-5"> |
| <i class="fas fa-check-circle fa-5x text-success mb-4"></i> |
| <h3>Order Confirmed!</h3> |
| <p class="lead">Thank you for your purchase.</p> |
| <p>Your order number is: <strong>ORD-<span id="orderNumber">0000</span></strong></p> |
| <p>You will receive a confirmation email shortly.</p> |
| <button class="btn btn-primary" onclick="showSection('home')"> |
| Return to Home |
| </button> |
| </div> |
| </div> |
| </div> |
| </div> |
| |
| <div class="col-md-4"> |
| <div class="order-summary"> |
| <h5>Order Summary</h5> |
| <div id="checkoutCartItems"> |
| |
| </div> |
| <table class="table"> |
| <tr> |
| <td>Subtotal:</td> |
| <td class="text-end">$<span id="checkoutSubtotal">0.00</span></td> |
| </tr> |
| <tr> |
| <td>Shipping:</td> |
| <td class="text-end">$<span id="checkoutShipping">5.00</span></td> |
| </tr> |
| <tr> |
| <td>Tax:</td> |
| <td class="text-end">$<span id="checkoutTax">0.00</span></td> |
| </tr> |
| <tr class="table-active"> |
| <th>Total:</th> |
| <th class="text-end">$<span id="checkoutTotal">5.00</span></th> |
| </tr> |
| </table> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <footer class="bg-dark text-white mt-5 py-4"> |
| <div class="container text-center"> |
| <p>© 2024 ShopEasy. All rights reserved.</p> |
| <p class="mb-0"> |
| <a href="#" onclick="showSection('home')" class="text-white me-3">Home</a> | |
| <a href="#" onclick="showSection('products')" class="text-white me-3">Products</a> | |
| <a href="#" onclick="showSection('cart')" class="text-white me-3">Cart</a> | |
| <a href="#" onclick="showSection('checkout')" class="text-white">Checkout</a> |
| </p> |
| </div> |
| </footer> |
|
|
| |
| <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script> |
| <script> |
| |
| const products = [ |
| { id: 1, name: "Wireless Headphones", price: 99.99, image: "https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=400&h=300&fit=crop", category: "Electronics" }, |
| { id: 2, name: "Smart Watch", price: 199.99, image: "https://images.unsplash.com/photo-1523275335684-37898b6baf30?w=400&h=300&fit=crop", category: "Electronics" }, |
| { id: 3, name: "Running Shoes", price: 89.99, image: "https://images.unsplash.com/photo-1542291026-7eec264c27ff?w=400&h=300&fit=crop", category: "Fashion" }, |
| { id: 4, name: "Coffee Maker", price: 49.99, image: "https://images.unsplash.com/photo-1495474472287-4d71bcdd2085?w=400&h=300&fit=crop", category: "Home" }, |
| { id: 5, name: "Backpack", price: 39.99, image: "https://images.unsplash.com/photo-1553062407-98eeb64c6a62?w=400&h=300&fit=crop", category: "Fashion" }, |
| { id: 6, name: "Desk Lamp", price: 29.99, image: "https://images.unsplash.com/photo-1507473885765-e6ed057f782c?w=400&h=300&fit=crop", category: "Home" } |
| ]; |
| |
| |
| let cart = JSON.parse(localStorage.getItem('cart')) || []; |
| let currentStep = 1; |
| |
| |
| document.addEventListener('DOMContentLoaded', function() { |
| loadProducts(); |
| updateCartBadge(); |
| updateNav(); |
| }); |
| |
| |
| function showSection(sectionId) { |
| |
| document.querySelectorAll('.section').forEach(section => { |
| section.classList.remove('active-section'); |
| }); |
| |
| |
| document.getElementById(sectionId).classList.add('active-section'); |
| |
| |
| updateNav(); |
| |
| |
| if (sectionId === 'products') { |
| loadProducts(); |
| } else if (sectionId === 'cart') { |
| updateCartDisplay(); |
| } else if (sectionId === 'checkout') { |
| resetCheckoutSteps(); |
| updateCheckoutDisplay(); |
| } |
| } |
| |
| function updateNav() { |
| const navLinks = document.querySelectorAll('.nav-link'); |
| navLinks.forEach(link => link.classList.remove('active')); |
| |
| const activeSection = document.querySelector('.section.active-section'); |
| if (activeSection) { |
| const sectionId = activeSection.id; |
| const activeLink = document.querySelector(`.nav-link[onclick="showSection('${sectionId}')"]`); |
| if (activeLink) { |
| activeLink.classList.add('active'); |
| } |
| } |
| } |
| |
| |
| function loadProducts() { |
| const productsGrid = document.getElementById('productsGrid'); |
| productsGrid.innerHTML = ''; |
| |
| products.forEach(product => { |
| const productCard = ` |
| <div class="col-md-4 col-lg-4 mb-4"> |
| <div class="card"> |
| <img src="${product.image}" class="card-img-top product-img" alt="${product.name}"> |
| <div class="card-body"> |
| <h5 class="card-title">${product.name}</h5> |
| <p class="card-text">${product.category}</p> |
| <p class="card-text"><strong>$${product.price.toFixed(2)}</strong></p> |
| <button class="btn btn-primary" onclick="addToCart(${product.id})"> |
| <i class="fas fa-cart-plus me-2"></i>Add to Cart |
| </button> |
| </div> |
| </div> |
| </div> |
| `; |
| productsGrid.innerHTML += productCard; |
| }); |
| } |
| |
| |
| function addToCart(productId) { |
| const product = products.find(p => p.id === productId); |
| 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, |
| image: product.image, |
| quantity: 1 |
| }); |
| } |
| |
| saveCart(); |
| updateCartBadge(); |
| showToast(`${product.name} added to cart!`); |
| |
| |
| if (document.getElementById('cart').classList.contains('active-section')) { |
| updateCartDisplay(); |
| } |
| } |
| |
| function removeFromCart(productId) { |
| cart = cart.filter(item => item.id !== productId); |
| saveCart(); |
| updateCartBadge(); |
| updateCartDisplay(); |
| } |
| |
| function updateQuantity(productId, change) { |
| const item = cart.find(item => item.id === productId); |
| if (item) { |
| item.quantity += change; |
| if (item.quantity <= 0) { |
| removeFromCart(productId); |
| } else { |
| saveCart(); |
| updateCartBadge(); |
| updateCartDisplay(); |
| } |
| } |
| } |
| |
| function clearCart() { |
| cart = []; |
| saveCart(); |
| updateCartBadge(); |
| |
| |
| if (document.getElementById('cart').classList.contains('active-section')) { |
| updateCartDisplay(); |
| } |
| |
| |
| if (document.getElementById('checkout').classList.contains('active-section')) { |
| updateCheckoutDisplay(); |
| } |
| |
| showToast('Cart cleared!'); |
| } |
| |
| function saveCart() { |
| localStorage.setItem('cart', JSON.stringify(cart)); |
| updateCartBadge(); |
| } |
| |
| function updateCartBadge() { |
| const totalItems = cart.reduce((sum, item) => sum + item.quantity, 0); |
| document.getElementById('cartBadge').textContent = totalItems; |
| |
| |
| const checkoutBtn = document.getElementById('checkoutBtn'); |
| if (checkoutBtn) { |
| checkoutBtn.disabled = totalItems === 0; |
| } |
| } |
| |
| function updateCartDisplay() { |
| const cartItemsDiv = document.getElementById('cartItems'); |
| const emptyCartMessage = document.getElementById('emptyCartMessage'); |
| |
| |
| if (!cartItemsDiv || !emptyCartMessage) return; |
| |
| if (cart.length === 0) { |
| cartItemsDiv.innerHTML = '<p class="text-muted">Your cart is empty. <a href="#" onclick="showSection(\'products\')">Browse products</a></p>'; |
| emptyCartMessage.style.display = 'block'; |
| } else { |
| emptyCartMessage.style.display = 'none'; |
| |
| let cartHTML = ''; |
| let subtotal = 0; |
| |
| cart.forEach(item => { |
| const itemTotal = item.price * item.quantity; |
| subtotal += itemTotal; |
| |
| cartHTML += ` |
| <div class="cart-item"> |
| <div class="row align-items-center"> |
| <div class="col-2"> |
| <img src="${item.image}" class="img-fluid rounded" alt="${item.name}"> |
| </div> |
| <div class="col-4"> |
| <h6 class="mb-0">${item.name}</h6> |
| <p class="mb-0 text-muted">$${item.price.toFixed(2)}</p> |
| </div> |
| <div class="col-4"> |
| <div class="quantity-control"> |
| <button class="btn btn-sm btn-outline-secondary" onclick="updateQuantity(${item.id}, -1)">-</button> |
| <span class="mx-2">${item.quantity}</span> |
| <button class="btn btn-sm btn-outline-secondary" onclick="updateQuantity(${item.id}, 1)">+</button> |
| </div> |
| </div> |
| <div class="col-2 text-end"> |
| <h6 class="mb-0">$${itemTotal.toFixed(2)}</h6> |
| <button class="btn btn-sm btn-danger mt-1" onclick="removeFromCart(${item.id})"> |
| <i class="fas fa-trash"></i> |
| </button> |
| </div> |
| </div> |
| </div> |
| `; |
| }); |
| |
| cartItemsDiv.innerHTML = cartHTML; |
| |
| const shipping = 5.00; |
| const tax = subtotal * 0.08; |
| const total = subtotal + shipping + tax; |
| |
| |
| const subtotalEl = document.getElementById('subtotal'); |
| const taxEl = document.getElementById('tax'); |
| const totalEl = document.getElementById('total'); |
| |
| if (subtotalEl) subtotalEl.textContent = subtotal.toFixed(2); |
| if (taxEl) taxEl.textContent = tax.toFixed(2); |
| if (totalEl) totalEl.textContent = total.toFixed(2); |
| } |
| } |
| |
| |
| function resetCheckoutSteps() { |
| currentStep = 1; |
| document.querySelectorAll('.checkout-step').forEach(step => { |
| step.classList.remove('active'); |
| }); |
| document.getElementById('step1').classList.add('active'); |
| } |
| |
| function nextStep(stepNumber) { |
| if (stepNumber === 2) { |
| |
| const shippingForm = document.getElementById('shippingForm'); |
| if (!shippingForm.checkValidity()) { |
| shippingForm.reportValidity(); |
| return; |
| } |
| } else if (stepNumber === 3) { |
| |
| const paymentForm = document.getElementById('paymentForm'); |
| if (!paymentForm.checkValidity()) { |
| paymentForm.reportValidity(); |
| return; |
| } |
| updateReviewSection(); |
| } |
| |
| currentStep = stepNumber; |
| document.querySelectorAll('.checkout-step').forEach(step => { |
| step.classList.remove('active'); |
| }); |
| document.getElementById(`step${stepNumber}`).classList.add('active'); |
| } |
| |
| function prevStep(stepNumber) { |
| currentStep = stepNumber; |
| document.querySelectorAll('.checkout-step').forEach(step => { |
| step.classList.remove('active'); |
| }); |
| document.getElementById(`step${stepNumber}`).classList.add('active'); |
| } |
| |
| function updateCheckoutDisplay() { |
| const checkoutCartItems = document.getElementById('checkoutCartItems'); |
| if (!checkoutCartItems) return; |
| |
| let itemsHTML = ''; |
| let subtotal = 0; |
| |
| cart.forEach(item => { |
| const itemTotal = item.price * item.quantity; |
| subtotal += itemTotal; |
| |
| itemsHTML += ` |
| <div class="d-flex justify-content-between mb-2"> |
| <div> |
| <span>${item.name} x ${item.quantity}</span> |
| </div> |
| <div>$${itemTotal.toFixed(2)}</div> |
| </div> |
| `; |
| }); |
| |
| checkoutCartItems.innerHTML = itemsHTML || '<p class="text-muted">No items in cart</p>'; |
| |
| const shipping = 5.00; |
| const tax = subtotal * 0.08; |
| const total = subtotal + shipping + tax; |
| |
| |
| document.getElementById('checkoutSubtotal').textContent = subtotal.toFixed(2); |
| document.getElementById('checkoutTax').textContent = tax.toFixed(2); |
| document.getElementById('checkoutTotal').textContent = total.toFixed(2); |
| document.getElementById('reviewTotal').textContent = total.toFixed(2); |
| } |
| |
| function updateReviewSection() { |
| const reviewOrderItems = document.getElementById('reviewOrderItems'); |
| if (!reviewOrderItems) return; |
| |
| let itemsHTML = '<h5>Items:</h5>'; |
| |
| cart.forEach(item => { |
| itemsHTML += ` |
| <div class="d-flex justify-content-between mb-2"> |
| <div> |
| <span>${item.name} x ${item.quantity}</span> |
| </div> |
| <div>$${(item.price * item.quantity).toFixed(2)}</div> |
| </div> |
| `; |
| }); |
| |
| reviewOrderItems.innerHTML = itemsHTML; |
| |
| |
| const addressInput = document.querySelector('#shippingForm input[type="text"]'); |
| const address = addressInput ? addressInput.value : ''; |
| document.getElementById('reviewAddress').textContent = address || "Not provided"; |
| } |
| |
| function placeOrder() { |
| if (cart.length === 0) { |
| showToast('Your cart is empty!'); |
| return; |
| } |
| |
| |
| const orderNumber = Math.floor(1000 + Math.random() * 9000); |
| document.getElementById('orderNumber').textContent = orderNumber; |
| |
| |
| cart = []; |
| saveCart(); |
| updateCartBadge(); |
| |
| |
| nextStep(4); |
| |
| |
| console.log('Order placed:', orderNumber); |
| showToast('Order placed successfully!'); |
| } |
| |
| |
| function showToast(message) { |
| |
| const toast = document.createElement('div'); |
| toast.className = 'position-fixed bottom-0 end-0 p-3'; |
| toast.style.zIndex = '1050'; |
| toast.innerHTML = ` |
| <div class="toast show" role="alert"> |
| <div class="toast-header"> |
| <strong class="me-auto">ShopEasy</strong> |
| <button type="button" class="btn-close" onclick="this.parentElement.parentElement.parentElement.remove()"></button> |
| </div> |
| <div class="toast-body"> |
| ${message} |
| </div> |
| </div> |
| `; |
| |
| document.body.appendChild(toast); |
| |
| |
| setTimeout(() => { |
| if (toast.parentNode) { |
| toast.parentNode.removeChild(toast); |
| } |
| }, 3000); |
| } |
| </script> |
| </body> |
| </html> |