This commit is contained in:
Flatlogic Bot 2025-10-15 02:41:21 +00:00
parent ef71b241ae
commit ec17506c33
14 changed files with 385 additions and 30 deletions

134
admin/coupons.php Normal file
View File

@ -0,0 +1,134 @@
<?php
include 'header.php';
require_once '../db/config.php';
// Ensure user is admin
if (!isset($_SESSION['admin_logged_in']) || $_SESSION['admin_logged_in'] !== true) {
header('Location: login.php');
exit;
}
$pdo = db();
$feedback = [];
// Handle POST requests for creating or toggling coupons
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Create a new coupon
if (isset($_POST['create_coupon'])) {
$code = trim($_POST['code']);
$discount = trim($_POST['discount_percentage']);
if (!empty($code) && is_numeric($discount) && $discount > 0 && $discount <= 100) {
try {
$stmt = $pdo->prepare("INSERT INTO coupons (code, discount_percentage) VALUES (:code, :discount)");
$stmt->execute(['code' => $code, 'discount' => $discount]);
$feedback = ['type' => 'success', 'message' => 'Coupon created successfully.'];
} catch (PDOException $e) {
if ($e->getCode() == '23505') { // Unique violation
$feedback = ['type' => 'danger', 'message' => 'Error: Coupon code already exists.'];
} else {
$feedback = ['type' => 'danger', 'message' => 'Error creating coupon.'];
}
}
} else {
$feedback = ['type' => 'danger', 'message' => 'Invalid input. Please provide a valid code and a discount percentage between 0 and 100.'];
}
}
// Toggle coupon status
if (isset($_POST['toggle_status'])) {
$coupon_id = $_POST['coupon_id'];
$current_status = $_POST['current_status'];
$new_status = $current_status ? 'false' : 'true';
$stmt = $pdo->prepare("UPDATE coupons SET is_active = :status WHERE id = :id");
$stmt->execute(['status' => $new_status, 'id' => $coupon_id]);
$feedback = ['type' => 'success', 'message' => 'Coupon status updated.'];
}
}
// Fetch all coupons
$coupons = $pdo->query("SELECT * FROM coupons ORDER BY created_at DESC")->fetchAll();
?>
<div class="container mt-4">
<h2>Coupon Management</h2>
<?php if (!empty($feedback)): ?>
<div class="alert alert-<?php echo $feedback['type']; ?>" role="alert">
<?php echo htmlspecialchars($feedback['message']); ?>
</div>
<?php endif; ?>
<!-- Create Coupon Form -->
<div class="card mb-4">
<div class="card-header">Create New Coupon</div>
<div class="card-body">
<form action="coupons.php" method="POST">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="code">Coupon Code</label>
<input type="text" name="code" id="code" class="form-control" required>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label for="discount_percentage">Discount (%)</label>
<input type="number" name="discount_percentage" id="discount_percentage" class="form-control" step="0.01" min="0.01" max="100" required>
</div>
</div>
<div class="col-md-2 d-flex align-items-end">
<button type="submit" name="create_coupon" class="btn btn-primary w-100">Create</button>
</div>
</div>
</form>
</div>
</div>
<!-- Coupons Table -->
<div class="card">
<div class="card-header">Existing Coupons</div>
<div class="card-body">
<table class="table table-striped">
<thead>
<tr>
<th>Code</th>
<th>Discount</th>
<th>Status</th>
<th>Created At</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php foreach ($coupons as $coupon): ?>
<tr>
<td><?php echo htmlspecialchars($coupon['code']); ?></td>
<td><?php echo number_format($coupon['discount_percentage'], 2); ?>%</td>
<td>
<?php if ($coupon['is_active']): ?>
<span class="badge bg-success">Active</span>
<?php else: ?>
<span class="badge bg-secondary">Inactive</span>
<?php endif; ?>
</td>
<td><?php echo $coupon['created_at']; ?></td>
<td>
<form action="coupons.php" method="POST">
<input type="hidden" name="coupon_id" value="<?php echo $coupon['id']; ?>">
<input type="hidden" name="current_status" value="<?php echo $coupon['is_active']; ?>">
<button type="submit" name="toggle_status" class="btn btn-sm <?php echo $coupon['is_active'] ? 'btn-warning' : 'btn-success'; ?>">
<?php echo $coupon['is_active'] ? 'Deactivate' : 'Activate'; ?>
</button>
</form>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
<?php include 'footer.php'; ?>

View File

