π 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!