ASSISTANT
Creating a comprehensive PHP-based Management System for Kaak Alia Bakery involves several steps, including setting up the environment, designing the database, developing the backend and frontend, and implementing security measures. Below is a step-by-step guide, including code snippets and file structure organization, to help you build this system.
## Table of Contents
1. [Project Structure](#project-structure)
2. [Environment Setup](#environment-setup)
3. [Database Design](#database-design)
4. [Creating the Database and Tables](#creating-the-database-and-tables)
5. [Configuration File](#configuration-file)
6. [User Authentication](#user-authentication)
7. [Order Management](#order-management)
8. [Product Selection](#product-selection)
9. [Order Status Tracking](#order-status-tracking)
10. [Reporting](#reporting)
11. [User Management](#user-management)
12. [Security Measures](#security-measures)
13. [Running the Application](#running-the-application)
---
## Project Structure
Organize your project files in a structured manner to maintain clarity and scalability.
```
kaak_alia_management_system/
├── assets/
│ ├── css/
│ │ └── styles.css
│ ├── js/
│ │ └── scripts.js
│ └── bootstrap/
│ ├── css/
│ └── js/
├── config/
│ └── config.php
├── includes/
│ ├── header.php
│ ├── footer.php
│ ├── auth.php
│ └── db_connect.php
├── public/
│ ├── index.php
│ ├── login.php
│ ├── logout.php
│ ├── dashboard.php
│ ├── orders/
│ │ ├── add_order.php
│ │ ├── view_orders.php
│ │ └── edit_order.php
│ ├── products/
│ │ └── manage_products.php
│ ├── users/
│ │ └── manage_users.php
│ └── reports/
│ └── generate_reports.php
└── sql/
└── kaak_alia.sql
```
---
## Environment Setup
1. **Install PHP and MySQL:**
- Use [XAMPP](https://www.apachefriends.org/index.html) or similar to set up a local development environment.
2. **Install Composer (Optional):**
- Composer can help manage dependencies, although for this project, no external packages are required.
3. **Set Up the Project Directory:**
- Place the `kaak_alia_management_system` folder inside the `htdocs` directory (for XAMPP) or the equivalent public directory for your server.
---
## Database Design
Design the database to handle users, orders, products, and order statuses.
### Tables
1. **users**
- `id` (INT, Primary Key, Auto Increment)
- `username` (VARCHAR)
- `password` (VARCHAR)
- `role` (ENUM: 'admin', 'staff')
2. **customers**
- `id` (INT, Primary Key, Auto Increment)
- `name` (VARCHAR)
- `contact` (VARCHAR)
- `delivery_address` (TEXT)
3. **products**
- `id` (INT, Primary Key, Auto Increment)
- `name` (VARCHAR)
- `size` (VARCHAR)
- `price` (DECIMAL)
- `category` (VARCHAR)
4. **orders**
- `id` (INT, Primary Key, Auto Increment)
- `customer_id` (INT, Foreign Key)
- `product_id` (INT, Foreign Key)
- `quantity` (INT)
- `packaging_preferences` (VARCHAR)
- `status` (ENUM: 'Pending', 'In Progress', 'Completed', 'Delivered')
- `order_date` (DATETIME)
---
## Creating the Database and Tables
Create a database named `kaak_alia` and execute the following SQL script to create the necessary tables.
**File:** `sql/kaak_alia.sql`
```sql
CREATE DATABASE IF NOT EXISTS kaak_alia;
USE kaak_alia;
-- Users Table
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
role ENUM('admin', 'staff') NOT NULL
);
-- Customers Table
CREATE TABLE IF NOT EXISTS customers (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
contact VARCHAR(50),
delivery_address TEXT
);
-- Products Table
CREATE TABLE IF NOT EXISTS products (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
size VARCHAR(50),
price DECIMAL(10,2) NOT NULL,
category VARCHAR(50)
);
-- Orders Table
CREATE TABLE IF NOT EXISTS orders (
id INT AUTO_INCREMENT PRIMARY KEY,
customer_id INT NOT NULL,
product_id INT NOT NULL,
quantity INT NOT NULL,
packaging_preferences VARCHAR(255),
status ENUM('Pending', 'In Progress', 'Completed', 'Delivered') DEFAULT 'Pending',
order_date DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (customer_id) REFERENCES customers(id),
FOREIGN KEY (product_id) REFERENCES products(id)
);
-- Insert Default Admin User
INSERT INTO users (username, password, role) VALUES (
'admin',
'$2y$10$e0NR4EJkO3jUuL1KqJx3E.E0Iojb95czjJGb2a7v0GfN0V8pQBv8W', -- Password: admin123 (hashed)
'admin'
);
-- Insert Products
INSERT INTO products (name, size, price, category) VALUES
('Savory Cake', 'Large', 12.00, 'Savory Cake'),
('Mini Savory Cake', 'Mini', 6.00, 'Savory Cake'),
('Mini Savory Cake', 'Mini x24', 9.00, 'Savory Cake'),
('Mini Savory Cake', 'Mini x36', 12.00, 'Savory Cake'),
('Special Occasion Box', '35 pieces', 14.5, 'Savory Cake'),
('Crunchy Pudding', '12 pieces', 12.00, 'Crunchy Pudding'),
('Kaak - Regular Box Half-kilo', 'Half-kilo', 6.00, 'Kaak'),
('Kaak - Regular Box One-kilo', 'One-kilo', 8.00, 'Kaak'),
('Visitor’s Basket - Small', 'Small Basket', 8.00, 'Kaak'),
('Visitor’s Basket - Large', 'Large Basket', 10.00, 'Kaak'),
('Special Occasion Box - Kaak', '33 pieces', 11.00, 'Kaak');
```
**Instructions:**
1. Open phpMyAdmin or any MySQL client.
2. Execute the script above to set up the database and tables.
---
## Configuration File
Create a configuration file to manage database connections.
**File:** `config/config.php`
```php
<?php
// config/config.php
define('DB_HOST', 'localhost');
define('DB_USER', 'root'); // Change if different
define('DB_PASS', ''); // Change if you have a password
define('DB_NAME', 'kaak_alia');
?>
```
---
## Database Connection
Create a database connection script.
**File:** `includes/db_connect.php`
```php
<?php
// includes/db_connect.php
require_once '../config/config.php';
$conn = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
?>
```
---
## User Authentication
Implement user login and session management.
### Login Page
**File:** `public/login.php`
```php
<?php
// public/login.php
session_start();
require_once '../includes/db_connect.php';
if (isset($_SESSION['user_id'])) {
header("Location: dashboard.php");
exit();
}
$error = '';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$username = $conn->real_escape_string($_POST['username']);
$password = $_POST['password'];
$sql = "SELECT * FROM users WHERE username = '$username' LIMIT 1";
$result = $conn->query($sql);
if ($result->num_rows == 1) {
$user = $result->fetch_assoc();
if (password_verify($password, $user['password'])) {
// Password matches
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $user['username'];
$_SESSION['role'] = $user['role'];
header("Location: dashboard.php");
exit();
} else {
$error = "Invalid password.";
}
} else {
$error = "User not found.";
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Kaak Alia Management System - Login</title>
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
</head>
<body class="bg-light">
<div class="container mt-5">
<div class="row justify-content-center">
<div class="col-md-4">
<h3 class="text-center">Kaak Alia Management System</h3>
<div class="card mt-4">
<div class="card-body">
<?php if ($error): ?>
<div class="alert alert-danger"><?= $error ?></div>
<?php endif; ?>
<form method="POST" action="">
<div class="form-group mb-3">
<label>Username</label>
<input type="text" name="username" class="form-control" required/>
</div>
<div class="form-group mb-3">
<label>Password</label>
<input type="password" name="password" class="form-control" required/>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-primary">Login</button>
</div>
</form>
</div>
</div>
<p class="text-center mt-3">© 2024 Kaak Alia Bakery</p>
</div>
</div>
</div>
<script src="bootstrap/js/bootstrap.bundle.min.js"></script>
</body>
</html>
```
### Logout Script
**File:** `public/logout.php`
```php
<?php
// public/logout.php
session_start();
session_unset();
session_destroy();
header("Location: login.php");
exit();
?>
```
### Authentication Check
Create a script to protect pages.
**File:** `includes/auth.php`
```php
<?php
// includes/auth.php
session_start();
if (!isset($_SESSION['user_id'])) {
header("Location: login.php");
exit();
}
?>
```
---
## Dashboard
Create a dashboard page that serves as the main navigation hub.
**File:** `public/dashboard.php`
```php
<?php
// public/dashboard.php
require_once '../includes/auth.php';
require_once '../includes/db_connect.php';
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Dashboard - Kaak Alia Management System</title>
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
</head>
<body>
<?php include '../includes/header.php'; ?>
<div class="container mt-4">
<h2>Welcome, <?= htmlspecialchars($_SESSION['username']) ?>!</h2>
<div class="row mt-3">
<div class="col-md-3">
<a href="orders/add_order.php" class="btn btn-primary btn-block w-100 mb-2">Add New Order</a>
</div>
<div class="col-md-3">
<a href="orders/view_orders.php" class="btn btn-secondary btn-block w-100 mb-2">View Orders</a>
</div>
<div class="col-md-3">
<a href="products/manage_products.php" class="btn btn-info btn-block w-100 mb-2">Manage Products</a>
</div>
<div class="col-md-3">
<a href="users/manage_users.php" class="btn btn-warning btn-block w-100 mb-2">Manage Users</a>
</div>
<div class="col-md-3">
<a href="reports/generate_reports.php" class="btn btn-success btn-block w-100 mb-2">Generate Reports</a>
</div>
</div>
</div>
<?php include '../includes/footer.php'; ?>
<script src="bootstrap/js/bootstrap.bundle.min.js"></script>
</body>
</html>
```
---
## Header and Footer
Create reusable header and footer components.
### Header
**File:** `includes/header.php`
```php
<?php
// includes/header.php
?>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="dashboard.php">Kaak Alia</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse justify-content-end" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="dashboard.php">Dashboard</a>
</li>
<!-- Add more navigation items if needed -->
<li class="nav-item">
<a class="nav-link" href="logout.php">Logout (<?= htmlspecialchars($_SESSION['username']) ?>)</a>
</li>
</ul>
</div>
</div>
</nav>
```
### Footer
**File:** `includes/footer.php`
```php
<?php
// includes/footer.php
?>
<footer class="bg-light text-center text-lg-start mt-5">
<div class="text-center p-3">
© 2024 Kaak Alia Bakery
</div>
</footer>
```
---
## Order Management
Implement functionalities to add, view, and edit orders.
### Add New Order
**File:** `public/orders/add_order.php`
```php
<?php
// public/orders/add_order.php
require_once '../../includes/auth.php';
require_once '../../includes/db_connect.php';
$success = '';
$error = '';
// Fetch products for selection
$products_sql = "SELECT * FROM products ORDER BY name ASC";
$products_result = $conn->query($products_sql);
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Sanitize and validate input
$customer_name = $conn->real_escape_string($_POST['customer_name']);
$contact = $conn->real_escape_string($_POST['contact']);
$delivery_address = $conn->real_escape_string($_POST['delivery_address']);
$product_id = intval($_POST['product_id']);
$quantity = intval($_POST['quantity']);
$packaging_preferences = $conn->real_escape_string($_POST['packaging_preferences']);
if ($customer_name && $product_id && $quantity) {
// Insert into customers table
$customer_sql = "INSERT INTO customers (name, contact, delivery_address)
VALUES ('$customer_name', '$contact', '$delivery_address')";
if ($conn->query($customer_sql) === TRUE) {
$customer_id = $conn->insert_id;
// Insert into orders table
$order_sql = "INSERT INTO orders
(customer_id, product_id, quantity, packaging_preferences)
VALUES
('$customer_id', '$product_id', '$quantity', '$packaging_preferences')";
if ($conn->query($order_sql) === TRUE) {
$success = "Order added successfully!";
} else {
$error = "Error adding order: " . $conn->error;
}
} else {
$error = "Error adding customer: " . $conn->error;
}
} else {
$error = "Please fill in all required fields.";
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Add New Order - Kaak Alia Management System</title>
<link rel="stylesheet" href="../../public/bootstrap/css/bootstrap.min.css">
</head>
<body>
<?php include '../../includes/header.php'; ?>
<div class="container mt-4">
<h3>Add New Order</h3>
<?php if ($success): ?>
<div class="alert alert-success"><?= $success ?></div>
<?php endif; ?>
<?php if ($error): ?>
<div class="alert alert-danger"><?= $error ?></div>
<?php endif; ?>
<form method="POST" action="">
<h5>Customer Details</h5>
<div class="row">
<div class="col-md-4 mb-3">
<label>Name</label>
<input type="text" name="customer_name" class="form-control" required>
</div>
<div class="col-md-4 mb-3">
<label>Contact</label>
<input type="text" name="contact" class="form-control">
</div>
<div class="col-md-4 mb-3">
<label>Delivery Address</label>
<textarea name="delivery_address" class="form-control"></textarea>
</div>
</div>
<hr>
<h5>Order Details</h5>
<div class="row">
<div class="col-md-4 mb-3">
<label>Product</label>
<select name="product_id" class="form-control" required>
<option value="">Select Product</option>
<?php while($product = $products_result->fetch_assoc()): ?>
<option value="<?= $product['id'] ?>">
<?= htmlspecialchars($product['name'] . " - " . $product['size'] . " (" . $product['price'] . " KD)") ?>
</option>
<?php endwhile; ?>
</select>
</div>
<div class="col-md-2 mb-3">
<label>Quantity</label>
<input type="number" name="quantity" class="form-control" min="1" required>
</div>
<div class="col-md-6 mb-3">
<label>Packaging Preferences</label>
<input type="text" name="packaging_preferences" class="form-control">
</div>
</div>
<button type="submit" class="btn btn-primary">Add Order</button>
</form>
</div>
<?php include '../../includes/footer.php'; ?>
<script src="../../public/bootstrap/js/bootstrap.bundle.min.js"></script>
</body>
</html>
```
### View Orders
**File:** `public/orders/view_orders.php`
```php
<?php
// public/orders/view_orders.php
require_once '../../includes/auth.php';
require_once '../../includes/db_connect.php';
// Handle status update
if (isset($_GET['update_status'])) {
$order_id = intval($_GET['order_id']);
$new_status = $conn->real_escape_string($_GET['new_status']);
$update_sql = "UPDATE orders SET status='$new_status' WHERE id='$order_id'";
$conn->query($update_sql);
header("Location: view_orders.php");
exit();
}
// Fetch orders with customer and product details
$orders_sql = "SELECT orders.*, customers.name as customer_name, products.name as product_name, products.size as product_size
FROM orders
JOIN customers ON orders.customer_id = customers.id
JOIN products ON orders.product_id = products.id
ORDER BY orders.order_date DESC";
$orders_result = $conn->query($orders_sql);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>View Orders - Kaak Alia Management System</title>
<link rel="stylesheet" href="../../public/bootstrap/css/bootstrap.min.css">
</head>
<body>
<?php include '../../includes/header.php'; ?>
<div class="container mt-4">
<h3>Orders</h3>
<table class="table table-bordered table-striped mt-3">
<thead class="table-dark">
<tr>
<th>ID</th>
<th>Customer</th>
<th>Product</th>
<th>Size</th>
<th>Quantity</th>
<th>Packaging</th>
<th>Status</th>
<th>Order Date</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php if ($orders_result->num_rows > 0): ?>
<?php while($order = $orders_result->fetch_assoc()): ?>
<tr>
<td><?= $order['id'] ?></td>
<td><?= htmlspecialchars($order['customer_name']) ?></td>
<td><?= htmlspecialchars($order['product_name']) ?></td>
<td><?= htmlspecialchars($order['product_size']) ?></td>
<td><?= $order['quantity'] ?></td>
<td><?= htmlspecialchars($order['packaging_preferences']) ?></td>
<td>
<?= htmlspecialchars($order['status']) ?>
<!-- Optionally, add visual indicators or badges -->
</td>
<td><?= $order['order_date'] ?></td>
<td>
<a href="edit_order.php?id=<?= $order['id'] ?>" class="btn btn-sm btn-warning">Edit</a>
<!-- Dropdown to change status -->
<div class="btn-group">
<button type="button" class="btn btn-sm btn-info dropdown-toggle" data-bs-toggle="dropdown">
Change Status
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="?update_status=1&order_id=<?= $order['id'] ?>&new_status=Pending">Pending</a></li>
<li><a class="dropdown-item" href="?update_status=1&order_id=<?= $order['id'] ?>&new_status=In Progress">In Progress</a></li>
<li><a class="dropdown-item" href="?update_status=1&order_id=<?= $order['id'] ?>&new_status=Completed">Completed</a></li>
<li><a class="dropdown-item" href="?update_status=1&order_id=<?= $order['id'] ?>&new_status=Delivered">Delivered</a></li>
</ul>
</div>
</td>
</tr>
<?php endwhile; ?>
<?php else: ?>
<tr>
<td colspan="9" class="text-center">No orders found.</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
<?php include '../../includes/footer.php'; ?>
<script src="../../public/bootstrap/js/bootstrap.bundle.min.js"></script>
</body>
</html>
```
### Edit Order
**File:** `public/orders/edit_order.php`
```php
<?php
// public/orders/edit_order.php
require_once '../../includes/auth.php';
require_once '../../includes/db_connect.php';
$order_id = intval($_GET['id']);
$success = '';
$error = '';
// Fetch order details
$order_sql = "SELECT * FROM orders WHERE id = '$order_id' LIMIT 1";
$order_result = $conn->query($order_sql);
if ($order_result->num_rows != 1) {
header("Location: view_orders.php");
exit();
}
$order = $order_result->fetch_assoc();
// Handle form submission
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$product_id = intval($_POST['product_id']);
$quantity = intval($_POST['quantity']);
$packaging_preferences = $conn->real_escape_string($_POST['packaging_preferences']);
$status = $conn->real_escape_string($_POST['status']);
// Update order
$update_order_sql = "UPDATE orders
SET product_id='$product_id', quantity='$quantity',
packaging_preferences='$packaging_preferences', status='$status'
WHERE id='$order_id'";
if ($conn->query($update_order_sql) === TRUE) {
$success = "Order updated successfully!";
// Refresh order data
$order = $conn->query($order_sql)->fetch_assoc();
} else {
$error = "Error updating order: " . $conn->error;
}
}
// Fetch products for selection
$products_sql = "SELECT * FROM products ORDER BY name ASC";
$products_result = $conn->query($products_sql);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Edit Order - Kaak Alia Management System</title>
<link rel="stylesheet" href="../../public/bootstrap/css/bootstrap.min.css">
</head>
<body>
<?php include '../../includes/header.php'; ?>
<div class="container mt-4">
<h3>Edit Order #<?= $order_id ?></h3>
<?php if ($success): ?>
<div class="alert alert-success"><?= $success ?></div>
<?php endif; ?>
<?php if ($error): ?>
<div class="alert alert-danger"><?= $error ?></div>
<?php endif; ?>
<form method="POST" action="">
<div class="row">
<div class="col-md-4 mb-3">
<label>Product</label>
<select name="product_id" class="form-control" required>
<?php while($product = $products_result->fetch_assoc()): ?>
<option value="<?= $product['id'] ?>" <?= ($product['id'] == $order['product_id']) ? 'selected' : '' ?>>
<?= htmlspecialchars($product['name'] . " - " . $product['size'] . " (" . $product['price'] . " KD)") ?>
</option>
<?php endwhile; ?>
</select>
</div>
<div class="col-md-2 mb-3">
<label>Quantity</label>
<input type="number" name="quantity" class="form-control" min="1" value="<?= $order['quantity'] ?>" required>
</div>
<div class="col-md-6 mb-3">
<label>Packaging Preferences</label>
<input type="text" name="packaging_preferences" class="form-control" value="<?= htmlspecialchars($order['packaging_preferences']) ?>">
</div>
</div>
<div class="row">
<div class="col-md-4 mb-3">
<label>Status</label>
<select name="status" class="form-control" required>
<option value="Pending" <?= ($order['status'] == 'Pending') ? 'selected' : '' ?>>Pending</option>
<option value="In Progress" <?= ($order['status'] == 'In Progress') ? 'selected' : '' ?>>In Progress</option>
<option value="Completed" <?= ($order['status'] == 'Completed') ? 'selected' : '' ?>>Completed</option>
<option value="Delivered" <?= ($order['status'] == 'Delivered') ? 'selected' : '' ?>>Delivered</option>
</select>
</div>
</div>
<button type="submit" class="btn btn-primary">Update Order</button>
<a href="view_orders.php" class="btn btn-secondary">Cancel</a>
</form>
</div>
<?php include '../../includes/footer.php'; ?>
<script src="../../public/bootstrap/js/bootstrap.bundle.min.js"></script>
</body>
</html>
```
---
## Product Selection and Management
Allow administrators to manage products.
### Manage Products
**File:** `public/products/manage_products.php`
```php
<?php
// public/products/manage_products.php
require_once '../../includes/auth.php';
require_once '../../includes/db_connect.php';
$success = '';
$error = '';
// Handle Add/Edit/Delete actions
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (isset($_POST['add_product'])) {
// Add new product
$name = $conn->real_escape_string($_POST['name']);
$size = $conn->real_escape_string($_POST['size']);
$price = floatval($_POST['price']);
$category = $conn->real_escape_string($_POST['category']);
$add_sql = "INSERT INTO products (name, size, price, category)
VALUES ('$name', '$size', '$price', '$category')";
if ($conn->query($add_sql) === TRUE) {
$success = "Product added successfully!";
} else {
$error = "Error adding product: " . $conn->error;
}
}
elseif (isset($_POST['edit_product'])) {
// Edit existing product
$id = intval($_POST['id']);
$name = $conn->real_escape_string($_POST['name']);
$size = $conn->real_escape_string($_POST['size']);
$price = floatval($_POST['price']);
$category = $conn->real_escape_string($_POST['category']);
$edit_sql = "UPDATE products
SET name='$name', size='$size', price='$price', category='$category'
WHERE id='$id'";
if ($conn->query($edit_sql) === TRUE) {
$success = "Product updated successfully!";
} else {
$error = "Error updating product: " . $conn->error;
}
}
elseif (isset($_POST['delete_product'])) {
// Delete product
$id = intval($_POST['id']);
$delete_sql = "DELETE FROM products WHERE id='$id'";
if ($conn->query($delete_sql) === TRUE) {
$success = "Product deleted successfully!";
} else {
$error = "Error deleting product: " . $conn->error;
}
}
}
// Fetch all products
$products_sql = "SELECT * FROM products ORDER BY name ASC";
$products_result = $conn->query($products_sql);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Manage Products - Kaak Alia Management System</title>
<link rel="stylesheet" href="../../public/bootstrap/css/bootstrap.min.css">
</head>
<body>
<?php include '../../includes/header.php'; ?>
<div class="container mt-4">
<h3>Manage Products</h3>
<?php if ($success): ?>
<div class="alert alert-success"><?= $success ?></div>
<?php endif; ?>
<?php if ($error): ?>
<div class="alert alert-danger"><?= $error ?></div>
<?php endif; ?>
<!-- Add Product Form -->
<div class="card mb-4">
<div class="card-header">Add New Product</div>
<div class="card-body">
<form method="POST" action="">
<div class="row">
<div class="col-md-3 mb-3">
<label>Name</label>
<input type="text" name="name" class="form-control" required>
</div>
<div class="col-md-3 mb-3">
<label>Size</label>
<input type="text" name="size" class="form-control" required>
</div>
<div class="col-md-3 mb-3">
<label>Price (KD)</label>
<input type="number" name="price" class="form-control" step="0.01" required>
</div>
<div class="col-md-3 mb-3">
<label>Category</label>
<input type="text" name="category" class="form-control" required>
</div>
</div>
<button type="submit" name="add_product" class="btn btn-primary">Add Product</button>
</form>
</div>
</div>
<!-- Products List -->
<table class="table table-bordered table-striped">
<thead class="table-dark">
<tr>
<th>ID</th>
<th>Name</th>
<th>Size</th>
<th>Price (KD)</th>
<th>Category</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php if ($products_result->num_rows > 0): ?>
<?php while($product = $products_result->fetch_assoc()): ?>
<tr>
<td><?= $product['id'] ?></td>
<td><?= htmlspecialchars($product['name']) ?></td>
<td><?= htmlspecialchars($product['size']) ?></td>
<td><?= number_format($product['price'], 2) ?></td>
<td><?= htmlspecialchars($product['category']) ?></td>
<td>
<!-- Edit Button triggers modal -->
<button type="button" class="btn btn-sm btn-warning" data-bs-toggle="modal" data-bs-target="#editModal<?= $product['id'] ?>">
Edit
</button>
<!-- Delete Form -->
<form method="POST" action="" class="d-inline" onsubmit="return confirm('Are you sure you want to delete this product?');">
<input type="hidden" name="id" value="<?= $product['id'] ?>">
<button type="submit" name="delete_product" class="btn btn-sm btn-danger">Delete</button>
</form>
<!-- Edit Modal -->
<div class="modal fade" id="editModal<?= $product['id'] ?>" tabindex="-1" aria-labelledby="editModalLabel<?= $product['id'] ?>" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<form method="POST" action="">
<div class="modal-header">
<h5 class="modal-title" id="editModalLabel<?= $product['id'] ?>">Edit Product</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<input type="hidden" name="id" value="<?= $product['id'] ?>">
<div class="mb-3">
<label>Name</label>
<input type="text" name="name" class="form-control" value="<?= htmlspecialchars($product['name']) ?>" required>
</div>
<div class="mb-3">
<label>Size</label>
<input type="text" name="size" class="form-control" value="<?= htmlspecialchars($product['size']) ?>" required>
</div>
<div class="mb-3">
<label>Price (KD)</label>
<input type="number" name="price" class="form-control" step="0.01" value="<?= $product['price'] ?>" required>
</div>
<div class="mb-3">
<label>Category</label>
<input type="text" name="category" class="form-control" value="<?= htmlspecialchars($product['category']) ?>" required>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="submit" name="edit_product" class="btn btn-primary">Save Changes</button>
</div>
</form>
</div>
</div>
</div>
</td>
</tr>
<?php endwhile; ?>
<?php else: ?>
<tr>
<td colspan="6" class="text-center">No products found.</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
<?php include '../../includes/footer.php'; ?>
<script src="../../public/bootstrap/js/bootstrap.bundle.min.js"></script>
</body>
</html>
```
---
## User Management
Allow administrators to manage data-entry staff with role-based permissions.
### Manage Users
**File:** `public/users/manage_users.php`
```php
<?php
// public/users/manage_users.php
require_once '../../includes/auth.php';
require_once '../../includes/db_connect.php';
if ($_SESSION['role'] != 'admin') {
die("Access denied. Only admins can manage users.");
}
$success = '';
$error = '';
// Handle Add/Edit/Delete actions
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (isset($_POST['add_user'])) {
// Add new user
$username = $conn->real_escape_string($_POST['username']);
$password = password_hash($_POST['password'], PASSWORD_BCRYPT);
$role = $conn->real_escape_string($_POST['role']);
$add_sql = "INSERT INTO users (username, password, role)
VALUES ('$username', '$password', '$role')";
if ($conn->query($add_sql) === TRUE) {
$success = "User added successfully!";
} else {
$error = "Error adding user: " . $conn->error;
}
}
elseif (isset($_POST['edit_user'])) {
// Edit existing user
$id = intval($_POST['id']);
$username = $conn->real_escape_string($_POST['username']);
$role = $conn->real_escape_string($_POST['role']);
$password = $_POST['password'];
if ($password) {
$hashed_password = password_hash($password, PASSWORD_BCRYPT);
$edit_sql = "UPDATE users
SET username='$username', role='$role', password='$hashed_password'
WHERE id='$id'";
} else {
$edit_sql = "UPDATE users
SET username='$username', role='$role'
WHERE id='$id'";
}
if ($conn->query($edit_sql) === TRUE) {
$success = "User updated successfully!";
} else {
$error = "Error updating user: " . $conn->error;
}
}
elseif (isset($_POST['delete_user'])) {
// Delete user
$id = intval($_POST['id']);
// Prevent deleting self
if ($id == $_SESSION['user_id']) {
$error = "You cannot delete yourself.";
} else {
$delete_sql = "DELETE FROM users WHERE id='$id'";
if ($conn->query($delete_sql) === TRUE) {
$success = "User deleted successfully!";
} else {
$error = "Error deleting user: " . $conn->error;
}
}
}
}
// Fetch all users
$users_sql = "SELECT * FROM users ORDER BY username ASC";
$users_result = $conn->query($users_sql);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Manage Users - Kaak Alia Management System</title>
<link rel="stylesheet" href="../../public/bootstrap/css/bootstrap.min.css">
</head>
<body>
<?php include '../../includes/header.php'; ?>
<div class="container mt-4">
<h3>Manage Users</h3>
<?php if ($success): ?>
<div class="alert alert-success"><?= $success ?></div>
<?php endif; ?>
<?php if ($error): ?>
<div class="alert alert-danger"><?= $error ?></div>
<?php endif; ?>
<!-- Add User Form -->
<div class="card mb-4">
<div class="card-header">Add New User</div>
<div class="card-body">
<form method="POST" action="">
<div class="row">
<div class="col-md-4 mb-3">
<label>Username</label>
<input type="text" name="username" class="form-control" required>
</div>
<div class="col-md-4 mb-3">
<label>Password</label>
<input type="password" name="password" class="form-control" required>
</div>
<div class="col-md-4 mb-3">
<label>Role</label>
<select name="role" class="form-control" required>
<option value="staff">Staff</option>
<option value="admin">Admin</option>
</select>
</div>
</div>
<button type="submit" name="add_user" class="btn btn-primary">Add User</button>
</form>
</div>
</div>
<!-- Users List -->
<table class="table table-bordered table-striped">
<thead class="table-dark">
<tr>
<th>ID</th>
<th>Username</th>
<th>Role</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php if ($users_result->num_rows > 0): ?>
<?php while($user = $users_result->fetch_assoc()): ?>
<tr>
<td><?= $user['id'] ?></td>
<td><?= htmlspecialchars($user['username']) ?></td>
<td><?= htmlspecialchars($user['role']) ?></td>
<td>
<!-- Edit Button triggers modal -->
<button type="button" class="btn btn-sm btn-warning" data-bs-toggle="modal" data-bs-target="#editModal<?= $user['id'] ?>">
Edit
</button>
<!-- Delete Form -->
<form method="POST" action="" class="d-inline" onsubmit="return confirm('Are you sure you want to delete this user?');">
<input type="hidden" name="id" value="<?= $user['id'] ?>">
<button type="submit" name="delete_user" class="btn btn-sm btn-danger">Delete</button>
</form>
<!-- Edit Modal -->
<div class="modal fade" id="editModal<?= $user['id'] ?>" tabindex="-1" aria-labelledby="editModalLabel<?= $user['id'] ?>" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<form method="POST" action="">
<div class="modal-header">
<h5 class="modal-title" id="editModalLabel<?= $user['id'] ?>">Edit User</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<input type="hidden" name="id" value="<?= $user['id'] ?>">
<div class="mb-3">
<label>Username</label>
<input type="text" name="username" class="form-control" value="<?= htmlspecialchars($user['username']) ?>" required>
</div>
<div class="mb-3">
<label>Password (Leave blank to keep current password)</label>
<input type="password" name="password" class="form-control">
</div>
<div class="mb-3">
<label>Role</label>
<select name="role" class="form-control" required>
<option value="staff" <?= ($user['role'] == 'staff') ? 'selected' : '' ?>>Staff</option>
<option value="admin" <?= ($user['role'] == 'admin') ? 'selected' : '' ?>>Admin</option>
</select>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="submit" name="edit_user" class="btn btn-primary">Save Changes</button>
</div>
</form>
</div>
</div>
</div>
</td>
</tr>
<?php endwhile; ?>
<?php else: ?>
<tr>
<td colspan="4" class="text-center">No users found.</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
<?php include '../../includes/footer.php'; ?>
<script src="../../public/bootstrap/js/bootstrap.bundle.min.js"></script>
</body>
</html>
```
---
## Reporting
Implement reporting functionalities to view order history and export reports.
### Generate Reports
**File:** `public/reports/generate_reports.php`
```php
<?php
// public/reports/generate_reports.php
require_once '../../includes/auth.php';
require_once '../../includes/db_connect.php';
// Initialize filter variables
$filter_date = '';
$filter_status = '';
$conditions = [];
if ($_SERVER['REQUEST_METHOD'] == 'GET') {
if (!empty($_GET['filter_date'])) {
$filter_date = $conn->real_escape_string($_GET['filter_date']);
$conditions[] = "DATE(orders.order_date) = '$filter_date'";
}
if (!empty($_GET['filter_status'])) {
$filter_status = $conn->real_escape_string($_GET['filter_status']);
$conditions[] = "orders.status = '$filter_status'";
}
}
$where = '';
if (count($conditions) > 0) {
$where = "WHERE " . implode(" AND ", $conditions);
}
// Fetch orders based on filters
$orders_sql = "SELECT orders.*, customers.name as customer_name, products.name as product_name
FROM orders
JOIN customers ON orders.customer_id = customers.id
JOIN products ON orders.product_id = products.id
$where
ORDER BY orders.order_date DESC";
$orders_result = $conn->query($orders_sql);
// Handle Export to CSV
if (isset($_GET['export'])) {
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=orders_report.csv');
$output = fopen('php://output', 'w');
// Column headings
fputcsv($output, ['Order ID', 'Customer Name', 'Product', 'Quantity', 'Packaging Preferences', 'Status', 'Order Date']);
// Data rows
while ($row = $orders_result->fetch_assoc()) {
fputcsv($output, [
$row['id'],
$row['customer_name'],
$row['product_name'],
$row['quantity'],
$row['packaging_preferences'],
$row['status'],
$row['order_date']
]);
}
fclose($output);
exit();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Generate Reports - Kaak Alia Management System</title>
<link rel="stylesheet" href="../../public/bootstrap/css/bootstrap.min.css">
</head>
<body>
<?php include '../../includes/header.php'; ?>
<div class="container mt-4">
<h3>Generate Reports</h3>
<form method="GET" action="" class="row g-3">
<div class="col-md-4">
<label>Date</label>
<input type="date" name="filter_date" class="form-control" value="<?= htmlspecialchars($filter_date) ?>">
</div>
<div class="col-md-4">
<label>Status</label>
<select name="filter_status" class="form-control">
<option value="">All</option>
<option value="Pending" <?= ($filter_status == 'Pending') ? 'selected' : '' ?>>Pending</option>
<option value="In Progress" <?= ($filter_status == 'In Progress') ? 'selected' : '' ?>>In Progress</option>
<option value="Completed" <?= ($filter_status == 'Completed') ? 'selected' : '' ?>>Completed</option>
<option value="Delivered" <?= ($filter_status == 'Delivered') ? 'selected' : '' ?>>Delivered</option>
</select>
</div>
<div class="col-md-4 align-self-end">
<button type="submit" class="btn btn-primary">Filter</button>
<a href="generate_reports.php?export=1&filter_date=<?= $filter_date ?>&filter_status=<?= $filter_status ?>" class="btn btn-success">Export CSV</a>
</div>
</form>
<table class="table table-bordered table-striped mt-4">
<thead class="table-dark">
<tr>
<th>Order ID</th>
<th>Customer</th>
<th>Product</th>
<th>Quantity</th>
<th>Packaging</th>
<th>Status</th>
<th>Order Date</th>
</tr>
</thead>
<tbody>
<?php if ($orders_result->num_rows > 0): ?>
<?php while($order = $orders_result->fetch_assoc()): ?>
<tr>
<td><?= $order['id'] ?></td>
<td><?= htmlspecialchars($order['customer_name']) ?></td>
<td><?= htmlspecialchars($order['product_name']) ?></td>
<td><?= $order['quantity'] ?></td>
<td><?= htmlspecialchars($order['packaging_preferences']) ?></td>
<td><?= htmlspecialchars($order['status']) ?></td>
<td><?= $order['order_date'] ?></td>
</tr>
<?php endwhile; ?>
<?php else: ?>
<tr>
<td colspan="7" class="text-center">No orders found for the selected criteria.</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
<?php include '../../includes/footer.php'; ?>
<script src="../../public/bootstrap/js/bootstrap.bundle.min.js"></script>
</body>
</html>
```
---
## Security Measures
Implement basic security practices to secure your application.
1. **SQL Injection Prevention:**
- Use prepared statements or sanitize all user inputs using `$conn->real_escape_string()`.
2. **Session Management:**
- Use `session_start()` at the beginning of scripts that require authentication.
- Regenerate session IDs upon login to prevent session fixation.
3. **Password Hashing:**
- Store hashed passwords using `password_hash()`.
- Verify passwords using `password_verify()`.
4. **Access Control:**
- Restrict access to certain pages based on user roles (e.g., only admins can manage users).
5. **XSS Prevention:**
- Escape all output using `htmlspecialchars()` to prevent cross-site scripting.
6. **CSRF Protection:**
- Implement CSRF tokens in forms to prevent cross-site request forgery (Not implemented in the code above but recommended for production).
---
## Running the Application
1. **Start Your Server:**
- Ensure your local server (e.g., XAMPP) is running.
2. **Access the Application:**
- Navigate to `http://localhost/kaak_alia_management_system/public/login.php` in your browser.
3. **Login Credentials:**
- **Username:** `admin`
- **Password:** `admin123`
4. **Default Admin User:**
- The password is hashed in the SQL script. If you need to change it, you can update the `users` table with a new hashed password using PHP's `password_hash()` function.
5. **Navigate the Dashboard:**
- After logging in, you can access different sections such as Orders, Products, Users, and Reports.
---
## Additional Recommendations
1. **Enhance Security:**
- Implement HTTPS to encrypt data transmission.
- Use more robust authentication mechanisms (e.g., Two-Factor Authentication).
2. **Improve UI/UX:**
- Enhance the frontend with better styling and user-friendly interfaces.
- Implement AJAX for smoother interactions without full page reloads.
3. **Error Handling:**
- Implement proper error handling and logging mechanisms for debugging and maintenance.
4. **Backup and Recovery:**
- Regularly backup your database to prevent data loss.
5. **Scalability:**
- Consider using a PHP framework like Laravel for larger projects to facilitate better scalability and maintainability.
---
This guide provides a foundational structure for the Kaak Alia Management System. Depending on your specific needs, you may further customize and expand the functionalities. Ensure to thoroughly test each component and implement additional security measures as necessary before deploying the application in a production environment.