@ -17,7 +17,21 @@ if (!isset($_SESSION['admin_logged_in']) || $_SESSION['admin_logged_in'] !== tru
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="index.php">Admin Panel</a>
<div class="collapse navbar-collapse">
<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" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="index.php">Restaurants</a>
</li>
<li class="nav-item">
<a class="nav-link" href="orders.php">Orders</a>
</li>
<li class="nav-item">
<a class="nav-link" href="coupons.php">Coupons</a>
</li>
</ul>
<ul class="navbar-nav ms-auto">
<li class="nav-item">
<a class="nav-link" href="logout.php">Logout</a>

81
admin/orders.php Normal file
View File

@ -0,0 +1,81 @@
<?php
include 'header.php';
require_once '../db/config.php';
// Check if the user is logged in as an admin
if (!isset($_SESSION['admin_logged_in']) || $_SESSION['admin_logged_in'] !== true) {
header('Location: login.php');
exit;
}
$pdo = db();
// Handle status update
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['order_id']) && isset($_POST['status'])) {
$order_id = $_POST['order_id'];
$status = $_POST['status'];
$update_stmt = $pdo->prepare("UPDATE orders SET status = :status WHERE id = :order_id");
$update_stmt->execute(['status' => $status, 'order_id' => $order_id]);
// Redirect to the same page to prevent form resubmission
header('Location: orders.php');
exit;
}
// Fetch all orders with user information
$stmt = $pdo->query("
SELECT o.id, o.total_price, o.status, o.created_at, u.name as user_name
FROM orders o
JOIN users u ON o.user_id = u.id
ORDER BY o.created_at DESC
");
$orders = $stmt->fetchAll();
$possible_statuses = ['Pending', 'Confirmed', 'Preparing', 'Out for Delivery', 'Delivered', 'Cancelled'];
?>
<div class="container mt-4">
<h2>Order Management</h2>
<table class="table table-striped">
<thead>
<tr>
<th>Order ID</th>
<th>Customer</th>
<th>Total Price</th>
<th>Order Date</th>
<th>Status</th>
<th>Update Status</th>
</tr>
</thead>
<tbody>
<?php foreach ($orders as $order): ?>
<tr>
<td><?php echo $order['id']; ?></td>
<td><?php echo htmlspecialchars($order['user_name']); ?></td>
<td>$<?php echo number_format($order['total_price'], 2); ?></td>
<td><?php echo $order['created_at']; ?></td>
<td><?php echo htmlspecialchars($order['status']); ?></td>
<td>
<form action="orders.php" method="POST" class="form-inline">
<input type="hidden" name="order_id" value="<?php echo $order['id']; ?>">
<div class="form-group">
<select name="status" class="form-control form-control-sm">
<?php foreach ($possible_statuses as $status): ?>
<option value="<?php echo $status; ?>" <?php echo ($order['status'] === $status) ? 'selected' : ''; ?>>
<?php echo htmlspecialchars($status); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<button type="submit" class="btn btn-primary btn-sm ml-2">Update</button>
</form>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php include 'footer.php'; ?>

27
apply_coupon.php Normal file
View File

@ -0,0 +1,27 @@
<?php
session_start();
require_once 'db/config.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['coupon_code'])) {
$coupon_code = trim($_POST['coupon_code']);
$pdo = db();
$stmt = $pdo->prepare("SELECT * FROM coupons WHERE code = :code AND is_active = TRUE");
$stmt->execute(['code' => $coupon_code]);
$coupon = $stmt->fetch();
if ($coupon) {
$_SESSION['coupon'] = [
'id' => $coupon['id'],
'code' => $coupon['code'],
'discount_percentage' => $coupon['discount_percentage']
];
unset($_SESSION['coupon_error']);
} else {
$_SESSION['coupon_error'] = "Invalid or expired coupon code.";
unset($_SESSION['coupon']);
}
}
header('Location: cart.php');
exit;

View File

@ -26,6 +26,12 @@ include 'header.php';
<div class="container mt-5">
<h2 class="text-center mb-4">Your Shopping Cart</h2>
<?php if (isset($_SESSION['coupon_error'])): ?>
<div class="alert alert-danger" role="alert">
<?php echo $_SESSION['coupon_error']; unset($_SESSION['coupon_error']); ?>
</div>
<?php endif; ?>
<?php if (count($cartItems) > 0): ?>
<table class="table">
<thead>
@ -52,9 +58,34 @@ include 'header.php';
</tbody>
</table>
<div class="text-end">
<h4>Subtotal: $<?php echo number_format($totalPrice, 2); ?></h4>
<a href="checkout.php" class="btn btn-primary mt-3">Proceed to Checkout</a>
<div class="row mt-4">
<div class="col-md-6">
<form action="apply_coupon.php" method="POST">
<div class="input-group mb-3">
<input type="text" class="form-control" placeholder="Coupon Code" name="coupon_code" required>
<button class="btn btn-secondary" type="submit">Apply Coupon</button>
</div>
</form>
</div>
<div class="col-md-6 text-end">
<h4>Subtotal: $<?php echo number_format($totalPrice, 2); ?></h4>
<?php if (isset($_SESSION['coupon'])): ?>
<?php
$discount_percentage = $_SESSION['coupon']['discount_percentage'];
$discount_amount = ($totalPrice * $discount_percentage) / 100;
$discounted_total = $totalPrice - $discount_amount;
$_SESSION['discount_amount'] = $discount_amount;
$_SESSION['total_price'] = $discounted_total;
?>
<h5 class="text-success">Discount (<?php echo $discount_percentage; ?>%): -$<?php echo number_format($discount_amount, 2); ?></h5>
<h3>Total: $<?php echo number_format($discounted_total, 2); ?></h3>
<a href="remove_coupon.php" class="btn btn-danger btn-sm">Remove Coupon</a>
<?php else: ?>
<?php $_SESSION['total_price'] = $totalPrice; $_SESSION['discount_amount'] = 0; ?>
<h3>Total: $<?php echo number_format($totalPrice, 2); ?></h3>
<?php endif; ?>
<a href="checkout.php" class="btn btn-primary mt-3">Proceed to Checkout</a>
</div>
</div>
<?php else: ?>
<div class="text-center">

