🛒 Project Introduction: Basic E-Commerce Website
This project is a fully functional Basic E-Commerce Website that allows customers to browse products, add them to a cart, and proceed to checkout. It also includes a password-protected Admin Panel for the store owner to manage the product inventory.
The Problem it Solves:
Small business owners often need a simple online store without the complexity of large platforms like Shopify or Magento. This system provides a lightweight, self-hosted solution where the owner can easily add, update, or remove products through an admin interface, and customers can make purchases.
Key Features:
- Customer Side (Public View):
- Product Catalog: Displays all products with images, names, prices, and descriptions.
- Product Categories: Filter products by category.
- Shopping Cart: Add/remove products, update quantities, and view total price.
- Checkout Page: Collect customer information and place orders.
- Order Confirmation: Display order summary after successful checkout.
- Responsive Design: Works on mobile, tablet, and desktop.
- Admin Side (Private Panel):
- Secure Login: Password-protected access.
- Dashboard: Overview of total products, orders, and revenue.
- Product Management: Add, Edit, and Delete products (name, price, description, image, category).
- Order Management: View all customer orders and update order status (Pending, Completed, Cancelled).
- Category Management: Add, Edit, and Delete product categories.
- Logout Functionality.
Technology Stack:
- Frontend: HTML5, CSS3, JavaScript (Vanilla JS for cart functionality).
- Backend: PHP (Core PHP for CRUD operations and session management).
- Database: MySQL.
- Server: Apache (XAMPP/WAMP/LAMP).
📁 Project File Structure
Create this structure in your server's root directory (e.g., htdocs for XAMPP).
ecommerce-basic/ │ ├── index.php # Public homepage - Product listing ├── product.php # Single product details page ├── cart.php # Shopping cart page ├── checkout.php # Checkout page ├── order-confirmation.php # Order success page ├── login.php # Customer login/register (optional) ├── logout.php # Logout script │ ├── admin/ # Admin Panel Directory │ ├── index.php # Admin Login Page │ ├── dashboard.php # Admin Dashboard │ ├── products.php # Manage products (CRUD) │ ├── add-product.php # Add new product form │ ├── edit-product.php # Edit product form │ ├── delete-product.php # Delete product script │ ├── categories.php # Manage categories │ ├── orders.php # View all orders │ ├── logout.php # Admin logout │ └── css/ │ └── admin-style.css # Admin panel styles │ ├── includes/ # Backend PHP logic │ ├── config.php # Database connection │ ├── functions.php # Helper functions │ ├── auth.php # Admin authentication check │ ├── header.php # Public site header │ └── footer.php # Public site footer │ ├── assets/ # Static assets │ ├── css/ │ │ └── style.css # Main CSS for public site │ ├── js/ │ │ └── script.js # Main JS (cart functionality) │ └── images/ │ ├── products/ # Product images (uploaded here) │ └── placeholder.jpg # Default image │ └── database/ └── ecommerce.sql # Database dump file
🗄️ Database Setup (database/ecommerce.sql)
Create a database named ecommerce_db and run this SQL.
-- phpMyAdmin SQL Dump -- Database: `ecommerce_db` CREATE DATABASE IF NOT EXISTS `ecommerce_db`; USE `ecommerce_db`; -- -------------------------------------------------------- -- Table structure for table `categories` -- -------------------------------------------------------- CREATE TABLE `categories` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(100) NOT NULL, `description` text DEFAULT NULL, `created_at` timestamp NOT NULL DEFAULT current_timestamp(), PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- Sample categories INSERT INTO `categories` (`name`, `description`) VALUES ('Electronics', 'Gadgets, devices, and electronic accessories'), ('Clothing', 'Fashionable apparel for men and women'), ('Books', 'Bestsellers and timeless classics'); -- -------------------------------------------------------- -- Table structure for table `products` -- -------------------------------------------------------- CREATE TABLE `products` ( `id` int(11) NOT NULL AUTO_INCREMENT, `category_id` int(11) DEFAULT NULL, `name` varchar(200) NOT NULL, `description` text NOT NULL, `price` decimal(10,2) NOT NULL, `image` varchar(255) DEFAULT 'placeholder.jpg', `stock` int(11) NOT NULL DEFAULT 0, `created_at` timestamp NOT NULL DEFAULT current_timestamp(), PRIMARY KEY (`id`), KEY `category_id` (`category_id`), CONSTRAINT `products_ibfk_1` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE SET NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- Sample products INSERT INTO `products` (`category_id`, `name`, `description`, `price`, `image`, `stock`) VALUES (1, 'Wireless Headphones', 'High-quality wireless headphones with noise cancellation.', 79.99, 'headphones.jpg', 25), (1, 'Smart Watch', 'Track your fitness and stay connected.', 199.99, 'smartwatch.jpg', 15), (2, 'Cotton T-Shirt', 'Comfortable 100% cotton t-shirt, available in multiple colors.', 24.99, 'tshirt.jpg', 50), (3, 'The Great Novel', 'A captivating story that will keep you hooked.', 14.99, 'novel.jpg', 100); -- -------------------------------------------------------- -- Table structure for table `orders` -- -------------------------------------------------------- CREATE TABLE `orders` ( `id` int(11) NOT NULL AUTO_INCREMENT, `customer_name` varchar(100) NOT NULL, `customer_email` varchar(100) NOT NULL, `customer_address` text NOT NULL, `total_amount` decimal(10,2) NOT NULL, `status` enum('pending','processing','completed','cancelled') DEFAULT 'pending', `created_at` timestamp NOT NULL DEFAULT current_timestamp(), PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- -------------------------------------------------------- -- Table structure for table `order_items` -- -------------------------------------------------------- CREATE TABLE `order_items` ( `id` int(11) NOT NULL AUTO_INCREMENT, `order_id` int(11) NOT NULL, `product_id` int(11) NOT NULL, `product_name` varchar(200) NOT NULL, `quantity` int(11) NOT NULL, `price` decimal(10,2) NOT NULL, PRIMARY KEY (`id`), KEY `order_id` (`order_id`), CONSTRAINT `order_items_ibfk_1` FOREIGN KEY (`order_id`) REFERENCES `orders` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- -------------------------------------------------------- -- Table structure for table `admin` -- -------------------------------------------------------- CREATE TABLE `admin` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL, `password` varchar(255) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- Default admin: username = admin, password = admin123 (hashed) -- You need to hash this manually or use a script INSERT INTO `admin` (`username`, `password`) VALUES ('admin', '$2y$10$YourHashedPasswordHere'); -- Replace with actual hash COMMIT; 💻 The Core Code
Here are the essential code snippets for the main functionality.
1. Database Configuration (includes/config.php)
<?php // Database configuration $host = 'localhost'; $dbname = 'ecommerce_db'; $username = 'root'; // Default XAMPP username $password = ''; // Default XAMPP password (empty) try { $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8mb4", $username, $password); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); } catch(PDOException $e) { die("Connection failed: " . $e->getMessage()); } // Start session for cart functionality if (session_status() == PHP_SESSION_NONE) { session_start(); } // Initialize cart if it doesn't exist if (!isset($_SESSION['cart'])) { $_SESSION['cart'] = []; } // Helper function to sanitize input function sanitize($data) { $data = trim($data); $data = stripslashes($data); $data = htmlspecialchars($data); return $data; } // Helper function to format currency function formatCurrency($amount) { return '$' . number_format($amount, 2); } // Get total items in cart function getCartCount() { return array_sum(array_column($_SESSION['cart'], 'quantity')); } // Get cart subtotal function getCartSubtotal() { $subtotal = 0; foreach ($_SESSION['cart'] as $item) { $subtotal += $item['price'] * $item['quantity']; } return $subtotal; } ?> 2. Public Header (includes/header.php)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title><?php echo $page_title ?? 'E-Commerce Store'; ?></title> <link rel="stylesheet" href="assets/css/style.css"> </head> <body> <header> <nav class="navbar"> <div class="container"> <a href="index.php" class="logo">MyStore</a> <ul class="nav-links"> <li><a href="index.php">Home</a></li> <li><a href="index.php?category=1">Electronics</a></li> <li><a href="index.php?category=2">Clothing</a></li> <li><a href="index.php?category=3">Books</a></li> </ul> <div class="cart-icon"> <a href="cart.php"> 🛒 Cart <span class="cart-count"><?php echo getCartCount(); ?></span> </a> </div> </div> </nav> </header> <main>
3. Public Footer (includes/footer.php)
</main> <footer> <div class="container"> <p>© 2023 MyStore. All rights reserved.</p> </div> </footer> <script src="assets/js/script.js"></script> </body> </html>
4. Product Listing Page (index.php)
<?php $page_title = 'Home - MyStore'; require_once 'includes/config.php'; require_once 'includes/header.php'; // Get category filter $category_id = isset($_GET['category']) ? (int)$_GET['category'] : 0; // Fetch categories for filter $categories = $pdo->query("SELECT * FROM categories ORDER BY name")->fetchAll(); // Fetch products with optional category filter if ($category_id > 0) { $stmt = $pdo->prepare("SELECT p.*, c.name as category_name FROM products p LEFT JOIN categories c ON p.category_id = c.id WHERE p.category_id = ? ORDER BY p.created_at DESC"); $stmt->execute([$category_id]); $products = $stmt->fetchAll(); } else { $products = $pdo->query("SELECT p.*, c.name as category_name FROM products p LEFT JOIN categories c ON p.category_id = c.id ORDER BY p.created_at DESC")->fetchAll(); } ?> <div class="container"> <div class="row"> <!-- Sidebar with categories --> <aside class="sidebar"> <h3>Categories</h3> <ul class="category-list"> <li><a href="index.php" class="<?php echo !$category_id ? 'active' : ''; ?>">All Products</a></li> <?php foreach ($categories as $cat): ?> <li> <a href="index.php?category=<?php echo $cat['id']; ?>" class="<?php echo $category_id == $cat['id'] ? 'active' : ''; ?>"> <?php echo htmlspecialchars($cat['name']); ?> </a> </li> <?php endforeach; ?> </ul> </aside> <!-- Main content - Product grid --> <main class="main-content"> <h1>Our Products</h1> <?php if (empty($products)): ?> <p>No products found in this category.</p> <?php else: ?> <div class="product-grid"> <?php foreach ($products as $product): ?> <div class="product-card"> <img src="assets/images/products/<?php echo htmlspecialchars($product['image']); ?>" alt="<?php echo htmlspecialchars($product['name']); ?>" onerror="this.src='assets/images/placeholder.jpg'"> <h3><?php echo htmlspecialchars($product['name']); ?></h3> <p class="price"><?php echo formatCurrency($product['price']); ?></p> <p class="stock">Stock: <?php echo $product['stock']; ?></p> <a href="product.php?id=<?php echo $product['id']; ?>" class="btn">View Details</a> <button onclick="addToCart(<?php echo $product['id']; ?>, 1)" class="btn btn-primary">Add to Cart</button> </div> <?php endforeach; ?> </div> <?php endif; ?> </main> </div> </div> <script> function addToCart(productId, quantity) { fetch('cart-actions.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: 'action=add&product_id=' + productId + '&quantity=' + quantity }) .then(response => response.json()) .then(data => { if (data.success) { // Update cart count in header document.querySelector('.cart-count').textContent = data.cart_count; alert('Product added to cart!'); } }); } </script> <?php require_once 'includes/footer.php'; ?> 5. Cart Page (cart.php)
<?php $page_title = 'Shopping Cart - MyStore'; require_once 'includes/config.php'; require_once 'includes/header.php'; // Handle quantity updates if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (isset($_POST['update_cart'])) { foreach ($_POST['quantity'] as $product_id => $quantity) { if ($quantity <= 0) { unset($_SESSION['cart'][$product_id]); } else { $_SESSION['cart'][$product_id]['quantity'] = (int)$quantity; } } } if (isset($_POST['remove_item'])) { $product_id = $_POST['product_id']; unset($_SESSION['cart'][$product_id]); } // Redirect to prevent form resubmission header('Location: cart.php'); exit; } ?> <div class="container"> <h1>Shopping Cart</h1> <?php if (empty($_SESSION['cart'])): ?> <p>Your cart is empty. <a href="index.php">Continue shopping</a></p> <?php else: ?> <form method="POST" action=""> <table class="cart-table"> <thead> <tr> <th>Product</th> <th>Price</th> <th>Quantity</th> <th>Subtotal</th> <th>Action</th> </tr> </thead> <tbody> <?php $total = 0; foreach ($_SESSION['cart'] as $product_id => $item): $subtotal = $item['price'] * $item['quantity']; $total += $subtotal; ?> <tr> <td> <img src="assets/images/products/<?php echo htmlspecialchars($item['image']); ?>" alt="<?php echo htmlspecialchars($item['name']); ?>" width="50"> <?php echo htmlspecialchars($item['name']); ?> </td> <td><?php echo formatCurrency($item['price']); ?></td> <td> <input type="number" name="quantity[<?php echo $product_id; ?>]" value="<?php echo $item['quantity']; ?>" min="0" max="99" style="width: 60px;"> </td> <td><?php echo formatCurrency($subtotal); ?></td> <td> <button type="submit" name="remove_item" value="1" onclick="this.form.product_id.value='<?php echo $product_id; ?>'"> Remove </button> <input type="hidden" name="product_id" value=""> </td> </tr> <?php endforeach; ?> </tbody> <tfoot> <tr> <td colspan="3" align="right"><strong>Total:</strong></td> <td><strong><?php echo formatCurrency($total); ?></strong></td> <td></td> </tr> </tfoot> </table> <div class="cart-actions"> <button type="submit" name="update_cart" class="btn">Update Cart</button> <a href="checkout.php" class="btn btn-primary">Proceed to Checkout</a> </div> </form> <?php endif; ?> </div> <?php require_once 'includes/footer.php'; ?> 6. Cart Actions AJAX Handler (cart-actions.php)
<?php require_once 'includes/config.php'; header('Content-Type: application/json'); $action = $_POST['action'] ?? ''; switch ($action) { case 'add': $product_id = (int)$_POST['product_id']; $quantity = (int)$_POST['quantity']; // Fetch product details from database $stmt = $pdo->prepare("SELECT id, name, price, image FROM products WHERE id = ?"); $stmt->execute([$product_id]); $product = $stmt->fetch(); if ($product) { if (isset($_SESSION['cart'][$product_id])) { $_SESSION['cart'][$product_id]['quantity'] += $quantity; } else { $_SESSION['cart'][$product_id] = [ 'name' => $product['name'], 'price' => $product['price'], 'image' => $product['image'], 'quantity' => $quantity ]; } echo json_encode([ 'success' => true, 'cart_count' => getCartCount(), 'message' => 'Product added to cart' ]); } else { echo json_encode(['success' => false, 'message' => 'Product not found']); } break; case 'remove': $product_id = (int)$_POST['product_id']; unset($_SESSION['cart'][$product_id]); echo json_encode([ 'success' => true, 'cart_count' => getCartCount(), 'message' => 'Product removed from cart' ]); break; default: echo json_encode(['success' => false, 'message' => 'Invalid action']); } ?> 7. Checkout Page (checkout.php)
<?php $page_title = 'Checkout - MyStore'; require_once 'includes/config.php'; // Redirect if cart is empty if (empty($_SESSION['cart'])) { header('Location: index.php'); exit; } $error = ''; $success = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST') { $name = sanitize($_POST['name'] ?? ''); $email = sanitize($_POST['email'] ?? ''); $address = sanitize($_POST['address'] ?? ''); if (empty($name) || empty($email) || empty($address)) { $error = 'Please fill in all fields'; } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) { $error = 'Please enter a valid email address'; } else { try { $pdo->beginTransaction(); // Calculate total $total = getCartSubtotal(); // Insert order $stmt = $pdo->prepare("INSERT INTO orders (customer_name, customer_email, customer_address, total_amount) VALUES (?, ?, ?, ?)"); $stmt->execute([$name, $email, $address, $total]); $order_id = $pdo->lastInsertId(); // Insert order items $stmt = $pdo->prepare("INSERT INTO order_items (order_id, product_id, product_name, quantity, price) VALUES (?, ?, ?, ?, ?)"); foreach ($_SESSION['cart'] as $product_id => $item) { $stmt->execute([ $order_id, $product_id, $item['name'], $item['quantity'], $item['price'] ]); // Update stock (optional) $updateStock = $pdo->prepare("UPDATE products SET stock = stock - ? WHERE id = ?"); $updateStock->execute([$item['quantity'], $product_id]); } $pdo->commit(); // Clear cart $_SESSION['cart'] = []; // Redirect to confirmation page header("Location: order-confirmation.php?order_id=$order_id"); exit; } catch (Exception $e) { $pdo->rollBack(); $error = 'An error occurred. Please try again.'; } } } require_once 'includes/header.php'; ?> <div class="container"> <h1>Checkout</h1> <?php if ($error): ?> <div class="alert alert-error"><?php echo $error; ?></div> <?php endif; ?> <div class="checkout-container"> <div class="checkout-form"> <h2>Customer Information</h2> <form method="POST" action=""> <div class="form-group"> <label for="name">Full Name *</label> <input type="text" id="name" name="name" required value="<?php echo htmlspecialchars($_POST['name'] ?? ''); ?>"> </div> <div class="form-group"> <label for="email">Email *</label> <input type="email" id="email" name="email" required value="<?php echo htmlspecialchars($_POST['email'] ?? ''); ?>"> </div> <div class="form-group"> <label for="address">Shipping Address *</label> <textarea id="address" name="address" rows="4" required><?php echo htmlspecialchars($_POST['address'] ?? ''); ?></textarea> </div> <button type="submit" class="btn btn-primary btn-block">Place Order</button> </form> </div> <div class="order-summary"> <h2>Order Summary</h2> <table> <?php foreach ($_SESSION['cart'] as $item): ?> <tr> <td><?php echo htmlspecialchars($item['name']); ?> x <?php echo $item['quantity']; ?></td> <td><?php echo formatCurrency($item['price'] * $item['quantity']); ?></td> </tr> <?php endforeach; ?> <tr class="total"> <td><strong>Total:</strong></td> <td><strong><?php echo formatCurrency(getCartSubtotal()); ?></strong></td> </tr> </table> </div> </div> </div> <?php require_once 'includes/footer.php'; ?> 8. Admin Authentication (admin/index.php)
<?php session_start(); // If already logged in, redirect to dashboard if (isset($_SESSION['admin_loggedin']) && $_SESSION['admin_loggedin'] === true) { header('Location: dashboard.php'); exit; } require_once '../includes/config.php'; $error = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST') { $username = $_POST['username'] ?? ''; $password = $_POST['password'] ?? ''; $stmt = $pdo->prepare("SELECT id, username, password FROM admin WHERE username = ?"); $stmt->execute([$username]); $admin = $stmt->fetch(); if ($admin && password_verify($password, $admin['password'])) { $_SESSION['admin_loggedin'] = true; $_SESSION['admin_id'] = $admin['id']; $_SESSION['admin_username'] = $admin['username']; header('Location: dashboard.php'); exit; } else { $error = 'Invalid username or password'; } } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Admin Login</title> <link rel="stylesheet" href="css/admin-style.css"> </head> <body class="login-page"> <div class="login-container"> <h1>Admin Login</h1> <?php if ($error): ?> <div class="alert alert-error"><?php echo $error; ?></div> <?php endif; ?> <form method="POST" action=""> <div class="form-group"> <label for="username">Username</label> <input type="text" id="username" name="username" required> </div> <div class="form-group"> <label for="password">Password</label> <input type="password" id="password" name="password" required> </div> <button type="submit" class="btn btn-primary btn-block">Login</button> </form> </div> </body> </html> 9. Admin Dashboard (admin/dashboard.php)
<?php require_once '../includes/config.php'; require_once '../includes/auth.php'; // Get statistics $totalProducts = $pdo->query("SELECT COUNT(*) FROM products")->fetchColumn(); $totalOrders = $pdo->query("SELECT COUNT(*) FROM orders")->fetchColumn(); $totalRevenue = $pdo->query("SELECT SUM(total_amount) FROM orders WHERE status != 'cancelled'")->fetchColumn(); $recentOrders = $pdo->query("SELECT * FROM orders ORDER BY created_at DESC LIMIT 5")->fetchAll(); ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Admin Dashboard</title> <link rel="stylesheet" href="css/admin-style.css"> </head> <body> <div class="admin-container"> <?php include 'includes/sidebar.php'; ?> <main class="admin-main"> <h1>Dashboard</h1> <div class="stats-grid"> <div class="stat-card"> <h3>Total Products</h3> <p class="stat-number"><?php echo $totalProducts; ?></p> </div> <div class="stat-card"> <h3>Total Orders</h3> <p class="stat-number"><?php echo $totalOrders; ?></p> </div> <div class="stat-card"> <h3>Total Revenue</h3> <p class="stat-number"><?php echo formatCurrency($totalRevenue ?? 0); ?></p> </div> </div> <h2>Recent Orders</h2> <table class="data-table"> <thead> <tr> <th>Order ID</th> <th>Customer</th> <th>Total</th> <th>Status</th> <th>Date</th> <th>Actions</th> </tr> </thead> <tbody> <?php foreach ($recentOrders as $order): ?> <tr> <td>#<?php echo $order['id']; ?></td> <td><?php echo htmlspecialchars($order['customer_name']); ?></td> <td><?php echo formatCurrency($order['total_amount']); ?></td> <td> <span class="status status-<?php echo $order['status']; ?>"> <?php echo $order['status']; ?> </span> </td> <td><?php echo date('M d, Y', strtotime($order['created_at'])); ?></td> <td> <a href="order-details.php?id=<?php echo $order['id']; ?>" class="btn-small">View</a> </td> </tr> <?php endforeach; ?> </tbody> </table> </main> </div> </body> </html> 10. CSS Styling (assets/css/style.css)
/* Reset and Base Styles */ * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; } .container { max-width: 1200px; margin: 0 auto; padding: 0 20px; } /* Navigation */ .navbar { background: #333; color: #fff; padding: 1rem 0; } .navbar .container { display: flex; justify-content: space-between; align-items: center; } .logo { color: #fff; text-decoration: none; font-size: 1.5rem; font-weight: bold; } .nav-links { list-style: none; display: flex; } .nav-links li { margin-left: 20px; } .nav-links a { color: #fff; text-decoration: none; } .nav-links a:hover { color: #ff6b6b; } .cart-icon a { color: #fff; text-decoration: none; padding: 5px 10px; background: #ff6b6b; border-radius: 4px; } .cart-count { background: #fff; color: #333; padding: 2px 6px; border-radius: 50%; font-size: 0.8rem; margin-left: 5px; } /* Layout */ .row { display: flex; gap: 30px; margin-top: 30px; } .sidebar { flex: 1; background: #f4f4f4; padding: 20px; border-radius: 8px; } .main-content { flex: 3; } /* Category List */ .category-list { list-style: none; margin-top: 15px; } .category-list li { margin-bottom: 10px; } .category-list a { color: #333; text-decoration: none; display: block; padding: 5px 10px; border-radius: 4px; } .category-list a:hover, .category-list a.active { background: #ff6b6b; color: #fff; } /* Product Grid */ .product-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 20px; margin-top: 20px; } .product-card { border: 1px solid #ddd; border-radius: 8px; padding: 15px; text-align: center; } .product-card img { max-width: 100%; height: 200px; object-fit: cover; border-radius: 4px; margin-bottom: 10px; } .product-card h3 { margin-bottom: 10px; } .price { font-size: 1.2rem; font-weight: bold; color: #ff6b6b; margin-bottom: 10px; } .stock { color: #666; margin-bottom: 15px; } .btn { display: inline-block; padding: 8px 16px; background: #f4f4f4; color: #333; text-decoration: none; border: none; border-radius: 4px; cursor: pointer; margin: 2px; } .btn-primary { background: #ff6b6b; color: #fff; } .btn-block { display: block; width: 100%; } /* Cart Table */ .cart-table { width: 100%; border-collapse: collapse; margin-top: 20px; } .cart-table th, .cart-table td { padding: 10px; text-align: left; border-bottom: 1px solid #ddd; } .cart-table th { background: #f4f4f4; } .cart-actions { margin-top: 20px; display: flex; gap: 10px; justify-content: flex-end; } /* Checkout */ .checkout-container { display: grid; grid-template-columns: 2fr 1fr; gap: 30px; margin-top: 20px; } .form-group { margin-bottom: 15px; } .form-group label { display: block; margin-bottom: 5px; font-weight: bold; } .form-group input, .form-group textarea { width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; } .order-summary { background: #f4f4f4; padding: 20px; border-radius: 8px; } .order-summary table { width: 100%; margin-top: 15px; } .order-summary td { padding: 10px 0; } .order-summary .total { border-top: 2px solid #ddd; font-size: 1.2rem; } /* Alerts */ .alert { padding: 10px 15px; border-radius: 4px; margin-bottom: 20px; } .alert-error { background: #ffe6e6; color: #cc0000; border: 1px solid #ff9999; } /* Footer */ footer { background: #333; color: #fff; text-align: center; padding: 20px 0; margin-top: 40px; } /* Responsive */ @media (max-width: 768px) { .row { flex-direction: column; } .checkout-container { grid-template-columns: 1fr; } .nav-links { display: none; } } 📝 How to Use This Project (Step-by-Step Guide)
Step 1: Install Local Server
- Download and install XAMPP from apachefriends.org
- Install and launch XAMPP Control Panel
- Start Apache and MySQL services
Step 2: Create Project Folder
- Navigate to
C:\xampp\htdocs\(Windows) or/Applications/XAMPP/htdocs/(Mac) - Create a new folder named
ecommerce-basic
Step 3: Set Up Database
- Open browser and go to
http://localhost/phpmyadmin - Click on "SQL" tab
- Copy the entire SQL from
database/ecommerce.sqlabove - Paste and click "Go" to create database and tables
Step 4: Create Admin Password Hash
- Create a file named
hash.phpin your project root:
<?php echo password_hash('admin123', PASSWORD_DEFAULT); ?> - Run it:
http://localhost/ecommerce-basic/hash.php - Copy the output (long hash string)
- In phpMyAdmin, open
admintable - Replace the password field value with your copied hash
- Delete
hash.phpafter done
Step 5: Add Product Images
- Download some sample product images
- Place them in
assets/images/products/ - Make sure filenames match those in database (headphones.jpg, smartwatch.jpg, etc.)
Step 6: Configure Database Connection
- Open
includes/config.php - Verify database credentials:
$host = 'localhost'; $dbname = 'ecommerce_db'; $username = 'root'; // Default XAMPP username $password = ''; // Default XAMPP password (empty)
Step 7: Test the Website
Customer Side:
- Open:
http://localhost/ecommerce-basic/ - Browse products
- Add items to cart
- View cart and update quantities
- Proceed to checkout
Admin Side:
- Open:
http://localhost/ecommerce-basic/admin/ - Login with: Username: admin, Password: admin123
- View dashboard
- Manage products (add/edit/delete)
- View orders
Step 8: Add Sample Products via Admin
- Log in to admin panel
- Go to "Products" → "Add New"
- Fill in product details:
- Name: "Gaming Mouse"
- Category: Electronics
- Price: 49.99
- Description: "High-precision gaming mouse with RGB lighting"
- Stock: 30
- Image: Upload an image
Step 9: Customize the Store
- Edit
includes/header.phpto change store name - Modify
assets/css/style.cssto change colors and styling - Add more categories in admin panel
- Add payment gateway integration (optional)
Step 10: Deploy to Live Server
- Upload all files to your web hosting
- Create MySQL database on hosting
- Import the SQL file
- Update
includes/config.phpwith live database credentials - Generate new password hash on live server
- Update file permissions for image uploads
🎯 Features Summary
Customer Features:
- ✅ Browse products by category
- ✅ View product details
- ✅ Add to cart with AJAX
- ✅ Update cart quantities
- ✅ Remove items from cart
- ✅ Checkout form
- ✅ Order confirmation
- ✅ Responsive design
Admin Features:
- ✅ Secure login
- ✅ Dashboard with statistics
- ✅ Add new products
- ✅ Edit existing products
- ✅ Delete products
- ✅ Manage categories
- ✅ View all orders
- ✅ Update order status
- ✅ Product image upload
Database Features:
- ✅ Products table with categories
- ✅ Orders and order items tracking
- ✅ Stock management
- ✅ Admin authentication
- ✅ Foreign key relationships
🚀 Future Enhancements Ideas
- User Accounts: Allow customers to create accounts and view order history
- Payment Integration: Add Stripe or PayPal payment gateway
- Product Search: Add search functionality
- Product Reviews: Let customers leave reviews
- Email Notifications: Send order confirmation emails
- Discount Codes: Add coupon/promo code system
- Product Variants: Support sizes, colors, etc.
- Wishlist: Let customers save items for later
- Related Products: Show related items on product page
- Inventory Alerts: Notify admin when stock is low
This basic e-commerce website provides a solid foundation that you can build upon and customize according to your specific needs!