View File

@ -19,6 +19,12 @@ session_start();
<div class="address-container">
<span id="address-display">Enter delivery address</span>
</div>
<div class="search-container">
<form action="search.php" method="get">
<input type="text" name="query" placeholder="Search restaurants..." required>
<button type="submit">Search</button>
</form>
</div>
<div class="user-actions">
<?php
require_once 'db/config.php';

View File

@ -6,22 +6,21 @@
<h1>Order from Majuro's best</h1>
<form action="index.php" method="get" class="search-form">
<input type="text" name="search" class="search-bar" placeholder="Search restaurants..." value="<?= isset($_GET['search']) ? htmlspecialchars($_GET['search']) : '' ?>">
<button type="submit" class="search-button">Search</button>
</form>
<div class="cuisine-filters">
<a href="index.php<?= isset($_GET['search']) ? '?search=' . urlencode($_GET['search']) : '' ?>" class="cuisine-filter-link <?= !isset($_GET['cuisine']) || $_GET['cuisine'] == '' ? 'active' : '' ?>">All Cuisines</a>
<?php
require_once 'db/config.php';
$pdo = db();
$cuisine_stmt = $pdo->query("SELECT DISTINCT cuisine FROM restaurants ORDER BY cuisine");
$cuisines = $cuisine_stmt->fetchAll(PDO::FETCH_COLUMN);
$search_param = isset($_GET['search']) ? '&search=' . urlencode($_GET['search']) : '';
foreach ($cuisines as $cuisine):
?>
<select name="cuisine" class="cuisine-filter">
<option value="">All Cuisines</option>
<?php foreach ($cuisines as $cuisine): ?>
<option value="<?= htmlspecialchars($cuisine) ?>" <?= (isset($_GET['cuisine']) && $_GET['cuisine'] == $cuisine) ? 'selected' : '' ?>><?= htmlspecialchars($cuisine) ?></option>
<?php endforeach; ?>
</select>
<button type="submit" class="search-button">Filter</button>
</form>
<a href="index.php?cuisine=<?= htmlspecialchars($cuisine) ?><?= $search_param ?>" class="cuisine-filter-link <?= (isset($_GET['cuisine']) && $_GET['cuisine'] == $cuisine) ? 'active' : '' ?>"><?= htmlspecialchars($cuisine) ?></a>
<?php endforeach; ?>
</div>
</div>
</section>

View File

@ -0,0 +1 @@
ALTER TABLE orders ADD COLUMN status VARCHAR(50) NOT NULL DEFAULT 'Pending';

View File

@ -0,0 +1,7 @@
CREATE TABLE IF NOT EXISTS "coupons" (
"id" SERIAL PRIMARY KEY,
"code" VARCHAR(255) NOT NULL UNIQUE,
"discount_percentage" DECIMAL(5, 2) NOT NULL,
"is_active" BOOLEAN NOT NULL DEFAULT TRUE,
"created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

View File

@ -0,0 +1,4 @@
ALTER TABLE "orders"
ADD COLUMN "coupon_id" INT NULL,
ADD COLUMN "discount_amount" DECIMAL(10, 2) DEFAULT 0.00,
ADD CONSTRAINT "fk_coupon" FOREIGN KEY ("coupon_id") REFERENCES "coupons"("id");

View File

@ -34,14 +34,9 @@ try {
exit();
}
$total_price = 0;
$restaurant_id = null;
foreach ($cart_items as $item) {
$total_price += $item['price'] * $item['quantity'];
$restaurant_id = $item['restaurant_id']; // Assuming all items in cart are from the same restaurant
}
$delivery_fee = 5.00;
$total_price += $delivery_fee;
$total_price = $_SESSION['total_price'] ?? 0;
$discount_amount = $_SESSION['discount_amount'] ?? 0;
$coupon_id = $_SESSION['coupon']['id'] ?? null;
// Get delivery details stored in cart
$delivery_name = $cart_items[0]['delivery_name'];
@ -49,8 +44,8 @@ try {
$delivery_phone = $cart_items[0]['delivery_phone'];
// Create order
$stmt = $pdo->prepare("INSERT INTO orders (user_id, restaurant_id, total_price, status, stripe_session_id, delivery_name, delivery_address, delivery_phone) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->execute([$user_id, $restaurant_id, $total_price, 'paid', $stripe_session_id, $delivery_name, $delivery_address, $delivery_phone]);
$stmt = $pdo->prepare("INSERT INTO orders (user_id, restaurant_id, total_price, status, stripe_session_id, delivery_name, delivery_address, delivery_phone, coupon_id, discount_amount) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->execute([$user_id, $restaurant_id, $total_price, 'paid', $stripe_session_id, $delivery_name, $delivery_address, $delivery_phone, $coupon_id, $discount_amount]);
$order_id = $pdo->lastInsertId();
// Insert order items

View File

@ -66,22 +66,21 @@ if (isset($details->status) && $details->status == 'COMPLETED') {
exit();
}
$total_price = 0;
$total_price = $_SESSION['total_price'] ?? 0;
$discount_amount = $_SESSION['discount_amount'] ?? 0;
$coupon_id = $_SESSION['coupon']['id'] ?? null;
$restaurant_id = null;
foreach ($cart_items as $item) {
$total_price += $item['price'] * $item['quantity'];
$restaurant_id = $item['restaurant_id'];
}
$delivery_fee = 5.00;
$total_price += $delivery_fee;
$delivery_name = $_POST['name'];
$delivery_address = $_POST['address'];
$delivery_phone = $_POST['phone'];
// Create order
$stmt = $pdo->prepare("INSERT INTO orders (user_id, restaurant_id, total_price, status, stripe_session_id, delivery_name, delivery_address, delivery_phone) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->execute([$user_id, $restaurant_id, $total_price, 'paid', $orderID, $delivery_name, $delivery_address, $delivery_phone]);
$stmt = $pdo->prepare("INSERT INTO orders (user_id, restaurant_id, total_price, status, stripe_session_id, delivery_name, delivery_address, delivery_phone, coupon_id, discount_amount) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->execute([$user_id, $restaurant_id, $total_price, 'paid', $orderID, $delivery_name, $delivery_address, $delivery_phone, $coupon_id, $discount_amount]);
$order_id = $pdo->lastInsertId();
// Insert order items

9
remove_coupon.php Normal file
View File

@ -0,0 +1,9 @@
<?php
session_start();
unset($_SESSION['coupon']);
unset($_SESSION['coupon_error']);
unset($_SESSION['discount_amount']);
header('Location: cart.php');
exit;

48
search.php Normal file
View File

@ -0,0 +1,48 @@
<?php
require_once 'header.php';
require_once 'db/config.php';
$query = $_GET['query'] ?? '';
$db = db();
if ($query) {
$stmt = $db->prepare(
'SELECT r.*, COALESCE(AVG(ra.rating), 0) as rating, COUNT(ra.id) as rating_count '
. 'FROM restaurants r LEFT JOIN ratings ra ON r.id = ra.restaurant_id '
. 'WHERE r.name LIKE ? OR r.cuisine LIKE ? GROUP BY r.id'
);
$stmt->execute(['%' . $query . '%', '%' . $query . '%']);
$restaurants = $stmt->fetchAll();
} else {
$restaurants = [];
}
?>
<main class="container">
<h1 class="page-title">Search Results for "<?php echo htmlspecialchars($query); ?>"</h1>
<div class="restaurant-list">
<?php if (empty($restaurants)): ?>
<p>No restaurants found.</p>
<?php else: ?>
<?php foreach ($restaurants as $restaurant): ?>
<div class="restaurant-card">
<a href="menu.php?restaurant_id=<?php echo $restaurant['id']; ?>">
<img src="<?php echo htmlspecialchars($restaurant['image_url']); ?>" alt="<?php echo htmlspecialchars($restaurant['name']); ?>">
<div class="restaurant-info">
<h3><?php echo htmlspecialchars($restaurant['name']); ?></h3>
<p><?php echo htmlspecialchars($restaurant['cuisine']); ?></p>
<div class="rating">
<span> <?php echo number_format($restaurant['rating'], 1); ?></span>
<span>(<?php echo $restaurant['rating_count']; ?>)</span>
</div>
</div>
</a>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</main>
<?php require_once 'footer.php'; ?>